diff --git a/.clang-format b/.clang-format index 8d32bb250b42..9fdba8f2fda5 100644 --- a/.clang-format +++ b/.clang-format @@ -12,7 +12,7 @@ BasedOnStyle: WebKit Standard: Cpp11 -ColumnLimit: 0 +ColumnLimit: 120 # Disable reflow of qdoc comments: indentation rules are different. # Translation comments are also excluded @@ -61,3 +61,5 @@ ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCH MaxEmptyLinesToKeep: 2 KeepEmptyLinesAtTheStartOfBlocks: false +SpaceBeforeCpp11BracedList: false +Cpp11BracedListStyle: true diff --git a/.clang-tidy b/.clang-tidy index d24954c3916d..c064c54d8fbc 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -24,7 +24,7 @@ Checks: '-*, modernize-use-nodiscard, modernize-use-equals-default, modernize-use-noexcept, - modernize-user-override, + modernize-use-override, modernize-use-nullptr, modernize-use-transparent-functors, modernize-use-uncaught-exceptions, diff --git a/.drone.yml b/.drone.yml index e50ea03d9638..6e2eefe60281 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,17 +1,17 @@ kind: pipeline -name: qt-5.12 +name: qt-5.15 steps: - name: cmake - image: ghcr.io/nextcloud/continuous-integration-client:client-5.12-18 + image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 volumes: - name: build path: /drone/build commands: - cd /drone/build - - 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 ../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 - image: ghcr.io/nextcloud/continuous-integration-client:client-5.12-18 + image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 volumes: - name: build path: /drone/build @@ -19,7 +19,7 @@ steps: - cd /drone/build - make -j$(nproc) - name: test - image: ghcr.io/nextcloud/continuous-integration-client:client-5.12-18 + image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 volumes: - name: build path: /drone/build @@ -27,7 +27,7 @@ steps: - cd /drone/build - useradd -m -s /bin/bash test - chown -R test:test . - - su -c 'ASAN_OPTIONS=detect_leaks=0 ctest --output-on-failure' test + - su -c 'ASAN_OPTIONS=detect_leaks=0 xvfb-run ctest --output-on-failure' test volumes: - name: build @@ -43,27 +43,27 @@ trigger: --- kind: pipeline -name: qt-5.12-clang +name: qt-5.15-clang steps: - name: cmake - image: ghcr.io/nextcloud/continuous-integration-client:client-5.12-18 + image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 volumes: - name: build path: /drone/build commands: - cd /drone/build - - cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clazy -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DECM_ENABLE_SANITIZERS=address ../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 - image: ghcr.io/nextcloud/continuous-integration-client:client-5.12-18 + image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 volumes: - name: build path: /drone/build commands: - cd /drone/build - - ninja 2>1 | /drone/src/admin/linux/count_compiler_warnings.py /drone/src + - ninja - name: test - image: ghcr.io/nextcloud/continuous-integration-client:client-5.12-18 + image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 volumes: - name: build path: /drone/build @@ -71,9 +71,9 @@ steps: - cd /drone/build - useradd -m -s /bin/bash test - chown -R test:test . - - su -c 'ASAN_OPTIONS=detect_leaks=0 ctest --output-on-failure' test + - su -c 'ASAN_OPTIONS=detect_leaks=0 xvfb-run ctest --output-on-failure' test - name: clang-tidy - image: ghcr.io/nextcloud/continuous-integration-client:client-5.12-18 + image: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 volumes: - name: build path: /drone/build @@ -98,14 +98,14 @@ name: AppImage steps: - name: build - image: ghcr.io/nextcloud/continuous-integration-client-appimage:client-appimage-1 + image: ghcr.io/nextcloud/continuous-integration-client-appimage:client-appimage-3 environment: CI_UPLOAD_GIT_TOKEN: from_secret: CI_UPLOAD_GIT_TOKEN CI_UPLOAD_GIT_USERNAME: from_secret: CI_UPLOAD_GIT_USERNAME commands: - - /bin/bash -c "./admin/linux/build-appimage.sh" + - BUILDNR=$DRONE_BUILD_NUMBER VERSION_SUFFIX=$DRONE_PULL_REQUEST BUILD_UPDATER=ON DESKTOP_CLIENT_ROOT=$DRONE_WORKSPACE /bin/bash -c "./admin/linux/build-appimage.sh" - /bin/bash -c "./admin/linux/upload-appimage.sh" || echo "Upload failed, however this is an optional step." trigger: branch: diff --git a/.github/workflows/command-rebase.yml b/.github/workflows/command-rebase.yml index 1eea580d3394..c497cb38e2d5 100644 --- a/.github/workflows/command-rebase.yml +++ b/.github/workflows/command-rebase.yml @@ -3,25 +3,44 @@ # https://github.com/nextcloud/.github # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization +name: Rebase command + on: issue_comment: - types: [ created ] -name: Automatic Rebase + types: created jobs: rebase: - name: Rebase + runs-on: ubuntu-latest + # On pull requests and if the comment starts with `/rebase` if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/rebase') - runs-on: ubuntu-latest steps: + - name: Add reaction on start + uses: peter-evans/create-or-update-comment@v1 + with: + token: ${{ secrets.COMMAND_BOT_PAT }} + repository: ${{ github.event.repository.full_name }} + comment-id: ${{ github.event.comment.id }} + reaction-type: "+1" + - name: Checkout the latest code uses: actions/checkout@v2 with: fetch-depth: 0 - + token: ${{ secrets.COMMAND_BOT_PAT }} + - name: Automatic Rebase uses: cirrus-actions/rebase@1.5 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.COMMAND_BOT_PAT }} + + - name: Add reaction on failure + uses: peter-evans/create-or-update-comment@v1 + if: failure() + with: + token: ${{ secrets.COMMAND_BOT_PAT }} + repository: ${{ github.event.repository.full_name }} + comment-id: ${{ github.event.comment.id }} + reaction-type: "-1" diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml new file mode 100644 index 000000000000..4843f25b6a0b --- /dev/null +++ b/.github/workflows/sonarcloud.yml @@ -0,0 +1,50 @@ +name: SonarCloud analysis +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + name: Build + runs-on: ubuntu-latest + container: ghcr.io/nextcloud/continuous-integration-client:client-5.15-4 + env: + SONAR_SERVER_URL: "https://sonarcloud.io" + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Restore cache + uses: actions/cache@v2 + with: + path: /cache + key: ${{ runner.os }} + + - name: Run build-wrapper + run: | + mkdir build + cd build + cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DBUILD_COVERAGE=ON + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} make -j 2 + - name: Run tests + run: | + cd build + useradd -m -s /bin/bash test + chown -R test:test . + su -c 'xvfb-run ctest --output-on-failure --output-junit testResult.xml' test + - name: Generate coverage report + run: | + cd build + su -c 'ctest -T Coverage' test + - name: Run sonar-scanner + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + cp sonar-project.properties build + cd build + sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" diff --git a/.tx/nextcloud.client-desktop/bg_translation b/.tx/nextcloud.client-desktop/bg_translation index 0d42c09ec715..85e50ee51a42 100644 --- a/.tx/nextcloud.client-desktop/bg_translation +++ b/.tx/nextcloud.client-desktop/bg_translation @@ -22,5 +22,6 @@ Icon=@APPLICATION_EXECUTABLE@ # Translations Icon[bg_BG]=@APPLICATION_ICON_NAME@ +Name[bg_BG]=@APPLICATION_NAME@ десктоп клиент за синхронизиране Comment[bg_BG]=@APPLICATION_NAME@ десктоп клиент за синхронизиране GenericName[bg_BG]=Синхронизиране на папка diff --git a/.tx/nextcloud.client-desktop/en_GB_translation b/.tx/nextcloud.client-desktop/en_GB_translation index 90240242d353..0319e7b91a8e 100644 --- a/.tx/nextcloud.client-desktop/en_GB_translation +++ b/.tx/nextcloud.client-desktop/en_GB_translation @@ -22,5 +22,6 @@ Icon=@APPLICATION_EXECUTABLE@ # Translations Icon[en_GB]=@APPLICATION_ICON_NAME@ +Name[en_GB]=@APPLICATION_NAME@ Desktop Comment[en_GB]=@APPLICATION_NAME@ desktop synchronisation client GenericName[en_GB]=Folder Sync diff --git a/.tx/nextcloud.client-desktop/ru_translation b/.tx/nextcloud.client-desktop/ru_translation index dcc333ba5e48..80bdd78f2a73 100644 --- a/.tx/nextcloud.client-desktop/ru_translation +++ b/.tx/nextcloud.client-desktop/ru_translation @@ -22,5 +22,6 @@ Icon=@APPLICATION_EXECUTABLE@ # Translations Icon[ru]=@APPLICATION_ICON_NAME@ +Name[ru]=@APPLICATION_NAME@ Desktop Comment[ru]=Клиент синхронизации @APPLICATION_NAME@ для ПК GenericName[ru]=Синхронизация папок diff --git a/.tx/nextcloud.client-desktop/vi_translation b/.tx/nextcloud.client-desktop/vi_translation new file mode 100644 index 000000000000..7c740854fb1f --- /dev/null +++ b/.tx/nextcloud.client-desktop/vi_translation @@ -0,0 +1,27 @@ +[Desktop Entry] +Categories=Utility;X-SuSE-SyncUtility; +Type=Application +Exec=@APPLICATION_EXECUTABLE@ +Name=@APPLICATION_NAME@ Desktop +Comment=@APPLICATION_NAME@ desktop synchronization client +GenericName=Folder Sync +Icon=@APPLICATION_ICON_NAME@ +Keywords=@APPLICATION_NAME@;syncing;file;sharing; +X-GNOME-Autostart-Delay=3 +MimeType=application/vnd.@APPLICATION_EXECUTABLE@; +Actions=Quit; + +# Translations + + +[Desktop Action Quit] +Exec=@APPLICATION_EXECUTABLE@ --quit +Name=Quit @APPLICATION_NAME@ +Icon=@APPLICATION_EXECUTABLE@ + + +# Translations +Icon[vi]=@APPLICATION_ICON_NAME@ +Name[vi]=@APPLICATION_NAME@ Máy tính +Comment[vi]=Ứng dụng đồng bộ @APPLICATION_NAME@ cho máy tính +GenericName[vi]=Đồng bộ thư mục diff --git a/CMakeLists.txt b/CMakeLists.txt index ce4807428634..c73a620d1fda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,11 +42,14 @@ if(NOT CRASHREPORTER_EXECUTABLE) set(CRASHREPORTER_EXECUTABLE "${APPLICATION_EXECUTABLE}_crash_reporter") endif() -set(synclib_NAME "${APPLICATION_EXECUTABLE}sync") -set(csync_NAME "${APPLICATION_EXECUTABLE}_csync") - include(Warnings) +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + add_compile_options(-fdiagnostics-color=always) +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + add_compile_options(-fcolor-diagnostics) +endif() + include(${CMAKE_SOURCE_DIR}/VERSION.cmake) # For config.h include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) @@ -74,9 +77,9 @@ include(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA1) add_definitions( + -DQT_DISABLE_DEPRECATED_BEFORE=0x000000 -DQT_USE_QSTRINGBUILDER -DQT_MESSAGELOGCONTEXT #enable function name and line number in debug output - -DQT_DEPRECATED_WARNINGS ) # if we cannot get it from git, directly try .tag (packages) @@ -93,11 +96,7 @@ endif() message(STATUS "GIT_SHA1 ${GIT_SHA1}") set(SYSCONFDIR ${SYSCONF_INSTALL_DIR}) -set(DATADIR ${DATA_INSTALL_DIR}) -if(WIN32) -set(DATADIR "share") -endif(WIN32) -set(SHAREDIR ${DATADIR}) +set(SHAREDIR ${CMAKE_INSTALL_DATADIR}) ##### ## handle BUILD_OWNCLOUD_OSX_BUNDLE diff --git a/NEXTCLOUD.cmake b/NEXTCLOUD.cmake index 82f1bd4b7a5f..d34e682af89b 100644 --- a/NEXTCLOUD.cmake +++ b/NEXTCLOUD.cmake @@ -11,6 +11,8 @@ set( APPLICATION_SERVER_URL "" CACHE STRING "URL for the server to use. If enter set( APPLICATION_SERVER_URL_ENFORCE ON ) # If set and APPLICATION_SERVER_URL is defined, the server can only connect to the pre-defined URL set( APPLICATION_REV_DOMAIN "com.nextcloud.desktopclient" ) set( APPLICATION_VIRTUALFILE_SUFFIX "nextcloud" CACHE STRING "Virtual file suffix (not including the .)") +set( APPLICATION_OCSP_STAPLING_ENABLED OFF ) +set( APPLICATION_FORBID_BAD_SSL OFF ) set( LINUX_PACKAGE_SHORTNAME "nextcloud" ) set( LINUX_APPLICATION_ID "${APPLICATION_REV_DOMAIN}.${LINUX_PACKAGE_SHORTNAME}") @@ -32,6 +34,7 @@ option( BUILD_UPDATER "Build updater" OFF ) option( WITH_PROVIDERS "Build with providers list" ON ) +option( ENFORCE_VIRTUAL_FILES_SYNC_FOLDER "Enforce use of virtual files sync folder when available" OFF ) ## Theming options set(NEXTCLOUD_BACKGROUND_COLOR "#0082c9" CACHE STRING "Default Nextcloud background color") diff --git a/VERSION.cmake b/VERSION.cmake index c6f3658b06f4..8338cb3bc7fd 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -1,11 +1,11 @@ set( MIRALL_VERSION_MAJOR 3 ) set( MIRALL_VERSION_MINOR 3 ) -set( MIRALL_VERSION_PATCH 50 ) +set( MIRALL_VERSION_PATCH 81 ) set( MIRALL_VERSION_YEAR 2021 ) set( MIRALL_SOVERSION 0 ) # Minimum supported server version according to https://docs.nextcloud.com/server/latest/admin_manual/release_schedule.html -set(NEXTCLOUD_SERVER_VERSION_MIN_SUPPORTED_MAJOR 20) +set(NEXTCLOUD_SERVER_VERSION_MIN_SUPPORTED_MAJOR 16) set(NEXTCLOUD_SERVER_VERSION_MIN_SUPPORTED_MINOR 0) set(NEXTCLOUD_SERVER_VERSION_MIN_SUPPORTED_PATCH 0) diff --git a/admin/linux/build-appimage.sh b/admin/linux/build-appimage.sh index 52c7ba406a6b..e88577b5a0b6 100755 --- a/admin/linux/build-appimage.sh +++ b/admin/linux/build-appimage.sh @@ -2,78 +2,88 @@ set -xe -mkdir /app -mkdir /build +export APPNAME=${APPNAME:-nextcloud} +export BUILD_UPDATER=${BUILD_UPDATER:-OFF} +export BUILDNR=${BUILDNR:-0000} +export DESKTOP_CLIENT_ROOT=${DESKTOP_CLIENT_ROOT:-/home/user} + +#Set Qt-5.15 +export QT_BASE_DIR=/opt/qt5.15 -#Set Qt-5.12 -export QT_BASE_DIR=/opt/qt5.12.10 export QTDIR=$QT_BASE_DIR export PATH=$QT_BASE_DIR/bin:$PATH export LD_LIBRARY_PATH=$QT_BASE_DIR/lib/x86_64-linux-gnu:$QT_BASE_DIR/lib:$LD_LIBRARY_PATH export PKG_CONFIG_PATH=$QT_BASE_DIR/lib/pkgconfig:$PKG_CONFIG_PATH -#Set APPID for .desktop file processing -export LINUX_APPLICATION_ID=com.nextcloud.desktopclient.nextcloud - -#set defaults +# Set defaults export SUFFIX=${DRONE_PULL_REQUEST:=master} if [ $SUFFIX != "master" ]; then SUFFIX="PR-$SUFFIX" fi +if [ "$BUILD_UPDATER" != "OFF" ]; then + BUILD_UPDATER=ON +fi + +mkdir /app -#QtKeyChain v0.10.0 -cd /build +# QtKeyChain git clone https://github.com/frankosterfeld/qtkeychain.git cd qtkeychain git checkout v0.10.0 mkdir build cd build -cmake -D CMAKE_INSTALL_PREFIX=/usr ../ -make -j4 -make install +cmake -G Ninja -D CMAKE_INSTALL_PREFIX=/app/usr .. +cmake --build . --target all +cmake --build . --target install + -#Build client -cd /build +# Build client mkdir build-client cd build-client -cmake -D CMAKE_INSTALL_PREFIX=/usr \ +cmake \ + -G Ninja \ + -D CMAKE_INSTALL_PREFIX=/app/usr \ -D BUILD_TESTING=OFF \ - -D BUILD_UPDATER=ON \ - -DMIRALL_VERSION_SUFFIX=PR-$DRONE_PULL_REQUEST \ - -DMIRALL_VERSION_BUILD=$DRONE_BUILD_NUMBER \ - $DRONE_WORKSPACE -make -j4 -make DESTDIR=/app install + -D BUILD_UPDATER=$BUILD_UPDATER \ + -D MIRALL_VERSION_BUILD=$BUILDNR \ + -D MIRALL_VERSION_SUFFIX="$VERSION_SUFFIX" \ + ${DESKTOP_CLIENT_ROOT} +cmake --build . --target all +cmake --build . --target install # Move stuff around cd /app -mv ./usr/lib/x86_64-linux-gnu/* ./usr/lib/ -rm -rf ./usr/lib/cmake -rm -rf ./usr/include -rm -rf ./usr/mkspecs -rm -rf ./usr/lib/x86_64-linux-gnu/ +mv usr/lib/x86_64-linux-gnu/* usr/lib/ + +mkdir usr/plugins +mv usr/lib/${APPNAME}sync_vfs_suffix.so usr/plugins +mv usr/lib/${APPNAME}sync_vfs_xattr.so usr/plugins -# Don't bundle nextcloudcmd as we don't run it anyway -rm -rf ./usr/bin/nextcloudcmd + +rm -rf usr/lib/cmake +rm -rf usr/include +rm -rf usr/mkspecs +rm -rf usr/lib/x86_64-linux-gnu/ # Don't bundle the explorer extentions as we can't do anything with them in the AppImage -rm -rf ./usr/share/caja-python/ -rm -rf ./usr/share/nautilus-python/ -rm -rf ./usr/share/nemo-python/ +rm -rf usr/share/caja-python/ +rm -rf usr/share/nautilus-python/ +rm -rf usr/share/nemo-python/ # Move sync exclude to right location -mv ./etc/Nextcloud/sync-exclude.lst ./usr/bin/ -rm -rf ./etc +mv usr/etc/*/sync-exclude.lst usr/bin/ +rm -rf etc -DESKTOP_FILE=/app/usr/share/applications/${LINUX_APPLICATION_ID}.desktop +# com.nextcloud.desktopclient.nextcloud.desktop +DESKTOP_FILE=$(ls /app/usr/share/applications/*.desktop) sed -i -e 's|Icon=nextcloud|Icon=Nextcloud|g' ${DESKTOP_FILE} # Bug in desktop file? cp ./usr/share/icons/hicolor/512x512/apps/Nextcloud.png . # Workaround for linuxeployqt bug, FIXME # Because distros need to get their shit together -cp -R /lib/x86_64-linux-gnu/libssl.so* ./usr/lib/ -cp -R /lib/x86_64-linux-gnu/libcrypto.so* ./usr/lib/ +cp -R /usr/lib/x86_64-linux-gnu/libssl.so* ./usr/lib/ +cp -R /usr/lib/x86_64-linux-gnu/libcrypto.so* ./usr/lib/ cp -P /usr/local/lib/libssl.so* ./usr/lib/ cp -P /usr/local/lib/libcrypto.so* ./usr/lib/ @@ -81,19 +91,23 @@ cp -P /usr/local/lib/libcrypto.so* ./usr/lib/ cp -P -r /usr/lib/x86_64-linux-gnu/nss ./usr/lib/ # Use linuxdeployqt to deploy -cd /build -wget --ca-directory=/etc/ssl/certs/ -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" +wget --ca-directory=/etc/ssl/certs -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" chmod a+x linuxdeployqt*.AppImage ./linuxdeployqt-continuous-x86_64.AppImage --appimage-extract rm ./linuxdeployqt-continuous-x86_64.AppImage unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH export LD_LIBRARY_PATH=/app/usr/lib/ -./squashfs-root/AppRun ${DESKTOP_FILE} -bundle-non-qt-libs -qmldir=$DRONE_WORKSPACE/src/gui +./squashfs-root/AppRun ${DESKTOP_FILE} -bundle-non-qt-libs -qmldir=${DESKTOP_CLIENT_ROOT}/src/gui # Set origin -./squashfs-root/usr/bin/patchelf --set-rpath '$ORIGIN/' /app/usr/lib/libnextcloudsync.so.0 +./squashfs-root/usr/bin/patchelf --set-rpath '$ORIGIN/' /app/usr/lib/lib${APPNAME}sync.so.0 # Build AppImage -./squashfs-root/AppRun ${DESKTOP_FILE} -appimage +./squashfs-root/AppRun ${DESKTOP_FILE} -appimage -updateinformation="gh-releases-zsync|nextcloud-releases|desktop|latest|Nextcloud-*-x86_64.AppImage.zsync" -mv Nextcloud*.AppImage Nextcloud-${SUFFIX}-${DRONE_COMMIT}-x86_64.AppImage +#move AppImage +if [ ! -z "$DRONE_COMMIT" ] +then + mv Nextcloud*.AppImage Nextcloud-${SUFFIX}-${DRONE_COMMIT}-x86_64.AppImage +fi +mv *.AppImage ${DESKTOP_CLIENT_ROOT}/ diff --git a/admin/linux/count_compiler_warnings.py b/admin/linux/count_compiler_warnings.py deleted file mode 100755 index c31be25a6b62..000000000000 --- a/admin/linux/count_compiler_warnings.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -# Small script that counts the warnings which the compiler emits -# and takes care that not more warnings are added. - -import sys -import re -import requests - - -if len(sys.argv) != 2: - print(f"Usage: {sys.argv[0]} REPOSITORY_PATH") - sys.exit(1) - -repository_path = sys.argv[1] -warning_regex = re.compile(r'warning:', re.M) -max_allowed_warnings_count_response = requests.get( - "https://nextclouddesktopwarningscount.felixweilbach.de") - -if max_allowed_warnings_count_response.status_code != 200: - print('Can not get maximum number of allowed warnings') - sys.exit(1) - -max_allowed_warnings_count = int(max_allowed_warnings_count_response.content) - -print("Max number of allowed warnings:", max_allowed_warnings_count) - -warnings_count = 0 - -for line in sys.stdin: - if warning_regex.findall(line): - warnings_count += 1 - - print(line, end="") - - if warnings_count > max_allowed_warnings_count: - print("Error: Too many warnings! You probably introduced a new warning!") - sys.exit(1) - -print("Total number of warnings:", warnings_count) diff --git a/admin/linux/upload-appimage.sh b/admin/linux/upload-appimage.sh index 97f3ac95dfbf..db36e845438d 100755 --- a/admin/linux/upload-appimage.sh +++ b/admin/linux/upload-appimage.sh @@ -24,6 +24,7 @@ cd /build # AppImage export APPIMAGE=$(readlink -f ./Nextcloud*.AppImage) +export UPDATE=$(readlink -f ./Nextcloud*.AppImage.zsync) export BASENAME=$(basename ${APPIMAGE}) if ! test -e $APPIMAGE ; then @@ -70,6 +71,7 @@ upload_release_asset() { uploadUrl=$1 echo $(curl --max-time 900 -u $GIT_USERNAME:$GIT_TOKEN -X POST $uploadUrl --header "Content-Type: application/octet-stream" --upload-file $APPIMAGE) + echo $(curl --max-time 900 -u $GIT_USERNAME:$GIT_TOKEN -X POST $uploadUrl --header "Content-Type: application/octet-stream" --upload-file $UPDATE) } delete_release_asset() @@ -132,4 +134,4 @@ if [ $TAG_NAME != "master" ]; then fi echo -echo "AppImage link: $browserDownloadUrl" \ No newline at end of file +echo "AppImage link: $browserDownloadUrl" diff --git a/admin/osx/CMakeLists.txt b/admin/osx/CMakeLists.txt index ba818684f863..226d7d4eeefd 100644 --- a/admin/osx/CMakeLists.txt +++ b/admin/osx/CMakeLists.txt @@ -9,7 +9,7 @@ else() set(MAC_INSTALLER_DO_CUSTOM_BACKGROUND "0") endif() -find_package(Qt5 5.12 COMPONENTS Core REQUIRED) +find_package(Qt5 5.15 COMPONENTS Core REQUIRED) configure_file(create_mac.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/create_mac.sh) configure_file(macosx.pkgproj.cmake ${CMAKE_CURRENT_BINARY_DIR}/macosx.pkgproj) configure_file(pre_install.sh.cmake ${CMAKE_CURRENT_BINARY_DIR}/pre_install.sh) diff --git a/admin/osx/macosx.pkgproj.cmake b/admin/osx/macosx.pkgproj.cmake index 50d33831023b..401326e39f6c 100644 --- a/admin/osx/macosx.pkgproj.cmake +++ b/admin/osx/macosx.pkgproj.cmake @@ -695,7 +695,12 @@ PROJECT_SETTINGS ADVANCED_OPTIONS - + + installer-script.options:hostArchitectures + + x86_64,arm64 + + BUILD_FORMAT 0 BUILD_PATH diff --git a/admin/osx/make_universal.py b/admin/osx/make_universal.py new file mode 100755 index 000000000000..abc6e671fbc7 --- /dev/null +++ b/admin/osx/make_universal.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +import sys +import os +import subprocess + + +# A general note: We first produce a x86_64 and a arm64 app package +# and then merge them together instead of compiling the desktop client +# with the CMake option CMAKE_OSX_ARCHITECTURES="x86_64;arm64" because +# macdeployqt can not handle universal binaries well. In the future +# with Qt6 this might change and this script will become obsolete. + + +def usage(program_name): + print("Creates a universal app package from a x86_64 and a arm64 app package.") + print("Usage: {} x86_64_app_file arm64_app_file output_directory".format(program_name)) + print("Example: {} some_dir/Nextcloud.app some_other_dir/Nextcloud.app output_dir".format(program_name)) + + +def execute(command): + return subprocess.check_output(command) + + +def path_relative_to_package(app_package_file_path, file_path): + if file_path.startswith(app_package_file_path): + relative_path = file_path[len(app_package_file_path):] + if relative_path.startswith("/"): + return relative_path[1:] + return relative_path + return file_path + + +def is_executable(file_path): + output = str(execute(["file", file_path])) + if (("Mach-O 64-bit dynamically linked shared library" in output) + or ("Mach-O 64-bit executable" in output)): + return True + return False + + +if __name__ == "__main__": + if len(sys.argv) != 4: + usage(sys.argv[0]) + sys.exit(1) + + x86_64_app_file = sys.argv[1] + if not os.path.exists(x86_64_app_file): + print("Can't create universal: Path {} already exists".format(x86_64_app_file)) + sys.exit(1) + arm64_app_file = sys.argv[2] + if not os.path.exists(arm64_app_file): + print("Can't create universal: Path {} already exists".format(arm64_app_file)) + sys.exit(1) + output_dir = sys.argv[3] + + # Copy the Arm64 variant to the output location if possible + if not os.path.exists(output_dir): + os.makedirs(output_dir) + app_file_name = os.path.basename(arm64_app_file) + universal_app_file = os.path.join(output_dir, app_file_name) + if os.path.exists(universal_app_file): + print("Can't create universal: Path {} already exists".format(universal_app_file)) + sys.exit(1) + + execute(["cp", "-a", arm64_app_file, output_dir]) + + # Now walk through the copied arm64 version and replace the binaries + for root, dirs, files in os.walk(universal_app_file): + for f in files: + absoulte_file_path = os.path.join(root, f) + root_relative = path_relative_to_package(universal_app_file, root) + x86_64_absolute_path = os.path.join(x86_64_app_file, root_relative, f) + arm64_absolute_path = os.path.join(arm64_app_file, root_relative, f) + if os.path.islink(absoulte_file_path) or not is_executable(absoulte_file_path): + continue + try: + execute(["lipo", "-create", "-output", absoulte_file_path, arm64_absolute_path, x86_64_absolute_path]) + except: + print("Could not merge {} with {} into {}!".format(arm64_absolute_path, x86_64_absolute_path, absoulte_file_path)) + + print("Finished :)") diff --git a/admin/osx/post_install.sh.cmake b/admin/osx/post_install.sh.cmake index 55d5e1c1d0e2..583f5e9cba59 100644 --- a/admin/osx/post_install.sh.cmake +++ b/admin/osx/post_install.sh.cmake @@ -3,7 +3,7 @@ # Always enable the new 10.10 finder plugin if available if [ -x "$(command -v pluginkit)" ]; then # add it to DB. This happens automatically too but we try to push it a bit harder for issue #3463 - pluginkit -a "/Applications/@APPLICATION_EXECUTABLE@.app/Contents/PlugIns/FinderSyncExt.appex/" + pluginkit -a "/Applications/@APPLICATION_NAME@.app/Contents/PlugIns/FinderSyncExt.appex/" # Since El Capitan we need to sleep #4650 sleep 10s # enable it diff --git a/admin/osx/pre_install.sh.cmake b/admin/osx/pre_install.sh.cmake index cd909e29ad1e..dededc67d4de 100644 --- a/admin/osx/pre_install.sh.cmake +++ b/admin/osx/pre_install.sh.cmake @@ -2,5 +2,6 @@ # kill the old version. see issue #2044 killall @APPLICATION_EXECUTABLE@ +killall @APPLICATION_NAME@ exit 0 diff --git a/cmake/modules/GNUInstallDirs.cmake b/cmake/modules/GNUInstallDirs.cmake deleted file mode 100644 index 5249477cb0dd..000000000000 --- a/cmake/modules/GNUInstallDirs.cmake +++ /dev/null @@ -1,253 +0,0 @@ -#.rst: -# GNUInstallDirs -# -------------- -# -# Define GNU standard installation directories -# -# Provides install directory variables as defined for GNU software: -# -# :: -# -# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html -# -# Inclusion of this module defines the following variables: -# -# :: -# -# CMAKE_INSTALL_ - destination for files of a given type -# CMAKE_INSTALL_FULL_ - corresponding absolute path -# -# where is one of: -# -# :: -# -# BINDIR - user executables (bin) -# SBINDIR - system admin executables (sbin) -# LIBEXECDIR - program executables (libexec) -# SYSCONFDIR - read-only single-machine data (etc) -# SHAREDSTATEDIR - modifiable architecture-independent data (com) -# LOCALSTATEDIR - modifiable single-machine data (var) -# LIBDIR - object code libraries (lib or lib64 or lib/ on Debian) -# INCLUDEDIR - C header files (include) -# OLDINCLUDEDIR - C header files for non-gcc (/usr/include) -# DATAROOTDIR - read-only architecture-independent data root (share) -# DATADIR - read-only architecture-independent data (DATAROOTDIR) -# INFODIR - info documentation (DATAROOTDIR/info) -# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale) -# MANDIR - man documentation (DATAROOTDIR/man) -# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME) -# -# Each CMAKE_INSTALL_ value may be passed to the DESTINATION -# options of install() commands for the corresponding file type. If the -# includer does not define a value the above-shown default will be used -# and the value will appear in the cache for editing by the user. Each -# CMAKE_INSTALL_FULL_ value contains an absolute path constructed -# from the corresponding destination by prepending (if necessary) the -# value of CMAKE_INSTALL_PREFIX. - -#============================================================================= -# Copyright 2011 Nikita Krupen'ko -# Copyright 2011 Kitware, Inc. -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -# Installation directories -# -if(NOT DEFINED CMAKE_INSTALL_BINDIR) - set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)") -endif() - -if(NOT DEFINED CMAKE_INSTALL_SBINDIR) - set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)") -endif() - -if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR) - set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)") -endif() - -if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR) - set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)") -endif() - -if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR) - set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)") -endif() - -if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR) - set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)") -endif() - -# We check if the variable was manually set and not cached, in order to -# allow projects to set the values as normal variables before including -# GNUInstallDirs to avoid having the entries cached or user-editable. It -# replaces the "if(NOT DEFINED CMAKE_INSTALL_XXX)" checks in all the -# other cases. -# If CMAKE_INSTALL_LIBDIR is defined, if _libdir_set is false, then the -# variable is a normal one, otherwise it is a cache one. -get_property(_libdir_set CACHE CMAKE_INSTALL_LIBDIR PROPERTY TYPE SET) -if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set - AND DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX - AND NOT "${_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX}" STREQUAL "${CMAKE_INSTALL_PREFIX}")) - # If CMAKE_INSTALL_LIBDIR is not defined, it is always executed. - # Otherwise: - # * if _libdir_set is false it is not executed (meaning that it is - # not a cache variable) - # * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is not defined it is - # not executed - # * if _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX and - # CMAKE_INSTALL_PREFIX are the same string it is not executed. - # _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX is updated after the - # execution, of this part of code, therefore at the next inclusion - # of the file, CMAKE_INSTALL_LIBDIR is defined, and the 2 strings - # are equal, meaning that the if is not executed the code the - # second time. - - set(_LIBDIR_DEFAULT "lib") - # Override this default 'lib' with 'lib64' iff: - # - we are on Linux system but NOT cross-compiling - # - we are NOT on debian - # - we are on a 64 bits system - # reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf - # For Debian with multiarch, use 'lib/${CMAKE_LIBRARY_ARCHITECTURE}' if - # CMAKE_LIBRARY_ARCHITECTURE is set (which contains e.g. "i386-linux-gnu" - # and CMAKE_INSTALL_PREFIX is "/usr" - # See http://wiki.debian.org/Multiarch - if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX) - set(__LAST_LIBDIR_DEFAULT "lib") - # __LAST_LIBDIR_DEFAULT is the default value that we compute from - # _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX, not a cache entry for - # the value that was last used as the default. - # This value is used to figure out whether the user changed the - # CMAKE_INSTALL_LIBDIR value manually, or if the value was the - # default one. When CMAKE_INSTALL_PREFIX changes, the value is - # updated to the new default, unless the user explicitly changed it. - endif() - if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$" - AND NOT CMAKE_CROSSCOMPILING) - if (EXISTS "/etc/debian_version") # is this a debian system ? - if(CMAKE_LIBRARY_ARCHITECTURE) - set(_LIBDIR_DEFAULT "lib/${CMAKE_LIBRARY_ARCHITECTURE}") - endif() - else() # not debian, rely on CMAKE_SIZEOF_VOID_P: - if(NOT DEFINED CMAKE_SIZEOF_VOID_P) - message(AUTHOR_WARNING - "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. " - "Please enable at least one language before including GNUInstallDirs.") - else() - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(_LIBDIR_DEFAULT "lib64") - if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX) - set(__LAST_LIBDIR_DEFAULT "lib64") - endif() - endif() - endif() - endif() - endif() - if(NOT DEFINED CMAKE_INSTALL_LIBDIR) - set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})") - elseif(DEFINED __LAST_LIBDIR_DEFAULT - AND "${__LAST_LIBDIR_DEFAULT}" STREQUAL "${CMAKE_INSTALL_LIBDIR}") - set_property(CACHE CMAKE_INSTALL_LIBDIR PROPERTY VALUE "${_LIBDIR_DEFAULT}") - endif() -endif() -# Save for next run -set(_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE INTERNAL "CMAKE_INSTALL_PREFIX during last run") -unset(_libdir_set) -unset(__LAST_LIBDIR_DEFAULT) - - -if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR) - set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)") -endif() - -if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR) - set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)") -endif() - -if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR) - set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)") -endif() - -#----------------------------------------------------------------------------- -# Values whose defaults are relative to DATAROOTDIR. Store empty values in -# the cache and store the defaults in local variables if the cache values are -# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes. - -if(NOT CMAKE_INSTALL_DATADIR) - set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)") - set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}") -endif() - -if(NOT CMAKE_INSTALL_INFODIR) - set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)") - set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info") -endif() - -if(NOT CMAKE_INSTALL_LOCALEDIR) - set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)") - set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale") -endif() - -if(NOT CMAKE_INSTALL_MANDIR) - set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)") - set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man") -endif() - -if(NOT CMAKE_INSTALL_DOCDIR) - set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)") - set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}") -endif() - -#----------------------------------------------------------------------------- - -mark_as_advanced( - CMAKE_INSTALL_BINDIR - CMAKE_INSTALL_SBINDIR - CMAKE_INSTALL_LIBEXECDIR - CMAKE_INSTALL_SYSCONFDIR - CMAKE_INSTALL_SHAREDSTATEDIR - CMAKE_INSTALL_LOCALSTATEDIR - CMAKE_INSTALL_LIBDIR - CMAKE_INSTALL_INCLUDEDIR - CMAKE_INSTALL_OLDINCLUDEDIR - CMAKE_INSTALL_DATAROOTDIR - CMAKE_INSTALL_DATADIR - CMAKE_INSTALL_INFODIR - CMAKE_INSTALL_LOCALEDIR - CMAKE_INSTALL_MANDIR - CMAKE_INSTALL_DOCDIR - ) - -# Result directories -# -foreach(dir - BINDIR - SBINDIR - LIBEXECDIR - SYSCONFDIR - SHAREDSTATEDIR - LOCALSTATEDIR - LIBDIR - INCLUDEDIR - OLDINCLUDEDIR - DATAROOTDIR - DATADIR - INFODIR - LOCALEDIR - MANDIR - DOCDIR - ) - if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}}) - set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}") - else() - set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}") - endif() -endforeach() diff --git a/cmake/modules/Warnings.cmake b/cmake/modules/Warnings.cmake index 7b38e0329187..ccac090e562a 100644 --- a/cmake/modules/Warnings.cmake +++ b/cmake/modules/Warnings.cmake @@ -27,7 +27,4 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") endif() - if(DEFINED MIRALL_FATAL_WARNINGS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") - endif(DEFINED MIRALL_FATAL_WARNINGS) endif() diff --git a/config.h.in b/config.h.in index 13d4cdf08c3a..e9eff6c92962 100644 --- a/config.h.in +++ b/config.h.in @@ -29,7 +29,10 @@ #cmakedefine APPLICATION_WIZARD_HEADER_TITLE_COLOR "@APPLICATION_WIZARD_HEADER_TITLE_COLOR@" #cmakedefine APPLICATION_WIZARD_USE_CUSTOM_LOGO "@APPLICATION_WIZARD_USE_CUSTOM_LOGO@" #cmakedefine APPLICATION_VIRTUALFILE_SUFFIX "@APPLICATION_VIRTUALFILE_SUFFIX@" +#cmakedefine APPLICATION_OCSP_STAPLING_ENABLED "@APPLICATION_OCSP_STAPLING_ENABLED@" +#cmakedefine APPLICATION_FORBID_BAD_SSL "@APPLICATION_FORBID_BAD_SSL@" #define APPLICATION_DOTVIRTUALFILE_SUFFIX "." APPLICATION_VIRTUALFILE_SUFFIX +#cmakedefine01 ENFORCE_VIRTUAL_FILES_SYNC_FOLDER #cmakedefine ZLIB_FOUND @ZLIB_FOUND@ diff --git a/doc/architecture.rst b/doc/architecture.rst index a317b1893a5a..315e6ef4aa1b 100644 --- a/doc/architecture.rst +++ b/doc/architecture.rst @@ -406,7 +406,7 @@ Virtual Files ------------- .. note:: - * This feature is currently only available on ``Windows`` by default. ``Linux`` implementation is experimental and must be enabled by adding ``showExperimentalOptions=true`` to the ``nextcloud.cfg`` configuration file in the ``App Data`` folder. ``macOS``, at the moment, is using the same backend as ``Linux`` one. It can be enabled with the same ``showExperimentalOptions`` flag. + * This feature is currently only available on ``Windows`` by default. ``Linux`` and ``macOS`` implementations are experimental and must be enabled by adding ``showExperimentalOptions=true`` to the ``nextcloud.cfg`` configuration file in the ``App Data`` folder. Oftentimes, users are working with a huge amount of files that are big in size. Synchronizing every such file to a device that's running a Nextcloud desktop client is not always possible due to the user's device storage space limitation. Let's assume that your desktop client is connected to a server that has 1TB of data. You want all those files at hand, so you can quickly access any file via the file explorer. Your device has 512GB local storage device. @@ -416,8 +416,15 @@ Needless to say, this is far from being convenient. That's why, starting from 3.2.0, we are introducing the VFS (Virtual Files) feature. You may have had experience working with a similar feature in other cloud sync clients. This feature is known by different names: Files On-Demand, SmartSync, etc. The VFS does not occupy much space on the user's storage. It just creates placeholders for each file and folder. These files are quite small and only contain metadata needed to display them properly and to fetch the actual file when needed. -One will see a hydration (in other words - file download) process when double-clicking on a file that must become available. There will be a progress-bar popup displayed if the file is large enough. So, the hydration process can be observed and it makes it easy to then find out, how long, it would take to fetch the actual file from the server. -The "Hydration" can be thought of as "downloading" or "fetching" the file contents. As soon as hydration is complete, the file will then be opened normally as now it is a real file on the user's storage. It won't disappear, and, from now on, will always be available, unless it is manually dehydrated. +When one tries to open a file, for example by double clicking on a +file in the Windows Explorer, one will see that the file gets +downloaded and becomes available locally. This can be observed by a +small progress-bar popup if the file is large enough. + +As soon as the download is complete, the file will then be opened +normally as now it is a real file on the user's storage. It won't +disappear, and, from now on, will always be available, unless it is +manually dehydrated. .. image:: images/vfs_hydration_progress_bar.png :alt: VFS hydration progress bar diff --git a/doc/autoupdate.rst b/doc/autoupdate.rst index ce50b2b65aa1..43f1de621c8a 100644 --- a/doc/autoupdate.rst +++ b/doc/autoupdate.rst @@ -32,10 +32,9 @@ itself. Should the silent update fail, the client offers a manual download. macOS ^^^^^ -If a new update is available, the Nextcloud client initializes a pop-up dialog -to alert you of the update and requesting that you update to the latest -version. Due to their use of the Sparkle frameworks, this is the default -process for macOS applications. +There is no automatic updater on macOS. If a new update is available, +the Nextcloud client initializes a pop-up dialog to alert you of the +update and requesting that you update to the latest version manually. Linux ^^^^^ @@ -96,14 +95,6 @@ To prevent automatic updates and disallow manual overrides: .. note:: branded clients have different key names -Preventing Automatic Updates in macOS Environments -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You can disable the automatic update mechanism, in the macOS operating system, -by copying the file -``nextcloud.app/Contents/Resources/deny_autoupdate_com.nextcloud.desktopclient.plist`` -to ``/Library/Preferences/com.nextcloud.desktopclient.plist``. - Preventing Automatic Updates in Linux Environments ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/conf.py b/doc/conf.py index 0b47d0d98aa6..6cc91ef10eae 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -50,7 +50,7 @@ # The short X.Y version. version = '3.3' # The full version, including alpha/beta/rc tags. -release = '3.3.50' +release = '3.3.81' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/images/user_status-selector_dialog.png b/doc/images/user_status-selector_dialog.png new file mode 100644 index 000000000000..6f82cfcf1cd0 Binary files /dev/null and b/doc/images/user_status-selector_dialog.png differ diff --git a/doc/images/user_status_selector_main_dialog.png b/doc/images/user_status_selector_main_dialog.png new file mode 100644 index 000000000000..4c38f89f54f9 Binary files /dev/null and b/doc/images/user_status_selector_main_dialog.png differ diff --git a/doc/installing.rst b/doc/installing.rst index 0325d11cf903..dfddfb1a67ba 100644 --- a/doc/installing.rst +++ b/doc/installing.rst @@ -31,7 +31,7 @@ download page. System Requirements ---------------------------------- -- Windows 10+ +- Windows 8.1+ - macOS 10.12+ (64-bit only) - Linux - FreeBSD diff --git a/doc/navigating.rst b/doc/navigating.rst index b9ee0efec11a..245929bf2d9b 100644 --- a/doc/navigating.rst +++ b/doc/navigating.rst @@ -157,6 +157,35 @@ icon. If a directory includes ignored files that are marked with warning icons that does not change the status of the parent directories. +Set the user status +------------------- + +If you have the user status app installed on your Nextcloud server, +you can set your user status from the desktop client. To do so, open +the main dialog. Then click on your avatar and then click on the three +dots. In the menu that opens click on **Set status**. + +.. figure:: images/user_status_selector_main_dialog.png + :alt: Open user status dialog from main dialog. + +In the dialog that opens, you can set your online status if +you click on either **Online**, **Away**, **Do not disturb** or +**Invisible**. You can also set a custom status message with the text +field below or choose one of the predefined status messages below. It +is also possible to set a custom emoji if you click on the button with +the emoji beside the text input field. The last thing you might want +to set is when your user status should be cleared. You can choose the +period after which the user status will be cleared by clicking on the +button on the left hand side of the text **Clear status message after**. + +.. figure:: images/user_status-selector_dialog.png + :alt: Dialog to set user status. + +If you are happy with the status you have created you can enable this +status with the button **Set status message**. If you had already a +status set, you can clear the status by clicking the cutton **Clear +status message**. + Sharing From Your Desktop ------------------------- diff --git a/doc/nextcloudcmd.rst b/doc/nextcloudcmd.rst index a0630192ce8e..7cd41f3ad1fa 100644 --- a/doc/nextcloudcmd.rst +++ b/doc/nextcloudcmd.rst @@ -46,6 +46,9 @@ the server URL. Other command line switches supported by ``nextcloudcmd`` include the following: +``--path`` + Overrides default remote root folder to a specific subfolder on the server(e.g.: /Documents would sync the Documents subfolder on the server) + ``--user``, ``-u`` ``[user]`` Use ``user`` as the login name. @@ -67,12 +70,6 @@ Other command line switches supported by ``nextcloudcmd`` include the following: ``--httpproxy http://[user@pass:]:`` Uses ``server`` as HTTP proxy. -``--nonshib`` - Uses Non Shibboleth WebDAV Authentication - -``--davpath [path]`` - Overrides the WebDAV Path with ``path`` - ``--exclude [file]`` Exclude list file @@ -92,15 +89,15 @@ Credential Handling :: - $ nextcloudcmd /home/user/my_sync_folder https://carla:secret@server/nextcloud/remote.php/dav/ + $ nextcloudcmd /home/user/my_sync_folder https://carla:secret@server/nextcloud To synchronize the Nextcloud directory ``Music`` to the local directory ``media/music``, through a proxy listening on port ``8080``, and on a gateway machine using IP address ``192.168.178.1``, the command line would be:: - $ nextcloudcmd --httpproxy http://192.168.178.1:8080 \ + $ nextcloudcmd --httpproxy http://192.168.178.1:8080 --path /Music \ $HOME/media/music \ - https://server/nextcloud/remote.php/dav/Music + https://server/nextcloud ``nextcloudcmd`` will prompt for the user name and password, unless they have been specified on the command line or ``-n`` has been passed. @@ -120,5 +117,5 @@ Example :: - $ nextcloudcmd /home/user/ \ - https://:@/remote.php/dav/ + $ nextcloudcmd --path / /home/user/ \ + https://:@ diff --git a/man/nextcloudcmd.1.rst b/man/nextcloudcmd.1.rst index 84a95a65cb8b..a78a99a2366e 100644 --- a/man/nextcloudcmd.1.rst +++ b/man/nextcloudcmd.1.rst @@ -24,11 +24,14 @@ The first parameter is the local directory. The second parameter is the server URL. .. note:: Prior to the 1.6 release of nextcloudcmd, the tool only accepted - ``nextcloud://`` or ``nextclouds://`` in place of ``http://`` and ``https://`` as + ``owncloud://`` or ``ownclouds://`` in place of ``http://`` and ``https://`` as a scheme. See ``Examples`` for details. OPTIONS ======= +``--path`` + Overrides default remote root folder to a specific subfolder on the server(e.g.: /Documents would sync the Documents subfolder on the server) + ``—user``, ``-u`` ``[user]`` Use ``user`` as the login name. @@ -50,12 +53,6 @@ OPTIONS ``—httpproxy http://[user@pass:]:`` Uses ``server`` as HTTP proxy. -``—nonshib`` - Uses Non Shibboleth WebDAV Authentication - -``—davpath [path]`` - Overrides the WebDAV Path with ``path`` - ``—exclude [file]`` Exclude list file @@ -74,18 +71,18 @@ To synchronize the nextCloud directory ``Music`` to the local directory ``media/ through a proxy listening on port ``8080`` on the gateway machine ``192.168.178.1``, the command line would be:: - $ nextcloudcmd —httpproxy http://192.168.178.1:8080 \ + $ nextcloudcmd —httpproxy http://192.168.178.1:8080 --path /Music \ $HOME/media/music \ - https://server/nextcloud/remote.php/dav/Music + https://server/nextcloud ``nextcloudcmd`` will enquire user name and password, unless they have been specified on the command line or ``-n`` (see `netrc(5)`) has been passed. Using the legacy scheme, it would be:: - $ nextcloudcmd —httpproxy http://192.168.178.1:8080 \ + $ nextcloudcmd —httpproxy http://192.168.178.1:8080 --path /Music \ $HOME/media/music \ - nextclouds://server/nextcloud/remote.php/dav/Music + ownclouds://server/nextcloud BUGS diff --git a/resources.qrc b/resources.qrc index 54c4b5cd98b2..43b277f77a5c 100644 --- a/resources.qrc +++ b/resources.qrc @@ -1,11 +1,27 @@ + src/gui/UserStatusSelector.qml + src/gui/UserStatusSelectorDialog.qml + src/gui/EmojiPicker.qml + src/gui/ErrorBox.qml src/gui/tray/Window.qml src/gui/tray/UserLine.qml src/gui/tray/HeaderButton.qml + src/gui/tray/SyncStatus.qml theme/Style/Style.qml theme/Style/qmldir src/gui/tray/ActivityActionButton.qml src/gui/tray/ActivityItem.qml + src/gui/tray/AutoSizingMenu.qml + src/gui/tray/ActivityList.qml + src/gui/tray/FileActivityDialog.qml + src/gui/tray/UnifiedSearchInputContainer.qml + src/gui/tray/UnifiedSearchResultFetchMoreTrigger.qml + src/gui/tray/UnifiedSearchResultItem.qml + src/gui/tray/UnifiedSearchResultItemSkeleton.qml + src/gui/tray/UnifiedSearchResultItemSkeletonContainer.qml + src/gui/tray/UnifiedSearchResultListItem.qml + src/gui/tray/UnifiedSearchResultNothingFound.qml + src/gui/tray/UnifiedSearchResultSectionItem.qml diff --git a/shell_integration/MacOSX/CMakeLists.txt b/shell_integration/MacOSX/CMakeLists.txt index 4173f6e9429e..b11efaf1f194 100644 --- a/shell_integration/MacOSX/CMakeLists.txt +++ b/shell_integration/MacOSX/CMakeLists.txt @@ -14,7 +14,7 @@ add_custom_target( mac_overlayplugin ALL "OC_SOCKETAPI_TEAM_IDENTIFIER_PREFIX=${SOCKETAPI_TEAM_IDENTIFIER_PREFIX}" COMMENT building Mac Overlay icons VERBATIM) -add_dependencies(mac_overlayplugin ${APPLICATION_EXECUTABLE}) # for the ownCloud.icns to be generated +add_dependencies(mac_overlayplugin nextcloud) # for the ownCloud.icns to be generated INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Release/FinderSyncExt.appex DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns diff --git a/shell_integration/dolphin/CMakeLists.txt b/shell_integration/dolphin/CMakeLists.txt index f2fda6e1d37f..60a38e389971 100644 --- a/shell_integration/dolphin/CMakeLists.txt +++ b/shell_integration/dolphin/CMakeLists.txt @@ -2,7 +2,7 @@ project(dolphin-owncloud) cmake_minimum_required(VERSION 2.8.12) -set(QT_MIN_VERSION "5.12.0") +set(QT_MIN_VERSION "5.15.0") set(KF5_MIN_VERSION "5.16.0") set(KDE_INSTALL_USE_QT_SYS_PATHS ON CACHE BOOL "Install the plugin in the right directory") diff --git a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp index 4e5966e7fd8f..5403a0b5d998 100644 --- a/shell_integration/dolphin/ownclouddolphinactionplugin.cpp +++ b/shell_integration/dolphin/ownclouddolphinactionplugin.cpp @@ -37,7 +37,7 @@ class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin explicit OwncloudDolphinPluginAction(QObject* parent, const QList&) : KAbstractFileItemActionPlugin(parent) { } - QList actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) Q_DECL_OVERRIDE + QList actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) override { auto helper = OwncloudDolphinPluginHelper::instance(); if (!helper->isConnected() || !fileItemInfos.isLocal()) diff --git a/shell_integration/icons/CMakeLists.txt b/shell_integration/icons/CMakeLists.txt index 04235c55b476..c77fecac7b8c 100644 --- a/shell_integration/icons/CMakeLists.txt +++ b/shell_integration/icons/CMakeLists.txt @@ -1,6 +1,6 @@ if( UNIX AND NOT APPLE ) - SET(ICON_DIR ${DATADIR}/icons/hicolor) + SET(ICON_DIR ${CMAKE_INSTALL_DATADIR}/icons/hicolor) FOREACH(size 128x128 16x16 256x256 32x32 48x48 64x64 72x72) file(GLOB files "${size}/*.png") diff --git a/shell_integration/libcloudproviders/CMakeLists.txt b/shell_integration/libcloudproviders/CMakeLists.txt index 1dd464d25ae0..d5391a7a401d 100644 --- a/shell_integration/libcloudproviders/CMakeLists.txt +++ b/shell_integration/libcloudproviders/CMakeLists.txt @@ -41,7 +41,7 @@ macro(libcloudproviders_add_config _sources) endmacro(libcloudproviders_add_config _sources) -find_package(Qt5 5.12 COMPONENTS DBus) +find_package(Qt5 5.15 COMPONENTS DBus) IF (Qt5DBus_FOUND) STRING(TOLOWER "${APPLICATION_VENDOR}" DBUS_VENDOR) STRING(REGEX REPLACE "[^A-z0-9]" "" DBUS_VENDOR "${DBUS_VENDOR}") diff --git a/shell_integration/nautilus/CMakeLists.txt b/shell_integration/nautilus/CMakeLists.txt index d8f75d8a57c4..8d8a759a3cb5 100644 --- a/shell_integration/nautilus/CMakeLists.txt +++ b/shell_integration/nautilus/CMakeLists.txt @@ -25,9 +25,9 @@ if( UNIX AND NOT APPLE ) ERROR_VARIABLE errors OUTPUT_VARIABLE out) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate.py DESTINATION ${DATADIR}/nautilus-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_nemo.py DESTINATION ${DATADIR}/nemo-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_caja.py DESTINATION ${DATADIR}/caja-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate.py DESTINATION ${CMAKE_INSTALL_DATADIR}/nautilus-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_nemo.py DESTINATION ${CMAKE_INSTALL_DATADIR}/nemo-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/syncstate_caja.py DESTINATION ${CMAKE_INSTALL_DATADIR}/caja-python/extensions RENAME syncstate-${APPLICATION_SHORTNAME}.py) diff --git a/shell_integration/windows/NCUtil/RemotePathChecker.h b/shell_integration/windows/NCUtil/RemotePathChecker.h index 5758a9a5c7ef..134138f13724 100644 --- a/shell_integration/windows/NCUtil/RemotePathChecker.h +++ b/shell_integration/windows/NCUtil/RemotePathChecker.h @@ -26,7 +26,7 @@ #pragma once -class __declspec(dllexport) RemotePathChecker { +class RemotePathChecker { public: enum FileState { // Order synced with NCOverlay diff --git a/shell_integration/windows/WinShellExt.wxs.in b/shell_integration/windows/WinShellExt.wxs.in index f3ad4dd77108..065aafd3ba62 100644 --- a/shell_integration/windows/WinShellExt.wxs.in +++ b/shell_integration/windows/WinShellExt.wxs.in @@ -63,6 +63,7 @@ + diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 000000000000..b039ad360f77 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,12 @@ +sonar.projectKey=nextcloud_desktop +sonar.organization=nextcloud +sonar.projectBaseDir=.. +sonar.sources=src +sonar.exclusions=3rdparty/** +sonar.language=c++ +sonar.cfamily.cache.enabled=false +sonar.sourceEncoding=UTF-8 +sonar.cfamily.threads=2 +sonar.cfamily.gcov.reportsPath=build/Testing/CoverageInfo +sonar.cfamily.cache.enabled=true, +sonar.cfamily.cache.path=/cache/sonarcloud diff --git a/src/3rdparty/QProgressIndicator/QProgressIndicator.h b/src/3rdparty/QProgressIndicator/QProgressIndicator.h index 4871cb8a25ee..536516106397 100644 --- a/src/3rdparty/QProgressIndicator/QProgressIndicator.h +++ b/src/3rdparty/QProgressIndicator/QProgressIndicator.h @@ -67,8 +67,8 @@ class QProgressIndicator : public QWidget */ const QColor & color() const { return m_color; } - virtual QSize sizeHint() const; - int heightForWidth(int w) const; + QSize sizeHint() const override; + int heightForWidth(int w) const override; public slots: /*! Starts the spin animation. \sa stopAnimation isAnimated @@ -98,8 +98,8 @@ public slots: */ void setColor(const QColor & color); protected: - virtual void timerEvent(QTimerEvent * event); - virtual void paintEvent(QPaintEvent * event); + void timerEvent(QTimerEvent * event) override; + void paintEvent(QPaintEvent * event) override; private: int m_angle = 0; int m_timerId = -1; diff --git a/src/3rdparty/libcrashreporter-qt b/src/3rdparty/libcrashreporter-qt index 34b4665bd7ae..5423c0ef54f9 160000 --- a/src/3rdparty/libcrashreporter-qt +++ b/src/3rdparty/libcrashreporter-qt @@ -1 +1 @@ -Subproject commit 34b4665bd7ae5a86115f366b3ec4935d7ecb769f +Subproject commit 5423c0ef54f99cea2628c2cb3f48e39e215f9961 diff --git a/src/3rdparty/qtlockedfile/qtlockedfile.h b/src/3rdparty/qtlockedfile/qtlockedfile.h index fcfb8cc24f72..128cbf0ff900 100644 --- a/src/3rdparty/qtlockedfile/qtlockedfile.h +++ b/src/3rdparty/qtlockedfile/qtlockedfile.h @@ -57,7 +57,7 @@ class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile QtLockedFile(); QtLockedFile(const QString &name); - ~QtLockedFile(); + ~QtLockedFile() override; bool lock(LockMode mode, bool block = true); bool unlock(); diff --git a/src/3rdparty/qtsingleapplication/qtsingleapplication.h b/src/3rdparty/qtsingleapplication/qtsingleapplication.h index 384a71ce864d..674649e4cf07 100644 --- a/src/3rdparty/qtsingleapplication/qtsingleapplication.h +++ b/src/3rdparty/qtsingleapplication/qtsingleapplication.h @@ -44,13 +44,13 @@ class QtSingleApplication : public QApplication public: QtSingleApplication(const QString &id, int &argc, char **argv); - ~QtSingleApplication(); + ~QtSingleApplication() override; bool isRunning(qint64 pid = -1); void setActivationWindow(QWidget* aw, bool activateOnMessage = true); QWidget* activationWindow() const; - bool event(QEvent *event) Q_DECL_OVERRIDE; + bool event(QEvent *event) override; QString applicationId() const; void setBlock(bool value); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c5162564013a..0c051c9a46d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,10 +4,8 @@ endif() include(ECMEnableSanitizers) -set(synclib_NAME ${APPLICATION_EXECUTABLE}sync) - -find_package(Qt5 5.12 COMPONENTS Core Network Xml Concurrent REQUIRED) -find_package(Qt5 5.12 COMPONENTS WebEngineWidgets WebEngine) +find_package(Qt5 5.15 COMPONENTS Core Network Xml Concurrent REQUIRED) +find_package(Qt5 5.15 COMPONENTS WebEngineWidgets WebEngine) if(Qt5WebEngine_FOUND AND Qt5WebEngineWidgets_FOUND) add_compile_definitions(WITH_WEBENGINE=1) @@ -61,10 +59,6 @@ elseif(UNIX AND NOT APPLE) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now") endif() -include_directories( - ${CMAKE_SOURCE_DIR}/src/3rdparty -) - set(QML_IMPORT_PATH ${CMAKE_SOURCE_DIR}/theme CACHE STRING "" FORCE) add_subdirectory(csync) diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 81c2460e0107..118ca3cb400f 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -1,14 +1,11 @@ project(cmd) set(CMAKE_AUTOMOC TRUE) -set(cmd_NAME ${APPLICATION_EXECUTABLE}cmd) - add_library(cmdCore STATIC simplesslerrorhandler.cpp netrcparser.cpp) target_link_libraries(cmdCore PUBLIC - "${csync_NAME}" - "${synclib_NAME}" + Nextcloud::sync Qt5::Core Qt5::Network ) @@ -27,20 +24,22 @@ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") endif() if(NOT BUILD_LIBRARIES_ONLY) - add_executable(${cmd_NAME} cmd.cpp) + add_executable(nextcloudcmd cmd.cpp) + set_target_properties(nextcloudcmd PROPERTIES + RUNTIME_OUTPUT_NAME "${APPLICATION_EXECUTABLE}cmd") + + target_link_libraries(nextcloudcmd cmdCore) if(BUILD_OWNCLOUD_OSX_BUNDLE) - set_target_properties(${cmd_NAME} PROPERTIES + set_target_properties(nextcloudcmd PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${BIN_OUTPUT_DIRECTORY}/${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS") else() - set_target_properties(${cmd_NAME} PROPERTIES + set_target_properties(nextcloudcmd PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) - install(TARGETS ${cmd_NAME} + install(TARGETS nextcloudcmd RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() - - target_link_libraries(${cmd_NAME} cmdCore) endif() diff --git a/src/cmd/cmd.cpp b/src/cmd/cmd.cpp index 39f4533de536..0e26990516f1 100644 --- a/src/cmd/cmd.cpp +++ b/src/cmd/cmd.cpp @@ -66,6 +66,7 @@ struct CmdOptions { QString source_dir; QString target_url; + QString remotePath = QStringLiteral("/"); QString config_directory; QString user; QString password; @@ -77,7 +78,6 @@ struct CmdOptions bool ignoreHiddenFiles; QString exclude; QString unsyncedfolders; - QString davPath; int restartTimes; int downlimit; int uplimit; @@ -142,7 +142,7 @@ class HttpCredentialsText : public HttpCredentials { } - void askFromUser() Q_DECL_OVERRIDE + void askFromUser() override { _password = ::queryPassword(user()); _ready = true; @@ -155,7 +155,7 @@ class HttpCredentialsText : public HttpCredentials _sslTrusted = isTrusted; } - bool sslIsTrusted() Q_DECL_OVERRIDE + bool sslIsTrusted() override { return _sslTrusted; } @@ -193,6 +193,7 @@ void help() std::cout << " -h Sync hidden files, do not ignore them" << std::endl; std::cout << " --version, -v Display version and exit" << std::endl; std::cout << " --logdebug More verbose logging" << std::endl; + std::cout << " --path Path to a folder on a remote server" << std::endl; std::cout << "" << std::endl; exit(0); } @@ -269,7 +270,10 @@ void parseOptions(const QStringList &app_args, CmdOptions *options) } else if (option == "--logdebug") { Logger::instance()->setLogFile("-"); Logger::instance()->setLogDebug(true); - } else { + } else if (option == "--path" && !it.peekNext().startsWith("-")) { + options->remotePath = it.next(); + } + else { help(); } } @@ -291,9 +295,10 @@ void selectiveSyncFixup(OCC::SyncJournalDb *journal, const QStringList &newList) bool ok = false; - auto oldBlackListSet = journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok).toSet(); + const auto selectiveSyncList = journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok); + const QSet oldBlackListSet(selectiveSyncList.begin(), selectiveSyncList.end()); if (ok) { - auto blackListSet = newList.toSet(); + const QSet blackListSet(newList.begin(), newList.end()); const auto changes = (oldBlackListSet - blackListSet) + (blackListSet - oldBlackListSet); for (const auto &it : changes) { journal->schedulePathForRemoteDiscovery(it); @@ -305,6 +310,9 @@ void selectiveSyncFixup(OCC::SyncJournalDb *journal, const QStringList &newList) int main(int argc, char **argv) { +#ifdef Q_OS_WIN + SetDllDirectory(L""); +#endif QCoreApplication app(argc, argv); #ifdef Q_OS_WIN @@ -313,8 +321,6 @@ int main(int argc, char **argv) qputenv("OPENSSL_CONF", opensslConf.toLocal8Bit()); #endif - qsrand(std::random_device()()); - CmdOptions options; options.silent = false; options.trustSSL = false; @@ -339,16 +345,15 @@ int main(int argc, char **argv) qFatal("Could not initialize account!"); return EXIT_FAILURE; } - // check if the webDAV path was added to the url and append if not. - if (!options.target_url.endsWith("/")) { - options.target_url.append("/"); - } - if (!options.target_url.contains(account->davPath())) { - options.target_url.append(account->davPath()); + if (options.target_url.contains("/webdav", Qt::CaseInsensitive) || options.target_url.contains("/dav", Qt::CaseInsensitive)) { + qWarning("Dav or webdav in server URL."); + std::cerr << "Error! Please specify only the base URL of your host with username and password. Example:" << std::endl + << "http(s)://username:password@cloud.example.com" << std::endl; + return EXIT_FAILURE; } - QUrl url = QUrl::fromUserInput(options.target_url); + QUrl hostUrl = QUrl::fromUserInput((options.target_url.endsWith(QLatin1Char('/')) || options.target_url.endsWith(QLatin1Char('\\'))) ? options.target_url.chopped(1) : options.target_url); // Order of retrieval attempt (later attempts override earlier ones): // 1. From URL @@ -356,8 +361,8 @@ int main(int argc, char **argv) // 3. From netrc (if enabled) // 4. From prompt (if interactive) - QString user = url.userName(); - QString password = url.password(); + QString user = hostUrl.userName(); + QString password = hostUrl.password(); if (!options.user.isEmpty()) { user = options.user; @@ -370,7 +375,7 @@ int main(int argc, char **argv) if (options.useNetrc) { NetrcParser parser; if (parser.parse()) { - NetrcParser::LoginPair pair = parser.find(url.host()); + NetrcParser::LoginPair pair = parser.find(hostUrl.host()); user = pair.first; password = pair.second; } @@ -388,24 +393,15 @@ int main(int argc, char **argv) } } - // take the unmodified url to pass to csync_create() - QByteArray remUrl = options.target_url.toUtf8(); - // Find the folder and the original owncloud url - QStringList splitted = url.path().split("/" + account->davPath()); - url.setPath(splitted.value(0)); - url.setScheme(url.scheme().replace("owncloud", "http")); + hostUrl.setScheme(hostUrl.scheme().replace("owncloud", "http")); - QUrl credentialFreeUrl = url; + QUrl credentialFreeUrl = hostUrl; credentialFreeUrl.setUserName(QString()); credentialFreeUrl.setPassword(QString()); - // Remote folders typically start with a / and don't end with one - QString folder = "/" + splitted.value(1); - if (folder.endsWith("/") && folder != "/") { - folder.chop(1); - } + const QString folder = options.remotePath; if (!options.proxy.isNull()) { QString host; @@ -442,7 +438,7 @@ int main(int argc, char **argv) } #endif - account->setUrl(url); + account->setUrl(hostUrl); account->setSslErrorHandler(sslErrorHandler); QEventLoop loop; @@ -487,7 +483,7 @@ int main(int argc, char **argv) qCritical() << "Could not open file containing the list of unsynced folders: " << options.unsyncedfolders; } else { // filter out empty lines and comments - selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n').filter(QRegExp("\\S+")).filter(QRegExp("^[^#]")); + selectiveSyncList = QString::fromUtf8(f.readAll()).split('\n').filter(QRegularExpression("\\S+")).filter(QRegularExpression("^[^#]")); for (int i = 0; i < selectiveSyncList.count(); ++i) { if (!selectiveSyncList.at(i).endsWith(QLatin1Char('/'))) { @@ -505,6 +501,9 @@ int main(int argc, char **argv) selectiveSyncFixup(&db, selectiveSyncList); } + SyncOptions opt; + opt.fillFromEnvironmentVariables(); + opt.verifyChunkSizes(); SyncEngine engine(account, options.source_dir, folder, &db); engine.setIgnoreHiddenFiles(options.ignoreHiddenFiles); engine.setNetworkLimits(options.uplimit, options.downlimit); diff --git a/src/cmd/simplesslerrorhandler.h b/src/cmd/simplesslerrorhandler.h index 33376b820d64..31e89bff19a2 100644 --- a/src/cmd/simplesslerrorhandler.h +++ b/src/cmd/simplesslerrorhandler.h @@ -28,7 +28,7 @@ namespace OCC { class SimpleSslErrorHandler : public OCC::AbstractSslErrorHandler { public: - bool handleErrors(QList errors, const QSslConfiguration &conf, QList *certs, OCC::AccountPtr) Q_DECL_OVERRIDE; + bool handleErrors(QList errors, const QSslConfiguration &conf, QList *certs, OCC::AccountPtr) override; }; } diff --git a/src/common/checksums.cpp b/src/common/checksums.cpp index c6857e549b54..0c016ef4dafa 100644 --- a/src/common/checksums.cpp +++ b/src/common/checksums.cpp @@ -144,6 +144,9 @@ QByteArray makeChecksumHeader(const QByteArray &checksumType, const QByteArray & QByteArray findBestChecksum(const QByteArray &_checksums) { + if (_checksums.isEmpty()) { + return {}; + } const auto checksums = QString::fromUtf8(_checksums); int i = 0; // The order of the searches here defines the preference ordering. @@ -162,7 +165,7 @@ QByteArray findBestChecksum(const QByteArray &_checksums) return _checksums.mid(i, end - i); } qCWarning(lcChecksums) << "Failed to parse" << _checksums; - return QByteArray(); + return {}; } bool parseChecksumHeader(const QByteArray &header, QByteArray *type, QByteArray *checksum) diff --git a/src/common/checksums.h b/src/common/checksums.h index 5c8d39d5c33e..351fa745d9e2 100644 --- a/src/common/checksums.h +++ b/src/common/checksums.h @@ -81,7 +81,7 @@ class OCSYNC_EXPORT ComputeChecksum : public QObject Q_OBJECT public: explicit ComputeChecksum(QObject *parent = nullptr); - ~ComputeChecksum(); + ~ComputeChecksum() override; /** * Sets the checksum type to be used. The default is empty. diff --git a/src/common/common.cmake b/src/common/common.cmake index 5c7cd52c902b..ebe69f565281 100644 --- a/src/common/common.cmake +++ b/src/common/common.cmake @@ -5,6 +5,7 @@ set(common_SOURCES ${CMAKE_CURRENT_LIST_DIR}/checksums.cpp ${CMAKE_CURRENT_LIST_DIR}/filesystembase.cpp ${CMAKE_CURRENT_LIST_DIR}/ownsql.cpp + ${CMAKE_CURRENT_LIST_DIR}/preparedsqlquerymanager.cpp ${CMAKE_CURRENT_LIST_DIR}/syncjournaldb.cpp ${CMAKE_CURRENT_LIST_DIR}/syncjournalfilerecord.cpp ${CMAKE_CURRENT_LIST_DIR}/utility.cpp diff --git a/src/common/constants.h b/src/common/constants.h new file mode 100644 index 000000000000..761a6cee15b1 --- /dev/null +++ b/src/common/constants.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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. + */ + +#pragma once + +#include + +namespace OCC { +namespace Constants { + constexpr qint32 e2EeTagSize = 16; +} +} diff --git a/src/common/filesystembase.cpp b/src/common/filesystembase.cpp index 57e67ffcd1f8..3f54a6880df6 100644 --- a/src/common/filesystembase.cpp +++ b/src/common/filesystembase.cpp @@ -395,13 +395,13 @@ bool FileSystem::moveToTrash(const QString &fileName, QString *errorString) suffix_number++; } if (!file.rename(f.absoluteFilePath(), path + QString::number(suffix_number))) { // rename(file old path, file trash path) - *errorString = QCoreApplication::translate("FileSystem", R"(Could not move "%1" to "%1")") + *errorString = QCoreApplication::translate("FileSystem", R"(Could not move "%1" to "%2")") .arg(f.absoluteFilePath(), path + QString::number(suffix_number)); return false; } } else { if (!file.rename(f.absoluteFilePath(), trashFilePath + f.fileName())) { // rename(file old path, file trash path) - *errorString = QCoreApplication::translate("FileSystem", R"(Could not move "%1" to "%1")") + *errorString = QCoreApplication::translate("FileSystem", R"(Could not move "%1" to "%2")") .arg(f.absoluteFilePath(), trashFilePath + f.fileName()); return false; } diff --git a/src/common/ownsql.cpp b/src/common/ownsql.cpp index 46cf96e86e2f..736f7f03f22a 100644 --- a/src/common/ownsql.cpp +++ b/src/common/ownsql.cpp @@ -490,28 +490,4 @@ void SqlQuery::reset_and_clear_bindings() } } -PreparedSqlQueryRAII::PreparedSqlQueryRAII(SqlQuery *query) - : _query(query) -{ - Q_ASSERT(!sqlite3_stmt_busy(_query->_stmt)); -} - -PreparedSqlQueryRAII::PreparedSqlQueryRAII(SqlQuery *query, const QByteArray &sql, SqlDatabase &db) - : _query(query) -{ - Q_ASSERT(!sqlite3_stmt_busy(_query->_stmt)); - ENFORCE(!query->_sqldb || &db == query->_sqldb) - query->_sqldb = &db; - query->_db = db.sqliteDb(); - if (!query->_stmt) { - _ok = query->prepare(sql) == 0; - } -} - -PreparedSqlQueryRAII::~PreparedSqlQueryRAII() -{ - _query->reset_and_clear_bindings(); -} - - } // namespace OCC diff --git a/src/common/ownsql.h b/src/common/ownsql.h index e0d340e882e3..d409dc827997 100644 --- a/src/common/ownsql.h +++ b/src/common/ownsql.h @@ -168,42 +168,9 @@ class OCSYNC_EXPORT SqlQuery QByteArray _sql; friend class SqlDatabase; - friend class PreparedSqlQueryRAII; + friend class PreparedSqlQueryManager; }; -class OCSYNC_EXPORT PreparedSqlQueryRAII -{ -public: - /** - * Simple Guard which allow reuse of prepared querys. - * The queries are reset in the destructor to prevent wal locks - */ - PreparedSqlQueryRAII(SqlQuery *query); - /** - * Prepare the SqlQuery if it was not prepared yet. - */ - PreparedSqlQueryRAII(SqlQuery *query, const QByteArray &sql, SqlDatabase &db); - ~PreparedSqlQueryRAII(); - - explicit operator bool() const { return _ok; } - - SqlQuery *operator->() const - { - Q_ASSERT(_ok); - return _query; - } - - SqlQuery &operator*() const & - { - Q_ASSERT(_ok); - return *_query; - } - -private: - SqlQuery *const _query; - bool _ok = true; - Q_DISABLE_COPY(PreparedSqlQueryRAII); -}; } // namespace OCC #endif // OWNSQL_H diff --git a/src/common/pinstate.h b/src/common/pinstate.h index a50ed7eab269..106d9385d370 100644 --- a/src/common/pinstate.h +++ b/src/common/pinstate.h @@ -77,7 +77,7 @@ enum class PinState { */ Unspecified = 3, }; -Q_ENUM_NS(PinState); +Q_ENUM_NS(PinState) /** A user-facing version of PinState. * diff --git a/src/common/preparedsqlquerymanager.cpp b/src/common/preparedsqlquerymanager.cpp new file mode 100644 index 000000000000..4c748e58b3e1 --- /dev/null +++ b/src/common/preparedsqlquerymanager.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) by Hannah von Reth + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "preparedsqlquerymanager.h" + +#include + +using namespace OCC; + +PreparedSqlQuery::PreparedSqlQuery(SqlQuery *query, bool ok) + : _query(query) + , _ok(ok) +{ +} + +PreparedSqlQuery::~PreparedSqlQuery() +{ + _query->reset_and_clear_bindings(); +} + +const PreparedSqlQuery PreparedSqlQueryManager::get(PreparedSqlQueryManager::Key key) +{ + auto &query = _queries[key]; + ENFORCE(query._stmt) + Q_ASSERT(!sqlite3_stmt_busy(query._stmt)); + return { &query }; +} + +const PreparedSqlQuery PreparedSqlQueryManager::get(PreparedSqlQueryManager::Key key, const QByteArray &sql, SqlDatabase &db) +{ + auto &query = _queries[key]; + Q_ASSERT(!sqlite3_stmt_busy(query._stmt)); + ENFORCE(!query._sqldb || &db == query._sqldb) + if (!query._stmt) { + query._sqldb = &db; + query._db = db.sqliteDb(); + return { &query, query.prepare(sql) == 0 }; + } + return { &query }; +} diff --git a/src/common/preparedsqlquerymanager.h b/src/common/preparedsqlquerymanager.h new file mode 100644 index 000000000000..64cecabbd02d --- /dev/null +++ b/src/common/preparedsqlquerymanager.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) by Hannah von Reth + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include "ocsynclib.h" +#include "ownsql.h" +#include "common/asserts.h" + +namespace OCC { + +class OCSYNC_EXPORT PreparedSqlQuery +{ +public: + ~PreparedSqlQuery(); + + explicit operator bool() const { return _ok; } + + SqlQuery *operator->() const + { + Q_ASSERT(_ok); + return _query; + } + + SqlQuery &operator*() const & + { + Q_ASSERT(_ok); + return *_query; + } + +private: + PreparedSqlQuery(SqlQuery *query, bool ok = true); + + SqlQuery *_query; + bool _ok; + + friend class PreparedSqlQueryManager; +}; + +/** + * @brief Manage PreparedSqlQuery + */ +class OCSYNC_EXPORT PreparedSqlQueryManager +{ +public: + enum Key { + GetFileRecordQuery, + GetFileRecordQueryByMangledName, + GetFileRecordQueryByInode, + GetFileRecordQueryByFileId, + GetFilesBelowPathQuery, + GetAllFilesQuery, + ListFilesInPathQuery, + SetFileRecordQuery, + SetFileRecordChecksumQuery, + SetFileRecordLocalMetadataQuery, + GetDownloadInfoQuery, + SetDownloadInfoQuery, + DeleteDownloadInfoQuery, + GetUploadInfoQuery, + SetUploadInfoQuery, + DeleteUploadInfoQuery, + DeleteFileRecordPhash, + DeleteFileRecordRecursively, + GetErrorBlacklistQuery, + SetErrorBlacklistQuery, + GetSelectiveSyncListQuery, + GetChecksumTypeIdQuery, + GetChecksumTypeQuery, + InsertChecksumTypeQuery, + GetDataFingerprintQuery, + SetDataFingerprintQuery1, + SetDataFingerprintQuery2, + SetKeyValueStoreQuery, + GetKeyValueStoreQuery, + DeleteKeyValueStoreQuery, + GetConflictRecordQuery, + SetConflictRecordQuery, + DeleteConflictRecordQuery, + GetRawPinStateQuery, + GetEffectivePinStateQuery, + GetSubPinsQuery, + CountDehydratedFilesQuery, + SetPinStateQuery, + WipePinStateQuery, + + PreparedQueryCount + }; + PreparedSqlQueryManager() = default; + /** + * The queries are reset in the destructor to prevent wal locks + */ + const PreparedSqlQuery get(Key key); + /** + * Prepare the SqlQuery if it was not prepared yet. + */ + const PreparedSqlQuery get(Key key, const QByteArray &sql, SqlDatabase &db); + +private: + SqlQuery _queries[PreparedQueryCount]; + Q_DISABLE_COPY(PreparedSqlQueryManager) +}; + +} diff --git a/src/common/result.h b/src/common/result.h index 25129e875167..77a9d121c122 100644 --- a/src/common/result.h +++ b/src/common/result.h @@ -104,6 +104,7 @@ class Result ASSERT(!_isError); return _result; } + T operator*() && { ASSERT(!_isError); @@ -116,6 +117,12 @@ class Result return &_result; } + const T &get() const + { + ASSERT(!_isError) + return _result; + } + const Error &error() const & { ASSERT(_isError); diff --git a/src/common/syncjournaldb.cpp b/src/common/syncjournaldb.cpp index a0655208989a..5c5195bba440 100644 --- a/src/common/syncjournaldb.cpp +++ b/src/common/syncjournaldb.cpp @@ -31,6 +31,7 @@ #include "filesystembase.h" #include "common/asserts.h" #include "common/checksums.h" +#include "common/preparedsqlquerymanager.h" #include "common/c_jhash.h" @@ -92,7 +93,6 @@ static QByteArray defaultJournalMode(const QString &dbPath) SyncJournalDb::SyncJournalDb(const QString &dbFilePath, QObject *parent) : QObject(parent) , _dbFile(dbFilePath) - , _mutex(QMutex::Recursive) , _transaction(0) , _metadataTableIsEmpty(false) { @@ -586,16 +586,15 @@ bool SyncJournalDb::checkConnect() if (forceRemoteDiscovery) { forceRemoteDiscoveryNextSyncLocked(); } - - const PreparedSqlQueryRAII deleteDownloadInfo(&_deleteDownloadInfoQuery, QByteArrayLiteral("DELETE FROM downloadinfo WHERE path=?1"), _db); + const auto deleteDownloadInfo = _queryManager.get(PreparedSqlQueryManager::DeleteDownloadInfoQuery, QByteArrayLiteral("DELETE FROM downloadinfo WHERE path=?1"), _db); if (!deleteDownloadInfo) { - return sqlFail(QStringLiteral("prepare _deleteDownloadInfoQuery"), _deleteDownloadInfoQuery); + return sqlFail(QStringLiteral("prepare _deleteDownloadInfoQuery"), *deleteDownloadInfo); } - const PreparedSqlQueryRAII deleteUploadInfoQuery(&_deleteUploadInfoQuery, QByteArrayLiteral("DELETE FROM uploadinfo WHERE path=?1"), _db); + const auto deleteUploadInfoQuery = _queryManager.get(PreparedSqlQueryManager::DeleteUploadInfoQuery, QByteArrayLiteral("DELETE FROM uploadinfo WHERE path=?1"), _db); if (!deleteUploadInfoQuery) { - return sqlFail(QStringLiteral("prepare _deleteUploadInfoQuery"), _deleteUploadInfoQuery); + return sqlFail(QStringLiteral("prepare _deleteUploadInfoQuery"), *deleteUploadInfoQuery); } QByteArray sql("SELECT lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget, errorCategory, requestId " @@ -605,7 +604,7 @@ bool SyncJournalDb::checkConnect() // case insensitively sql += " COLLATE NOCASE"; } - const PreparedSqlQueryRAII getErrorBlacklistQuery(&_getErrorBlacklistQuery, sql, _db); + const auto getErrorBlacklistQuery = _queryManager.get(PreparedSqlQueryManager::GetErrorBlacklistQuery, sql, _db); if (!getErrorBlacklistQuery) { return sqlFail(QStringLiteral("prepare _getErrorBlacklistQuery"), *getErrorBlacklistQuery); } @@ -892,7 +891,7 @@ QVector SyncJournalDb::tableColumns(const QByteArray &table) qint64 SyncJournalDb::getPHash(const QByteArray &file) { - int64_t h = 0; + qint64 h = 0; int len = file.length(); h = c_jhash64((uint8_t *)file.data(), len, 0); @@ -922,7 +921,7 @@ Result SyncJournalDb::setFileRecord(const SyncJournalFileRecord & << "fileSize:" << record._fileSize << "checksum:" << record._checksumHeader << "e2eMangledName:" << record.e2eMangledName() << "isE2eEncrypted:" << record._isE2eEncrypted; - qlonglong phash = getPHash(record._path); + const qint64 phash = getPHash(record._path); if (checkConnect()) { int plen = record._path.length(); @@ -937,10 +936,10 @@ Result SyncJournalDb::setFileRecord(const SyncJournalFileRecord & parseChecksumHeader(record._checksumHeader, &checksumType, &checksum); int contentChecksumTypeId = mapChecksumType(checksumType); - const PreparedSqlQueryRAII query(&_setFileRecordQuery, QByteArrayLiteral("INSERT OR REPLACE INTO metadata " - "(phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentChecksum, contentChecksumTypeId, e2eMangledName, isE2eEncrypted) " - "VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18);"), - _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::SetFileRecordQuery, QByteArrayLiteral("INSERT OR REPLACE INTO metadata " + "(phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, contentChecksum, contentChecksumTypeId, e2eMangledName, isE2eEncrypted) " + "VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18);"), + _db); if (!query) { return query->error(); } @@ -985,7 +984,7 @@ void SyncJournalDb::keyValueStoreSet(const QString &key, QVariant value) return; } - const PreparedSqlQueryRAII query(&_setKeyValueStoreQuery, QByteArrayLiteral("INSERT OR REPLACE INTO key_value_store (key, value) VALUES(?1, ?2);"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::SetKeyValueStoreQuery, QByteArrayLiteral("INSERT OR REPLACE INTO key_value_store (key, value) VALUES(?1, ?2);"), _db); if (!query) { return; } @@ -1002,7 +1001,7 @@ qint64 SyncJournalDb::keyValueStoreGetInt(const QString &key, qint64 defaultValu return defaultValue; } - const PreparedSqlQueryRAII query(&_getKeyValueStoreQuery, QByteArrayLiteral("SELECT value FROM key_value_store WHERE key = ?1;"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetKeyValueStoreQuery, QByteArrayLiteral("SELECT value FROM key_value_store WHERE key = ?1;"), _db); if (!query) { return defaultValue; } @@ -1024,7 +1023,7 @@ QVariant SyncJournalDb::keyValueStoreGet(const QString &key, QVariant defaultVal return defaultValue; } - const PreparedSqlQueryRAII query(&_getKeyValueStoreQuery, QByteArrayLiteral("SELECT value FROM key_value_store WHERE key = ?1;"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetKeyValueStoreQuery, QByteArrayLiteral("SELECT value FROM key_value_store WHERE key = ?1;"), _db); if (!query) { return defaultValue; } @@ -1041,7 +1040,7 @@ QVariant SyncJournalDb::keyValueStoreGet(const QString &key, QVariant defaultVal void SyncJournalDb::keyValueStoreDelete(const QString &key) { - const PreparedSqlQueryRAII query(&_deleteKeyValueStoreQuery, QByteArrayLiteral("DELETE FROM key_value_store WHERE key=?1;"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::DeleteKeyValueStoreQuery, QByteArrayLiteral("DELETE FROM key_value_store WHERE key=?1;"), _db); if (!query) { qCWarning(lcDb) << "Failed to initOrReset _deleteKeyValueStoreQuery"; Q_ASSERT(false); @@ -1063,12 +1062,12 @@ bool SyncJournalDb::deleteFileRecord(const QString &filename, bool recursively) // always delete the actual file. { - const PreparedSqlQueryRAII query(&_deleteFileRecordPhash, QByteArrayLiteral("DELETE FROM metadata WHERE phash=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::DeleteFileRecordPhash, QByteArrayLiteral("DELETE FROM metadata WHERE phash=?1"), _db); if (!query) { return false; } - qlonglong phash = getPHash(filename.toUtf8()); + const qint64 phash = getPHash(filename.toUtf8()); query->bindValue(1, phash); if (!query->exec()) { @@ -1077,7 +1076,7 @@ bool SyncJournalDb::deleteFileRecord(const QString &filename, bool recursively) } if (recursively) { - const PreparedSqlQueryRAII query(&_deleteFileRecordRecursively, QByteArrayLiteral("DELETE FROM metadata WHERE " IS_PREFIX_PATH_OF("?1", "path")), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::DeleteFileRecordRecursively, QByteArrayLiteral("DELETE FROM metadata WHERE " IS_PREFIX_PATH_OF("?1", "path")), _db); if (!query) return false; query->bindValue(1, filename); @@ -1109,7 +1108,7 @@ bool SyncJournalDb::getFileRecord(const QByteArray &filename, SyncJournalFileRec return false; if (!filename.isEmpty()) { - const PreparedSqlQueryRAII query(&_getFileRecordQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE phash=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetFileRecordQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE phash=?1"), _db); if (!query) { return false; } @@ -1153,7 +1152,7 @@ bool SyncJournalDb::getFileRecordByE2eMangledName(const QString &mangledName, Sy } if (!mangledName.isEmpty()) { - const PreparedSqlQueryRAII query(&_getFileRecordQueryByMangledName, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE e2eMangledName=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetFileRecordQueryByMangledName, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE e2eMangledName=?1"), _db); if (!query) { return false; } @@ -1193,7 +1192,7 @@ bool SyncJournalDb::getFileRecordByInode(quint64 inode, SyncJournalFileRecord *r if (!checkConnect()) return false; - const PreparedSqlQueryRAII query(&_getFileRecordQueryByInode, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE inode=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetFileRecordQueryByInode, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE inode=?1"), _db); if (!query) return false; @@ -1221,7 +1220,7 @@ bool SyncJournalDb::getFileRecordsByFileId(const QByteArray &fileId, const std:: if (!checkConnect()) return false; - const PreparedSqlQueryRAII query(&_getFileRecordQueryByFileId, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE fileid=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetFileRecordQueryByFileId, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE fileid=?1"), _db); if (!query) { return false; } @@ -1281,7 +1280,7 @@ bool SyncJournalDb::getFilesBelowPath(const QByteArray &path, const std::functio // and find nothing. So, unfortunately, we have to use a different query for // retrieving the whole tree. - const PreparedSqlQueryRAII query(&_getAllFilesQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " ORDER BY path||'/' ASC"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetAllFilesQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " ORDER BY path||'/' ASC"), _db); if (!query) { return false; } @@ -1289,15 +1288,15 @@ bool SyncJournalDb::getFilesBelowPath(const QByteArray &path, const std::functio } else { // This query is used to skip discovery and fill the tree from the // database instead - const PreparedSqlQueryRAII query(&_getFilesBelowPathQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE " IS_PREFIX_PATH_OF("?1", "path") - " OR " IS_PREFIX_PATH_OF("?1", "e2eMangledName") - // We want to ensure that the contents of a directory are sorted - // directly behind the directory itself. Without this ORDER BY - // an ordering like foo, foo-2, foo/file would be returned. - // With the trailing /, we get foo-2, foo, foo/file. This property - // is used in fill_tree_from_db(). - " ORDER BY path||'/' ASC"), - _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetFilesBelowPathQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE " IS_PREFIX_PATH_OF("?1", "path") + " OR " IS_PREFIX_PATH_OF("?1", "e2eMangledName") + // We want to ensure that the contents of a directory are sorted + // directly behind the directory itself. Without this ORDER BY + // an ordering like foo, foo-2, foo/file would be returned. + // With the trailing /, we get foo-2, foo, foo/file. This property + // is used in fill_tree_from_db(). + " ORDER BY path||'/' ASC"), + _db); if (!query) { return false; } @@ -1317,7 +1316,7 @@ bool SyncJournalDb::listFilesInPath(const QByteArray& path, if (!checkConnect()) return false; - const PreparedSqlQueryRAII query(&_listFilesInPathQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE parent_hash(path) = ?1 ORDER BY path||'/' ASC"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::ListFilesInPathQuery, QByteArrayLiteral(GET_FILE_RECORD_QUERY " WHERE parent_hash(path) = ?1 ORDER BY path||'/' ASC"), _db); if (!query) { return false; } @@ -1372,7 +1371,7 @@ bool SyncJournalDb::updateFileRecordChecksum(const QString &filename, qCInfo(lcDb) << "Updating file checksum" << filename << contentChecksum << contentChecksumType; - qlonglong phash = getPHash(filename.toUtf8()); + const qint64 phash = getPHash(filename.toUtf8()); if (!checkConnect()) { qCWarning(lcDb) << "Failed to connect database."; return false; @@ -1380,9 +1379,9 @@ bool SyncJournalDb::updateFileRecordChecksum(const QString &filename, int checksumTypeId = mapChecksumType(contentChecksumType); - const PreparedSqlQueryRAII query(&_setFileRecordChecksumQuery, QByteArrayLiteral("UPDATE metadata" - " SET contentChecksum = ?2, contentChecksumTypeId = ?3" - " WHERE phash == ?1;"), + const auto query = _queryManager.get(PreparedSqlQueryManager::SetFileRecordChecksumQuery, QByteArrayLiteral("UPDATE metadata" + " SET contentChecksum = ?2, contentChecksumTypeId = ?3" + " WHERE phash == ?1;"), _db); if (!query) { return false; @@ -1401,15 +1400,15 @@ bool SyncJournalDb::updateLocalMetadata(const QString &filename, qCInfo(lcDb) << "Updating local metadata for:" << filename << modtime << size << inode; - qlonglong phash = getPHash(filename.toUtf8()); + const qint64 phash = getPHash(filename.toUtf8()); if (!checkConnect()) { qCWarning(lcDb) << "Failed to connect database."; return false; } - const PreparedSqlQueryRAII query(&_setFileRecordLocalMetadataQuery, QByteArrayLiteral("UPDATE metadata" - " SET inode=?2, modtime=?3, filesize=?4" - " WHERE phash == ?1;"), + const auto query = _queryManager.get(PreparedSqlQueryManager::SetFileRecordLocalMetadataQuery, QByteArrayLiteral("UPDATE metadata" + " SET inode=?2, modtime=?3, filesize=?4" + " WHERE phash == ?1;"), _db); if (!query) { return false; @@ -1428,8 +1427,8 @@ Optional SyncJournalDb::hasHydratedOrDehyd if (!checkConnect()) return {}; - const PreparedSqlQueryRAII query(&_countDehydratedFilesQuery, QByteArrayLiteral("SELECT DISTINCT type FROM metadata" - " WHERE (" IS_PREFIX_PATH_OR_EQUAL("?1", "path") " OR ?1 == '');"), + const auto query = _queryManager.get(PreparedSqlQueryManager::CountDehydratedFilesQuery, QByteArrayLiteral("SELECT DISTINCT type FROM metadata" + " WHERE (" IS_PREFIX_PATH_OR_EQUAL("?1", "path") " OR ?1 == '');"), _db); if (!query) { return {}; @@ -1490,7 +1489,7 @@ SyncJournalDb::DownloadInfo SyncJournalDb::getDownloadInfo(const QString &file) DownloadInfo res; if (checkConnect()) { - const PreparedSqlQueryRAII query(&_getDownloadInfoQuery, QByteArrayLiteral("SELECT tmpfile, etag, errorcount FROM downloadinfo WHERE path=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetDownloadInfoQuery, QByteArrayLiteral("SELECT tmpfile, etag, errorcount FROM downloadinfo WHERE path=?1"), _db); if (!query) { return res; } @@ -1518,9 +1517,9 @@ void SyncJournalDb::setDownloadInfo(const QString &file, const SyncJournalDb::Do if (i._valid) { - const PreparedSqlQueryRAII query(&_setDownloadInfoQuery, QByteArrayLiteral("INSERT OR REPLACE INTO downloadinfo " - "(path, tmpfile, etag, errorcount) " - "VALUES ( ?1 , ?2, ?3, ?4 )"), + const auto query = _queryManager.get(PreparedSqlQueryManager::SetDownloadInfoQuery, QByteArrayLiteral("INSERT OR REPLACE INTO downloadinfo " + "(path, tmpfile, etag, errorcount) " + "VALUES ( ?1 , ?2, ?3, ?4 )"), _db); if (!query) { return; @@ -1531,7 +1530,7 @@ void SyncJournalDb::setDownloadInfo(const QString &file, const SyncJournalDb::Do query->bindValue(4, i._errorCount); query->exec(); } else { - const PreparedSqlQueryRAII query(&_deleteDownloadInfoQuery); + const auto query = _queryManager.get(PreparedSqlQueryManager::DeleteDownloadInfoQuery); query->bindValue(1, file); query->exec(); } @@ -1568,7 +1567,7 @@ QVector SyncJournalDb::getAndDeleteStaleDownloadInf } { - const PreparedSqlQueryRAII query(&_deleteDownloadInfoQuery); + const auto query = _queryManager.get(PreparedSqlQueryManager::DeleteDownloadInfoQuery); if (!deleteBatch(*query, superfluousPaths, QStringLiteral("downloadinfo"))) { return empty_result; } @@ -1602,8 +1601,8 @@ SyncJournalDb::UploadInfo SyncJournalDb::getUploadInfo(const QString &file) UploadInfo res; if (checkConnect()) { - const PreparedSqlQueryRAII query(&_getUploadInfoQuery, QByteArrayLiteral("SELECT chunk, transferid, errorcount, size, modtime, contentChecksum FROM " - "uploadinfo WHERE path=?1"), + const auto query = _queryManager.get(PreparedSqlQueryManager::GetUploadInfoQuery, QByteArrayLiteral("SELECT chunk, transferid, errorcount, size, modtime, contentChecksum FROM " + "uploadinfo WHERE path=?1"), _db); if (!query) { return res; @@ -1637,9 +1636,9 @@ void SyncJournalDb::setUploadInfo(const QString &file, const SyncJournalDb::Uplo } if (i._valid) { - const PreparedSqlQueryRAII query(&_setUploadInfoQuery, QByteArrayLiteral("INSERT OR REPLACE INTO uploadinfo " - "(path, chunk, transferid, errorcount, size, modtime, contentChecksum) " - "VALUES ( ?1 , ?2, ?3 , ?4 , ?5, ?6 , ?7 )"), + const auto query = _queryManager.get(PreparedSqlQueryManager::SetUploadInfoQuery, QByteArrayLiteral("INSERT OR REPLACE INTO uploadinfo " + "(path, chunk, transferid, errorcount, size, modtime, contentChecksum) " + "VALUES ( ?1 , ?2, ?3 , ?4 , ?5, ?6 , ?7 )"), _db); if (!query) { return; @@ -1657,7 +1656,7 @@ void SyncJournalDb::setUploadInfo(const QString &file, const SyncJournalDb::Uplo return; } } else { - const PreparedSqlQueryRAII query(&_deleteUploadInfoQuery); + const auto query = _queryManager.get(PreparedSqlQueryManager::DeleteUploadInfoQuery); query->bindValue(1, file); if (!query->exec()) { @@ -1692,7 +1691,7 @@ QVector SyncJournalDb::deleteStaleUploadInfos(const QSet &keep) } } - const PreparedSqlQueryRAII deleteUploadInfoQuery(&_deleteUploadInfoQuery); + const auto deleteUploadInfoQuery = _queryManager.get(PreparedSqlQueryManager::DeleteUploadInfoQuery); deleteBatch(*deleteUploadInfoQuery, superfluousPaths, QStringLiteral("uploadinfo")); return ids; } @@ -1706,7 +1705,7 @@ SyncJournalErrorBlacklistRecord SyncJournalDb::errorBlacklistEntry(const QString return entry; if (checkConnect()) { - const PreparedSqlQueryRAII query(&_getErrorBlacklistQuery); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetErrorBlacklistQuery); query->bindValue(1, file); if (query->exec()) { if (query->next().hasData) { @@ -1847,9 +1846,9 @@ void SyncJournalDb::setErrorBlacklistEntry(const SyncJournalErrorBlacklistRecord return; } - const PreparedSqlQueryRAII query(&_setErrorBlacklistQuery, QByteArrayLiteral("INSERT OR REPLACE INTO blacklist " - "(path, lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget, errorCategory, requestId) " - "VALUES ( ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"), + const auto query = _queryManager.get(PreparedSqlQueryManager::SetErrorBlacklistQuery, QByteArrayLiteral("INSERT OR REPLACE INTO blacklist " + "(path, lastTryEtag, lastTryModtime, retrycount, errorstring, lastTryTime, ignoreDuration, renameTarget, errorCategory, requestId) " + "VALUES ( ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"), _db); if (!query) { return; @@ -1927,7 +1926,7 @@ QStringList SyncJournalDb::getSelectiveSyncList(SyncJournalDb::SelectiveSyncList return result; } - const PreparedSqlQueryRAII query(&_getSelectiveSyncListQuery, QByteArrayLiteral("SELECT path FROM selectivesync WHERE type=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetSelectiveSyncListQuery, QByteArrayLiteral("SELECT path FROM selectivesync WHERE type=?1"), _db); if (!query) { *ok = false; return result; @@ -2064,7 +2063,7 @@ QByteArray SyncJournalDb::getChecksumType(int checksumTypeId) } // Retrieve the id - const PreparedSqlQueryRAII query(&_getChecksumTypeQuery, QByteArrayLiteral("SELECT name FROM checksumtype WHERE id=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetChecksumTypeQuery, QByteArrayLiteral("SELECT name FROM checksumtype WHERE id=?1"), _db); if (!query) { return {}; } @@ -2092,7 +2091,7 @@ int SyncJournalDb::mapChecksumType(const QByteArray &checksumType) // Ensure the checksum type is in the db { - const PreparedSqlQueryRAII query(&_insertChecksumTypeQuery, QByteArrayLiteral("INSERT OR IGNORE INTO checksumtype (name) VALUES (?1)"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::InsertChecksumTypeQuery, QByteArrayLiteral("INSERT OR IGNORE INTO checksumtype (name) VALUES (?1)"), _db); if (!query) { return 0; } @@ -2104,7 +2103,7 @@ int SyncJournalDb::mapChecksumType(const QByteArray &checksumType) // Retrieve the id { - const PreparedSqlQueryRAII query(&_getChecksumTypeIdQuery, QByteArrayLiteral("SELECT id FROM checksumtype WHERE name=?1"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetChecksumTypeIdQuery, QByteArrayLiteral("SELECT id FROM checksumtype WHERE name=?1"), _db); if (!query) { return 0; } @@ -2130,7 +2129,7 @@ QByteArray SyncJournalDb::dataFingerprint() return QByteArray(); } - const PreparedSqlQueryRAII query(&_getDataFingerprintQuery, QByteArrayLiteral("SELECT fingerprint FROM datafingerprint"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetDataFingerprintQuery, QByteArrayLiteral("SELECT fingerprint FROM datafingerprint"), _db); if (!query) { return QByteArray(); } @@ -2152,16 +2151,16 @@ void SyncJournalDb::setDataFingerprint(const QByteArray &dataFingerprint) return; } - const PreparedSqlQueryRAII setDataFingerprintQuery1(&_setDataFingerprintQuery1, QByteArrayLiteral("DELETE FROM datafingerprint;"), _db); - const PreparedSqlQueryRAII setDataFingerprintQuery2(&_setDataFingerprintQuery2, QByteArrayLiteral("INSERT INTO datafingerprint (fingerprint) VALUES (?1);"), _db); + const auto setDataFingerprintQuery1 = _queryManager.get(PreparedSqlQueryManager::SetDataFingerprintQuery1, QByteArrayLiteral("DELETE FROM datafingerprint;"), _db); + const auto setDataFingerprintQuery2 = _queryManager.get(PreparedSqlQueryManager::SetDataFingerprintQuery2, QByteArrayLiteral("INSERT INTO datafingerprint (fingerprint) VALUES (?1);"), _db); if (!setDataFingerprintQuery1 || !setDataFingerprintQuery2) { return; } - _setDataFingerprintQuery1.exec(); + setDataFingerprintQuery1->exec(); - _setDataFingerprintQuery2.bindValue(1, dataFingerprint); - _setDataFingerprintQuery2.exec(); + setDataFingerprintQuery2->bindValue(1, dataFingerprint); + setDataFingerprintQuery2->exec(); } void SyncJournalDb::setConflictRecord(const ConflictRecord &record) @@ -2170,10 +2169,10 @@ void SyncJournalDb::setConflictRecord(const ConflictRecord &record) if (!checkConnect()) return; - const PreparedSqlQueryRAII query(&_setConflictRecordQuery, QByteArrayLiteral("INSERT OR REPLACE INTO conflicts " - "(path, baseFileId, baseModtime, baseEtag, basePath) " - "VALUES (?1, ?2, ?3, ?4, ?5);"), - _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::SetConflictRecordQuery, QByteArrayLiteral("INSERT OR REPLACE INTO conflicts " + "(path, baseFileId, baseModtime, baseEtag, basePath) " + "VALUES (?1, ?2, ?3, ?4, ?5);"), + _db); ASSERT(query) query->bindValue(1, record.path); query->bindValue(2, record.baseFileId); @@ -2191,7 +2190,7 @@ ConflictRecord SyncJournalDb::conflictRecord(const QByteArray &path) if (!checkConnect()) { return entry; } - const PreparedSqlQueryRAII query(&_getConflictRecordQuery, QByteArrayLiteral("SELECT baseFileId, baseModtime, baseEtag, basePath FROM conflicts WHERE path=?1;"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::GetConflictRecordQuery, QByteArrayLiteral("SELECT baseFileId, baseModtime, baseEtag, basePath FROM conflicts WHERE path=?1;"), _db); ASSERT(query) query->bindValue(1, path); ASSERT(query->exec()) @@ -2212,7 +2211,7 @@ void SyncJournalDb::deleteConflictRecord(const QByteArray &path) if (!checkConnect()) return; - const PreparedSqlQueryRAII query(&_deleteConflictRecordQuery, QByteArrayLiteral("DELETE FROM conflicts WHERE path=?1;"), _db); + const auto query = _queryManager.get(PreparedSqlQueryManager::DeleteConflictRecordQuery, QByteArrayLiteral("DELETE FROM conflicts WHERE path=?1;"), _db); ASSERT(query) query->bindValue(1, path); ASSERT(query->exec()) @@ -2288,7 +2287,7 @@ Optional SyncJournalDb::PinStateInterface::rawForPath(const QByteArray if (!_db->checkConnect()) return {}; - const PreparedSqlQueryRAII query(&_db->_getRawPinStateQuery, QByteArrayLiteral("SELECT pinState FROM flags WHERE path == ?1;"), _db->_db); + const auto query = _db->_queryManager.get(PreparedSqlQueryManager::GetRawPinStateQuery, QByteArrayLiteral("SELECT pinState FROM flags WHERE path == ?1;"), _db->_db); ASSERT(query) query->bindValue(1, path); query->exec(); @@ -2309,14 +2308,13 @@ Optional SyncJournalDb::PinStateInterface::effectiveForPath(const QByt if (!_db->checkConnect()) return {}; - const PreparedSqlQueryRAII query(&_db->_getEffectivePinStateQuery, QByteArrayLiteral( - "SELECT pinState FROM flags WHERE" - // explicitly allow "" to represent the root path - // (it'd be great if paths started with a / and "/" could be the root) - " (" IS_PREFIX_PATH_OR_EQUAL("path", "?1") " OR path == '')" - " AND pinState is not null AND pinState != 0" - " ORDER BY length(path) DESC LIMIT 1;"), - _db->_db); + const auto query = _db->_queryManager.get(PreparedSqlQueryManager::GetEffectivePinStateQuery, QByteArrayLiteral("SELECT pinState FROM flags WHERE" + // explicitly allow "" to represent the root path + // (it'd be great if paths started with a / and "/" could be the root) + " (" IS_PREFIX_PATH_OR_EQUAL("path", "?1") " OR path == '')" + " AND pinState is not null AND pinState != 0" + " ORDER BY length(path) DESC LIMIT 1;"), + _db->_db); ASSERT(query) query->bindValue(1, path); query->exec(); @@ -2344,10 +2342,10 @@ Optional SyncJournalDb::PinStateInterface::effectiveForPathRecursive(c return {}; // Find all the non-inherited pin states below the item - const PreparedSqlQueryRAII query(&_db->_getSubPinsQuery, QByteArrayLiteral("SELECT DISTINCT pinState FROM flags WHERE" - " (" IS_PREFIX_PATH_OF("?1", "path") " OR ?1 == '')" - " AND pinState is not null and pinState != 0;"), - _db->_db); + const auto query = _db->_queryManager.get(PreparedSqlQueryManager::GetSubPinsQuery, QByteArrayLiteral("SELECT DISTINCT pinState FROM flags WHERE" + " (" IS_PREFIX_PATH_OF("?1", "path") " OR ?1 == '')" + " AND pinState is not null and pinState != 0;"), + _db->_db); ASSERT(query) query->bindValue(1, path); query->exec(); @@ -2373,13 +2371,13 @@ void SyncJournalDb::PinStateInterface::setForPath(const QByteArray &path, PinSta if (!_db->checkConnect()) return; - const PreparedSqlQueryRAII query(&_db->_setPinStateQuery, QByteArrayLiteral( - // If we had sqlite >=3.24.0 everywhere this could be an upsert, - // making further flags columns easy - //"INSERT INTO flags(path, pinState) VALUES(?1, ?2)" - //" ON CONFLICT(path) DO UPDATE SET pinState=?2;"), - // Simple version that doesn't work nicely with multiple columns: - "INSERT OR REPLACE INTO flags(path, pinState) VALUES(?1, ?2);"), + const auto query = _db->_queryManager.get(PreparedSqlQueryManager::SetPinStateQuery, QByteArrayLiteral( + // If we had sqlite >=3.24.0 everywhere this could be an upsert, + // making further flags columns easy + //"INSERT INTO flags(path, pinState) VALUES(?1, ?2)" + //" ON CONFLICT(path) DO UPDATE SET pinState=?2;"), + // Simple version that doesn't work nicely with multiple columns: + "INSERT OR REPLACE INTO flags(path, pinState) VALUES(?1, ?2);"), _db->_db); ASSERT(query) query->bindValue(1, path); @@ -2393,10 +2391,10 @@ void SyncJournalDb::PinStateInterface::wipeForPathAndBelow(const QByteArray &pat if (!_db->checkConnect()) return; - const PreparedSqlQueryRAII query(&_db->_wipePinStateQuery, QByteArrayLiteral("DELETE FROM flags WHERE " - // Allow "" to delete everything - " (" IS_PREFIX_PATH_OR_EQUAL("?1", "path") " OR ?1 == '');"), - _db->_db); + const auto query = _db->_queryManager.get(PreparedSqlQueryManager::WipePinStateQuery, QByteArrayLiteral("DELETE FROM flags WHERE " + // Allow "" to delete everything + " (" IS_PREFIX_PATH_OR_EQUAL("?1", "path") " OR ?1 == '');"), + _db->_db); ASSERT(query) query->bindValue(1, path); query->exec(); diff --git a/src/common/syncjournaldb.h b/src/common/syncjournaldb.h index aa949752a886..ba4c0ede8ee7 100644 --- a/src/common/syncjournaldb.h +++ b/src/common/syncjournaldb.h @@ -28,6 +28,7 @@ #include "common/utility.h" #include "common/ownsql.h" +#include "common/preparedsqlquerymanager.h" #include "common/syncjournalfilerecord.h" #include "common/result.h" #include "common/pinstate.h" @@ -46,7 +47,7 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject Q_OBJECT public: explicit SyncJournalDb(const QString &dbFilePath, QObject *parent = nullptr); - virtual ~SyncJournalDb(); + ~SyncJournalDb() override; /// Create a journal path for a specific configuration static QString makeDbName(const QString &localPath, @@ -392,51 +393,11 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject SqlDatabase _db; QString _dbFile; - QMutex _mutex; // Public functions are protected with the mutex. + QRecursiveMutex _mutex; // Public functions are protected with the mutex. QMap _checksymTypeCache; int _transaction; bool _metadataTableIsEmpty; - SqlQuery _getFileRecordQuery; - SqlQuery _getFileRecordQueryByMangledName; - SqlQuery _getFileRecordQueryByInode; - SqlQuery _getFileRecordQueryByFileId; - SqlQuery _getFilesBelowPathQuery; - SqlQuery _getAllFilesQuery; - SqlQuery _listFilesInPathQuery; - SqlQuery _setFileRecordQuery; - SqlQuery _setFileRecordChecksumQuery; - SqlQuery _setFileRecordLocalMetadataQuery; - SqlQuery _getDownloadInfoQuery; - SqlQuery _setDownloadInfoQuery; - SqlQuery _deleteDownloadInfoQuery; - SqlQuery _getUploadInfoQuery; - SqlQuery _setUploadInfoQuery; - SqlQuery _deleteUploadInfoQuery; - SqlQuery _deleteFileRecordPhash; - SqlQuery _deleteFileRecordRecursively; - SqlQuery _getErrorBlacklistQuery; - SqlQuery _setErrorBlacklistQuery; - SqlQuery _getSelectiveSyncListQuery; - SqlQuery _getChecksumTypeIdQuery; - SqlQuery _getChecksumTypeQuery; - SqlQuery _insertChecksumTypeQuery; - SqlQuery _getDataFingerprintQuery; - SqlQuery _setDataFingerprintQuery1; - SqlQuery _setDataFingerprintQuery2; - SqlQuery _setKeyValueStoreQuery; - SqlQuery _getKeyValueStoreQuery; - SqlQuery _deleteKeyValueStoreQuery; - SqlQuery _getConflictRecordQuery; - SqlQuery _setConflictRecordQuery; - SqlQuery _deleteConflictRecordQuery; - SqlQuery _getRawPinStateQuery; - SqlQuery _getEffectivePinStateQuery; - SqlQuery _getSubPinsQuery; - SqlQuery _countDehydratedFilesQuery; - SqlQuery _setPinStateQuery; - SqlQuery _wipePinStateQuery; - /* Storing etags to these folders, or their parent folders, is filtered out. * * When schedulePathForRemoteDiscovery() is called some etags to _invalid_ in the @@ -458,6 +419,8 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject * variable, for specific filesystems, or when WAL fails in a particular way. */ QByteArray _journalMode; + + PreparedSqlQueryManager _queryManager; }; bool OCSYNC_EXPORT diff --git a/src/common/utility.cpp b/src/common/utility.cpp index e31534ca3808..bd9394b8c3e6 100644 --- a/src/common/utility.cpp +++ b/src/common/utility.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef Q_OS_UNIX @@ -64,14 +65,13 @@ Q_LOGGING_CATEGORY(lcUtility, "nextcloud.sync.utility", QtInfoMsg) bool Utility::writeRandomFile(const QString &fname, int size) { int maxSize = 10 * 10 * 1024; - qsrand(QDateTime::currentMSecsSinceEpoch()); if (size == -1) - size = qrand() % maxSize; + size = rand() % maxSize; QString randString; for (int i = 0; i < size; i++) { - int r = qrand() % 128; + int r = rand() % 128; randString.append(QChar(r)); } @@ -259,6 +259,11 @@ QString Utility::escape(const QString &in) return in.toHtmlEscaped(); } +int Utility::rand() +{ + return QRandomGenerator::global()->bounded(0, RAND_MAX); +} + void Utility::sleep(int sec) { QThread::sleep(sec); diff --git a/src/common/utility.h b/src/common/utility.h index 0d0bc3ade383..9522d188e7dd 100644 --- a/src/common/utility.h +++ b/src/common/utility.h @@ -50,6 +50,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcUtility) * @{ */ namespace Utility { + OCSYNC_EXPORT int rand(); OCSYNC_EXPORT void sleep(int sec); OCSYNC_EXPORT void usleep(int usec); OCSYNC_EXPORT QString formatFingerprint(const QByteArray &, bool colonSeparated = true); diff --git a/src/common/utility_unix.cpp b/src/common/utility_unix.cpp index 010408395f19..087254e60060 100644 --- a/src/common/utility_unix.cpp +++ b/src/common/utility_unix.cpp @@ -80,17 +80,17 @@ void setLaunchOnStartup_private(const QString &appName, const QString &guiName, QTextStream ts(&iniFile); ts.setCodec("UTF-8"); - ts << QLatin1String("[Desktop Entry]") << endl - << QLatin1String("Name=") << guiName << endl - << QLatin1String("GenericName=") << QLatin1String("File Synchronizer") << endl - << QLatin1String("Exec=\"") << executablePath << "\" --background" << endl - << QLatin1String("Terminal=") << "false" << endl - << QLatin1String("Icon=") << APPLICATION_ICON_NAME << endl - << QLatin1String("Categories=") << QLatin1String("Network") << endl - << QLatin1String("Type=") << QLatin1String("Application") << endl - << QLatin1String("StartupNotify=") << "false" << endl - << QLatin1String("X-GNOME-Autostart-enabled=") << "true" << endl - << QLatin1String("X-GNOME-Autostart-Delay=10") << endl; + ts << QLatin1String("[Desktop Entry]\n") + << QLatin1String("Name=") << guiName << QLatin1Char('\n') + << QLatin1String("GenericName=") << QLatin1String("File Synchronizer\n") + << QLatin1String("Exec=\"") << executablePath << "\" --background\n" + << QLatin1String("Terminal=") << "false\n" + << QLatin1String("Icon=") << APPLICATION_ICON_NAME << QLatin1Char('\n') + << QLatin1String("Categories=") << QLatin1String("Network\n") + << QLatin1String("Type=") << QLatin1String("Application\n") + << QLatin1String("StartupNotify=") << "false\n" + << QLatin1String("X-GNOME-Autostart-enabled=") << "true\n" + << QLatin1String("X-GNOME-Autostart-Delay=10") << Qt::endl; } else { if (!QFile::remove(desktopFileLocation)) { qCWarning(lcUtility) << "Could not remove autostart desktop file"; diff --git a/src/common/vfs.cpp b/src/common/vfs.cpp index 71ff5dae02d4..593c4c3bcdc6 100644 --- a/src/common/vfs.cpp +++ b/src/common/vfs.cpp @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "vfs.h" #include "plugin.h" #include "version.h" diff --git a/src/common/vfs.h b/src/common/vfs.h index 0f12f8c2e691..259dadbe7d0b 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -126,7 +126,7 @@ class OCSYNC_EXPORT Vfs : public QObject public: explicit Vfs(QObject* parent = nullptr); - virtual ~Vfs(); + ~Vfs() override; virtual Mode mode() const = 0; @@ -291,7 +291,7 @@ class OCSYNC_EXPORT VfsOff : public Vfs public: VfsOff(QObject* parent = nullptr); - virtual ~VfsOff(); + ~VfsOff() override; Mode mode() const override { return Vfs::Off; } diff --git a/src/crashreporter/main.cpp b/src/crashreporter/main.cpp index 7d647426f007..9d057e05a885 100644 --- a/src/crashreporter/main.cpp +++ b/src/crashreporter/main.cpp @@ -18,7 +18,9 @@ #include #include +#include #include +#include int main(int argc, char *argv[]) { @@ -52,6 +54,14 @@ int main(int argc, char *argv[]) reporter.setWindowTitle(CRASHREPORTER_PRODUCT_NAME); reporter.setText("

Sorry! " CRASHREPORTER_PRODUCT_NAME " crashed. Please tell us about it! " CRASHREPORTER_PRODUCT_NAME " has created an error report for you that can help improve the stability in the future. You can now send this report directly to the " CRASHREPORTER_PRODUCT_NAME " developers.

"); + const QFileInfo crashLog(QDir::tempPath() + QStringLiteral("/" CRASHREPORTER_PRODUCT_NAME "-crash.log")); + if (crashLog.exists()) { + QFile inFile(crashLog.filePath()); + if (inFile.open(QFile::ReadOnly)) { + reporter.setComment(inFile.readAll()); + } + } + reporter.setReportData("BuildID", CRASHREPORTER_BUILD_ID); reporter.setReportData("ProductName", CRASHREPORTER_PRODUCT_NAME); reporter.setReportData("Version", CRASHREPORTER_VERSION_STRING); diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 2a7cdff6df7c..ec655df6783d 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -58,10 +58,11 @@ endif() configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h) -add_library("${csync_NAME}" SHARED ${common_SOURCES} ${csync_SRCS}) +add_library(nextcloud_csync SHARED ${common_SOURCES} ${csync_SRCS}) +add_library(Nextcloud::csync ALIAS nextcloud_csync) target_include_directories( - "${csync_NAME}" + nextcloud_csync PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/std ) @@ -69,26 +70,26 @@ if(USE_OUR_OWN_SQLITE3) message(STATUS "Using own sqlite3 version") add_library(sqlite3 STATIC "${CMAKE_SOURCE_DIR}/src/3rdparty/sqlite3/sqlite3.c") target_include_directories(sqlite3 PUBLIC "${CMAKE_SOURCE_DIR}/src/3rdparty/sqlite3") - target_link_libraries("${csync_NAME}" PUBLIC sqlite3) + target_link_libraries(nextcloud_csync PUBLIC sqlite3) else() - target_include_directories("${csync_NAME}" PUBLIC ${SQLITE3_INCLUDE_DIR}) - target_link_libraries("${csync_NAME}" PUBLIC ${SQLITE3_LIBRARIES}) + target_include_directories(nextcloud_csync PUBLIC ${SQLITE3_INCLUDE_DIR}) + target_link_libraries(nextcloud_csync PUBLIC ${SQLITE3_LIBRARIES}) endif() -generate_export_header("${csync_NAME}" +generate_export_header(nextcloud_csync EXPORT_MACRO_NAME OCSYNC_EXPORT EXPORT_FILE_NAME ocsynclib.h ) -target_link_libraries("${csync_NAME}" +target_link_libraries(nextcloud_csync PUBLIC ${CSYNC_REQUIRED_LIBRARIES} Qt5::Core Qt5::Concurrent ) if(ZLIB_FOUND) - target_link_libraries("${csync_NAME}" PUBLIC ZLIB::ZLIB) + target_link_libraries(nextcloud_csync PUBLIC ZLIB::ZLIB) endif(ZLIB_FOUND) @@ -96,11 +97,11 @@ endif(ZLIB_FOUND) if (APPLE) find_library(FOUNDATION_LIBRARY NAMES Foundation) find_library(CORESERVICES_LIBRARY NAMES CoreServices) - target_link_libraries("${csync_NAME}" PUBLIC ${FOUNDATION_LIBRARY} ${CORESERVICES_LIBRARY}) + target_link_libraries(nextcloud_csync PUBLIC ${FOUNDATION_LIBRARY} ${CORESERVICES_LIBRARY}) endif() set_target_properties( - "${csync_NAME}" + nextcloud_csync PROPERTIES VERSION ${LIBRARY_VERSION} @@ -108,11 +109,15 @@ set_target_properties( ${LIBRARY_SOVERSION} RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}_csync + RUNTIME_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}_csync ) if(BUILD_OWNCLOUD_OSX_BUNDLE) INSTALL( TARGETS - "${csync_NAME}" + nextcloud_csync LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION @@ -123,7 +128,7 @@ if(BUILD_OWNCLOUD_OSX_BUNDLE) else() INSTALL( TARGETS - "${csync_NAME}" + nextcloud_csync LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION diff --git a/src/csync/ConfigureChecks.cmake b/src/csync/ConfigureChecks.cmake index 9aac6673ac14..64bdf1770ee6 100644 --- a/src/csync/ConfigureChecks.cmake +++ b/src/csync/ConfigureChecks.cmake @@ -7,7 +7,6 @@ include(CheckCXXSourceCompiles) set(PACKAGE ${APPLICATION_NAME}) set(VERSION ${APPLICATION_VERSION}) -set(DATADIR ${DATA_INSTALL_DIR}) set(LIBDIR ${LIB_INSTALL_DIR}) set(SYSCONFDIR ${SYSCONF_INSTALL_DIR}) @@ -23,6 +22,12 @@ if (NOT LINUX) check_library_exists(rt nanosleep "" HAVE_LIBRT) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ) + + # Systems not using glibc require linker flag for argp + check_library_exists(argp argp_parse "" HAVE_LIBARGP) + if(HAVE_ARGP_H AND HAVE_LIBARGP) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} argp) + endif() endif (NOT LINUX) if(WIN32) diff --git a/src/csync/csync_exclude.cpp b/src/csync/csync_exclude.cpp index f9968ae7b89e..eb850758917a 100644 --- a/src/csync/csync_exclude.cpp +++ b/src/csync/csync_exclude.cpp @@ -19,6 +19,7 @@ */ #include "config_csync.h" +#include #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -34,10 +35,8 @@ #include #include -#include #include - /** Expands C-like escape sequences (in place) */ OCSYNC_EXPORT void csync_exclude_expand_escapes(QByteArray &input) @@ -199,13 +198,13 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(const QString &path, bool exclu } #endif - /* We create a Desktop.ini on Windows for the sidebar icon, make sure we don't sync it. */ - if (blen == 11 && path == bname) { - if (bname.compare(QLatin1String("Desktop.ini"), Qt::CaseInsensitive) == 0) { - return CSYNC_FILE_SILENTLY_EXCLUDED; - } + /* Do not sync desktop.ini files anywhere in the tree. */ + const auto desktopIniFile = QStringLiteral("desktop.ini"); + if (blen == static_cast(desktopIniFile.length()) && bname.compare(desktopIniFile, Qt::CaseInsensitive) == 0) { + return CSYNC_FILE_SILENTLY_EXCLUDED; } + if (excludeConflictFiles && OCC::Utility::isConflictFile(path)) { return CSYNC_FILE_EXCLUDE_CONFLICT; } @@ -231,24 +230,21 @@ ExcludedFiles::ExcludedFiles(const QString &localPath) // We're in a detached exclude probably coming from a partial sync or test if (_localPath.isEmpty()) return; - - // Load exclude file from base dir - QFileInfo fi(_localPath + QStringLiteral(".sync-exclude.lst")); - if (fi.isReadable()) - addInTreeExcludeFilePath(fi.absoluteFilePath()); } ExcludedFiles::~ExcludedFiles() = default; void ExcludedFiles::addExcludeFilePath(const QString &path) { - _excludeFiles[_localPath].append(path); -} - -void ExcludedFiles::addInTreeExcludeFilePath(const QString &path) -{ - BasePathString basePath = leftIncludeLast(path, QLatin1Char('/')); - _excludeFiles[basePath].append(path); + const QFileInfo excludeFileInfo(path); + const auto fileName = excludeFileInfo.fileName(); + const auto basePath = fileName.compare(QStringLiteral("sync-exclude.lst"), Qt::CaseInsensitive) == 0 + ? _localPath + : leftIncludeLast(path, QLatin1Char('/')); + auto &excludeFilesLocalPath = _excludeFiles[basePath]; + if (std::find(excludeFilesLocalPath.cbegin(), excludeFilesLocalPath.cend(), path) == excludeFilesLocalPath.cend()) { + excludeFilesLocalPath.append(path); + } } void ExcludedFiles::setExcludeConflictFiles(bool onoff) @@ -288,32 +284,26 @@ void ExcludedFiles::setClientVersion(ExcludedFiles::Version version) _clientVersion = version; } -bool ExcludedFiles::loadExcludeFile(const QString &basePath, const QString & file) +void ExcludedFiles::loadExcludeFilePatterns(const QString &basePath, QFile &file) { - QFile f(file); - if (!f.open(QIODevice::ReadOnly)) - return false; - QStringList patterns; - while (!f.atEnd()) { - QByteArray line = f.readLine().trimmed(); + while (!file.atEnd()) { + QByteArray line = file.readLine().trimmed(); if (line.startsWith("#!version")) { if (!versionDirectiveKeepNextLine(line)) - f.readLine(); + file.readLine(); } if (line.isEmpty() || line.startsWith('#')) continue; csync_exclude_expand_escapes(line); patterns.append(QString::fromUtf8(line)); } - _allExcludes.insert(basePath, patterns); + _allExcludes[basePath].append(patterns); // nothing to prepare if the user decided to not exclude anything if (!_allExcludes.value(basePath).isEmpty()){ prepare(basePath); } - - return true; } bool ExcludedFiles::reloadExcludeFiles() @@ -330,8 +320,14 @@ bool ExcludedFiles::reloadExcludeFiles() bool success = true; const auto keys = _excludeFiles.keys(); for (const auto& basePath : keys) { - for (const auto& file : _excludeFiles.value(basePath)) { - success = loadExcludeFile(basePath, file); + for (const auto &excludeFile : _excludeFiles.value(basePath)) { + QFile file(excludeFile); + if (file.exists() && file.open(QIODevice::ReadOnly)) { + loadExcludeFilePatterns(basePath, file); + } else { + success = false; + qWarning() << "System exclude list file could not be opened:" << excludeFile; + } } } @@ -422,11 +418,14 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(const QString &path, Ite // Directories are guaranteed to be visited before their files if (filetype == ItemTypeDirectory) { const auto basePath = QString(_localPath + path + QLatin1Char('/')); - const auto fi = QFileInfo(basePath + QStringLiteral(".sync-exclude.lst")); + const QString absolutePath = basePath + QStringLiteral(".sync-exclude.lst"); + QFileInfo excludeFileInfo(absolutePath); - if (fi.isReadable()) { - addInTreeExcludeFilePath(fi.absoluteFilePath()); - loadExcludeFile(basePath, fi.absoluteFilePath()); + if (excludeFileInfo.isReadable()) { + addExcludeFilePath(absolutePath); + reloadExcludeFiles(); + } else { + qWarning() << "System exclude list file could not be read:" << absolutePath; } } diff --git a/src/csync/csync_exclude.h b/src/csync/csync_exclude.h index bbb0a2cda965..856ac67eff8a 100644 --- a/src/csync/csync_exclude.h +++ b/src/csync/csync_exclude.h @@ -48,6 +48,7 @@ enum CSYNC_EXCLUDE_TYPE { }; class ExcludedFilesTest; +class QFile; /** * Manages file/directory exclusion. @@ -69,7 +70,7 @@ class OCSYNC_EXPORT ExcludedFiles : public QObject using Version = std::tuple; explicit ExcludedFiles(const QString &localPath = QStringLiteral("/")); - ~ExcludedFiles(); + ~ExcludedFiles() override; /** * Adds a new path to a file containing exclude patterns. @@ -77,7 +78,6 @@ class OCSYNC_EXPORT ExcludedFiles : public QObject * Does not load the file. Use reloadExcludeFiles() afterwards. */ void addExcludeFilePath(const QString &path); - void addInTreeExcludeFilePath(const QString &path); /** * Whether conflict files shall be excluded. @@ -148,7 +148,7 @@ public slots: /** * Loads the exclude patterns from file the registered base paths. */ - bool loadExcludeFile(const QString &basePath, const QString &file); + void loadExcludeFilePatterns(const QString &basePath, QFile &file); private: /** diff --git a/src/csync/vio/csync_vio_local_win.cpp b/src/csync/vio/csync_vio_local_win.cpp index 7aa07f4da4ea..4ddd4f545fa4 100644 --- a/src/csync/vio/csync_vio_local_win.cpp +++ b/src/csync/vio/csync_vio_local_win.cpp @@ -34,6 +34,7 @@ #include "csync.h" #include "vio/csync_vio_local.h" #include "common/filesystembase.h" +#include "common/utility.h" #include @@ -52,8 +53,6 @@ struct csync_vio_handle_t { QString path; // Always ends with '\' }; -static int _csync_vio_local_stat_mb(const QString &path, csync_file_stat_t *buf); - csync_vio_handle_t *csync_vio_local_opendir(const QString &name) { QScopedPointer handle(new csync_vio_handle_t{}); @@ -175,12 +174,9 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h file_stat->size = (handle->ffd.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + handle->ffd.nFileSizeLow; file_stat->modtime = FileTimeToUnixTime(&handle->ffd.ftLastWriteTime, &rem); - QString fullPath; - fullPath.reserve(handle->path.size() + std::wcslen(handle->ffd.cFileName)); - fullPath += handle->path; // path always ends with '\', by construction - fullPath += QString::fromWCharArray(handle->ffd.cFileName); + // path always ends with '\', by construction - if (_csync_vio_local_stat_mb(fullPath, file_stat.get()) < 0) { + if (csync_vio_local_stat(handle->path + QString::fromWCharArray(handle->ffd.cFileName), file_stat.get()) < 0) { // Will get excluded by _csync_detect_update. file_stat->type = ItemTypeSkip; } @@ -188,14 +184,7 @@ std::unique_ptr csync_vio_local_readdir(csync_vio_handle_t *h return file_stat; } - int csync_vio_local_stat(const QString &uri, csync_file_stat_t *buf) -{ - int rc = _csync_vio_local_stat_mb(uri, buf); - return rc; -} - -static int _csync_vio_local_stat_mb(const QString &path, csync_file_stat_t *buf) { /* Almost nothing to do since csync_vio_local_readdir already filled up most of the information But we still need to fetch the file ID. @@ -206,21 +195,19 @@ static int _csync_vio_local_stat_mb(const QString &path, csync_file_stat_t *buf) BY_HANDLE_FILE_INFORMATION fileInfo; ULARGE_INTEGER FileIndex; - const auto longPath = OCC::FileSystem::longWinPath(path); - - h = CreateFileW(longPath.toStdWString().data(), 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, - nullptr, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, - nullptr ); + h = CreateFileW(reinterpret_cast(OCC::FileSystem::longWinPath(uri).utf16()), 0, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, + NULL); if( h == INVALID_HANDLE_VALUE ) { - qCCritical(lcCSyncVIOLocal) << "CreateFileW failed on" << longPath; errno = GetLastError(); + qCCritical(lcCSyncVIOLocal) << "CreateFileW failed on" << uri << OCC::Utility::formatWinError(errno); return -1; } if(!GetFileInformationByHandle( h, &fileInfo ) ) { - qCCritical(lcCSyncVIOLocal) << "GetFileInformationByHandle failed on" << longPath; errno = GetLastError(); + qCCritical(lcCSyncVIOLocal) << "GetFileInformationByHandle failed on" << uri << OCC::Utility::formatWinError(errno); CloseHandle(h); return -1; } diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 6b365afd81a1..a29518fe02ce 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1,5 +1,8 @@ project(gui) -find_package(Qt5 REQUIRED COMPONENTS Widgets Svg Qml Quick QuickControls2) +find_package(Qt5 REQUIRED COMPONENTS Widgets Svg Qml Quick QuickControls2 Xml Network) +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.") +endif() if(CMAKE_BUILD_TYPE MATCHES Debug) add_definitions(-DQT_QML_DEBUG) @@ -18,6 +21,7 @@ set(theme_dir ${CMAKE_SOURCE_DIR}/theme) set(client_UI_SRCS accountsettings.ui conflictdialog.ui + invalidfilenamedialog.ui foldercreationdialog.ui folderwizardsourcepage.ui folderwizardtargetpage.ui @@ -35,17 +39,27 @@ set(client_UI_SRCS addcertificatedialog.ui proxyauthdialog.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/owncloudadvancedsetuppage.ui wizard/owncloudconnectionmethoddialog.ui wizard/owncloudhttpcredspage.ui wizard/owncloudoauthcredspage.ui wizard/owncloudsetupnocredspage.ui - wizard/owncloudwizardresultpage.ui wizard/webview.ui wizard/welcomepage.ui ) @@ -54,6 +68,7 @@ set(client_SRCS accountmanager.cpp accountsettings.cpp application.cpp + invalidfilenamedialog.cpp conflictdialog.cpp conflictsolver.cpp connectionvalidator.cpp @@ -86,15 +101,14 @@ set(client_SRCS sharelinkwidget.cpp sharemanager.cpp shareusergroupwidget.cpp + profilepagewidget.cpp sharee.cpp - socketapi.cpp sslbutton.cpp sslerrordialog.cpp syncrunfilelog.cpp systray.cpp thumbnailjob.cpp userinfo.cpp - userstatus.cpp accountstate.cpp addcertificatedialog.cpp authenticationdialog.cpp @@ -105,13 +119,21 @@ set(client_SRCS guiutility.cpp elidedlabel.cpp headerbanner.cpp - iconjob.cpp + iconutils.cpp remotewipe.cpp - tray/ActivityData.cpp - tray/ActivityListModel.cpp - tray/UserModel.cpp - tray/NotificationHandler.cpp - tray/NotificationCache.cpp + userstatusselectormodel.cpp + emojimodel.cpp + fileactivitylistmodel.cpp + tray/svgimageprovider.cpp + tray/syncstatussummary.cpp + tray/activitydata.cpp + tray/activitylistmodel.cpp + tray/unifiedsearchresult.cpp + tray/unifiedsearchresultimageprovider.cpp + tray/unifiedsearchresultslistmodel.cpp + tray/usermodel.cpp + tray/notificationhandler.cpp + tray/notificationcache.cpp creds/credentialsfactory.cpp creds/httpcredentialsgui.cpp creds/oauth.cpp @@ -129,7 +151,6 @@ set(client_SRCS wizard/owncloudsetuppage.cpp wizard/owncloudwizardcommon.cpp wizard/owncloudwizard.cpp - wizard/owncloudwizardresultpage.cpp wizard/slideshow.cpp wizard/welcomepage.cpp wizard/linklabel.cpp @@ -241,13 +262,13 @@ if (NOT DEFINED APPLICATION_ICON_NAME) endif() # Generate png icons from svg -find_program(INKSCAPE - NAMES inkscape inkscape.exe +find_program(SVG_CONVERTER + NAMES inkscape inkscape.exe rsvg-convert REQUIRED - HINTS "C:\\Program Files\\Inkscape\\bin" "/usr/bin" ENV INKSCAPE_DIR) + HINTS "C:\\Program Files\\Inkscape\\bin" "/usr/bin" ENV SVG_CONVERTER_DIR) # REQUIRED keyword is only supported on CMake 3.18 and above -if (NOT INKSCAPE) - message(FATAL_ERROR "Could not find inkscape. Set INKSCAPE_DIR to the path of executable.") +if (NOT SVG_CONVERTER) + message(FATAL_ERROR "Could not find a suitable svg converter. Set SVG_CONVERTER_DIR to the path of either the inkscape or rsvg-convert executable.") endif() function(generate_sized_png_from_svg icon_path size) @@ -261,16 +282,16 @@ function(generate_sized_png_from_svg icon_path size) set(icon_output_name "${size}-${icon_name_wle}.png") message(STATUS "Generate ${icon_output_name}") execute_process(COMMAND - "${INKSCAPE}" -w ${size} -h ${size} "${icon_path}" -o "${icon_output_name}" + "${SVG_CONVERTER}" -w ${size} -h ${size} "${icon_path}" -o "${icon_output_name}" WORKING_DIRECTORY "${icon_name_dir}" RESULT_VARIABLE - INKSCAPE_SIDEBAR_ERROR + SVG_CONVERTER_SIDEBAR_ERROR OUTPUT_QUIET ERROR_QUIET) - if (INKSCAPE_SIDEBAR_ERROR) + if (SVG_CONVERTER_SIDEBAR_ERROR) message(FATAL_ERROR - "inkscape could not generate icon: ${INKSCAPE_SIDEBAR_ERROR}") + "${SVG_CONVERTER} could not generate icon: ${SVG_CONVERTER_SIDEBAR_ERROR}") else() endif() endfunction() @@ -330,6 +351,7 @@ add_library(nextcloudCore STATIC ${final_src}) target_link_libraries(nextcloudCore PUBLIC + Nextcloud::sync Qt5::Widgets Qt5::GuiPrivate Qt5::Svg @@ -338,9 +360,10 @@ target_link_libraries(nextcloudCore Qt5::Qml Qt5::Quick Qt5::QuickControls2 - ${synclib_NAME} ) +add_subdirectory(socketapi) + if(Qt5WebEngine_FOUND AND Qt5WebEngineWidgets_FOUND) target_link_libraries(nextcloudCore PUBLIC Qt5::WebEngineWidgets) endif() @@ -368,9 +391,9 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) foreach(_file ${_icons}) string(REPLACE "${theme_dir}/colored/" "" _res ${_file}) string(REPLACE "-${APPLICATION_ICON_NAME}-icon.png" "" _res ${_res}) - install(FILES ${_file} RENAME ${APPLICATION_ICON_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps) + install(FILES ${_file} RENAME ${APPLICATION_ICON_NAME}.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/${_res}x${_res}/apps) endforeach(_file) - install(FILES ${client_I18N} DESTINATION ${SHAREDIR}/${APPLICATION_EXECUTABLE}/i18n) + install(FILES ${client_I18N} DESTINATION ${CMAKE_INSTALL_DATADIR}/${APPLICATION_EXECUTABLE}/i18n) else() file(GLOB_RECURSE VISUAL_ELEMENTS "${theme_dir}/colored/*-${APPLICATION_ICON_NAME}-w10startmenu*") install(FILES ${VISUAL_ELEMENTS} DESTINATION bin/visualelements) @@ -379,17 +402,23 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) endif() # we may not add MACOSX_BUNDLE here, if not building one - add_executable(${APPLICATION_EXECUTABLE} WIN32 main.cpp ${client_version} ${client_manifest} ${APP_ICON}) + add_executable(nextcloud WIN32 main.cpp ${client_version} ${client_manifest} ${APP_ICON}) + set_target_properties(nextcloud PROPERTIES + OUTPUT_NAME "${APPLICATION_EXECUTABLE}" + ) else() # set(CMAKE_INSTALL_PREFIX ".") # Examples use /Applications. hurmpf. set(MACOSX_BUNDLE_ICON_FILE "${APPLICATION_ICON_NAME}.icns") # we must add MACOSX_BUNDLE only if building a bundle - add_executable(${APPLICATION_EXECUTABLE} WIN32 MACOSX_BUNDLE main.cpp ${APP_ICON}) + add_executable(nextcloud WIN32 MACOSX_BUNDLE main.cpp ${APP_ICON}) if (BUILD_OWNCLOUD_OSX_BUNDLE) - set_target_properties(${APPLICATION_EXECUTABLE} PROPERTIES + set_target_properties(nextcloud PROPERTIES OUTPUT_NAME "${APPLICATION_NAME}") + else() + set_target_properties(nextcloud PROPERTIES + OUTPUT_NAME "${APPLICATION_EXECUTABLE}") endif() set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations) @@ -409,22 +438,17 @@ endif() IF(BUILD_UPDATER) add_library(updater STATIC ${updater_SRCS}) - target_link_libraries(updater ${synclib_NAME} ${updater_DEPS} Qt5::Widgets Qt5::Svg Qt5::Network Qt5::Xml) + target_link_libraries(updater Nextcloud::sync ${updater_DEPS} Qt5::Widgets Qt5::Svg Qt5::Network Qt5::Xml) target_include_directories(updater PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties(updater PROPERTIES AUTOMOC ON) + target_link_libraries(nextcloudCore PUBLIC updater) endif() -set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} +set_target_properties(nextcloud PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} ) -target_link_libraries(${APPLICATION_EXECUTABLE} nextcloudCore) - -IF(BUILD_UPDATER) - target_link_libraries(nextcloudCore PUBLIC updater) -endif() - -target_link_libraries(nextcloudCore PUBLIC ${OS_SPECIFIC_LINK_LIBRARIES}) +target_link_libraries(nextcloud PRIVATE nextcloudCore) if(TARGET PkgConfig::CLOUDPROVIDERS) message("Building with libcloudproviderssupport") @@ -470,11 +494,7 @@ if(WITH_CRASHREPORTER) endif() endif() -# application.cpp still uses QDesktopServices::storageLocation -target_compile_definitions(nextcloudCore PRIVATE "QT_DISABLE_DEPRECATED_BEFORE=0") - - -install(TARGETS ${APPLICATION_EXECUTABLE} +install(TARGETS nextcloud RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib @@ -501,12 +521,12 @@ if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY) set(NO_STRIP "") endif() - add_custom_command(TARGET ${APPLICATION_EXECUTABLE} POST_BUILD + add_custom_command(TARGET nextcloud POST_BUILD COMMAND "${MACDEPLOYQT_EXECUTABLE}" - "$/../.." + "$/../.." -qmldir=${CMAKE_SOURCE_DIR}/src/gui -always-overwrite - -executable="$/${cmd_NAME}" + -executable="$/${cmd_NAME}" ${NO_STRIP} COMMAND "${CMAKE_COMMAND}" -E rm -rf "${BIN_OUTPUT_DIRECTORY}/${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns/bearer" @@ -517,13 +537,13 @@ endif() if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT WIN32) configure_file(${CMAKE_SOURCE_DIR}/mirall.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${LINUX_APPLICATION_ID}.desktop) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LINUX_APPLICATION_ID}.desktop DESTINATION ${DATADIR}/applications ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LINUX_APPLICATION_ID}.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications ) configure_file(owncloud.xml.in ${APPLICATION_EXECUTABLE}.xml) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_EXECUTABLE}.xml DESTINATION ${DATADIR}/mime/packages ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPLICATION_EXECUTABLE}.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages ) find_package(SharedMimeInfo) if(SharedMimeInfo_FOUND) - update_xdg_mimetypes( ${DATADIR}/mime/packages ) + update_xdg_mimetypes( ${CMAKE_INSTALL_DATADIR}/mime/packages ) endif(SharedMimeInfo_FOUND) endif() diff --git a/src/gui/EmojiPicker.qml b/src/gui/EmojiPicker.qml new file mode 100644 index 000000000000..6a66dbdcb190 --- /dev/null +++ b/src/gui/EmojiPicker.qml @@ -0,0 +1,112 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import com.nextcloud.desktopclient 1.0 as NC + +ColumnLayout { + NC.EmojiModel { + id: emojiModel + } + + signal chosen(string emoji) + + spacing: 0 + + FontMetrics { + id: metrics + } + + ListView { + id: headerLayout + Layout.fillWidth: true + implicitWidth: contentItem.childrenRect.width + implicitHeight: metrics.height * 2 + + orientation: ListView.Horizontal + + model: emojiModel.emojiCategoriesModel + + delegate: ItemDelegate { + width: metrics.height * 2 + height: headerLayout.height + + contentItem: Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: emoji + } + + Rectangle { + anchors.bottom: parent.bottom + + width: parent.width + height: 2 + + visible: ListView.isCurrentItem + + color: "grey" + } + + + onClicked: { + emojiModel.setCategory(label) + } + } + + } + + Rectangle { + height: 1 + Layout.fillWidth: true + color: "grey" + } + + GridView { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: metrics.height * 8 + + cellWidth: metrics.height * 2 + cellHeight: metrics.height * 2 + + boundsBehavior: Flickable.DragOverBounds + clip: true + + model: emojiModel.model + + delegate: ItemDelegate { + + width: metrics.height * 2 + height: metrics.height * 2 + + contentItem: Text { + anchors.centerIn: parent + text: modelData === undefined ? "" : modelData.unicode + } + + onClicked: { + chosen(modelData.unicode); + emojiModel.emojiUsed(modelData); + } + } + + ScrollBar.vertical: ScrollBar {} + + } + +} diff --git a/src/gui/ErrorBox.qml b/src/gui/ErrorBox.qml new file mode 100644 index 000000000000..8ef5d053c831 --- /dev/null +++ b/src/gui/ErrorBox.qml @@ -0,0 +1,32 @@ +import QtQuick 2.15 + +import Style 1.0 + +Item { + id: errorBox + + property var text: "" + + property color color: Style.errorBoxTextColor + property color backgroundColor: Style.errorBoxBackgroundColor + property color borderColor: Style.errorBoxBorderColor + + implicitHeight: errorMessage.implicitHeight + 2 * 8 + + Rectangle { + anchors.fill: parent + color: errorBox.backgroundColor + border.color: errorBox.borderColor + } + + Text { + id: errorMessage + + anchors.fill: parent + anchors.margins: 8 + width: parent.width + color: errorBox.color + wrapMode: Text.WordWrap + text: errorBox.text + } +} diff --git a/src/gui/UserStatusSelector.qml b/src/gui/UserStatusSelector.qml new file mode 100644 index 000000000000..82620a92006f --- /dev/null +++ b/src/gui/UserStatusSelector.qml @@ -0,0 +1,200 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +import QtQuick 2.6 +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 +import QtQuick.Window 2.15 +import com.nextcloud.desktopclient 1.0 as NC + +ColumnLayout { + id: rootLayout + spacing: 0 + property NC.UserStatusSelectorModel userStatusSelectorModel + + FontMetrics { + id: metrics + } + + Text { + Layout.topMargin: 16 + Layout.leftMargin: 8 + Layout.rightMargin: 8 + Layout.bottomMargin: 8 + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + font.bold: true + text: qsTr("Online status") + } + + GridLayout { + Layout.margins: 8 + Layout.alignment: Qt.AlignTop + columns: 2 + rows: 2 + columnSpacing: 8 + rowSpacing: 8 + + Button { + Layout.fillWidth: true + checked: NC.UserStatus.Online == userStatusSelectorModel.onlineStatus + checkable: true + icon.source: userStatusSelectorModel.onlineIcon + icon.color: "transparent" + text: qsTr("Online") + onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.Online) + implicitWidth: 100 + } + Button { + Layout.fillWidth: true + checked: NC.UserStatus.Away == userStatusSelectorModel.onlineStatus + checkable: true + icon.source: userStatusSelectorModel.awayIcon + icon.color: "transparent" + text: qsTr("Away") + onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.Away) + implicitWidth: 100 + + } + Button { + Layout.fillWidth: true + checked: NC.UserStatus.DoNotDisturb == userStatusSelectorModel.onlineStatus + checkable: true + icon.source: userStatusSelectorModel.dndIcon + icon.color: "transparent" + text: qsTr("Do not disturb") + onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.DoNotDisturb) + implicitWidth: 100 + } + Button { + Layout.fillWidth: true + checked: NC.UserStatus.Invisible == userStatusSelectorModel.onlineStatus + checkable: true + icon.source: userStatusSelectorModel.invisibleIcon + icon.color: "transparent" + text: qsTr("Invisible") + onClicked: userStatusSelectorModel.setOnlineStatus(NC.UserStatus.Invisible) + implicitWidth: 100 + } + } + + Text { + Layout.topMargin: 16 + Layout.leftMargin: 8 + Layout.rightMargin: 8 + Layout.bottomMargin: 8 + Layout.alignment: Qt.AlignTop | Qt.AlignHCenter + font.bold: true + text: qsTr("Status message") + } + + RowLayout { + Layout.topMargin: 8 + Layout.leftMargin: 8 + Layout.rightMargin: 8 + Layout.bottomMargin: 16 + Layout.alignment: Qt.AlignTop + Layout.fillWidth: true + + Button { + Layout.preferredWidth: userStatusMessageTextField.height // metrics.height * 2 + Layout.preferredHeight: userStatusMessageTextField.height // metrics.height * 2 + text: userStatusSelectorModel.userStatusEmoji + onClicked: emojiDialog.open() + } + + Popup { + id: emojiDialog + padding: 0 + margins: 0 + + anchors.centerIn: Overlay.overlay + + EmojiPicker { + id: emojiPicker + + onChosen: { + userStatusSelectorModel.userStatusEmoji = emoji + emojiDialog.close() + } + } + } + + TextField { + id: userStatusMessageTextField + Layout.fillWidth: true + placeholderText: qsTr("What is your status?") + text: userStatusSelectorModel.userStatusMessage + selectByMouse: true + onEditingFinished: userStatusSelectorModel.setUserStatusMessage(text) + } + } + + Repeater { + model: userStatusSelectorModel.predefinedStatusesCount + + Button { + id: control + Layout.fillWidth: true + flat: !hovered + hoverEnabled: true + text: userStatusSelectorModel.predefinedStatus(index).icon + " " + userStatusSelectorModel.predefinedStatus(index).message + " - " + userStatusSelectorModel.predefinedStatusClearAt(index) + onClicked: userStatusSelectorModel.setPredefinedStatus(index) + } + } + + RowLayout { + Layout.topMargin: 16 + Layout.leftMargin: 8 + Layout.rightMargin: 8 + Layout.bottomMargin: 8 + Layout.alignment: Qt.AlignTop + + Text { + text: qsTr("Clear status message after") + } + + ComboBox { + Layout.fillWidth: true + model: userStatusSelectorModel.clearAtValues + displayText: userStatusSelectorModel.clearAt + onActivated: userStatusSelectorModel.setClearAt(index) + } + } + + RowLayout { + Layout.margins: 8 + Layout.alignment: Qt.AlignTop + + Button { + Layout.fillWidth: true + text: qsTr("Clear status message") + onClicked: userStatusSelectorModel.clearUserStatus() + } + Button { + highlighted: true + Layout.fillWidth: true + text: qsTr("Set status message") + onClicked: userStatusSelectorModel.setUserStatus() + } + } + + ErrorBox { + Layout.margins: 8 + Layout.fillWidth: true + + visible: userStatusSelectorModel.errorMessage != "" + text: "Error: " + userStatusSelectorModel.errorMessage + } +} diff --git a/src/gui/UserStatusSelectorDialog.qml b/src/gui/UserStatusSelectorDialog.qml new file mode 100644 index 000000000000..3f86f8cf9bd2 --- /dev/null +++ b/src/gui/UserStatusSelectorDialog.qml @@ -0,0 +1,27 @@ +import QtQuick.Window 2.15 + +import com.nextcloud.desktopclient 1.0 as NC + +Window { + id: dialog + + property NC.UserStatusSelectorModel model: NC.UserStatusSelectorModel { + onFinished: dialog.close() + } + + minimumWidth: view.implicitWidth + minimumHeight: view.implicitHeight + maximumWidth: view.implicitWidth + maximumHeight: view.implicitHeight + width: maximumWidth + height: maximumHeight + + visible: true + + flags: Qt.Dialog + + UserStatusSelector { + id: view + userStatusSelectorModel: model + } +} diff --git a/src/gui/accountmanager.h b/src/gui/accountmanager.h index 9a1b50497162..0cec19053dc7 100644 --- a/src/gui/accountmanager.h +++ b/src/gui/accountmanager.h @@ -28,7 +28,7 @@ class AccountManager : public QObject Q_OBJECT public: static AccountManager *instance(); - ~AccountManager() = default; + ~AccountManager() override = default; /** * Saves the accounts to a given settings file diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp index 43dab82a5769..76cf0cc39f28 100644 --- a/src/gui/accountsettings.cpp +++ b/src/gui/accountsettings.cpp @@ -593,6 +593,7 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos) ac = menu->addAction(tr("Disable virtual file support …")); connect(ac, &QAction::triggered, this, &AccountSettings::slotDisableVfsCurrentFolder); + ac->setDisabled(Theme::instance()->enforceVirtualFilesSyncFolder()); } if (Theme::instance()->showVirtualFilesOption() diff --git a/src/gui/accountsettings.h b/src/gui/accountsettings.h index 17e8398394b5..a9908138f99f 100644 --- a/src/gui/accountsettings.h +++ b/src/gui/accountsettings.h @@ -55,7 +55,7 @@ class AccountSettings : public QWidget public: explicit AccountSettings(AccountState *accountState, QWidget *parent = nullptr); - ~AccountSettings(); + ~AccountSettings() override; QSize sizeHint() const override { return ownCloudGui::settingsDialogSize(); } bool canEncryptOrDecrypt(const FolderStatusModel::SubFolderInfo* folderInfo); diff --git a/src/gui/accountstate.cpp b/src/gui/accountstate.cpp index bb2ab52738b2..7521dac799a7 100644 --- a/src/gui/accountstate.cpp +++ b/src/gui/accountstate.cpp @@ -44,7 +44,6 @@ AccountState::AccountState(AccountPtr account) , _waitingForNewCredentials(false) , _maintenanceToConnectedDelay(60000 + (qrand() % (4 * 60000))) // 1-5min delay , _remoteWipe(new RemoteWipe(_account)) - , _userStatus(new UserStatus(this)) , _isDesktopNotificationsAllowed(true) { qRegisterMetaType("AccountState*"); @@ -127,26 +126,6 @@ void AccountState::setState(State state) emit stateChanged(_state); } -UserStatus::Status AccountState::status() const -{ - return _userStatus->status(); -} - -QString AccountState::statusMessage() const -{ - return _userStatus->message(); -} - -QUrl AccountState::statusIcon() const -{ - return _userStatus->icon(); -} - -QString AccountState::statusEmoji() const -{ - return _userStatus->emoji(); -} - QString AccountState::stateString(State state) { switch (state) { @@ -462,12 +441,6 @@ void AccountState::fetchNavigationApps(){ job->getNavigationApps(); } -void AccountState::fetchUserStatus() -{ - connect(_userStatus, &UserStatus::fetchUserStatusFinished, this, &AccountState::statusChanged); - _userStatus->fetchUserStatus(_account); -} - void AccountState::slotEtagResponseHeaderReceived(const QByteArray &value, int statusCode){ if(statusCode == 200){ qCDebug(lcAccountState) << "New navigation apps ETag Response Header received " << value; diff --git a/src/gui/accountstate.h b/src/gui/accountstate.h index 6249159a101c..7946e2f969f3 100644 --- a/src/gui/accountstate.h +++ b/src/gui/accountstate.h @@ -21,7 +21,7 @@ #include #include "connectionvalidator.h" #include "creds/abstractcredentials.h" -#include "userstatus.h" + #include class QSettings; @@ -82,7 +82,7 @@ class AccountState : public QObject, public QSharedData /// Use the account as parent explicit AccountState(AccountPtr account); - ~AccountState(); + ~AccountState() override; /** Creates an account state from settings and an Account object. * @@ -162,23 +162,6 @@ class AccountState : public QObject, public QSharedData ///Asks for user credentials void handleInvalidCredentials(); - /** Returns the user status (Online, Dnd, Away, Offline, Invisible) - * https://gist.github.com/georgehrke/55a0412007f13be1551d1f9436a39675 - */ - UserStatus::Status status() const; - - /** Returns the user status Message (text) - */ - QString statusMessage() const; - - /** Returns the user status icon url - */ - QUrl statusIcon() const; - - /** Returns the user status emoji - */ - QString statusEmoji() const; - /** Returns the notifications status retrieved by the notificatons endpoint * https://github.com/nextcloud/desktop/issues/2318#issuecomment-680698429 */ @@ -188,10 +171,6 @@ class AccountState : public QObject, public QSharedData */ void setDesktopNotificationsAllowed(bool isAllowed); - /** Fetch the user status (status, icon, message) - */ - void fetchUserStatus(); - public slots: /// Triggers a ping to the server to update state and /// connection status and errors. @@ -256,7 +235,6 @@ protected Q_SLOTS: */ AccountAppList _apps; - UserStatus *_userStatus; bool _isDesktopNotificationsAllowed; }; diff --git a/src/gui/addcertificatedialog.h b/src/gui/addcertificatedialog.h index 158327b72720..bf7322ec89df 100644 --- a/src/gui/addcertificatedialog.h +++ b/src/gui/addcertificatedialog.h @@ -35,7 +35,7 @@ class AddCertificateDialog : public QDialog public: explicit AddCertificateDialog(QWidget *parent = nullptr); - ~AddCertificateDialog(); + ~AddCertificateDialog() override; QString getCertificatePath(); QString getCertificatePasswd(); void showErrorMessage(const QString message); diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 511da7558678..f153224b21fb 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -27,13 +27,14 @@ #include "folderman.h" #include "logger.h" #include "configfile.h" -#include "socketapi.h" +#include "socketapi/socketapi.h" #include "sslerrordialog.h" #include "theme.h" #include "clientproxy.h" #include "sharedialog.h" #include "accountmanager.h" #include "creds/abstractcredentials.h" +#include "pushnotifications.h" #if defined(BUILD_UPDATER) #include "updater/ocupdater.h" @@ -178,7 +179,7 @@ Application::Application(int &argc, char **argv) , _showLogWindow(false) , _logExpire(0) , _logFlush(false) - , _logDebug(false) + , _logDebug(true) , _userTriggeredConnect(false) , _debugMode(false) , _backgroundMode(false) @@ -349,6 +350,9 @@ Application::Application(int &argc, char **argv) connect(FolderMan::instance()->socketApi(), &SocketApi::shareCommandReceived, _gui.data(), &ownCloudGui::slotShowShareDialog); + connect(FolderMan::instance()->socketApi(), &SocketApi::fileActivityCommandReceived, + Systray::instance(), &Systray::showFileActivityDialog); + // startup procedure. connect(&_checkConnectionTimer, &QTimer::timeout, this, &Application::slotCheckConnection); _checkConnectionTimer.setInterval(ConnectionValidator::DefaultCallingIntervalMsec); // check for connection every 32 seconds. @@ -456,9 +460,10 @@ void Application::slotCheckConnection() // Don't check if we're manually signed out or // when the error is permanent. - if (state != AccountState::SignedOut - && state != AccountState::ConfigurationError - && state != AccountState::AskingCredentials) { + const auto pushNotifications = accountState->account()->pushNotifications(); + const auto pushNotificationsAvailable = (pushNotifications && pushNotifications->isReady()); + if (state != AccountState::SignedOut && state != AccountState::ConfigurationError + && state != AccountState::AskingCredentials && !pushNotificationsAvailable) { accountState->checkConnectivity(); } } @@ -524,7 +529,12 @@ void Application::setupLogging() logger->enterNextLogFile(); - qCInfo(lcApplication) << QString::fromLatin1("################## %1 locale:[%2] ui_lang:[%3] version:[%4] os:[%5]").arg(_theme->appName()).arg(QLocale::system().name()).arg(property("ui_lang").toString()).arg(_theme->version()).arg(Utility::platformName()); + qCInfo(lcApplication) << "##################" << _theme->appName() + << "locale:" << QLocale::system().name() + << "ui_lang:" << property("ui_lang") + << "version:" << _theme->version() + << "os:" << Utility::platformName(); + qCInfo(lcApplication) << "Arguments:" << qApp->arguments(); } void Application::slotUseMonoIconsChanged(bool) diff --git a/src/gui/application.h b/src/gui/application.h index aabaa63b023a..3f1436e65384 100644 --- a/src/gui/application.h +++ b/src/gui/application.h @@ -57,7 +57,7 @@ class Application : public SharedTools::QtSingleApplication Q_OBJECT public: explicit Application(int &argc, char **argv); - ~Application(); + ~Application() override; bool giveHelp(); void showHelp(); @@ -88,7 +88,7 @@ public slots: void parseOptions(const QStringList &); void setupTranslations(); void setupLogging(); - bool event(QEvent *event); + bool event(QEvent *event) override; signals: void folderRemoved(); diff --git a/src/gui/cloudproviders/cloudproviderwrapper.h b/src/gui/cloudproviders/cloudproviderwrapper.h index 22caf362985c..58d00336e151 100644 --- a/src/gui/cloudproviders/cloudproviderwrapper.h +++ b/src/gui/cloudproviders/cloudproviderwrapper.h @@ -39,7 +39,7 @@ class CloudProviderWrapper : public QObject Q_OBJECT public: explicit CloudProviderWrapper(QObject *parent = nullptr, Folder *folder = nullptr, int folderId = 0, CloudProvidersProviderExporter* cloudprovider = nullptr); - ~CloudProviderWrapper(); + ~CloudProviderWrapper() override; CloudProvidersAccountExporter* accountExporter(); Folder* folder(); GMenuModel* getMenuModel(); diff --git a/src/gui/creds/flow2auth.cpp b/src/gui/creds/flow2auth.cpp index b94de0afd858..54b7b28a816b 100644 --- a/src/gui/creds/flow2auth.cpp +++ b/src/gui/creds/flow2auth.cpp @@ -100,7 +100,7 @@ void Flow2Auth::fetchNewToken(const TokenAction action) pollToken = json.value("poll").toObject().value("token").toString(); pollEndpoint = json.value("poll").toObject().value("endpoint").toString(); if (_enforceHttps && QUrl(pollEndpoint).scheme() != QStringLiteral("https")) { - qCWarning(lcFlow2auth) << "Can not poll endpoint because the returned url" << _pollEndpoint << "does not start with https"; + qCWarning(lcFlow2auth) << "Can not poll endpoint because the returned url" << pollEndpoint << "does not start with https"; emit result(Error, tr("The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator.")); return; } diff --git a/src/gui/creds/flow2auth.h b/src/gui/creds/flow2auth.h index 6cb05c1d3968..3ac1cd0cd159 100644 --- a/src/gui/creds/flow2auth.h +++ b/src/gui/creds/flow2auth.h @@ -42,7 +42,7 @@ class Flow2Auth : public QObject }; Flow2Auth(Account *account, QObject *parent); - ~Flow2Auth(); + ~Flow2Auth() override; enum Result { NotSupported, LoggedIn, diff --git a/src/gui/creds/oauth.cpp b/src/gui/creds/oauth.cpp index 2c0e20410a89..aa528aa49ce4 100644 --- a/src/gui/creds/oauth.cpp +++ b/src/gui/creds/oauth.cpp @@ -70,13 +70,14 @@ void OAuth::start() QByteArray peek = socket->peek(qMin(socket->bytesAvailable(), 4000LL)); //The code should always be within the first 4K if (peek.indexOf('\n') < 0) return; // wait until we find a \n - QRegExp rx("^GET /\\?code=([a-zA-Z0-9]+)[& ]"); // Match a /?code=... URL - if (rx.indexIn(peek) != 0) { + const QRegularExpression rx("^GET /\\?code=([a-zA-Z0-9]+)[& ]"); // Match a /?code=... URL + const auto rxMatch = rx.match(peek); + if (!rxMatch.hasMatch()) { httpReplyAndClose(socket, "404 Not Found", "404 Not Found

404 Not Found

"); return; } - QString code = rx.cap(1); // The 'code' is the first capture of the regexp + QString code = rxMatch.captured(1); // The 'code' is the first capture of the regexp QUrl requestToken = Utility::concatUrlPath(_account->url().toString(), QLatin1String("/index.php/apps/oauth2/api/v1/token")); QNetworkRequest req; diff --git a/src/gui/creds/oauth.h b/src/gui/creds/oauth.h index 1c6b519e1331..0fa543b5e188 100644 --- a/src/gui/creds/oauth.h +++ b/src/gui/creds/oauth.h @@ -47,7 +47,7 @@ class OAuth : public QObject , _account(account) { } - ~OAuth(); + ~OAuth() override; enum Result { NotSupported, LoggedIn, diff --git a/src/gui/emojimodel.cpp b/src/gui/emojimodel.cpp new file mode 100644 index 000000000000..e6b281db1ed2 --- /dev/null +++ b/src/gui/emojimodel.cpp @@ -0,0 +1,1571 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 +#include + +#include "emojimodel.h" + +namespace OCC { + +QVariant EmojiCategoriesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return {}; + } + + switch (role) { + case Roles::EmojiRole: + return categories[index.row()].emoji; + + case Roles::LabelRole: + return categories[index.row()].label; + } + + return {}; +} + +int EmojiCategoriesModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return static_cast(categories.size()); +} + +QHash EmojiCategoriesModel::roleNames() const +{ + QHash roles; + roles[Roles::EmojiRole] = "emoji"; + roles[Roles::LabelRole] = "label"; + return roles; +} + +const std::vector EmojiCategoriesModel::categories = { + { "⌛️", "history" }, + { "😏", "people" }, + { "🌲", "nature" }, + { "🍛", "food" }, + { "🚁", "activity" }, + { "🚅", "travel" }, + { "💡", "objects" }, + { "🔣", "symbols" }, + { "🏁", "flags" }, +}; + +QVariantList EmojiModel::history() const +{ + return _settings.value("Editor/emojis", QVariantList()).toList(); +} + +void EmojiModel::setCategory(const QString &category) +{ + if (_category == category) { + return; + } + _category = category; + emit modelChanged(); +} + +QAbstractListModel *EmojiModel::emojiCategoriesModel() +{ + return &_emojiCategoriesModel; +} + +QVariantList EmojiModel::model() const +{ + if (_category == "history") { + return history(); + } else if (_category == "people") { + return people; + } else if (_category == "nature") { + return nature; + } else if (_category == "food") { + return food; + } else if (_category == "activity") { + return activity; + } else if (_category == "travel") { + return travel; + } else if (_category == "objects") { + return objects; + } else if (_category == "symbols") { + return symbols; + } else if (_category == "flags") { + return flags; + } + return history(); +} + +void EmojiModel::emojiUsed(const QVariant &modelData) +{ + auto historyEmojis = history(); + + auto historyEmojisIter = historyEmojis.begin(); + while (historyEmojisIter != historyEmojis.end()) { + if ((*historyEmojisIter).value().unicode == modelData.value().unicode) { + historyEmojisIter = historyEmojis.erase(historyEmojisIter); + } else { + historyEmojisIter++; + } + } + + historyEmojis.push_front(modelData); + _settings.setValue("Editor/emojis", historyEmojis); + + emit historyChanged(); +} + +const QVariantList EmojiModel::people = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x80"), ":grinning:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x81"), ":grin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x82"), ":joy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa3"), ":rofl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x83"), ":smiley:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x84"), ":smile:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x85"), ":sweat_smile:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x86"), ":laughing:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x89"), ":wink:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x8a"), ":blush:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x8b"), ":yum:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x8e"), ":sunglasses:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x8d"), ":heart_eyes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x98"), ":kissing_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x97"), ":kissing:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x99"), ":kissing_smiling_eyes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x9a"), ":kissing_closed_eyes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xba"), ":relaxed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x82"), ":slight_smile:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x97"), ":hugging:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x94"), ":thinking:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x90"), ":neutral_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x91"), ":expressionless:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb6"), ":no_mouth:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x84"), ":rolling_eyes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x8f"), ":smirk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa3"), ":persevere:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa5"), ":disappointed_relieved:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xae"), ":open_mouth:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x90"), ":zipper_mouth:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xaf"), ":hushed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xaa"), ":sleepy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xab"), ":tired_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb4"), ":sleeping:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x8c"), ":relieved:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x93"), ":nerd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x9b"), ":stuck_out_tongue:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x9c"), ":stuck_out_tongue_winking_eye:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x9d"), ":stuck_out_tongue_closed_eyes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa4"), ":drooling_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x92"), ":unamused:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x93"), ":sweat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x94"), ":pensive:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x95"), ":confused:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x83"), ":upside_down:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x91"), ":money_mouth:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb2"), ":astonished:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xb9"), ":frowning2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x81"), ":slight_frown:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x96"), ":confounded:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x9e"), ":disappointed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x9f"), ":worried:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa4"), ":triumph:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa2"), ":cry:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xad"), ":sob:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa6"), ":frowning:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa7"), ":anguished:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa8"), ":fearful:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa9"), ":weary:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xac"), ":grimacing:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb0"), ":cold_sweat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb1"), ":scream:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb3"), ":flushed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb5"), ":dizzy_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa1"), ":rage:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xa0"), ":angry:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x87"), ":innocent:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa0"), ":cowboy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa1"), ":clown:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa5"), ":lying_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb7"), ":mask:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x92"), ":thermometer_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x95"), ":head_bandage:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa2"), ":nauseated_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa7"), ":sneezing_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\x88"), ":smiling_imp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xbf"), ":imp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb9"), ":japanese_ogre:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xba"), ":japanese_goblin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x80"), ":skull:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xbb"), ":ghost:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xbd"), ":alien:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x96"), ":robot:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa9"), ":poop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xba"), ":smiley_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb8"), ":smile_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xb9"), ":joy_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xbb"), ":heart_eyes_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xbc"), ":smirk_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xbd"), ":kissing_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x80"), ":scream_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xbf"), ":crying_cat_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x98\xbe"), ":pouting_cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa6"), ":boy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa7"), ":girl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa8"), ":man:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa9"), ":woman:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb4"), ":older_man:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb5"), ":older_woman:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb6"), ":baby:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xbc"), ":angel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xae"), ":cop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb5"), ":spy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x82"), ":guardsman:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb7"), ":construction_worker:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb3"), ":man_with_turban:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb1"), ":person_with_blond_hair:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x85"), ":santa:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb6"), ":mrs_claus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb8"), ":princess:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb4"), ":prince:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb0"), ":bride_with_veil:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb5"), ":man_in_tuxedo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb0"), ":pregnant_woman:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xb2"), ":man_with_gua_pi_mao:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x8d"), ":person_frowning:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x8e"), ":person_with_pouting_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x85"), ":no_good:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x86"), ":ok_woman:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x81"), ":information_desk_person:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x8b"), ":raising_hand:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x87"), ":bow:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xa6"), ":face_palm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb7"), ":shrug:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x86"), ":massage:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x87"), ":haircut:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb6"), ":walking:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x83"), ":runner:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x83"), ":dancer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xba"), ":man_dancing:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xaf"), ":dancers:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xa3"), ":speaking_head:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa4"), ":bust_in_silhouette:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa5"), ":busts_in_silhouette:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xab"), ":couple:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xac"), ":two_men_holding_hands:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xad"), ":two_women_holding_hands:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x8f"), ":couplekiss:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x91"), ":couple_with_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xaa"), ":family:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xaa"), ":muscle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb3"), ":selfie:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x88"), ":point_left:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x89"), ":point_right:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x9d"), ":point_up:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x86"), ":point_up_2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x95"), ":middle_finger:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x87"), ":point_down:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x8c"), ":v:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x9e"), ":fingers_crossed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x96"), ":vulcan:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x98"), ":metal:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x99"), ":call_me:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x90"), ":hand_splayed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x8b"), ":raised_hand:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x8c"), ":ok_hand:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x8d"), ":thumbsup:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x8e"), ":thumbsdown:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x8a"), ":fist:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x8a"), ":punch:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x9b"), ":left_facing_fist:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x9c"), ":right_facing_fist:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x9a"), ":raised_back_of_hand:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x8b"), ":wave:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x8f"), ":clap:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x8d"), ":writing_hand:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x90"), ":open_hands:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x8c"), ":raised_hands:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x8f"), ":pray:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\x9d"), ":handshake:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x85"), ":nail_care:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x82"), ":ear:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x83"), ":nose:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa3"), ":footprints:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x80"), ":eyes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x81"), ":eye:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x85"), ":tongue:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x84"), ":lips:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x8b"), ":kiss:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa4"), ":zzz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x93"), ":eyeglasses:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb6"), ":dark_sunglasses:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x94"), ":necktie:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x95"), ":shirt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x96"), ":jeans:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x97"), ":dress:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x98"), ":kimono:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x99"), ":bikini:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x9a"), ":womans_clothes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x9b"), ":purse:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x9c"), ":handbag:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x9d"), ":pouch:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x92"), ":school_satchel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x9e"), ":mans_shoe:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x9f"), ":athletic_shoe:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa0"), ":high_heel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa1"), ":sandal:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xa2"), ":boot:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x91"), ":crown:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x92"), ":womans_hat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa9"), ":tophat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x93"), ":mortar_board:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x91"), ":helmet_with_cross:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x84"), ":lipstick:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x8d"), ":ring:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x82"), ":closed_umbrella:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xbc"), ":briefcase:" }), +}; + +const QVariantList EmojiModel::nature = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x88"), ":see_no_evil:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x89"), ":hear_no_evil:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x99\x8a"), ":speak_no_evil:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa6"), ":sweat_drops:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa8"), ":dash:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb5"), ":monkey_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x92"), ":monkey:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x8d"), ":gorilla:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb6"), ":dog:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x95"), ":dog2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa9"), ":poodle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xba"), ":wolf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x8a"), ":fox:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb1"), ":cat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x88"), ":cat2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x81"), ":lion_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xaf"), ":tiger:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x85"), ":tiger2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x86"), ":leopard:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb4"), ":horse:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x8e"), ":racehorse:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x8c"), ":deer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x84"), ":unicorn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xae"), ":cow:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x82"), ":ox:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x83"), ":water_buffalo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x84"), ":cow2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb7"), ":pig:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x96"), ":pig2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x97"), ":boar:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xbd"), ":pig_nose:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x8f"), ":ram:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x91"), ":sheep:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x90"), ":goat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xaa"), ":dromedary_camel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xab"), ":camel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x98"), ":elephant:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x8f"), ":rhino:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xad"), ":mouse:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x81"), ":mouse2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x80"), ":rat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb9"), ":hamster:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb0"), ":rabbit:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x87"), ":rabbit2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xbf"), ":chipmunk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x87"), ":bat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xbb"), ":bear:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa8"), ":koala:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xbc"), ":panda_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xbe"), ":feet:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x83"), ":turkey:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x94"), ":chicken:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x93"), ":rooster:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa3"), ":hatching_chick:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa4"), ":baby_chick:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa5"), ":hatched_chick:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa6"), ":bird:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa7"), ":penguin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x8a"), ":dove:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x85"), ":eagle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x86"), ":duck:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x89"), ":owl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb8"), ":frog:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x8a"), ":crocodile:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa2"), ":turtle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x8e"), ":lizard:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x8d"), ":snake:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb2"), ":dragon_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x89"), ":dragon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xb3"), ":whale:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x8b"), ":whale2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xac"), ":dolphin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x9f"), ":fish:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa0"), ":tropical_fish:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\xa1"), ":blowfish:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x88"), ":shark:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x99"), ":octopus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x9a"), ":shell:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x80"), ":crab:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x90"), ":shrimp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x91"), ":squid:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x8b"), ":butterfly:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x8c"), ":snail:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x9b"), ":bug:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x9c"), ":ant:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x9d"), ":bee:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x90\x9e"), ":beetle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb7"), ":spider:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb8"), ":spider_web:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa6\x82"), ":scorpion:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x90"), ":bouquet:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb8"), ":cherry_blossom:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb5"), ":rosette:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb9"), ":rose:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x80"), ":wilted_rose:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xba"), ":hibiscus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xbb"), ":sunflower:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xbc"), ":blossom:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb7"), ":tulip:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb1"), ":seedling:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb2"), ":evergreen_tree:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb3"), ":deciduous_tree:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb4"), ":palm_tree:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb5"), ":cactus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xbe"), ":ear_of_rice:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xbf"), ":herb:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x98"), ":shamrock:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x80"), ":four_leaf_clover:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x81"), ":maple_leaf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x82"), ":fallen_leaf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x83"), ":leaves:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x84"), ":mushroom:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb0"), ":chestnut:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x8d"), ":earth_africa:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x8e"), ":earth_americas:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x8f"), ":earth_asia:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x91"), ":new_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x92"), ":waxing_crescent_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x93"), ":first_quarter_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x94"), ":waxing_gibbous_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x95"), ":full_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x96"), ":waning_gibbous_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x97"), ":last_quarter_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x98"), ":waning_crescent_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x99"), ":crescent_moon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x9a"), ":new_moon_with_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x9b"), ":first_quarter_moon_with_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x9c"), ":last_quarter_moon_with_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x80"), ":sunny:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x9d"), ":full_moon_with_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x9e"), ":sun_with_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xad\x90"), ":star:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x9f"), ":star2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x81"), ":cloud:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x85"), ":partly_sunny:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x88"), ":thunder_cloud_rain:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa4"), ":white_sun_small_cloud:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa5"), ":white_sun_cloud:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa6"), ":white_sun_rain_cloud:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa7"), ":cloud_rain:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa8"), ":cloud_snow:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa9"), ":cloud_lightning:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xaa"), ":cloud_tornado:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xab"), ":fog:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xac"), ":wind_blowing_face:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x82"), ":umbrella2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x94"), ":umbrella:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xa1"), ":zap:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x84"), ":snowflake:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x83"), ":snowman2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x84"), ":snowman:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x84"), ":comet:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa5"), ":fire:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa7"), ":droplet:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x8a"), ":ocean:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x83"), ":jack_o_lantern:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x84"), ":christmas_tree:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\xa8"), ":sparkles:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x8b"), ":tanabata_tree:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x8d"), ":bamboo:" }), +}; + +const QVariantList EmojiModel::food = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x87"), ":grapes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x88"), ":melon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x89"), ":watermelon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x8a"), ":tangerine:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x8b"), ":lemon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x8c"), ":banana:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x8d"), ":pineapple:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x8e"), ":apple:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x8f"), ":green_apple:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x90"), ":pear:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x91"), ":peach:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x92"), ":cherries:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x93"), ":strawberry:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x9d"), ":kiwi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x85"), ":tomato:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x91"), ":avocado:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x86"), ":eggplant:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x94"), ":potato:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x95"), ":carrot:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xbd"), ":corn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xb6"), ":hot_pepper:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x92"), ":cucumber:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x9c"), ":peanuts:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x9e"), ":bread:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x90"), ":croissant:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x96"), ":french_bread:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x9e"), ":pancakes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa7\x80"), ":cheese:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x96"), ":meat_on_bone:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x97"), ":poultry_leg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x93"), ":bacon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x94"), ":hamburger:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x9f"), ":fries:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x95"), ":pizza:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xad"), ":hotdog:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xae"), ":taco:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xaf"), ":burrito:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x99"), ":stuffed_flatbread:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x9a"), ":egg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb3"), ":cooking:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x98"), ":shallow_pan_of_food:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb2"), ":stew:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x97"), ":salad:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xbf"), ":popcorn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb1"), ":bento:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x98"), ":rice_cracker:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x99"), ":rice_ball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x9a"), ":rice:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x9b"), ":curry:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x9c"), ":ramen:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\x9d"), ":spaghetti:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa0"), ":sweet_potato:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa2"), ":oden:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa3"), ":sushi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa4"), ":fried_shrimp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa5"), ":fish_cake:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa1"), ":dango:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa6"), ":icecream:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa7"), ":shaved_ice:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa8"), ":ice_cream:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xa9"), ":doughnut:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xaa"), ":cookie:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x82"), ":birthday:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb0"), ":cake:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xab"), ":chocolate_bar:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xac"), ":candy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xad"), ":lollipop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xae"), ":custard:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xaf"), ":honey_pot:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xbc"), ":baby_bottle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x9b"), ":milk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x95"), ":coffee:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb5"), ":tea:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb6"), ":sake:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xbe"), ":champagne:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb7"), ":wine_glass:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb8"), ":cocktail:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb9"), ":tropical_drink:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xba"), ":beer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xbb"), ":beers:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x82"), ":champagne_glass:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x83"), ":tumbler_glass:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xbd"), ":fork_knife_plate:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8d\xb4"), ":fork_and_knife:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x84"), ":spoon:" }), +}; + +const QVariantList EmojiModel::activity = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\xbe"), ":space_invader:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb4"), ":levitate:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xba"), ":fencer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x87"), ":horse_racing:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x87\xf0\x9f\x8f\xbb"), ":horse_racing_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x87\xf0\x9f\x8f\xbc"), ":horse_racing_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x87\xf0\x9f\x8f\xbd"), ":horse_racing_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x87\xf0\x9f\x8f\xbe"), ":horse_racing_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x87\xf0\x9f\x8f\xbf"), ":horse_racing_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb7"), ":skier:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x82"), ":snowboarder:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8c"), ":golfer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x84"), ":surfer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x84\xf0\x9f\x8f\xbb"), ":surfer_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x84\xf0\x9f\x8f\xbc"), ":surfer_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x84\xf0\x9f\x8f\xbd"), ":surfer_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x84\xf0\x9f\x8f\xbe"), ":surfer_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x84\xf0\x9f\x8f\xbf"), ":surfer_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa3"), ":rowboat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa3\xf0\x9f\x8f\xbb"), ":rowboat_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa3\xf0\x9f\x8f\xbc"), ":rowboat_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa3\xf0\x9f\x8f\xbd"), ":rowboat_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa3\xf0\x9f\x8f\xbe"), ":rowboat_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa3\xf0\x9f\x8f\xbf"), ":rowboat_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8a"), ":swimmer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8a\xf0\x9f\x8f\xbb"), ":swimmer_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8a\xf0\x9f\x8f\xbc"), ":swimmer_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8a\xf0\x9f\x8f\xbd"), ":swimmer_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8a\xf0\x9f\x8f\xbe"), ":swimmer_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8a\xf0\x9f\x8f\xbf"), ":swimmer_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb9"), ":basketball_player:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb9\xf0\x9f\x8f\xbb"), ":basketball_player_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb9\xf0\x9f\x8f\xbc"), ":basketball_player_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb9\xf0\x9f\x8f\xbd"), ":basketball_player_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb9\xf0\x9f\x8f\xbe"), ":basketball_player_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb9\xf0\x9f\x8f\xbf"), ":basketball_player_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8b"), ":lifter:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8b\xf0\x9f\x8f\xbb"), ":lifter_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8b\xf0\x9f\x8f\xbc"), ":lifter_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8b\xf0\x9f\x8f\xbd"), ":lifter_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8b\xf0\x9f\x8f\xbe"), ":lifter_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8b\xf0\x9f\x8f\xbf"), ":lifter_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb4"), ":bicyclist:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb4\xf0\x9f\x8f\xbb"), ":bicyclist_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb4\xf0\x9f\x8f\xbc"), ":bicyclist_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb4\xf0\x9f\x8f\xbd"), ":bicyclist_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb4\xf0\x9f\x8f\xbe"), ":bicyclist_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb4\xf0\x9f\x8f\xbf"), ":bicyclist_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb5"), ":mountain_bicyclist:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb5\xf0\x9f\x8f\xbb"), ":mountain_bicyclist_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb5\xf0\x9f\x8f\xbc"), ":mountain_bicyclist_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb5\xf0\x9f\x8f\xbd"), ":mountain_bicyclist_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb5\xf0\x9f\x8f\xbe"), ":mountain_bicyclist_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb5\xf0\x9f\x8f\xbf"), ":mountain_bicyclist_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb8"), ":cartwheel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb8\xf0\x9f\x8f\xbb"), ":cartwheel_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb8\xf0\x9f\x8f\xbc"), ":cartwheel_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb8\xf0\x9f\x8f\xbd"), ":cartwheel_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb8\xf0\x9f\x8f\xbe"), ":cartwheel_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb8\xf0\x9f\x8f\xbf"), ":cartwheel_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbc"), ":wrestlers:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbc\xf0\x9f\x8f\xbb"), ":wrestlers_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbc\xf0\x9f\x8f\xbc"), ":wrestlers_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbc\xf0\x9f\x8f\xbd"), ":wrestlers_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbc\xf0\x9f\x8f\xbe"), ":wrestlers_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbc\xf0\x9f\x8f\xbf"), ":wrestlers_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbd"), ":water_polo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbd\xf0\x9f\x8f\xbb"), ":water_polo_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbd\xf0\x9f\x8f\xbc"), ":water_polo_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbd\xf0\x9f\x8f\xbd"), ":water_polo_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbd\xf0\x9f\x8f\xbe"), ":water_polo_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbd\xf0\x9f\x8f\xbf"), ":water_polo_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbe"), ":handball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbe\xf0\x9f\x8f\xbb"), ":handball_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbe\xf0\x9f\x8f\xbc"), ":handball_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbe\xf0\x9f\x8f\xbd"), ":handball_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbe\xf0\x9f\x8f\xbe"), ":handball_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xbe\xf0\x9f\x8f\xbf"), ":handball_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb9"), ":juggling:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb9\xf0\x9f\x8f\xbb"), ":juggling_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb9\xf0\x9f\x8f\xbc"), ":juggling_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb9\xf0\x9f\x8f\xbd"), ":juggling_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb9\xf0\x9f\x8f\xbe"), ":juggling_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa4\xb9\xf0\x9f\x8f\xbf"), ":juggling_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xaa"), ":circus_tent:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xad"), ":performing_arts:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa8"), ":art:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb0"), ":slot_machine:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x80"), ":bath:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x80\xf0\x9f\x8f\xbb"), ":bath_tone1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x80\xf0\x9f\x8f\xbc"), ":bath_tone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x80\xf0\x9f\x8f\xbd"), ":bath_tone3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x80\xf0\x9f\x8f\xbe"), ":bath_tone4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x80\xf0\x9f\x8f\xbf"), ":bath_tone5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x97"), ":reminder_ribbon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x9f"), ":tickets:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xab"), ":ticket:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x96"), ":military_medal:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x86"), ":trophy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x85"), ":medal:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x87"), ":first_place:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x88"), ":second_place:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x89"), ":third_place:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xbd"), ":soccer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xbe"), ":baseball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x80"), ":basketball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x90"), ":volleyball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x88"), ":football:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x89"), ":rugby_football:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xbe"), ":tennis:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb1"), ":8ball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb3"), ":bowling:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8f"), ":cricket:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x91"), ":field_hockey:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x92"), ":hockey:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x93"), ":ping_pong:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb8"), ":badminton:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x8a"), ":boxing_glove:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x8b"), ":martial_arts_uniform:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x85"), ":goal:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xaf"), ":dart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb3"), ":golf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb8"), ":ice_skate:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa3"), ":fishing_pole_and_fish:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xbd"), ":running_shirt_with_sash:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xbf"), ":ski:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xae"), ":video_game:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb2"), ":game_die:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xbc"), ":musical_score:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa4"), ":microphone:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa7"), ":headphones:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb7"), ":saxophone:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb8"), ":guitar:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb9"), ":musical_keyboard:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xba"), ":trumpet:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xbb"), ":violin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\xa5\x81"), ":drum:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xac"), ":clapper:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb9"), ":bow_and_arrow:" }), +}; + +const QVariantList EmojiModel::travel = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8e"), ":race_car:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x8d"), ":motorcycle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xbe"), ":japan:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x94"), ":mountain_snow:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb0"), ":mountain:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x8b"), ":volcano:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xbb"), ":mount_fuji:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x95"), ":camping:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x96"), ":beach:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x9c"), ":desert:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x9d"), ":island:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x9e"), ":park:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x9f"), ":stadium:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x9b"), ":classical_building:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x97"), ":construction_site:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x98"), ":homes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x99"), ":cityscape:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x9a"), ":house_abandoned:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa0"), ":house:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa1"), ":house_with_garden:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa2"), ":office:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa3"), ":post_office:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa4"), ":european_post_office:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa5"), ":hospital:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa6"), ":bank:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa8"), ":hotel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa9"), ":love_hotel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xaa"), ":convenience_store:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xab"), ":school:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xac"), ":department_store:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xad"), ":factory:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xaf"), ":japanese_castle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb0"), ":european_castle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x92"), ":wedding:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xbc"), ":tokyo_tower:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xbd"), ":statue_of_liberty:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xaa"), ":church:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x8c"), ":mosque:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x8d"), ":synagogue:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xa9"), ":shinto_shrine:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x8b"), ":kaaba:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb2"), ":fountain:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xba"), ":tent:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x81"), ":foggy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x83"), ":night_with_stars:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x84"), ":sunrise_over_mountains:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x85"), ":sunrise:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x86"), ":city_dusk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x87"), ":city_sunset:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x89"), ":bridge_at_night:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x8c"), ":milky_way:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa0"), ":carousel_horse:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa1"), ":ferris_wheel:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa2"), ":roller_coaster:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x82"), ":steam_locomotive:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x83"), ":railway_car:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x84"), ":bullettrain_side:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x85"), ":bullettrain_front:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x86"), ":train2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x87"), ":metro:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x88"), ":light_rail:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x89"), ":station:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x8a"), ":tram:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x9d"), ":monorail:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x9e"), ":mountain_railway:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x8b"), ":train:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x8c"), ":bus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x8d"), ":oncoming_bus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x8e"), ":trolleybus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x90"), ":minibus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x91"), ":ambulance:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x92"), ":fire_engine:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x93"), ":police_car:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x94"), ":oncoming_police_car:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x95"), ":taxi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x96"), ":oncoming_taxi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x97"), ":red_car:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x98"), ":oncoming_automobile:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x99"), ":blue_car:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x9a"), ":truck:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x9b"), ":articulated_lorry:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x9c"), ":tractor:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb2"), ":bike:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xb4"), ":scooter:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xb5"), ":motor_scooter:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x8f"), ":busstop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xa3"), ":motorway:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xa4"), ":railway_track:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xbd"), ":fuelpump:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa8"), ":rotating_light:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa5"), ":traffic_light:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa6"), ":vertical_traffic_light:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa7"), ":construction:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x93"), ":anchor:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb5"), ":sailboat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xb6"), ":canoe:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa4"), ":speedboat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xb3"), ":cruise_ship:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb4"), ":ferry:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xa5"), ":motorboat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa2"), ":ship:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x88"), ":airplane:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xa9"), ":airplane_small:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xab"), ":airplane_departure:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xac"), ":airplane_arriving:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xba"), ":seat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x81"), ":helicopter:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x9f"), ":suspension_railway:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa0"), ":mountain_cableway:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa1"), ":aerial_tramway:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\x80"), ":rocket:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xb0"), ":satellite_orbital:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa0"), ":stars:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x88"), ":rainbow:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x86"), ":fireworks:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x87"), ":sparkler:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x91"), ":rice_scene:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\x81"), ":checkered_flag:" }), +}; + +const QVariantList EmojiModel::objects = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xa0"), ":skull_crossbones:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x8c"), ":love_letter:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa3"), ":bomb:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb3"), ":hole:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x8d"), ":shopping_bags:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xbf"), ":prayer_beads:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x8e"), ":gem:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xaa"), ":knife:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xba"), ":amphora:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xba"), ":map:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x88"), ":barber:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\xbc"), ":frame_photo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x8e"), ":bellhop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xaa"), ":door:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x8c"), ":sleeping_accommodation:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x8f"), ":bed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x8b"), ":couch:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xbd"), ":toilet:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xbf"), ":shower:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x81"), ":bathtub:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8c\x9b"), ":hourglass:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xb3"), ":hourglass_flowing_sand:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8c\x9a"), ":watch:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xb0"), ":alarm_clock:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xb1"), ":stopwatch:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xb2"), ":timer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb0"), ":clock:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\xa1"), ":thermometer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\xb1"), ":beach_umbrella:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x88"), ":balloon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x89"), ":tada:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x8a"), ":confetti_ball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x8e"), ":dolls:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x8f"), ":flags:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x90"), ":wind_chime:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x80"), ":ribbon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x81"), ":gift:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xb9"), ":joystick:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xaf"), ":postal_horn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x99"), ":microphone2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x9a"), ":level_slider:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x9b"), ":control_knobs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xbb"), ":radio:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb1"), ":iphone:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb2"), ":calling:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x8e"), ":telephone:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x9e"), ":telephone_receiver:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x9f"), ":pager:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa0"), ":fax:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x8b"), ":battery:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x8c"), ":electric_plug:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xbb"), ":computer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\xa5"), ":desktop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\xa8"), ":printer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8c\xa8"), ":keyboard:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\xb1"), ":mouse_three_button:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\xb2"), ":trackball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xbd"), ":minidisc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xbe"), ":floppy_disk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xbf"), ":cd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x80"), ":dvd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa5"), ":movie_camera:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x9e"), ":film_frames:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xbd"), ":projector:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xba"), ":tv:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb7"), ":camera:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb8"), ":camera_with_flash:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb9"), ":video_camera:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xbc"), ":vhs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x8d"), ":mag:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x8e"), ":mag_right:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xac"), ":microscope:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xad"), ":telescope:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa1"), ":satellite:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xaf"), ":candle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa1"), ":bulb:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa6"), ":flashlight:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xae"), ":izakaya_lantern:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x94"), ":notebook_with_decorative_cover:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x95"), ":closed_book:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x96"), ":book:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x97"), ":green_book:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x98"), ":blue_book:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x99"), ":orange_book:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x9a"), ":books:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x93"), ":notebook:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x92"), ":ledger:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x83"), ":page_with_curl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x9c"), ":scroll:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x84"), ":page_facing_up:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb0"), ":newspaper:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x9e"), ":newspaper2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x91"), ":bookmark_tabs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x96"), ":bookmark:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb7"), ":label:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb0"), ":moneybag:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb4"), ":yen:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb5"), ":dollar:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb6"), ":euro:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb7"), ":pound:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb8"), ":money_with_wings:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb3"), ":credit_card:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x89"), ":envelope:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa7"), ":e-mail:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa8"), ":incoming_envelope:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa9"), ":envelope_with_arrow:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa4"), ":outbox_tray:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa5"), ":inbox_tray:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa6"), ":package:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xab"), ":mailbox:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xaa"), ":mailbox_closed:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xac"), ":mailbox_with_mail:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xad"), ":mailbox_with_no_mail:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xae"), ":postbox:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xb3"), ":ballot_box:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x8f"), ":pencil2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x92"), ":black_nib:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x8b"), ":pen_fountain:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x8a"), ":pen_ballpoint:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x8c"), ":paintbrush:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x8d"), ":crayon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x9d"), ":pencil:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x81"), ":file_folder:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x82"), ":open_file_folder:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x82"), ":dividers:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x85"), ":date:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x86"), ":calendar:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x92"), ":notepad_spiral:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x93"), ":calendar_spiral:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x87"), ":card_index:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x88"), ":chart_with_upwards_trend:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x89"), ":chart_with_downwards_trend:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x8a"), ":bar_chart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x8b"), ":clipboard:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x8c"), ":pushpin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x8d"), ":round_pushpin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x8e"), ":paperclip:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\x87"), ":paperclips:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x8f"), ":straight_ruler:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x90"), ":triangular_ruler:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x82"), ":scissors:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x83"), ":card_box:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x84"), ":file_cabinet:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x91"), ":wastebasket:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x92"), ":lock:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x93"), ":unlock:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x8f"), ":lock_with_ink_pen:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x90"), ":closed_lock_with_key:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x91"), ":key:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x9d"), ":key2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa8"), ":hammer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x8f"), ":pick:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x92"), ":hammer_pick:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xa0"), ":tools:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xa1"), ":dagger:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x94"), ":crossed_swords:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xab"), ":gun:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xa1"), ":shield:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa7"), ":wrench:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa9"), ":nut_and_bolt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x99"), ":gear:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\x9c"), ":compression:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x97"), ":alembic:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x96"), ":scales:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x97"), ":link:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x93"), ":chains:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x89"), ":syringe:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x8a"), ":pill:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xac"), ":smoking:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xb0"), ":coffin:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xb1"), ":urn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xbf"), ":moyai:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\xa2"), ":oil:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xae"), ":crystal_ball:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x92"), ":shopping_cart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xa9"), ":triangular_flag_on_post:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\x8c"), ":crossed_flags:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb4"), ":flag_black:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb3"), ":flag_white:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xb3\xf0\x9f\x8c\x88"), ":rainbow_flag:" }), +}; + +const QVariantList EmojiModel::symbols = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x91\x81\xf0\x9f\x97\xa8"), ":eye_in_speech_bubble:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x98"), ":cupid:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\xa4"), ":heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x93"), ":heartbeat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x94"), ":broken_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x95"), ":two_hearts:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x96"), ":sparkling_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x97"), ":heartpulse:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x99"), ":blue_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x9a"), ":green_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x9b"), ":yellow_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x9c"), ":purple_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x96\xa4"), ":black_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x9d"), ":gift_heart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x9e"), ":revolving_hearts:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\x9f"), ":heart_decoration:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\xa3"), ":heart_exclamation:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa2"), ":anger:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa5"), ":boom:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xab"), ":dizzy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xac"), ":speech_balloon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xa8"), ":speech_left:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x97\xaf"), ":anger_right:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xad"), ":thought_balloon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xae"), ":white_flower:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x90"), ":globe_with_meridians:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\xa8"), ":hotsprings:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x91"), ":octagonal_sign:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x9b"), ":clock12:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa7"), ":clock1230:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x90"), ":clock1:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x9c"), ":clock130:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x91"), ":clock2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x9d"), ":clock230:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x92"), ":clock3:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x9e"), ":clock330:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x93"), ":clock4:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x9f"), ":clock430:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x94"), ":clock5:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa0"), ":clock530:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x95"), ":clock6:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa1"), ":clock630:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x96"), ":clock7:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa2"), ":clock730:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x97"), ":clock8:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa3"), ":clock830:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x98"), ":clock9:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa4"), ":clock930:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x99"), ":clock10:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa5"), ":clock1030:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x9a"), ":clock11:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\xa6"), ":clock1130:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8c\x80"), ":cyclone:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\xa0"), ":spades:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\xa5"), ":hearts:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\xa6"), ":diamonds:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\xa3"), ":clubs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x83\x8f"), ":black_joker:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x80\x84"), ":mahjong:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb4"), ":flower_playing_cards:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x87"), ":mute:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x88"), ":speaker:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x89"), ":sound:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x8a"), ":loud_sound:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa2"), ":loudspeaker:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xa3"), ":mega:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x94"), ":bell:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x95"), ":no_bell:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb5"), ":musical_note:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xb6"), ":notes:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb9"), ":chart:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb1"), ":currency_exchange:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xb2"), ":heavy_dollar_sign:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8f\xa7"), ":atm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xae"), ":put_litter_in_its_place:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb0"), ":potable_water:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\xbf"), ":wheelchair:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb9"), ":mens:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xba"), ":womens:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xbb"), ":restroom:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xbc"), ":baby_symbol:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xbe"), ":wc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x82"), ":passport_control:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x83"), ":customs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x84"), ":baggage_claim:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x85"), ":left_luggage:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xa0"), ":warning:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb8"), ":children_crossing:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x94"), ":no_entry:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xab"), ":no_entry_sign:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb3"), ":no_bicycles:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xad"), ":no_smoking:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xaf"), ":do_not_litter:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb1"), ":non-potable_water:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9a\xb7"), ":no_pedestrians:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb5"), ":no_mobile_phones:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x9e"), ":underage:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xa2"), ":radioactive:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xa3"), ":biohazard:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xac\x86"), ":arrow_up:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\x97"), ":arrow_upper_right:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9e\xa1"), ":arrow_right:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\x98"), ":arrow_lower_right:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xac\x87"), ":arrow_down:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\x99"), ":arrow_lower_left:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xac\x85"), ":arrow_left:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\x96"), ":arrow_upper_left:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\x95"), ":arrow_up_down:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\x94"), ":left_right_arrow:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\xa9"), ":leftwards_arrow_with_hook:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x86\xaa"), ":arrow_right_hook:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xa4\xb4"), ":arrow_heading_up:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xa4\xb5"), ":arrow_heading_down:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x83"), ":arrows_clockwise:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x84"), ":arrows_counterclockwise:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x99"), ":back:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x9a"), ":end:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x9b"), ":on:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x9c"), ":soon:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x9d"), ":top:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x9b\x90"), ":place_of_worship:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x9b"), ":atom:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x89"), ":om_symbol:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\xa1"), ":star_of_david:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xb8"), ":wheel_of_dharma:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xaf"), ":yin_yang:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x9d"), ":cross:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xa6"), ":orthodox_cross:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xaa"), ":star_and_crescent:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\xae"), ":peace:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x95\x8e"), ":menorah:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xaf"), ":six_pointed_star:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x88"), ":aries:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x89"), ":taurus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x8a"), ":gemini:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x8b"), ":cancer:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x8c"), ":leo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x8d"), ":virgo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x8e"), ":libra:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x8f"), ":scorpius:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x90"), ":sagittarius:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x91"), ":capricorn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x92"), ":aquarius:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\x93"), ":pisces:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9b\x8e"), ":ophiuchus:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x80"), ":twisted_rightwards_arrows:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x81"), ":repeat:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x82"), ":repeat_one:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x96\xb6"), ":arrow_forward:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xa9"), ":fast_forward:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xad"), ":track_next:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xaf"), ":play_pause:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x97\x80"), ":arrow_backward:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xaa"), ":rewind:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xae"), ":track_previous:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xbc"), ":arrow_up_small:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xab"), ":arrow_double_up:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xbd"), ":arrow_down_small:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xac"), ":arrow_double_down:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xb8"), ":pause_button:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xb9"), ":stop_button:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\xba"), ":record_button:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x8f\x8f"), ":eject:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x8e\xa6"), ":cinema:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x85"), ":low_brightness:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x86"), ":high_brightness:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb6"), ":signal_strength:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb3"), ":vibration_mode:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\xb4"), ":mobile_phone_off:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x99\xbb"), ":recycle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x93\x9b"), ":name_badge:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\x9c"), ":fleur-de-lis:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb0"), ":beginner:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb1"), ":trident:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xad\x95"), ":o:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x85"), ":white_check_mark:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x98\x91"), ":ballot_box_with_check:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x94"), ":heavy_check_mark:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\x96"), ":heavy_multiplication_x:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x8c"), ":x:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x8e"), ":negative_squared_cross_mark:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9e\x95"), ":heavy_plus_sign:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9e\x96"), ":heavy_minus_sign:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9e\x97"), ":heavy_division_sign:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9e\xb0"), ":curly_loop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9e\xbf"), ":loop:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe3\x80\xbd"), ":part_alternation_mark:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\xb3"), ":eight_spoked_asterisk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9c\xb4"), ":eight_pointed_black_star:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x87"), ":sparkle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x80\xbc"), ":bangbang:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x81\x89"), ":interrobang:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x93"), ":question:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x94"), ":grey_question:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x95"), ":grey_exclamation:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9d\x97"), ":exclamation:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe3\x80\xb0"), ":wavy_dash:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xc2\xa9"), ":copyright:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xc2\xae"), ":registered:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x84\xa2"), ":tm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("#\xe2\x83\xa3"), ":hash:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("*\xe2\x83\xa3"), ":asterisk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("0\xe2\x83\xa3"), ":zero:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("1\xe2\x83\xa3"), ":one:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("2\xe2\x83\xa3"), ":two:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("3\xe2\x83\xa3"), ":three:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("4\xe2\x83\xa3"), ":four:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("5\xe2\x83\xa3"), ":five:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("6\xe2\x83\xa3"), ":six:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("7\xe2\x83\xa3"), ":seven:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("8\xe2\x83\xa3"), ":eight:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("9\xe2\x83\xa3"), ":nine:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x9f"), ":keycap_ten:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xaf"), ":100:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa0"), ":capital_abcd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa1"), ":abcd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa2"), ":1234:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa3"), ":symbols:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xa4"), ":abc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x85\xb0"), ":a:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x8e"), ":ab:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x85\xb1"), ":b:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x91"), ":cl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x92"), ":cool:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x93"), ":free:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x84\xb9"), ":information_source:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x94"), ":id:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x93\x82"), ":m:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x95"), ":new:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x96"), ":ng:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x85\xbe"), ":o2:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x97"), ":ok:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x85\xbf"), ":parking:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x98"), ":sos:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x99"), ":up:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x86\x9a"), ":vs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\x81"), ":koko:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\x82"), ":sa:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb7"), ":u6708:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb6"), ":u6709:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xaf"), ":u6307:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x89\x90"), ":ideograph_advantage:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb9"), ":u5272:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\x9a"), ":u7121:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb2"), ":u7981:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x89\x91"), ":accept:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb8"), ":u7533:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb4"), ":u5408:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb3"), ":u7a7a:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe3\x8a\x97"), ":congratulations:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe3\x8a\x99"), ":secret:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xba"), ":u55b6:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x88\xb5"), ":u6e80:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x96\xaa"), ":black_small_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x96\xab"), ":white_small_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x97\xbb"), ":white_medium_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x97\xbc"), ":black_medium_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x97\xbd"), ":white_medium_small_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x97\xbe"), ":black_medium_small_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xac\x9b"), ":black_large_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\xac\x9c"), ":white_large_square:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb6"), ":large_orange_diamond:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb7"), ":large_blue_diamond:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb8"), ":small_orange_diamond:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb9"), ":small_blue_diamond:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xba"), ":small_red_triangle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xbb"), ":small_red_triangle_down:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x92\xa0"), ":diamond_shape_with_a_dot_inside:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\x98"), ":radio_button:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb2"), ":black_square_button:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb3"), ":white_square_button:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xaa"), ":white_circle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xe2\x9a\xab"), ":black_circle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb4"), ":red_circle:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x94\xb5"), ":blue_circle:" }), +}; + +const QVariantList EmojiModel::flags = { + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xa8"), ":flag_ac:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xa9"), ":flag_ad:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xaa"), ":flag_ae:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xab"), ":flag_af:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xac"), ":flag_ag:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xae"), ":flag_ai:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xb1"), ":flag_al:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xb2"), ":flag_am:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xb4"), ":flag_ao:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xb6"), ":flag_aq:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xb7"), ":flag_ar:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xb8"), ":flag_as:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xb9"), ":flag_at:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xba"), ":flag_au:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xbc"), ":flag_aw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xbd"), ":flag_ax:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa6\xf0\x9f\x87\xbf"), ":flag_az:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xa6"), ":flag_ba:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xa7"), ":flag_bb:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xa9"), ":flag_bd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xaa"), ":flag_be:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xab"), ":flag_bf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xac"), ":flag_bg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xad"), ":flag_bh:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xae"), ":flag_bi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xaf"), ":flag_bj:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb1"), ":flag_bl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb2"), ":flag_bm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb3"), ":flag_bn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb4"), ":flag_bo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb6"), ":flag_bq:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb7"), ":flag_br:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb8"), ":flag_bs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xb9"), ":flag_bt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xbb"), ":flag_bv:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xbc"), ":flag_bw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xbe"), ":flag_by:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa7\xf0\x9f\x87\xbf"), ":flag_bz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xa6"), ":flag_ca:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xa8"), ":flag_cc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xa9"), ":flag_cd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xab"), ":flag_cf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xac"), ":flag_cg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xad"), ":flag_ch:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xae"), ":flag_ci:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xb0"), ":flag_ck:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xb1"), ":flag_cl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xb2"), ":flag_cm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xb3"), ":flag_cn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xb4"), ":flag_co:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xb5"), ":flag_cp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xb7"), ":flag_cr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xba"), ":flag_cu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xbb"), ":flag_cv:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xbc"), ":flag_cw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xbd"), ":flag_cx:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xbe"), ":flag_cy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa8\xf0\x9f\x87\xbf"), ":flag_cz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa9\xf0\x9f\x87\xaa"), ":flag_de:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa9\xf0\x9f\x87\xac"), ":flag_dg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa9\xf0\x9f\x87\xaf"), ":flag_dj:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa9\xf0\x9f\x87\xb0"), ":flag_dk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa9\xf0\x9f\x87\xb2"), ":flag_dm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa9\xf0\x9f\x87\xb4"), ":flag_do:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xa9\xf0\x9f\x87\xbf"), ":flag_dz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xa6"), ":flag_ea:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xa8"), ":flag_ec:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xaa"), ":flag_ee:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xac"), ":flag_eg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xad"), ":flag_eh:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xb7"), ":flag_er:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xb8"), ":flag_es:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xb9"), ":flag_et:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaa\xf0\x9f\x87\xba"), ":flag_eu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xab\xf0\x9f\x87\xae"), ":flag_fi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xab\xf0\x9f\x87\xaf"), ":flag_fj:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xab\xf0\x9f\x87\xb0"), ":flag_fk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xab\xf0\x9f\x87\xb2"), ":flag_fm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xab\xf0\x9f\x87\xb4"), ":flag_fo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xab\xf0\x9f\x87\xb7"), ":flag_fr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xa6"), ":flag_ga:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xa7"), ":flag_gb:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xa9"), ":flag_gd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xaa"), ":flag_ge:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xab"), ":flag_gf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xac"), ":flag_gg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xad"), ":flag_gh:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xae"), ":flag_gi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb1"), ":flag_gl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb2"), ":flag_gm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb3"), ":flag_gn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb5"), ":flag_gp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb6"), ":flag_gq:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb7"), ":flag_gr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb8"), ":flag_gs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xb9"), ":flag_gt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xba"), ":flag_gu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xbc"), ":flag_gw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xac\xf0\x9f\x87\xbe"), ":flag_gy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xad\xf0\x9f\x87\xb0"), ":flag_hk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xad\xf0\x9f\x87\xb2"), ":flag_hm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xad\xf0\x9f\x87\xb3"), ":flag_hn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xad\xf0\x9f\x87\xb7"), ":flag_hr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xad\xf0\x9f\x87\xb9"), ":flag_ht:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xad\xf0\x9f\x87\xba"), ":flag_hu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xa8"), ":flag_ic:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xa9"), ":flag_id:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xaa"), ":flag_ie:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb1"), ":flag_il:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb2"), ":flag_im:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb3"), ":flag_in:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb4"), ":flag_io:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb6"), ":flag_iq:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb7"), ":flag_ir:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb8"), ":flag_is:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xae\xf0\x9f\x87\xb9"), ":flag_it:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaf\xf0\x9f\x87\xaa"), ":flag_je:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaf\xf0\x9f\x87\xb2"), ":flag_jm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaf\xf0\x9f\x87\xb4"), ":flag_jo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xaf\xf0\x9f\x87\xb5"), ":flag_jp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xaa"), ":flag_ke:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xac"), ":flag_kg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xad"), ":flag_kh:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xae"), ":flag_ki:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xb2"), ":flag_km:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xb3"), ":flag_kn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xb5"), ":flag_kp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xb7"), ":flag_kr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xbc"), ":flag_kw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xbe"), ":flag_ky:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb0\xf0\x9f\x87\xbf"), ":flag_kz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xa6"), ":flag_la:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xa7"), ":flag_lb:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xa8"), ":flag_lc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xae"), ":flag_li:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xb0"), ":flag_lk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xb7"), ":flag_lr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xb8"), ":flag_ls:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xb9"), ":flag_lt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xba"), ":flag_lu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xbb"), ":flag_lv:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb1\xf0\x9f\x87\xbe"), ":flag_ly:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xa6"), ":flag_ma:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xa8"), ":flag_mc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xa9"), ":flag_md:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xaa"), ":flag_me:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xab"), ":flag_mf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xac"), ":flag_mg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xad"), ":flag_mh:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb0"), ":flag_mk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb1"), ":flag_ml:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb2"), ":flag_mm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb3"), ":flag_mn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb4"), ":flag_mo:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb5"), ":flag_mp:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb6"), ":flag_mq:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb7"), ":flag_mr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb8"), ":flag_ms:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xb9"), ":flag_mt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xba"), ":flag_mu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xbb"), ":flag_mv:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xbc"), ":flag_mw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xbd"), ":flag_mx:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xbe"), ":flag_my:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb2\xf0\x9f\x87\xbf"), ":flag_mz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xa6"), ":flag_na:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xa8"), ":flag_nc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xaa"), ":flag_ne:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xab"), ":flag_nf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xac"), ":flag_ng:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xae"), ":flag_ni:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xb1"), ":flag_nl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xb4"), ":flag_no:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xb5"), ":flag_np:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xb7"), ":flag_nr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xba"), ":flag_nu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb3\xf0\x9f\x87\xbf"), ":flag_nz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb4\xf0\x9f\x87\xb2"), ":flag_om:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xa6"), ":flag_pa:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xaa"), ":flag_pe:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xab"), ":flag_pf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xac"), ":flag_pg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xad"), ":flag_ph:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xb0"), ":flag_pk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xb1"), ":flag_pl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xb2"), ":flag_pm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xb3"), ":flag_pn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xb7"), ":flag_pr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xb8"), ":flag_ps:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xb9"), ":flag_pt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xbc"), ":flag_pw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb5\xf0\x9f\x87\xbe"), ":flag_py:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb6\xf0\x9f\x87\xa6"), ":flag_qa:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb7\xf0\x9f\x87\xaa"), ":flag_re:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb7\xf0\x9f\x87\xb4"), ":flag_ro:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb7\xf0\x9f\x87\xb8"), ":flag_rs:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb7\xf0\x9f\x87\xba"), ":flag_ru:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb7\xf0\x9f\x87\xbc"), ":flag_rw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xa6"), ":flag_sa:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xa7"), ":flag_sb:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xa8"), ":flag_sc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xa9"), ":flag_sd:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xaa"), ":flag_se:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xac"), ":flag_sg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xad"), ":flag_sh:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xae"), ":flag_si:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xaf"), ":flag_sj:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb0"), ":flag_sk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb1"), ":flag_sl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb2"), ":flag_sm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb3"), ":flag_sn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb4"), ":flag_so:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb7"), ":flag_sr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb8"), ":flag_ss:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xb9"), ":flag_st:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xbb"), ":flag_sv:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xbd"), ":flag_sx:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xbe"), ":flag_sy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb8\xf0\x9f\x87\xbf"), ":flag_sz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xa6"), ":flag_ta:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xa8"), ":flag_tc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xa9"), ":flag_td:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xab"), ":flag_tf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xac"), ":flag_tg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xad"), ":flag_th:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xaf"), ":flag_tj:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xb0"), ":flag_tk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xb1"), ":flag_tl:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xb2"), ":flag_tm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xb3"), ":flag_tn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xb4"), ":flag_to:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xb7"), ":flag_tr:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xb9"), ":flag_tt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xbb"), ":flag_tv:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xbc"), ":flag_tw:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xb9\xf0\x9f\x87\xbf"), ":flag_tz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xba\xf0\x9f\x87\xa6"), ":flag_ua:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xba\xf0\x9f\x87\xac"), ":flag_ug:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xba\xf0\x9f\x87\xb2"), ":flag_um:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xba\xf0\x9f\x87\xb8"), ":flag_us:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xba\xf0\x9f\x87\xbe"), ":flag_uy:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xba\xf0\x9f\x87\xbf"), ":flag_uz:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbb\xf0\x9f\x87\xa6"), ":flag_va:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbb\xf0\x9f\x87\xa8"), ":flag_vc:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbb\xf0\x9f\x87\xaa"), ":flag_ve:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbb\xf0\x9f\x87\xac"), ":flag_vg:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbb\xf0\x9f\x87\xae"), ":flag_vi:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbb\xf0\x9f\x87\xb3"), ":flag_vn:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbb\xf0\x9f\x87\xba"), ":flag_vu:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbc\xf0\x9f\x87\xab"), ":flag_wf:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbc\xf0\x9f\x87\xb8"), ":flag_ws:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbd\xf0\x9f\x87\xb0"), ":flag_xk:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbe\xf0\x9f\x87\xaa"), ":flag_ye:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbe\xf0\x9f\x87\xb9"), ":flag_yt:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbf\xf0\x9f\x87\xa6"), ":flag_za:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbf\xf0\x9f\x87\xb2"), ":flag_zm:" }), + QVariant::fromValue(Emoji { QString::fromUtf8("\xf0\x9f\x87\xbf\xf0\x9f\x87\xbc"), ":flag_zw:" }), +}; +} diff --git a/src/gui/emojimodel.h b/src/gui/emojimodel.h new file mode 100644 index 000000000000..2d35305d4644 --- /dev/null +++ b/src/gui/emojimodel.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace OCC { + +struct Emoji +{ + Emoji(QString u, QString s, bool isCustom = false) + : unicode(std::move(std::move(u))) + , shortname(std::move(std::move(s))) + , isCustom(isCustom) + { + } + Emoji() = default; + + friend QDataStream &operator<<(QDataStream &arch, const Emoji &object) + { + arch << object.unicode; + arch << object.shortname; + return arch; + } + + friend QDataStream &operator>>(QDataStream &arch, Emoji &object) + { + arch >> object.unicode; + arch >> object.shortname; + object.isCustom = object.unicode.startsWith("image://"); + return arch; + } + + QString unicode; + QString shortname; + bool isCustom = false; + + Q_GADGET + Q_PROPERTY(QString unicode MEMBER unicode) + Q_PROPERTY(QString shortname MEMBER shortname) + Q_PROPERTY(bool isCustom MEMBER isCustom) +}; + +class EmojiCategoriesModel : public QAbstractListModel +{ +public: + QVariant data(const QModelIndex &index, int role) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QHash roleNames() const override; + +private: + enum Roles { + EmojiRole = 0, + LabelRole + }; + + struct Category + { + QString emoji; + QString label; + }; + + static const std::vector categories; +}; + +class EmojiModel : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QVariantList model READ model NOTIFY modelChanged) + Q_PROPERTY(QAbstractListModel *emojiCategoriesModel READ emojiCategoriesModel CONSTANT) + + Q_PROPERTY(QVariantList history READ history NOTIFY historyChanged) + + Q_PROPERTY(QVariantList people MEMBER people CONSTANT) + Q_PROPERTY(QVariantList nature MEMBER nature CONSTANT) + Q_PROPERTY(QVariantList food MEMBER food CONSTANT) + Q_PROPERTY(QVariantList activity MEMBER activity CONSTANT) + Q_PROPERTY(QVariantList travel MEMBER travel CONSTANT) + Q_PROPERTY(QVariantList objects MEMBER objects CONSTANT) + Q_PROPERTY(QVariantList symbols MEMBER symbols CONSTANT) + Q_PROPERTY(QVariantList flags MEMBER flags CONSTANT) + +public: + explicit EmojiModel(QObject *parent = nullptr) + : QObject(parent) + { + } + + Q_INVOKABLE QVariantList history() const; + Q_INVOKABLE void setCategory(const QString &category); + Q_INVOKABLE void emojiUsed(const QVariant &modelData); + + QVariantList model() const; + QAbstractListModel *emojiCategoriesModel(); + +signals: + void historyChanged(); + void modelChanged(); + +private: + static const QVariantList people; + static const QVariantList nature; + static const QVariantList food; + static const QVariantList activity; + static const QVariantList travel; + static const QVariantList objects; + static const QVariantList symbols; + static const QVariantList flags; + + QSettings _settings; + QString _category = "history"; + + EmojiCategoriesModel _emojiCategoriesModel; +}; + +} + +Q_DECLARE_METATYPE(OCC::Emoji) diff --git a/src/gui/fileactivitylistmodel.cpp b/src/gui/fileactivitylistmodel.cpp new file mode 100644 index 000000000000..104ff317c291 --- /dev/null +++ b/src/gui/fileactivitylistmodel.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 "fileactivitylistmodel.h" +#include "folderman.h" +#include "tray/activitylistmodel.h" + +namespace OCC { + +Q_LOGGING_CATEGORY(lcFileActivityListModel, "nextcloud.gui.fileactivitylistmodel", QtInfoMsg) + +FileActivityListModel::FileActivityListModel(QObject *parent) + : ActivityListModel(nullptr, parent) +{ + setDisplayActions(false); +} + +void FileActivityListModel::load(AccountState *accountState, const QString &localPath) +{ + Q_ASSERT(accountState); + if (!accountState || currentlyFetching()) { + return; + } + setAccountState(accountState); + + const auto folder = FolderMan::instance()->folderForPath(localPath); + if (!folder) { + return; + } + + const auto file = folder->fileFromLocalPath(localPath); + SyncJournalFileRecord fileRecord; + if (!folder->journalDb()->getFileRecord(file, &fileRecord) || !fileRecord.isValid()) { + return; + } + + _fileId = fileRecord._fileId; + slotRefreshActivity(); +} + +void FileActivityListModel::startFetchJob() +{ + if (!accountState()->isConnected()) { + return; + } + setCurrentlyFetching(true); + + const QString url(QStringLiteral("ocs/v2.php/apps/activity/api/v2/activity/filter")); + auto job = new JsonApiJob(accountState()->account(), url, this); + QObject::connect(job, &JsonApiJob::jsonReceived, + this, &FileActivityListModel::activitiesReceived); + + QUrlQuery params; + params.addQueryItem(QStringLiteral("sort"), QStringLiteral("asc")); + params.addQueryItem(QStringLiteral("object_type"), "files"); + params.addQueryItem(QStringLiteral("object_id"), _fileId); + job->addQueryParams(params); + setDoneFetching(true); + setHideOldActivities(true); + job->start(); +} +} diff --git a/src/gui/fileactivitylistmodel.h b/src/gui/fileactivitylistmodel.h new file mode 100644 index 000000000000..421c58128618 --- /dev/null +++ b/src/gui/fileactivitylistmodel.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +#pragma once + +#include "accountstate.h" +#include "tray/activitylistmodel.h" + +namespace OCC { + +class FileActivityListModel : public ActivityListModel +{ + Q_OBJECT + +public: + explicit FileActivityListModel(QObject *parent = nullptr); + +public slots: + void load(AccountState *accountState, const QString &fileId); + +protected: + void startFetchJob() override; + +private: + QString _fileId; +}; +} diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index cda9b0cb27f6..decbb927b52c 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -28,7 +28,7 @@ #include "clientproxy.h" #include "syncengine.h" #include "syncrunfilelog.h" -#include "socketapi.h" +#include "socketapi/socketapi.h" #include "theme.h" #include "filesystem.h" #include "localdiscoverytracker.h" @@ -353,7 +353,7 @@ void Folder::slotRunEtagJob() // The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null. } -void Folder::etagRetrieved(const QString &etag, const QDateTime &tp) +void Folder::etagRetrieved(const QByteArray &etag, const QDateTime &tp) { // re-enable sync if it was disabled because network was down FolderMan::instance()->setSyncEnabled(true); @@ -367,7 +367,7 @@ void Folder::etagRetrieved(const QString &etag, const QDateTime &tp) _accountState->tagLastSuccessfullETagRequest(tp); } -void Folder::etagRetrievedFromSyncEngine(const QString &etag, const QDateTime &time) +void Folder::etagRetrievedFromSyncEngine(const QByteArray &etag, const QDateTime &time) { qCInfo(lcFolder) << "Root etag from during sync:" << etag; accountState()->tagLastSuccessfullETagRequest(time); @@ -669,8 +669,10 @@ void Folder::setVirtualFilesEnabled(bool enabled) _definition.virtualFilesMode = newMode; startVfs(); - if (newMode != Vfs::Off) + if (newMode != Vfs::Off) { _saveInFoldersWithPlaceholders = true; + switchToVirtualFiles(); + } saveToSettings(); } } @@ -686,6 +688,11 @@ void Folder::setRootPinState(PinState state) slotNextSyncFullLocalDiscovery(); } +void Folder::switchToVirtualFiles() +{ + SyncEngine::switchToVirtualFiles(path(), _journal, *_vfs); +} + bool Folder::supportsSelectiveSync() const { return !virtualFilesEnabled() && !isVfsOnOffSwitchPending(); @@ -874,42 +881,15 @@ void Folder::setSyncOptions() opt._confirmExternalStorage = cfgFile.confirmExternalStorage(); opt._moveFilesToTrash = cfgFile.moveToTrash(); opt._vfs = _vfs; + opt._parallelNetworkJobs = _accountState->account()->isHttp2Supported() ? 20 : 6; - QByteArray chunkSizeEnv = qgetenv("OWNCLOUD_CHUNK_SIZE"); - if (!chunkSizeEnv.isEmpty()) { - opt._initialChunkSize = chunkSizeEnv.toUInt(); - } else { - opt._initialChunkSize = cfgFile.chunkSize(); - } - QByteArray minChunkSizeEnv = qgetenv("OWNCLOUD_MIN_CHUNK_SIZE"); - if (!minChunkSizeEnv.isEmpty()) { - opt._minChunkSize = minChunkSizeEnv.toUInt(); - } else { - opt._minChunkSize = cfgFile.minChunkSize(); - } - QByteArray maxChunkSizeEnv = qgetenv("OWNCLOUD_MAX_CHUNK_SIZE"); - if (!maxChunkSizeEnv.isEmpty()) { - opt._maxChunkSize = maxChunkSizeEnv.toUInt(); - } else { - opt._maxChunkSize = cfgFile.maxChunkSize(); - } - - int maxParallel = qgetenv("OWNCLOUD_MAX_PARALLEL").toUInt(); - opt._parallelNetworkJobs = maxParallel ? maxParallel : _accountState->account()->isHttp2Supported() ? 20 : 6; - - // Previously min/max chunk size values didn't exist, so users might - // have setups where the chunk size exceeds the new min/max default - // values. To cope with this, adjust min/max to always include the - // initial chunk size value. - opt._minChunkSize = qMin(opt._minChunkSize, opt._initialChunkSize); - opt._maxChunkSize = qMax(opt._maxChunkSize, opt._initialChunkSize); + opt._initialChunkSize = cfgFile.chunkSize(); + opt._minChunkSize = cfgFile.minChunkSize(); + opt._maxChunkSize = cfgFile.maxChunkSize(); + opt._targetChunkUploadDuration = cfgFile.targetChunkUploadDuration(); - QByteArray targetChunkUploadDurationEnv = qgetenv("OWNCLOUD_TARGET_CHUNK_UPLOAD_DURATION"); - if (!targetChunkUploadDurationEnv.isEmpty()) { - opt._targetChunkUploadDuration = std::chrono::milliseconds(targetChunkUploadDurationEnv.toUInt()); - } else { - opt._targetChunkUploadDuration = cfgFile.targetChunkUploadDuration(); - } + opt.fillFromEnvironmentVariables(); + opt.verifyChunkSizes(); _engine->setSyncOptions(opt); } @@ -1288,6 +1268,11 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction dir, std::functio msgBox->open(); } +QString Folder::fileFromLocalPath(const QString &localPath) const +{ + return localPath.mid(cleanPath().length() + 1); +} + void FolderDefinition::save(QSettings &settings, const FolderDefinition &folder) { settings.setValue(QLatin1String("localPath"), folder.localPath); @@ -1381,4 +1366,5 @@ QString FolderDefinition::defaultJournalPath(AccountPtr account) return SyncJournalDb::makeDbName(localPath, account->url(), targetPath, account->credentials()->user()); } + } // namespace OCC diff --git a/src/gui/folder.h b/src/gui/folder.h index 809ca85e7960..3bb96b2da487 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -117,7 +117,7 @@ class Folder : public QObject */ Folder(const FolderDefinition &definition, AccountState *accountState, std::unique_ptr vfs, QObject *parent = nullptr); - ~Folder(); + ~Folder() override; using Map = QMap; using MapIterator = QMapIterator; @@ -287,9 +287,13 @@ class Folder : public QObject bool isVfsOnOffSwitchPending() const { return _vfsOnOffPending; } void setVfsOnOffSwitchPending(bool pending) { _vfsOnOffPending = pending; } + void switchToVirtualFiles(); + /** Whether this folder should show selective sync ui */ bool supportsSelectiveSync() const; + QString fileFromLocalPath(const QString &localPath) const; + signals: void syncStateChange(); void syncStarted(); @@ -376,8 +380,8 @@ private slots: void slotItemCompleted(const SyncFileItemPtr &); void slotRunEtagJob(); - void etagRetrieved(const QString &, const QDateTime &tp); - void etagRetrievedFromSyncEngine(const QString &, const QDateTime &time); + void etagRetrieved(const QByteArray &, const QDateTime &tp); + void etagRetrievedFromSyncEngine(const QByteArray &, const QDateTime &time); void slotEmitFinishedDelayed(); @@ -447,7 +451,7 @@ private slots: SyncResult _syncResult; QScopedPointer _engine; QPointer _requestEtagJob; - QString _lastEtag; + QByteArray _lastEtag; QElapsedTimer _timeSinceLastSyncDone; QElapsedTimer _timeSinceLastSyncStart; QElapsedTimer _timeSinceLastFullLocalDiscovery; diff --git a/src/gui/foldercreationdialog.h b/src/gui/foldercreationdialog.h index 4797b5f932cd..3786b9f51018 100644 --- a/src/gui/foldercreationdialog.h +++ b/src/gui/foldercreationdialog.h @@ -29,7 +29,7 @@ class FolderCreationDialog : public QDialog public: explicit FolderCreationDialog(const QString &destination, QWidget *parent = nullptr); - ~FolderCreationDialog(); + ~FolderCreationDialog() override; private slots: void accept() override; diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 9b0f297e95cc..73ad0c5535ea 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -17,7 +17,7 @@ #include "folder.h" #include "syncresult.h" #include "theme.h" -#include "socketapi.h" +#include "socketapi/socketapi.h" #include "account.h" #include "accountstate.h" #include "accountmanager.h" @@ -292,6 +292,11 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account, SyncJournalDb::maybeMigrateDb(folderDefinition.localPath, folderDefinition.absoluteJournalPath()); } + const auto switchToVfs = isSwitchToVfsNeeded(folderDefinition); + if (switchToVfs) { + folderDefinition.virtualFilesMode = bestAvailableVfsMode(); + } + auto vfs = createVfsFromPlugin(folderDefinition.virtualFilesMode); if (!vfs) { // TODO: Must do better error handling @@ -300,6 +305,9 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account, Folder *f = addFolderInternal(std::move(folderDefinition), account.data(), std::move(vfs)); if (f) { + if (switchToVfs) { + f->switchToVirtualFiles(); + } // Migrate the old "usePlaceholders" setting to the root folder pin state if (settings.value(QLatin1String(versionC), 1).toInt() == 1 && settings.value(QLatin1String("usePlaceholders"), false).toBool()) { @@ -837,6 +845,19 @@ bool FolderMan::pushNotificationsFilesReady(Account *account) return pushFilesAvailable && pushNotifications && pushNotifications->isReady(); } +bool FolderMan::isSwitchToVfsNeeded(const FolderDefinition &folderDefinition) const +{ + auto result = false; + if (ENFORCE_VIRTUAL_FILES_SYNC_FOLDER && + folderDefinition.virtualFilesMode != bestAvailableVfsMode() && + folderDefinition.virtualFilesMode == Vfs::Off && + OCC::Theme::instance()->showVirtualFilesOption()) { + result = true; + } + + return result; +} + void FolderMan::slotEtagPollTimerTimeout() { qCInfo(lcFolderMan) << "Etag poll timer timeout"; diff --git a/src/gui/folderman.h b/src/gui/folderman.h index 815c1288f82d..5a6c234e7d71 100644 --- a/src/gui/folderman.h +++ b/src/gui/folderman.h @@ -62,7 +62,7 @@ class FolderMan : public QObject { Q_OBJECT public: - ~FolderMan(); + ~FolderMan() override; static FolderMan *instance(); int setupFolders(); @@ -324,6 +324,8 @@ private slots: bool pushNotificationsFilesReady(Account *account); + bool isSwitchToVfsNeeded(const FolderDefinition &folderDefinition) const; + QSet _disabledFolders; Folder::Map _folderMap; QString _folderConfigPath; diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp index 3ffc048497c6..51bbe4f74840 100644 --- a/src/gui/folderstatusmodel.cpp +++ b/src/gui/folderstatusmodel.cpp @@ -907,7 +907,7 @@ void FolderStatusModel::slotApplySelectiveSync() // The folders that were undecided or blacklisted and that are now checked should go on the white list. // The user confirmed them already just now. - QStringList toAddToWhiteList = ((oldBlackListSet + folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, &ok).toSet()) - blackListSet).toList(); + QStringList toAddToWhiteList = ((oldBlackListSet + folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncUndecidedList, &ok).toSet()) - blackListSet).values(); if (!toAddToWhiteList.isEmpty()) { auto whiteList = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, &ok); diff --git a/src/gui/folderstatusmodel.h b/src/gui/folderstatusmodel.h index 39d937f09c6e..896a19550bde 100644 --- a/src/gui/folderstatusmodel.h +++ b/src/gui/folderstatusmodel.h @@ -42,7 +42,7 @@ class FolderStatusModel : public QAbstractItemModel enum {FileIdRole = Qt::UserRole+1}; FolderStatusModel(QObject *parent = nullptr); - ~FolderStatusModel(); + ~FolderStatusModel() override; void setAccountState(const AccountState *accountState); Qt::ItemFlags flags(const QModelIndex &) const override; diff --git a/src/gui/folderwatcher.h b/src/gui/folderwatcher.h index c98db8f68816..9972dd50f0ff 100644 --- a/src/gui/folderwatcher.h +++ b/src/gui/folderwatcher.h @@ -53,7 +53,7 @@ class FolderWatcher : public QObject public: // Construct, connect signals, call init() explicit FolderWatcher(Folder *folder = nullptr); - virtual ~FolderWatcher(); + ~FolderWatcher() override; /** * @param root Path of the root of the folder diff --git a/src/gui/folderwatcher_linux.h b/src/gui/folderwatcher_linux.h index 277736b40b0d..620e037ed94e 100644 --- a/src/gui/folderwatcher_linux.h +++ b/src/gui/folderwatcher_linux.h @@ -37,7 +37,7 @@ class FolderWatcherPrivate : public QObject public: FolderWatcherPrivate() = default; FolderWatcherPrivate(FolderWatcher *p, const QString &path); - ~FolderWatcherPrivate(); + ~FolderWatcherPrivate() override; int testWatchCount() const { return _pathToWatch.size(); } diff --git a/src/gui/folderwizard.cpp b/src/gui/folderwizard.cpp index b55cb58e961b..b240d72355fa 100644 --- a/src/gui/folderwizard.cpp +++ b/src/gui/folderwizard.cpp @@ -201,21 +201,19 @@ void FolderWizardRemotePath::slotCreateRemoteFolder(const QString &folder) auto *job = new MkColJob(_account, fullPath, this); /* check the owncloud configuration file and query the ownCloud */ - connect(job, static_cast(&MkColJob::finished), + connect(job, &MkColJob::finishedWithoutError, this, &FolderWizardRemotePath::slotCreateRemoteFolderFinished); connect(job, &AbstractNetworkJob::networkError, this, &FolderWizardRemotePath::slotHandleMkdirNetworkError); job->start(); } -void FolderWizardRemotePath::slotCreateRemoteFolderFinished(QNetworkReply::NetworkError error) +void FolderWizardRemotePath::slotCreateRemoteFolderFinished() { - if (error == QNetworkReply::NoError) { - qCDebug(lcWizard) << "webdav mkdir request finished"; - showWarn(tr("Folder was successfully created on %1.").arg(Theme::instance()->appNameGUI())); - slotRefreshFolders(); - _ui.folderEntry->setText(static_cast(sender())->path()); - slotLsColFolderEntry(); - } + qCDebug(lcWizard) << "webdav mkdir request finished"; + showWarn(tr("Folder was successfully created on %1.").arg(Theme::instance()->appNameGUI())); + slotRefreshFolders(); + _ui.folderEntry->setText(static_cast(sender())->path()); + slotLsColFolderEntry(); } void FolderWizardRemotePath::slotHandleMkdirNetworkError(QNetworkReply *reply) @@ -547,6 +545,11 @@ void FolderWizardSelectiveSync::initializePage() _virtualFilesCheckBox->setChecked(bestAvailableVfsMode() == Vfs::WindowsCfApi); _virtualFilesCheckBox->setEnabled(true); _virtualFilesCheckBox->setText(tr("Use virtual files instead of downloading content immediately %1").arg(bestAvailableVfsMode() == Vfs::WindowsCfApi ? QString() : tr("(experimental)"))); + + if (Theme::instance()->enforceVirtualFilesSyncFolder()) { + _virtualFilesCheckBox->setChecked(true); + _virtualFilesCheckBox->setDisabled(true); + } } // } diff --git a/src/gui/folderwizard.h b/src/gui/folderwizard.h index 58ffa69c053d..c6e7d48ce69f 100644 --- a/src/gui/folderwizard.h +++ b/src/gui/folderwizard.h @@ -53,7 +53,7 @@ class FolderWizardLocalPath : public FormatWarningsWizardPage Q_OBJECT public: explicit FolderWizardLocalPath(const AccountPtr &account); - ~FolderWizardLocalPath(); + ~FolderWizardLocalPath() override; bool isComplete() const override; void initializePage() override; @@ -80,7 +80,7 @@ class FolderWizardRemotePath : public FormatWarningsWizardPage Q_OBJECT public: explicit FolderWizardRemotePath(const AccountPtr &account); - ~FolderWizardRemotePath(); + ~FolderWizardRemotePath() override; bool isComplete() const override; @@ -92,7 +92,7 @@ protected slots: void showWarn(const QString & = QString()) const; void slotAddRemoteFolder(); void slotCreateRemoteFolder(const QString &); - void slotCreateRemoteFolderFinished(QNetworkReply::NetworkError error); + void slotCreateRemoteFolderFinished(); void slotHandleMkdirNetworkError(QNetworkReply *); void slotHandleLsColNetworkError(QNetworkReply *); void slotUpdateDirectories(const QStringList &); @@ -124,7 +124,7 @@ class FolderWizardSelectiveSync : public QWizardPage Q_OBJECT public: explicit FolderWizardSelectiveSync(const AccountPtr &account); - ~FolderWizardSelectiveSync(); + ~FolderWizardSelectiveSync() override; bool validatePage() override; @@ -154,7 +154,7 @@ class FolderWizard : public QWizard }; explicit FolderWizard(AccountPtr account, QWidget *parent = nullptr); - ~FolderWizard(); + ~FolderWizard() override; bool eventFilter(QObject *watched, QEvent *event) override; void resizeEvent(QResizeEvent *event) override; diff --git a/src/gui/generalsettings.cpp b/src/gui/generalsettings.cpp index 0f4c21f5286c..058bdf1d6699 100644 --- a/src/gui/generalsettings.cpp +++ b/src/gui/generalsettings.cpp @@ -21,6 +21,7 @@ #include "configfile.h" #include "owncloudsetupwizard.h" #include "accountmanager.h" +#include "guiutility.h" #if defined(BUILD_UPDATER) #include "updater/updater.h" @@ -275,8 +276,13 @@ void GeneralSettings::slotUpdateInfo() connect(_ui->updateButton, &QAbstractButton::clicked, this, &GeneralSettings::slotUpdateCheckNow, Qt::UniqueConnection); connect(_ui->autoCheckForUpdatesCheckBox, &QAbstractButton::toggled, this, &GeneralSettings::slotToggleAutoUpdateCheck); - QString status = ocupdater->statusString(); + QString status = ocupdater->statusString(OCUpdater::UpdateStatusStringFormat::Html); Theme::replaceLinkColorStringBackgroundAware(status); + + _ui->updateStateLabel->setOpenExternalLinks(false); + connect(_ui->updateStateLabel, &QLabel::linkActivated, this, [](const QString &link) { + Utility::openBrowser(QUrl(link)); + }); _ui->updateStateLabel->setText(status); _ui->restartButton->setVisible(ocupdater->downloadState() == OCUpdater::DownloadComplete); diff --git a/src/gui/generalsettings.h b/src/gui/generalsettings.h index 9012b5eca8d2..06675c8cce49 100644 --- a/src/gui/generalsettings.h +++ b/src/gui/generalsettings.h @@ -36,7 +36,7 @@ class GeneralSettings : public QWidget public: explicit GeneralSettings(QWidget *parent = nullptr); - ~GeneralSettings(); + ~GeneralSettings() override; QSize sizeHint() const override; public slots: diff --git a/src/gui/iconutils.cpp b/src/gui/iconutils.cpp new file mode 100644 index 000000000000..40ad051ce15a --- /dev/null +++ b/src/gui/iconutils.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 "iconutils.h" + +#include + +#include +#include +#include +#include +#include + +namespace { +QString findSvgFilePath(const QString &fileName, const QStringList &possibleColors) +{ + QString result; + result = QString{OCC::Theme::themePrefix} + fileName; + if (QFile::exists(result)) { + return result; + } else { + for (const auto &color : possibleColors) { + result = QString{OCC::Theme::themePrefix} + color + QStringLiteral("/") + fileName; + + if (QFile::exists(result)) { + return result; + } + } + result.clear(); + } + + return result; +} +} + +namespace OCC { +namespace Ui { +namespace IconUtils { +Q_LOGGING_CATEGORY(lcIconUtils, "nextcloud.gui.iconutils", QtInfoMsg) +QPixmap pixmapForBackground(const QString &fileName, const QColor &backgroundColor) +{ + Q_ASSERT(!fileName.isEmpty()); + + const auto pixmapColor = backgroundColor.isValid() && !Theme::isDarkColor(backgroundColor) + ? QColorConstants::Svg::black + : QColorConstants::Svg::white; + ; + return createSvgPixmapWithCustomColorCached(fileName, pixmapColor); +} + +QImage createSvgImageWithCustomColor(const QString &fileName, const QColor &customColor, QSize *originalSize, const QSize &requestedSize) +{ + Q_ASSERT(!fileName.isEmpty()); + Q_ASSERT(customColor.isValid()); + + QImage result{}; + + if (fileName.isEmpty() || !customColor.isValid()) { + qWarning(lcIconUtils) << "invalid fileName or customColor"; + return result; + } + + // some icons are present in white or black only, so, we need to check both when needed + const auto iconBaseColors = QStringList{QStringLiteral("black"), QStringLiteral("white")}; + + // check if there is an existing image matching the custom color + { + const auto customColorName = [&customColor]() { + auto result = customColor.name(); + if (result.startsWith(QStringLiteral("#"))) { + if (result == QStringLiteral("#000000")) { + result = QStringLiteral("black"); + } + if (result == QStringLiteral("#ffffff")) { + result = QStringLiteral("white"); + } + } + return result; + }(); + + if (iconBaseColors.contains(customColorName)) { + result = QImage{QString{OCC::Theme::themePrefix} + customColorName + QStringLiteral("/") + fileName}; + if (!result.isNull()) { + return result; + } + } + } + + // find the first matching svg file + const auto sourceSvg = findSvgFilePath(fileName, iconBaseColors); + + Q_ASSERT(!sourceSvg.isEmpty()); + if (sourceSvg.isEmpty()) { + qWarning(lcIconUtils) << "Failed to find base SVG file for" << fileName; + return result; + } + + result = drawSvgWithCustomFillColor(sourceSvg, customColor, originalSize, requestedSize); + + Q_ASSERT(!result.isNull()); + if (result.isNull()) { + qWarning(lcIconUtils) << "Failed to load pixmap for" << fileName; + } + + return result; +} + +QPixmap createSvgPixmapWithCustomColorCached(const QString &fileName, const QColor &customColor, QSize *originalSize, const QSize &requestedSize) +{ + QPixmap cachedPixmap; + + const auto customColorName = customColor.name(); + + const QString cacheKey = fileName + QStringLiteral(",") + customColorName; + + // check for existing QPixmap in cache + if (QPixmapCache::find(cacheKey, &cachedPixmap)) { + if (originalSize) { + *originalSize = {}; + } + return cachedPixmap; + } + + cachedPixmap = QPixmap::fromImage(createSvgImageWithCustomColor(fileName, customColor, originalSize, requestedSize)); + + if (!cachedPixmap.isNull()) { + QPixmapCache::insert(cacheKey, cachedPixmap); + } + + return cachedPixmap; +} + +QImage drawSvgWithCustomFillColor( + const QString &sourceSvgPath, const QColor &fillColor, QSize *originalSize, const QSize &requestedSize) +{ + QSvgRenderer svgRenderer; + + if (!svgRenderer.load(sourceSvgPath)) { + qCWarning(lcIconUtils) << "Could no load initial SVG image"; + return {}; + } + + const auto reqSize = requestedSize.isValid() ? requestedSize : svgRenderer.defaultSize(); + + if (originalSize) { + *originalSize = svgRenderer.defaultSize(); + } + + // render source image + QImage svgImage(reqSize, QImage::Format_ARGB32); + { + QPainter svgImagePainter(&svgImage); + svgImage.fill(Qt::GlobalColor::transparent); + svgRenderer.render(&svgImagePainter); + } + + // draw target image with custom fillColor + QImage image(reqSize, QImage::Format_ARGB32); + image.fill(QColor(fillColor)); + { + QPainter imagePainter(&image); + imagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); + imagePainter.drawImage(0, 0, svgImage); + } + + return image; +} +} +} +} diff --git a/src/gui/iconutils.h b/src/gui/iconutils.h new file mode 100644 index 000000000000..af5930cb5acb --- /dev/null +++ b/src/gui/iconutils.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 ICONUTILS_H +#define ICONUTILS_H + +#include +#include + +namespace OCC { +namespace Ui { +namespace IconUtils { +QPixmap pixmapForBackground(const QString &fileName, const QColor &backgroundColor); +QImage createSvgImageWithCustomColor(const QString &fileName, const QColor &customColor, QSize *originalSize = nullptr, const QSize &requestedSize = {}); +QPixmap createSvgPixmapWithCustomColorCached(const QString &fileName, const QColor &customColor, QSize *originalSize = nullptr, const QSize &requestedSize = {}); +QImage drawSvgWithCustomFillColor(const QString &sourceSvgPath, const QColor &fillColor, QSize *originalSize = nullptr, const QSize &requestedSize = {}); +} +} +} +#endif // ICONUTILS_H diff --git a/src/gui/ignorelisteditor.h b/src/gui/ignorelisteditor.h index 39c38d74d457..e425fc784925 100644 --- a/src/gui/ignorelisteditor.h +++ b/src/gui/ignorelisteditor.h @@ -36,7 +36,7 @@ class IgnoreListEditor : public QDialog public: IgnoreListEditor(QWidget *parent = nullptr); - ~IgnoreListEditor(); + ~IgnoreListEditor() override; bool ignoreHiddenFiles(); diff --git a/src/gui/ignorelisttablewidget.h b/src/gui/ignorelisttablewidget.h index 3bded0462a0c..39d43fde9824 100644 --- a/src/gui/ignorelisttablewidget.h +++ b/src/gui/ignorelisttablewidget.h @@ -16,7 +16,7 @@ class IgnoreListTableWidget : public QWidget public: IgnoreListTableWidget(QWidget *parent = nullptr); - ~IgnoreListTableWidget(); + ~IgnoreListTableWidget() override; void readIgnoreFile(const QString &file, bool readOnly = false); int addPattern(const QString &pattern, bool deletable, bool readOnly); diff --git a/src/gui/invalidfilenamedialog.cpp b/src/gui/invalidfilenamedialog.cpp new file mode 100644 index 000000000000..8b318fed3a90 --- /dev/null +++ b/src/gui/invalidfilenamedialog.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 "invalidfilenamedialog.h" +#include "accountfwd.h" +#include "common/syncjournalfilerecord.h" +#include "propagateremotemove.h" +#include "ui_invalidfilenamedialog.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace { +constexpr std::array illegalCharacters({ '\\', '/', ':', '?', '*', '\"', '<', '>', '|' }); + +QVector getIllegalCharsFromString(const QString &string) +{ + QVector result; + for (const auto &character : string) { + if (std::find(illegalCharacters.begin(), illegalCharacters.end(), character) + != illegalCharacters.end()) { + result.push_back(character); + } + } + return result; +} + +QString illegalCharacterListToString(const QVector &illegalCharacters) +{ + QString illegalCharactersString; + if (illegalCharacters.size() > 0) { + illegalCharactersString += illegalCharacters[0]; + } + + for (int i = 1; i < illegalCharacters.count(); ++i) { + if (illegalCharactersString.contains(illegalCharacters[i])) { + continue; + } + illegalCharactersString += " " + illegalCharacters[i]; + } + return illegalCharactersString; +} +} + +namespace OCC { + +InvalidFilenameDialog::InvalidFilenameDialog(AccountPtr account, Folder *folder, QString filePath, QWidget *parent) + : QDialog(parent) + , _ui(new Ui::InvalidFilenameDialog) + , _account(account) + , _folder(folder) + , _filePath(std::move(filePath)) +{ + Q_ASSERT(_account); + Q_ASSERT(_folder); + + const auto filePathFileInfo = QFileInfo(_filePath); + _relativeFilePath = filePathFileInfo.path() + QStringLiteral("/"); + _relativeFilePath = _relativeFilePath.replace(folder->path(), QStringLiteral("")); + _relativeFilePath = _relativeFilePath.isEmpty() ? QStringLiteral("") : _relativeFilePath + QStringLiteral("/"); + + _originalFileName = _relativeFilePath + filePathFileInfo.fileName(); + + _ui->setupUi(this); + _ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + _ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Rename file")); + + _ui->descriptionLabel->setText(tr("The file %1 could not be synced because the name contains characters which are not allowed on this system.").arg(_originalFileName)); + _ui->explanationLabel->setText(tr("The following characters are not allowed on the system: * \" | & ? , ; : \\ / ~ < >")); + _ui->filenameLineEdit->setText(filePathFileInfo.fileName()); + + connect(_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + + connect(_ui->filenameLineEdit, &QLineEdit::textChanged, this, + &InvalidFilenameDialog::onFilenameLineEditTextChanged); + + checkIfAllowedToRename(); +} + +InvalidFilenameDialog::~InvalidFilenameDialog() = default; + +void InvalidFilenameDialog::checkIfAllowedToRename() +{ + const auto propfindJob = new PropfindJob(_account, QDir::cleanPath(_folder->remotePath() + _originalFileName)); + propfindJob->setProperties({ "http://owncloud.org/ns:permissions" }); + connect(propfindJob, &PropfindJob::result, this, &InvalidFilenameDialog::onPropfindPermissionSuccess); + propfindJob->start(); +} + +void InvalidFilenameDialog::onPropfindPermissionSuccess(const QVariantMap &values) +{ + if (!values.contains("permissions")) { + return; + } + const auto remotePermissions = RemotePermissions::fromServerString(values["permissions"].toString()); + if (!remotePermissions.hasPermission(remotePermissions.CanRename) + || !remotePermissions.hasPermission(remotePermissions.CanMove)) { + _ui->errorLabel->setText( + tr("You don't have the permission to rename this file. Please ask the author of the file to rename it.")); + _ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + _ui->filenameLineEdit->setEnabled(false); + } +} + +void InvalidFilenameDialog::accept() +{ + _newFilename = _relativeFilePath + _ui->filenameLineEdit->text().trimmed(); + const auto propfindJob = new PropfindJob(_account, QDir::cleanPath(_folder->remotePath() + _newFilename)); + connect(propfindJob, &PropfindJob::result, this, &InvalidFilenameDialog::onRemoteFileAlreadyExists); + connect(propfindJob, &PropfindJob::finishedWithError, this, &InvalidFilenameDialog::onRemoteFileDoesNotExist); + propfindJob->start(); +} + +void InvalidFilenameDialog::onFilenameLineEditTextChanged(const QString &text) +{ + const auto isNewFileNameDifferent = text != _originalFileName; + const auto illegalContainedCharacters = getIllegalCharsFromString(text); + const auto containsIllegalChars = !illegalContainedCharacters.empty() || text.endsWith(QLatin1Char('.')); + const auto isTextValid = isNewFileNameDifferent && !containsIllegalChars; + + if (isTextValid) { + _ui->errorLabel->setText(""); + } else { + _ui->errorLabel->setText(tr("Filename contains illegal characters: %1") + .arg(illegalCharacterListToString(illegalContainedCharacters))); + } + + _ui->buttonBox->button(QDialogButtonBox::Ok) + ->setEnabled(isTextValid); +} + +void InvalidFilenameDialog::onMoveJobFinished() +{ + const auto job = qobject_cast(sender()); + const auto error = job->reply()->error(); + + if (error != QNetworkReply::NoError) { + _ui->errorLabel->setText(tr("Could not rename file. Please make sure you are connected to the server.")); + return; + } + + QDialog::accept(); +} + +void InvalidFilenameDialog::onRemoteFileAlreadyExists(const QVariantMap &values) +{ + Q_UNUSED(values); + + _ui->errorLabel->setText(tr("Cannot rename file because a file with the same name does already exist on the server. Please pick another name.")); + _ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); +} + +void InvalidFilenameDialog::onRemoteFileDoesNotExist(QNetworkReply *reply) +{ + Q_UNUSED(reply); + + // File does not exist. We can rename it. + const auto remoteSource = QDir::cleanPath(_folder->remotePath() + _originalFileName); + const auto remoteDestionation = QDir::cleanPath(_account->davUrl().path() + _folder->remotePath() + _newFilename); + const auto moveJob = new MoveJob(_account, remoteSource, remoteDestionation, this); + connect(moveJob, &MoveJob::finishedSignal, this, &InvalidFilenameDialog::onMoveJobFinished); + moveJob->start(); +} +} diff --git a/src/gui/invalidfilenamedialog.h b/src/gui/invalidfilenamedialog.h new file mode 100644 index 000000000000..2b6ff0dedd33 --- /dev/null +++ b/src/gui/invalidfilenamedialog.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +#pragma once + +#include +#include + +#include + +#include + +namespace OCC { + +class Folder; + +namespace Ui { + class InvalidFilenameDialog; +} + + +class InvalidFilenameDialog : public QDialog +{ + Q_OBJECT + +public: + explicit InvalidFilenameDialog(AccountPtr account, Folder *folder, QString filePath, QWidget *parent = nullptr); + + ~InvalidFilenameDialog() override; + + void accept() override; + +private: + std::unique_ptr _ui; + + AccountPtr _account; + Folder *_folder; + QString _filePath; + QString _relativeFilePath; + QString _originalFileName; + QString _newFilename; + + void onFilenameLineEditTextChanged(const QString &text); + void onMoveJobFinished(); + void onRemoteFileAlreadyExists(const QVariantMap &values); + void onRemoteFileDoesNotExist(QNetworkReply *reply); + void checkIfAllowedToRename(); + void onPropfindPermissionSuccess(const QVariantMap &values); +}; +} diff --git a/src/gui/invalidfilenamedialog.ui b/src/gui/invalidfilenamedialog.ui new file mode 100644 index 000000000000..68008709deb1 --- /dev/null +++ b/src/gui/invalidfilenamedialog.ui @@ -0,0 +1,121 @@ + + + OCC::InvalidFilenameDialog + + + + 0 + 0 + 411 + 192 + + + + Invalid filename + + + + QLayout::SetDefaultConstraint + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + false + + + + + + + Error + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + false + + + + + + + Please enter a new name for the file: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + false + + + + + + + New filename + + + + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/src/gui/legalnotice.h b/src/gui/legalnotice.h index ee0cb9d4ea6f..031ca674084d 100644 --- a/src/gui/legalnotice.h +++ b/src/gui/legalnotice.h @@ -35,7 +35,7 @@ class LegalNotice : public QDialog public: explicit LegalNotice(QDialog *parent = nullptr); - ~LegalNotice(); + ~LegalNotice() override; protected: void changeEvent(QEvent *) override; diff --git a/src/gui/logbrowser.h b/src/gui/logbrowser.h index c49e26b73604..b1bb547ad893 100644 --- a/src/gui/logbrowser.h +++ b/src/gui/logbrowser.h @@ -38,7 +38,7 @@ class LogBrowser : public QDialog Q_OBJECT public: explicit LogBrowser(QWidget *parent = nullptr); - ~LogBrowser(); + ~LogBrowser() override; protected: void closeEvent(QCloseEvent *) override; diff --git a/src/gui/main.cpp b/src/gui/main.cpp index a7a47e16e71e..bf78b4c076db 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -16,6 +16,7 @@ #include #include +#include #ifdef Q_OS_UNIX #include @@ -23,9 +24,14 @@ #endif #include "application.h" +#include "fileactivitylistmodel.h" #include "theme.h" #include "common/utility.h" #include "cocoainitializer.h" +#include "userstatusselectormodel.h" +#include "emojimodel.h" +#include "tray/syncstatussummary.h" +#include "tray/unifiedsearchresultslistmodel.h" #if defined(BUILD_UPDATER) #include "updater/updater.h" @@ -36,6 +42,7 @@ #include #include #include +#include using namespace OCC; @@ -51,9 +58,27 @@ void warnSystray() int main(int argc, char **argv) { +#ifdef Q_OS_WIN + SetDllDirectory(L""); +#endif Q_INIT_RESOURCE(resources); Q_INIT_RESOURCE(theme); + qmlRegisterType("com.nextcloud.desktopclient", 1, 0, "SyncStatusSummary"); + qmlRegisterType("com.nextcloud.desktopclient", 1, 0, "EmojiModel"); + qmlRegisterType("com.nextcloud.desktopclient", 1, 0, "UserStatusSelectorModel"); + qmlRegisterType("com.nextcloud.desktopclient", 1, 0, "ActivityListModel"); + qmlRegisterType("com.nextcloud.desktopclient", 1, 0, "FileActivityListModel"); + qmlRegisterUncreatableType( + "com.nextcloud.desktopclient", 1, 0, "UnifiedSearchResultsListModel", "UnifiedSearchResultsListModel"); + qRegisterMetaType("UnifiedSearchResultsListModel*"); + + qmlRegisterUncreatableType("com.nextcloud.desktopclient", 1, 0, "UserStatus", "Access to Status enum"); + + qRegisterMetaTypeStreamOperators(); + qRegisterMetaType("UserStatus"); + + // Work around a bug in KDE's qqc2-desktop-style which breaks // buttons with icons not based on a name, by forcing a style name // the platformtheme plugin won't try to force qqc2-desktops-style @@ -101,6 +126,10 @@ int main(int argc, char **argv) } #endif + auto surfaceFormat = QSurfaceFormat::defaultFormat(); + surfaceFormat.setOption(QSurfaceFormat::ResetNotification); + QSurfaceFormat::setDefaultFormat(surfaceFormat); + // check a environment variable for core dumps #ifdef Q_OS_UNIX if (!qEnvironmentVariableIsEmpty("OWNCLOUD_CORE_DUMP")) { diff --git a/src/gui/networksettings.h b/src/gui/networksettings.h index 4fd6db5720a4..97b892731b1b 100644 --- a/src/gui/networksettings.h +++ b/src/gui/networksettings.h @@ -34,7 +34,7 @@ class NetworkSettings : public QWidget public: explicit NetworkSettings(QWidget *parent = nullptr); - ~NetworkSettings(); + ~NetworkSettings() override; QSize sizeHint() const override; private slots: diff --git a/src/gui/notificationconfirmjob.cpp b/src/gui/notificationconfirmjob.cpp index d9a7a4c344a0..09e147da3a7d 100644 --- a/src/gui/notificationconfirmjob.cpp +++ b/src/gui/notificationconfirmjob.cpp @@ -56,10 +56,11 @@ bool NotificationConfirmJob::finished() const QString replyStr = reply()->readAll(); if (replyStr.contains("")) { - QRegExp rex("(\\d+)"); - if (replyStr.contains(rex)) { + const QRegularExpression rex("(\\d+)"); + const auto rexMatch = rex.match(replyStr); + if (rexMatch.hasMatch()) { // this is a error message coming back from ocs. - replyCode = rex.cap(1).toInt(); + replyCode = rexMatch.captured(1).toInt(); } } emit jobFinished(replyStr, replyCode); diff --git a/src/gui/ocssharejob.cpp b/src/gui/ocssharejob.cpp index fcbfafe77ae0..900074dbcc3c 100644 --- a/src/gui/ocssharejob.cpp +++ b/src/gui/ocssharejob.cpp @@ -118,6 +118,17 @@ void OcsShareJob::setPermissions(const QString &shareId, start(); } +void OcsShareJob::setLabel(const QString &shareId, const QString &label) +{ + appendPath(shareId); + setVerb("PUT"); + + addParam(QStringLiteral("label"), label); + _value = label; + + start(); +} + void OcsShareJob::createLinkShare(const QString &path, const QString &name, const QString &password) diff --git a/src/gui/ocssharejob.h b/src/gui/ocssharejob.h index 074fa0762186..064706b5c6db 100644 --- a/src/gui/ocssharejob.h +++ b/src/gui/ocssharejob.h @@ -96,6 +96,11 @@ class OcsShareJob : public OcsJob */ void setPermissions(const QString &shareId, const Share::Permissions permissions); + + /** + * Set share link label + */ + void setLabel(const QString &shareId, const QString &label); /** * Create a new link share diff --git a/src/gui/openfilemanager.cpp b/src/gui/openfilemanager.cpp index 3754bbd9feab..4a4161434fed 100644 --- a/src/gui/openfilemanager.cpp +++ b/src/gui/openfilemanager.cpp @@ -103,7 +103,7 @@ void showInFileManager(const QString &localPath) return; #endif - QString explorer = "explorer.exe "; // FIXME: we trust it's in PATH + const QString explorer = "explorer.exe "; // FIXME: we trust it's in PATH QFileInfo fi(localPath); // canonicalFilePath returns empty if the file does not exist @@ -123,7 +123,7 @@ void showInFileManager(const QString &localPath) // only around the path. Use setNativeArguments to bypass this logic. p.setNativeArguments(nativeArgs); #endif - p.start(explorer); + p.start(explorer, QStringList {}); p.waitForFinished(5000); } } else if (Utility::isMac()) { diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 99fe2a998e97..9c86e9cf9eac 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -640,19 +640,7 @@ void ownCloudGui::slotShowShareDialog(const QString &sharePath, const QString &l } } - // As a first approximation, set the set of permissions that can be granted - // either to everything (resharing allowed) or nothing (no resharing). - // - // The correct value will be found with a propfind from ShareDialog. - // (we want to show the dialog directly, not wait for the propfind first) - SharePermissions maxSharingPermissions = - SharePermissionRead - | SharePermissionUpdate | SharePermissionCreate | SharePermissionDelete - | SharePermissionShare; - if (!resharingAllowed) { - maxSharingPermissions = {}; - } - + auto maxSharingPermissions = resharingAllowed? SharePermissions(accountState->account()->capabilities().shareDefaultPermissions()) : SharePermissions({}); ShareDialog *w = nullptr; if (_shareDialogs.contains(localPath) && _shareDialogs[localPath]) { diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp index ce0dd773fb4e..86c4524a8603 100644 --- a/src/gui/owncloudsetupwizard.cpp +++ b/src/gui/owncloudsetupwizard.cpp @@ -323,12 +323,29 @@ void OwncloudSetupWizard::slotConnectToOCUrl(const QString &url) qCInfo(lcWizard) << "Connect to url: " << url; AbstractCredentials *creds = _ocWizard->getCredentials(); _ocWizard->account()->setCredentials(creds); - _ocWizard->setField(QLatin1String("OCUrl"), url); - _ocWizard->appendToConfigurationLog(tr("Trying to connect to %1 at %2 …") - .arg(Theme::instance()->appNameGUI()) - .arg(url)); - testOwnCloudConnect(); + const auto fetchUserNameJob = new JsonApiJob(_ocWizard->account()->sharedFromThis(), QStringLiteral("/ocs/v1.php/cloud/user")); + connect(fetchUserNameJob, &JsonApiJob::jsonReceived, this, [this, url](const QJsonDocument &json, int statusCode) { + if (statusCode != 100) { + qCWarning(lcWizard) << "Could not fetch username."; + } + + sender()->deleteLater(); + + const auto objData = json.object().value("ocs").toObject().value("data").toObject(); + const auto userId = objData.value("id").toString(""); + const auto displayName = objData.value("display-name").toString(""); + _ocWizard->account()->setDavUser(userId); + _ocWizard->account()->setDavDisplayName(displayName); + + _ocWizard->setField(QLatin1String("OCUrl"), url); + _ocWizard->appendToConfigurationLog(tr("Trying to connect to %1 at %2 …") + .arg(Theme::instance()->appNameGUI()) + .arg(url)); + + testOwnCloudConnect(); + }); + fetchUserNameJob->start(); } void OwncloudSetupWizard::testOwnCloudConnect() @@ -536,26 +553,28 @@ void OwncloudSetupWizard::createRemoteFolder() _ocWizard->appendToConfigurationLog(tr("creating folder on Nextcloud: %1").arg(_remoteFolder)); auto *job = new MkColJob(_ocWizard->account(), _remoteFolder, this); - connect(job, SIGNAL(finished(QNetworkReply::NetworkError)), SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError))); + connect(job, &MkColJob::finishedWithError, this, &OwncloudSetupWizard::slotCreateRemoteFolderFinished); + connect(job, &MkColJob::finishedWithoutError, this, [this] { + _ocWizard->appendToConfigurationLog(tr("Remote folder %1 created successfully.").arg(_remoteFolder)); + finalizeSetup(true); + }); job->start(); } -void OwncloudSetupWizard::slotCreateRemoteFolderFinished(QNetworkReply::NetworkError error) +void OwncloudSetupWizard::slotCreateRemoteFolderFinished(QNetworkReply *reply) { + auto error = reply->error(); qCDebug(lcWizard) << "** webdav mkdir request finished " << error; // disconnect(ownCloudInfo::instance(), SIGNAL(webdavColCreated(QNetworkReply::NetworkError)), // this, SLOT(slotCreateRemoteFolderFinished(QNetworkReply::NetworkError))); bool success = true; - - if (error == QNetworkReply::NoError) { - _ocWizard->appendToConfigurationLog(tr("Remote folder %1 created successfully.").arg(_remoteFolder)); - } else if (error == 202) { + if (error == 202) { _ocWizard->appendToConfigurationLog(tr("The remote folder %1 already exists. Connecting it for syncing.").arg(_remoteFolder)); } else if (error > 202 && error < 300) { - _ocWizard->displayError(tr("The folder creation resulted in HTTP error code %1").arg((int)error), false); + _ocWizard->displayError(tr("The folder creation resulted in HTTP error code %1").arg(static_cast(error)), false); - _ocWizard->appendToConfigurationLog(tr("The folder creation resulted in HTTP error code %1").arg((int)error)); + _ocWizard->appendToConfigurationLog(tr("The folder creation resulted in HTTP error code %1").arg(static_cast(error))); } else if (error == QNetworkReply::OperationCanceledError) { _ocWizard->displayError(tr("The remote folder creation failed because the provided credentials " "are wrong!" @@ -577,9 +596,6 @@ void OwncloudSetupWizard::slotCreateRemoteFolderFinished(QNetworkReply::NetworkE void OwncloudSetupWizard::finalizeSetup(bool success) { - // enable/disable the finish button. - _ocWizard->enableFinishOnResultWidget(success); - const QString localFolder = _ocWizard->property("localFolder").toString(); if (success) { if (!(localFolder.isEmpty() || _remoteFolder.isEmpty())) { @@ -668,6 +684,7 @@ void OwncloudSetupWizard::slotAssistantFinished(int result) } // notify others. + _ocWizard->done(QWizard::Accepted); emit ownCloudWizardDone(result); } diff --git a/src/gui/owncloudsetupwizard.h b/src/gui/owncloudsetupwizard.h index 4762de1cd880..d7288ee6c8b7 100644 --- a/src/gui/owncloudsetupwizard.h +++ b/src/gui/owncloudsetupwizard.h @@ -65,13 +65,13 @@ private slots: void slotCreateLocalAndRemoteFolders(const QString &, const QString &); void slotRemoteFolderExists(QNetworkReply *); - void slotCreateRemoteFolderFinished(QNetworkReply::NetworkError); + void slotCreateRemoteFolderFinished(QNetworkReply *reply); void slotAssistantFinished(int); void slotSkipFolderConfiguration(); private: explicit OwncloudSetupWizard(QObject *parent = nullptr); - ~OwncloudSetupWizard(); + ~OwncloudSetupWizard() override; void startWizard(); void testOwnCloudConnect(); void createRemoteFolder(); diff --git a/src/gui/profilepagewidget.cpp b/src/gui/profilepagewidget.cpp new file mode 100644 index 000000000000..5bed47d8a5ad --- /dev/null +++ b/src/gui/profilepagewidget.cpp @@ -0,0 +1,46 @@ +#include "profilepagewidget.h" +#include "guiutility.h" +#include "ocsprofileconnector.h" + +namespace OCC { + +ProfilePageMenu::ProfilePageMenu(AccountPtr account, const QString &shareWithUserId, QWidget *parent) + : QWidget(parent) + , _profileConnector(account) +{ + connect(&_profileConnector, &OcsProfileConnector::hovercardFetched, this, &ProfilePageMenu::onHovercardFetched); + connect(&_profileConnector, &OcsProfileConnector::iconLoaded, this, &ProfilePageMenu::onIconLoaded); + _profileConnector.fetchHovercard(shareWithUserId); +} + +ProfilePageMenu::~ProfilePageMenu() = default; + +void ProfilePageMenu::exec(const QPoint &globalPosition) +{ + _menu.exec(globalPosition); +} + +void ProfilePageMenu::onHovercardFetched() +{ + _menu.clear(); + + const auto hovercardActions = _profileConnector.hovercard()._actions; + for (const auto &hovercardAction : hovercardActions) { + const auto action = _menu.addAction(hovercardAction._icon, hovercardAction._title); + const auto link = hovercardAction._link; + connect(action, &QAction::triggered, action, [link](bool) { Utility::openBrowser(link); }); + } +} + +void ProfilePageMenu::onIconLoaded(const std::size_t &hovercardActionIndex) +{ + const auto hovercardActions = _profileConnector.hovercard()._actions; + const auto menuActions = _menu.actions(); + if (hovercardActionIndex >= hovercardActions.size() + || hovercardActionIndex >= static_cast(menuActions.size())) { + return; + } + const auto menuAction = menuActions[static_cast(hovercardActionIndex)]; + menuAction->setIcon(hovercardActions[hovercardActionIndex]._icon); +} +} diff --git a/src/gui/profilepagewidget.h b/src/gui/profilepagewidget.h new file mode 100644 index 000000000000..637dbd460e15 --- /dev/null +++ b/src/gui/profilepagewidget.h @@ -0,0 +1,30 @@ +#pragma once + +#include "ocsprofileconnector.h" + +#include +#include +#include +#include + +#include + +namespace OCC { + +class ProfilePageMenu : public QWidget +{ + Q_OBJECT +public: + explicit ProfilePageMenu(AccountPtr account, const QString &shareWithUserId, QWidget *parent = nullptr); + ~ProfilePageMenu() override; + + void exec(const QPoint &globalPosition); + +private: + void onHovercardFetched(); + void onIconLoaded(const std::size_t &hovercardActionIndex); + + OcsProfileConnector _profileConnector; + QMenu _menu; +}; +} diff --git a/src/gui/proxyauthdialog.h b/src/gui/proxyauthdialog.h index 9ce75f691216..63a262b8a4c1 100644 --- a/src/gui/proxyauthdialog.h +++ b/src/gui/proxyauthdialog.h @@ -34,7 +34,7 @@ class ProxyAuthDialog : public QDialog public: explicit ProxyAuthDialog(QWidget *parent = nullptr); - ~ProxyAuthDialog(); + ~ProxyAuthDialog() override; void setProxyAddress(const QString &address); diff --git a/src/gui/proxyauthhandler.h b/src/gui/proxyauthhandler.h index e1a29141115a..06d28a62affe 100644 --- a/src/gui/proxyauthhandler.h +++ b/src/gui/proxyauthhandler.h @@ -49,7 +49,7 @@ class ProxyAuthHandler : public QObject public: static ProxyAuthHandler *instance(); - virtual ~ProxyAuthHandler(); + ~ProxyAuthHandler() override; public slots: /// Intended for QNetworkAccessManager::proxyAuthenticationRequired() diff --git a/src/gui/settingsdialog.h b/src/gui/settingsdialog.h index f46208d533a7..0d84a1cb19d3 100644 --- a/src/gui/settingsdialog.h +++ b/src/gui/settingsdialog.h @@ -49,7 +49,7 @@ class SettingsDialog : public QDialog public: explicit SettingsDialog(ownCloudGui *gui, QWidget *parent = nullptr); - ~SettingsDialog(); + ~SettingsDialog() override; QWidget* currentPage(); diff --git a/src/gui/sharedialog.cpp b/src/gui/sharedialog.cpp index f8c4b68d88ef..6f5e2837d2eb 100644 --- a/src/gui/sharedialog.cpp +++ b/src/gui/sharedialog.cpp @@ -96,8 +96,8 @@ ShareDialog::ShareDialog(QPointer accountState, QString ocDir(_sharePath); ocDir.truncate(ocDir.length() - fileName.length()); - ocDir.replace(QRegExp("^/*"), ""); - ocDir.replace(QRegExp("/*$"), ""); + ocDir.replace(QRegularExpression("^/*"), ""); + ocDir.replace(QRegularExpression("/*$"), ""); // Laying this out is complex because sharePath // may be in use or not. diff --git a/src/gui/sharedialog.h b/src/gui/sharedialog.h index 96a5f07e0d43..6431cb13194a 100644 --- a/src/gui/sharedialog.h +++ b/src/gui/sharedialog.h @@ -51,7 +51,7 @@ class ShareDialog : public QDialog const QByteArray &numericFileId, ShareDialogStartPage startPage, QWidget *parent = nullptr); - ~ShareDialog(); + ~ShareDialog() override; private slots: void done(int r) override; diff --git a/src/gui/sharelinkwidget.cpp b/src/gui/sharelinkwidget.cpp index 7a50639bf462..f0ea3c615799 100644 --- a/src/gui/sharelinkwidget.cpp +++ b/src/gui/sharelinkwidget.cpp @@ -20,6 +20,7 @@ #include "guiutility.h" #include "sharemanager.h" #include "theme.h" +#include "elidedlabel.h" #include "QProgressIndicator.h" #include @@ -78,11 +79,10 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account, connect(_ui->confirmPassword, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreatePassword); connect(_ui->confirmNote, &QAbstractButton::clicked, this, &ShareLinkWidget::slotCreateNote); connect(_ui->confirmExpirationDate, &QAbstractButton::clicked, this, &ShareLinkWidget::slotSetExpireDate); - connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareLinkWidget::slotSetExpireDate); _ui->errorLabel->hide(); - bool sharingPossible = true; + auto sharingPossible = true; if (!_account->capabilities().sharePublicLink()) { qCWarning(lcShareLink) << "Link shares have been disabled"; sharingPossible = false; @@ -103,7 +103,6 @@ ShareLinkWidget::ShareLinkWidget(AccountPtr account, togglePasswordOptions(false); toggleExpireDateOptions(false); toggleNoteOptions(false); - _ui->calendar->setMinimumDate(QDate::currentDate().addDays(1)); _ui->noteProgressIndicator->setVisible(false); _ui->passwordProgressIndicator->setVisible(false); @@ -122,7 +121,7 @@ ShareLinkWidget::~ShareLinkWidget() delete _ui; } -void ShareLinkWidget::slotToggleShareLinkAnimation(bool start) +void ShareLinkWidget::slotToggleShareLinkAnimation(const bool start) { _ui->sharelinkProgressIndicator->setVisible(start); if (start) { @@ -134,17 +133,19 @@ void ShareLinkWidget::slotToggleShareLinkAnimation(bool start) } } -void ShareLinkWidget::slotToggleButtonAnimation(QToolButton *button, QProgressIndicator *progressIndicator, bool optionEnabled, bool start) +void ShareLinkWidget::toggleButtonAnimation(QToolButton *button, QProgressIndicator *progressIndicator, const QAction *checkedAction) const { - button->setVisible(optionEnabled && !start); - progressIndicator->setVisible(start); - if (start) { - if (!progressIndicator->isAnimated()) { - progressIndicator->startAnimation(); - } + auto startAnimation = false; + const auto actionIsChecked = checkedAction->isChecked(); + if (!progressIndicator->isAnimated() && actionIsChecked) { + progressIndicator->startAnimation(); + startAnimation = true; } else { progressIndicator->stopAnimation(); } + + button->setVisible(!startAnimation && actionIsChecked); + progressIndicator->setVisible(startAnimation && actionIsChecked); } void ShareLinkWidget::setLinkShare(QSharedPointer linkShare) @@ -164,15 +165,15 @@ void ShareLinkWidget::focusPasswordLineEdit() void ShareLinkWidget::setupUiOptions() { - connect(_linkShare.data(), &LinkShare::expireDateSet, this, &ShareLinkWidget::slotExpireDateSet); connect(_linkShare.data(), &LinkShare::noteSet, this, &ShareLinkWidget::slotNoteSet); connect(_linkShare.data(), &LinkShare::passwordSet, this, &ShareLinkWidget::slotPasswordSet); connect(_linkShare.data(), &LinkShare::passwordSetError, this, &ShareLinkWidget::slotPasswordSetError); + connect(_linkShare.data(), &LinkShare::labelSet, this, &ShareLinkWidget::slotLabelSet); // Prepare permissions check and create group action const QDate expireDate = _linkShare.data()->getExpireDate().isValid() ? _linkShare.data()->getExpireDate() : QDate(); const SharePermissions perm = _linkShare.data()->getPermissions(); - bool checked = false; + auto checked = false; auto *permissionsGroup = new QActionGroup(this); // Prepare sharing menu @@ -189,7 +190,7 @@ void ShareLinkWidget::setupUiOptions() } else { checked = (perm == SharePermissionRead); - _readOnlyLinkAction = permissionsGroup->addAction(tr("Read only")); + _readOnlyLinkAction = permissionsGroup->addAction(tr("View only")); _readOnlyLinkAction->setCheckable(true); _readOnlyLinkAction->setChecked(checked); @@ -204,6 +205,41 @@ void ShareLinkWidget::setupUiOptions() _allowUploadLinkAction->setCheckable(true); _allowUploadLinkAction->setChecked(checked); } + + _shareLinkElidedLabel = new OCC::ElidedLabel(this); + _shareLinkElidedLabel->setElideMode(Qt::ElideRight); + displayShareLinkLabel(); + _ui->horizontalLayout->insertWidget(2, _shareLinkElidedLabel); + + _shareLinkLayout = new QHBoxLayout(this); + + _shareLinkLabel = new QLabel(this); + _shareLinkLabel->setPixmap(QString(":/client/theme/black/edit.svg")); + _shareLinkLayout->addWidget(_shareLinkLabel); + + _shareLinkEdit = new QLineEdit(this); + connect(_shareLinkEdit, &QLineEdit::returnPressed, this, &ShareLinkWidget::slotCreateLabel); + _shareLinkEdit->setPlaceholderText(tr("Link name")); + _shareLinkEdit->setText(_linkShare.data()->getLabel()); + _shareLinkLayout->addWidget(_shareLinkEdit); + + _shareLinkButton = new QToolButton(this); + connect(_shareLinkButton, &QToolButton::clicked, this, &ShareLinkWidget::slotCreateLabel); + _shareLinkButton->setIcon(QIcon(":/client/theme/confirm.svg")); + _shareLinkButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + _shareLinkLayout->addWidget(_shareLinkButton); + + _shareLinkProgressIndicator = new QProgressIndicator(this); + _shareLinkProgressIndicator->setVisible(false); + _shareLinkLayout->addWidget(_shareLinkProgressIndicator); + + _shareLinkDefaultWidget = new QWidget(this); + _shareLinkDefaultWidget->setLayout(_shareLinkLayout); + + _shareLinkWidgetAction = new QWidgetAction(this); + _shareLinkWidgetAction->setDefaultWidget(_shareLinkDefaultWidget); + _shareLinkWidgetAction->setCheckable(true); + _linkContextMenu->addAction(_shareLinkWidgetAction); // Adds permissions actions (radio button style) if (_isFile) { @@ -221,7 +257,7 @@ void ShareLinkWidget::setupUiOptions() if (_linkShare->getNote().isSimpleText() && !_linkShare->getNote().isEmpty()) { _ui->textEdit_note->setText(_linkShare->getNote()); _noteLinkAction->setChecked(true); - showNoteOptions(true); + toggleNoteOptions(); } // Adds action to display password widget (check box) @@ -231,7 +267,7 @@ void ShareLinkWidget::setupUiOptions() if (_linkShare.data()->isPasswordSet()) { _passwordProtectLinkAction->setChecked(true); _ui->lineEdit_password->setPlaceholderText(QString::fromUtf8(passwordIsSetPlaceholder)); - showPasswordOptions(true); + togglePasswordOptions(); } // If password is enforced then don't allow users to disable it @@ -249,8 +285,11 @@ void ShareLinkWidget::setupUiOptions() if (!expireDate.isNull()) { _ui->calendar->setDate(expireDate); _expirationDateLinkAction->setChecked(true); - showExpireDateOptions(true); + toggleExpireDateOptions(); } + connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareLinkWidget::slotSetExpireDate); + connect(_linkShare.data(), &LinkShare::expireDateSet, this, &ShareLinkWidget::slotExpireDateSet); + // If expiredate is enforced do not allow disable and set max days if (_account->capabilities().sharePublicLinkEnforceExpireDate()) { @@ -263,7 +302,7 @@ void ShareLinkWidget::setupUiOptions() // Adds action to unshare widget (check box) _unshareLinkAction = _linkContextMenu->addAction(QIcon(":/client/theme/delete.svg"), - tr("Delete share link")); + tr("Delete link")); _linkContextMenu->addSeparator(); @@ -285,32 +324,27 @@ void ShareLinkWidget::setupUiOptions() // show sharing options _ui->shareLinkToolButton->show(); - //TO DO - //startAnimation(0, height()); - customizeStyle(); } -void ShareLinkWidget::setNote(const QString ¬e) +void ShareLinkWidget::slotCreateNote() { - if (_linkShare) { - slotToggleButtonAnimation(_ui->confirmNote, _ui->noteProgressIndicator, _noteLinkAction->isChecked(), true); - _ui->errorLabel->hide(); - _linkShare->setNote(note); + const auto note = _ui->textEdit_note->toPlainText(); + if (!_linkShare || _linkShare->getNote() == note || note.isEmpty()) { + return; } -} - -void ShareLinkWidget::slotCreateNote() -{ - setNote(_ui->textEdit_note->toPlainText()); + + toggleButtonAnimation(_ui->confirmNote, _ui->noteProgressIndicator, _noteLinkAction); + _ui->errorLabel->hide(); + _linkShare->setNote(note); } void ShareLinkWidget::slotNoteSet() { - slotToggleButtonAnimation(_ui->confirmNote, _ui->noteProgressIndicator, _noteLinkAction->isChecked(), false); + toggleButtonAnimation(_ui->confirmNote, _ui->noteProgressIndicator, _noteLinkAction); } -void ShareLinkWidget::slotCopyLinkShare(bool clicked) +void ShareLinkWidget::slotCopyLinkShare(const bool clicked) const { Q_UNUSED(clicked); @@ -319,7 +353,7 @@ void ShareLinkWidget::slotCopyLinkShare(bool clicked) void ShareLinkWidget::slotExpireDateSet() { - slotToggleButtonAnimation(_ui->confirmExpirationDate, _ui->expirationDateProgressIndicator, _expirationDateLinkAction->isChecked(), false); + toggleButtonAnimation(_ui->confirmExpirationDate, _ui->expirationDateProgressIndicator, _expirationDateLinkAction); } void ShareLinkWidget::slotSetExpireDate() @@ -328,7 +362,7 @@ void ShareLinkWidget::slotSetExpireDate() return; } - slotToggleButtonAnimation(_ui->confirmExpirationDate, _ui->expirationDateProgressIndicator, _expirationDateLinkAction->isChecked(), true); + toggleButtonAnimation(_ui->confirmExpirationDate, _ui->expirationDateProgressIndicator, _expirationDateLinkAction); _ui->errorLabel->hide(); _linkShare->setExpireDate(_ui->calendar->date()); } @@ -339,12 +373,12 @@ void ShareLinkWidget::slotCreatePassword() return; } - slotToggleButtonAnimation(_ui->confirmPassword, _ui->passwordProgressIndicator, _passwordProtectLinkAction->isChecked(), true); + toggleButtonAnimation(_ui->confirmPassword, _ui->passwordProgressIndicator, _passwordProtectLinkAction); _ui->errorLabel->hide(); emit createPassword(_ui->lineEdit_password->text()); } -void ShareLinkWidget::slotCreateShareLink(bool clicked) +void ShareLinkWidget::slotCreateShareLink(const bool clicked) { Q_UNUSED(clicked); slotToggleShareLinkAnimation(true); @@ -353,27 +387,26 @@ void ShareLinkWidget::slotCreateShareLink(bool clicked) void ShareLinkWidget::slotPasswordSet() { - slotToggleButtonAnimation(_ui->confirmPassword, _ui->passwordProgressIndicator, _passwordProtectLinkAction->isChecked(), false); + toggleButtonAnimation(_ui->confirmPassword, _ui->passwordProgressIndicator, _passwordProtectLinkAction); + + _ui->lineEdit_password->setText({}); - _ui->lineEdit_password->setText(QString()); if (_linkShare->isPasswordSet()) { _ui->lineEdit_password->setEnabled(true); _ui->lineEdit_password->setPlaceholderText(QString::fromUtf8(passwordIsSetPlaceholder)); } else { - _ui->lineEdit_password->setPlaceholderText(QString()); + _ui->lineEdit_password->setPlaceholderText({}); } - setupUiOptions(); - emit createPasswordProcessed(); } -void ShareLinkWidget::slotPasswordSetError(int code, const QString &message) +void ShareLinkWidget::slotPasswordSetError(const int code, const QString &message) { - slotToggleButtonAnimation(_ui->confirmPassword, _ui->passwordProgressIndicator, _passwordProtectLinkAction->isChecked(), false); + toggleButtonAnimation(_ui->confirmPassword, _ui->passwordProgressIndicator, _passwordProtectLinkAction); slotServerError(code, message); - showPasswordOptions(true); + togglePasswordOptions(); _ui->lineEdit_password->setFocus(); emit createPasswordProcessed(); } @@ -398,9 +431,6 @@ void ShareLinkWidget::slotDeleteShareFetched() { slotToggleShareLinkAnimation(false); - // TODO - //startAnimation(height(), 0); - _linkShare.clear(); togglePasswordOptions(false); toggleNoteOptions(false); @@ -408,31 +438,40 @@ void ShareLinkWidget::slotDeleteShareFetched() emit deleteLinkShare(); } -void ShareLinkWidget::showNoteOptions(bool show) +void ShareLinkWidget::toggleNoteOptions(const bool enable) { - _ui->noteLabel->setVisible(show); - _ui->textEdit_note->setVisible(show); - _ui->confirmNote->setVisible(show); + _ui->noteLabel->setVisible(enable); + _ui->textEdit_note->setVisible(enable); + _ui->confirmNote->setVisible(enable); + _ui->textEdit_note->setText(enable && _linkShare ? _linkShare->getNote() : QString()); + + if (!enable && _linkShare && !_linkShare->getNote().isEmpty()) { + _linkShare->setNote({}); + } } - -void ShareLinkWidget::toggleNoteOptions(bool enable) +void ShareLinkWidget::slotAnimationFinished() { - showNoteOptions(enable); + emit resizeRequested(); + deleteLater(); +} - if (enable) { - _ui->textEdit_note->setFocus(); - } else { - // 'deletes' note - if (_linkShare) - _linkShare->setNote(QString()); +void ShareLinkWidget::slotCreateLabel() +{ + const auto labelText = _shareLinkEdit->text(); + if (!_linkShare || _linkShare->getLabel() == labelText || labelText.isEmpty()) { + return; } + _shareLinkWidgetAction->setChecked(true); + toggleButtonAnimation(_shareLinkButton, _shareLinkProgressIndicator, _shareLinkWidgetAction); + _ui->errorLabel->hide(); + _linkShare->setLabel(_shareLinkEdit->text()); } -void ShareLinkWidget::slotAnimationFinished() +void ShareLinkWidget::slotLabelSet() { - emit resizeRequested(); - deleteLater(); + toggleButtonAnimation(_shareLinkButton, _shareLinkProgressIndicator, _shareLinkWidgetAction); + displayShareLinkLabel(); } void ShareLinkWidget::slotDeleteAnimationFinished() @@ -447,7 +486,6 @@ void ShareLinkWidget::slotCreateShareRequiresPassword(const QString &message) { slotToggleShareLinkAnimation(message.isEmpty()); - showPasswordOptions(true); if (!message.isEmpty()) { _ui->errorLabel->setText(message); _ui->errorLabel->show(); @@ -455,49 +493,36 @@ void ShareLinkWidget::slotCreateShareRequiresPassword(const QString &message) _passwordRequired = true; - togglePasswordOptions(true); + togglePasswordOptions(); } -void ShareLinkWidget::showPasswordOptions(bool show) +void ShareLinkWidget::togglePasswordOptions(const bool enable) { - _ui->passwordLabel->setVisible(show); - _ui->lineEdit_password->setVisible(show); - _ui->confirmPassword->setVisible(show); -} - -void ShareLinkWidget::togglePasswordOptions(bool enable) -{ - showPasswordOptions(enable); - - if (enable) { - _ui->lineEdit_password->setFocus(); - } else { - // 'deletes' password - if (_linkShare) - _linkShare->setPassword(QString()); + _ui->passwordLabel->setVisible(enable); + _ui->lineEdit_password->setVisible(enable); + _ui->confirmPassword->setVisible(enable); + _ui->lineEdit_password->setFocus(); + + if (!enable && _linkShare && _linkShare->isPasswordSet()) { + _linkShare->setPassword({}); } } -void ShareLinkWidget::showExpireDateOptions(bool show) -{ - _ui->expirationLabel->setVisible(show); - _ui->calendar->setVisible(show); - _ui->confirmExpirationDate->setVisible(show); -} - -void ShareLinkWidget::toggleExpireDateOptions(bool enable) +void ShareLinkWidget::toggleExpireDateOptions(const bool enable) { - showExpireDateOptions(enable); - - if (enable) { - const QDate date = QDate::currentDate().addDays(1); - _ui->calendar->setDate(date); - _ui->calendar->setMinimumDate(date); - _ui->calendar->setFocus(); - } else { - // 'deletes' expire date - if (_linkShare) - _linkShare->setExpireDate(QDate()); + _ui->expirationLabel->setVisible(enable); + _ui->calendar->setVisible(enable); + _ui->confirmExpirationDate->setVisible(enable); + + const auto date = enable ? _linkShare->getExpireDate() : QDate::currentDate().addDays(1); + _ui->calendar->setDate(date); + _ui->calendar->setMinimumDate(QDate::currentDate().addDays(1)); + _ui->calendar->setMaximumDate( + QDate::currentDate().addDays(_account->capabilities().sharePublicLinkExpireDateDays())); + _ui->calendar->setFocus(); + + if (!enable && _linkShare && _linkShare->getExpireDate().isValid()) { + _linkShare->setExpireDate({}); } } @@ -542,7 +567,7 @@ void ShareLinkWidget::slotContextMenuButtonClicked() void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action) { - bool state = action->isChecked(); + const auto state = action->isChecked(); SharePermissions perm = SharePermissionRead; if (action == _addAnotherLinkAction) { @@ -577,7 +602,7 @@ void ShareLinkWidget::slotLinkContextMenuActionTriggered(QAction *action) } } -void ShareLinkWidget::slotServerError(int code, const QString &message) +void ShareLinkWidget::slotServerError(const int code, const QString &message) { slotToggleShareLinkAnimation(false); @@ -615,4 +640,12 @@ void ShareLinkWidget::customizeStyle() _ui->passwordProgressIndicator->setColor(QGuiApplication::palette().color(QPalette::Text)); } +void ShareLinkWidget::displayShareLinkLabel() +{ + _shareLinkElidedLabel->clear(); + if (!_linkShare->getLabel().isEmpty()) { + _shareLinkElidedLabel->setText(QString("(%1)").arg(_linkShare->getLabel())); + } +} + } diff --git a/src/gui/sharelinkwidget.h b/src/gui/sharelinkwidget.h index a9087b6bc2d5..d9c3dec123cf 100644 --- a/src/gui/sharelinkwidget.h +++ b/src/gui/sharelinkwidget.h @@ -23,6 +23,10 @@ #include #include #include +#include +#include +#include +#include class QMenu; class QTableWidgetItem; @@ -37,6 +41,7 @@ class AbstractCredentials; class SyncResult; class LinkShare; class Share; +class ElidedLabel; /** * @brief The ShareDialog class @@ -52,7 +57,7 @@ class ShareLinkWidget : public QWidget const QString &localPath, SharePermissions maxSharingPermissions, QWidget *parent = nullptr); - ~ShareLinkWidget(); + ~ShareLinkWidget() override; void toggleButton(bool show); void setupUiOptions(); @@ -64,20 +69,20 @@ class ShareLinkWidget : public QWidget public slots: void slotDeleteShareFetched(); - void slotToggleShareLinkAnimation(bool start); - void slotToggleButtonAnimation(QToolButton *button, QProgressIndicator *progressIndicator, bool optionEnabled, bool start); - void slotServerError(int code, const QString &message); + void slotToggleShareLinkAnimation(const bool start); + void slotServerError(const int code, const QString &message); void slotCreateShareRequiresPassword(const QString &message); void slotStyleChanged(); private slots: - void slotCreateShareLink(bool clicked); + void slotCreateShareLink(const bool clicked); + void slotCopyLinkShare(const bool clicked) const; void slotCreatePassword(); void slotPasswordSet(); - void slotPasswordSetError(int code, const QString &message); + void slotPasswordSetError(const int code, const QString &message); - void slotCreateNote(); + void slotCreateNote(); void slotNoteSet(); void slotSetExpireDate(); @@ -88,6 +93,9 @@ private slots: void slotDeleteAnimationFinished(); void slotAnimationFinished(); + + void slotCreateLabel(); + void slotLabelSet(); signals: void createLinkShare(); @@ -99,18 +107,11 @@ private slots: private: void displayError(const QString &errMsg); - - void showPasswordOptions(bool show); - void togglePasswordOptions(bool enable); - - void showNoteOptions(bool show); - void toggleNoteOptions(bool enable); - void setNote(const QString ¬e); - - void showExpireDateOptions(bool show); - void toggleExpireDateOptions(bool enable); - - void slotCopyLinkShare(bool clicked); + + void togglePasswordOptions(const bool enable = true); + void toggleNoteOptions(const bool enable = true); + void toggleExpireDateOptions(const bool enable = true); + void toggleButtonAnimation(QToolButton *button, QProgressIndicator *progressIndicator, const QAction *checkedAction) const; /** Confirm with the user and then delete the share */ void confirmAndDeleteShare(); @@ -121,6 +122,8 @@ private slots: void startAnimation(const int start, const int end); void customizeStyle(); + + void displayShareLinkLabel(); Ui::ShareLinkWidget *_ui; AccountPtr _account; @@ -146,6 +149,14 @@ private slots: QAction *_unshareLinkAction; QAction *_addAnotherLinkAction; QAction *_noteLinkAction; + QHBoxLayout *_shareLinkLayout{}; + QLabel *_shareLinkLabel{}; + ElidedLabel *_shareLinkElidedLabel{}; + QLineEdit *_shareLinkEdit{}; + QToolButton *_shareLinkButton{}; + QProgressIndicator *_shareLinkProgressIndicator{}; + QWidget *_shareLinkDefaultWidget{}; + QWidgetAction *_shareLinkWidgetAction{}; }; } diff --git a/src/gui/sharemanager.cpp b/src/gui/sharemanager.cpp index 6f89eb5734c7..154bcbec3196 100644 --- a/src/gui/sharemanager.cpp +++ b/src/gui/sharemanager.cpp @@ -146,6 +146,12 @@ void Share::deleteShare() job->deleteShare(getId()); } +bool Share::isShareTypeUserGroupEmailRoomOrRemote(const ShareType type) +{ + return (type == Share::TypeUser || type == Share::TypeGroup || type == Share::TypeEmail || type == Share::TypeRoom + || type == Share::TypeRemote); +} + void Share::slotDeleted() { updateFolder(_account, _path); @@ -195,12 +201,16 @@ LinkShare::LinkShare(AccountPtr account, Permissions permissions, bool isPasswordSet, const QUrl &url, - const QDate &expireDate) + const QDate &expireDate, + const QString ¬e, + const QString &label) : Share(account, id, uidowner, ownerDisplayName, path, Share::TypeLink, isPasswordSet, permissions) , _name(name) , _token(token) + , _note(note) , _expireDate(expireDate) , _url(url) + , _label(label) { } @@ -224,20 +234,19 @@ QString LinkShare::getNote() const return _note; } +QString LinkShare::getLabel() const +{ + return _label; +} + void LinkShare::setName(const QString &name) { - auto *job = new OcsShareJob(_account); - connect(job, &OcsShareJob::shareJobFinished, this, &LinkShare::slotNameSet); - connect(job, &OcsJob::ocsError, this, &LinkShare::slotOcsError); - job->setName(getId(), name); + createShareJob(&LinkShare::slotNameSet)->setName(getId(), name); } void LinkShare::setNote(const QString ¬e) { - auto *job = new OcsShareJob(_account); - connect(job, &OcsShareJob::shareJobFinished, this, &LinkShare::slotNoteSet); - connect(job, &OcsJob::ocsError, this, &LinkShare::slotOcsError); - job->setNote(getId(), note); + createShareJob(&LinkShare::slotNoteSet)->setNote(getId(), note); } void LinkShare::slotNoteSet(const QJsonDocument &, const QVariant ¬e) @@ -253,10 +262,20 @@ QString LinkShare::getToken() const void LinkShare::setExpireDate(const QDate &date) { + createShareJob(&LinkShare::slotExpireDateSet)->setExpireDate(getId(), date); +} + +void LinkShare::setLabel(const QString &label) +{ + createShareJob(&LinkShare::slotLabelSet)->setLabel(getId(), label); +} + +template +OcsShareJob *LinkShare::createShareJob(const LinkShareSlot slotFunction) { auto *job = new OcsShareJob(_account); - connect(job, &OcsShareJob::shareJobFinished, this, &LinkShare::slotExpireDateSet); + connect(job, &OcsShareJob::shareJobFinished, this, slotFunction); connect(job, &OcsJob::ocsError, this, &LinkShare::slotOcsError); - job->setExpireDate(getId(), date); + return job; } void LinkShare::slotExpireDateSet(const QJsonDocument &reply, const QVariant &value) @@ -281,6 +300,14 @@ void LinkShare::slotNameSet(const QJsonDocument &, const QVariant &value) emit nameSet(); } +void LinkShare::slotLabelSet(const QJsonDocument &, const QVariant &label) +{ + if (_label != label.toString()) { + _label = label.toString(); + emit labelSet(); + } +} + UserGroupShare::UserGroupShare(AccountPtr account, const QString &id, const QString &owner, @@ -296,7 +323,7 @@ UserGroupShare::UserGroupShare(AccountPtr account, , _note(note) , _expireDate(expireDate) { - Q_ASSERT(shareType == TypeUser || shareType == TypeGroup || shareType == TypeEmail); + Q_ASSERT(Share::isShareTypeUserGroupEmailRoomOrRemote(shareType)); Q_ASSERT(shareWith); } @@ -326,6 +353,11 @@ QDate UserGroupShare::getExpireDate() const void UserGroupShare::setExpireDate(const QDate &date) { + if (_expireDate == date) { + emit expireDateSet(); + return; + } + auto *job = new OcsShareJob(_account); connect(job, &OcsShareJob::shareJobFinished, this, &UserGroupShare::slotExpireDateSet); connect(job, &OcsJob::ocsError, this, &UserGroupShare::slotOcsError); @@ -461,7 +493,7 @@ void ShareManager::slotSharesFetched(const QJsonDocument &reply) if (shareType == Share::TypeLink) { newShare = parseLinkShare(data); - } else if (shareType == Share::TypeGroup || shareType == Share::TypeUser || shareType == Share::TypeEmail) { + } else if (Share::isShareTypeUserGroupEmailRoomOrRemote(static_cast (shareType))) { newShare = parseUserGroupShare(data); } else { newShare = parseShare(data); @@ -524,6 +556,11 @@ QSharedPointer ShareManager::parseLinkShare(const QJsonObject &data) if (data.value("expiration").isString()) { expireDate = QDate::fromString(data.value("expiration").toString(), "yyyy-MM-dd 00:00:00"); } + + QString note; + if (data.value("note").isString()) { + note = data.value("note").toString(); + } return QSharedPointer(new LinkShare(_account, data.value("id").toVariant().toString(), // "id" used to be an integer, support both @@ -535,7 +572,9 @@ QSharedPointer ShareManager::parseLinkShare(const QJsonObject &data) (Share::Permissions)data.value("permissions").toInt(), data.value("share_with").isString(), // has password? url, - expireDate)); + expireDate, + note, + data.value("label").toString())); } QSharedPointer ShareManager::parseShare(const QJsonObject &data) diff --git a/src/gui/sharemanager.h b/src/gui/sharemanager.h index a764163f63c3..a69ec449d985 100644 --- a/src/gui/sharemanager.h +++ b/src/gui/sharemanager.h @@ -31,6 +31,8 @@ class QJsonObject; namespace OCC { +class OcsShareJob; + class Share : public QObject { Q_OBJECT @@ -128,6 +130,11 @@ class Share : public QObject */ void deleteShare(); + /* + * Is it a share with a user or group (local or remote) + */ + static bool isShareTypeUserGroupEmailRoomOrRemote(const ShareType type); + signals: void permissionsSet(); void shareDeleted(); @@ -175,7 +182,9 @@ class LinkShare : public Share const Permissions permissions, bool isPasswordSet, const QUrl &url, - const QDate &expireDate); + const QDate &expireDate, + const QString ¬e, + const QString &label); /* * Get the share link @@ -205,8 +214,12 @@ class LinkShare : public Share /* * Returns the note of the link share. */ - QString getNote() const; + + /* + * Returns the label of the link share. + */ + QString getLabel() const; /* * Set the name of the link share. @@ -215,7 +228,6 @@ class LinkShare : public Share */ void setName(const QString &name); - /* * Set the note of the link share. */ @@ -238,16 +250,30 @@ class LinkShare : public Share * In case of a server error the serverError signal is emitted. */ void setExpireDate(const QDate &expireDate); - + + /* + * Set the label of the share link. + */ + void setLabel(const QString &label); + + /* + * Create OcsShareJob and connect to signal/slots + */ + template + OcsShareJob *createShareJob(const LinkShareSlot slotFunction); + + signals: void expireDateSet(); void noteSet(); void nameSet(); + void labelSet(); private slots: void slotNoteSet(const QJsonDocument &, const QVariant &value); void slotExpireDateSet(const QJsonDocument &reply, const QVariant &value); void slotNameSet(const QJsonDocument &, const QVariant &value); + void slotLabelSet(const QJsonDocument &, const QVariant &value); private: QString _name; @@ -255,6 +281,7 @@ private slots: QString _note; QDate _expireDate; QUrl _url; + QString _label; }; class UserGroupShare : public Share diff --git a/src/gui/shareusergroupwidget.cpp b/src/gui/shareusergroupwidget.cpp index 47e6ebc6cca0..9c9bc3fc0627 100644 --- a/src/gui/shareusergroupwidget.cpp +++ b/src/gui/shareusergroupwidget.cpp @@ -12,7 +12,9 @@ * for more details. */ +#include "ocsprofileconnector.h" #include "sharee.h" +#include "tray/usermodel.h" #include "ui_shareusergroupwidget.h" #include "ui_shareuserline.h" #include "shareusergroupwidget.h" @@ -27,6 +29,7 @@ #include "thumbnailjob.h" #include "sharemanager.h" #include "theme.h" +#include "iconutils.h" #include "QProgressIndicator.h" #include @@ -35,7 +38,9 @@ #include #include #include -#include +#include +#include +#include #include #include #include @@ -46,15 +51,38 @@ #include #include #include +#include +#include +#include #include namespace { - const char *passwordIsSetPlaceholder = "●●●●●●●●"; +const char *passwordIsSetPlaceholder = "●●●●●●●●"; + } namespace OCC { +AvatarEventFilter::AvatarEventFilter(QObject *parent) + : QObject(parent) +{ +} + + +bool AvatarEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::ContextMenu) { + const auto contextMenuEvent = dynamic_cast(event); + if (!contextMenuEvent) { + return false; + } + emit contextMenu(contextMenuEvent->globalPos()); + return true; + } + return QObject::eventFilter(obj, event); +} + ShareUserGroupWidget::ShareUserGroupWidget(AccountPtr account, const QString &sharePath, const QString &localPath, @@ -247,7 +275,7 @@ void ShareUserGroupWidget::slotSharesFetched(const QList> } - Q_ASSERT(share->getShareType() == Share::TypeUser || share->getShareType() == Share::TypeGroup || share->getShareType() == Share::TypeEmail); + Q_ASSERT(Share::isShareTypeUserGroupEmailRoomOrRemote(share->getShareType())); auto userGroupShare = qSharedPointerDynamicCast(share); auto *s = new ShareUserLine(_account, userGroupShare, _maxSharingPermissions, _isFile, _parentScrollArea); connect(s, &ShareUserLine::resizeRequested, this, &ShareUserGroupWidget::slotAdjustScrollWidgetSize); @@ -369,43 +397,30 @@ void ShareUserGroupWidget::slotCompleterActivated(const QModelIndex &index) */ _lastCreatedShareId = QString(); - - if (sharee->type() == Sharee::Federated - && _account->serverVersionInt() < Account::makeServerVersion(9, 1, 0)) { - int permissions = SharePermissionRead | SharePermissionUpdate; - if (!_isFile) { - permissions |= SharePermissionCreate | SharePermissionDelete; - } - _manager->createShare(_sharePath, Share::ShareType(sharee->type()), - sharee->shareWith(), SharePermission(permissions)); - } else { - QString password; - if (sharee->type() == Sharee::Email && _account->capabilities().shareEmailPasswordEnforced()) { - _ui->shareeLineEdit->clear(); - // always show a dialog for password-enforced email shares - bool ok = false; - - do { - password = QInputDialog::getText( - this, - tr("Password for share required"), - tr("Please enter a password for your email share:"), - QLineEdit::Password, - QString(), - &ok); - } while (password.isEmpty() && ok); - - if (!ok) { - return; - } + + QString password; + if (sharee->type() == Sharee::Email && _account->capabilities().shareEmailPasswordEnforced()) { + _ui->shareeLineEdit->clear(); + // always show a dialog for password-enforced email shares + bool ok = false; + + do { + password = QInputDialog::getText( + this, + tr("Password for share required"), + tr("Please enter a password for your email share:"), + QLineEdit::Password, + QString(), + &ok); + } while (password.isEmpty() && ok); + + if (!ok) { + return; } - - // Default permissions on creation - int permissions = SharePermissionCreate | SharePermissionUpdate - | SharePermissionDelete | SharePermissionShare; - _manager->createShare(_sharePath, Share::ShareType(sharee->type()), - sharee->shareWith(), SharePermission(permissions), password); } + + _manager->createShare(_sharePath, Share::ShareType(sharee->type()), + sharee->shareWith(), _maxSharingPermissions, password); _ui->shareeLineEdit->setEnabled(false); _ui->shareeLineEdit->clear(); @@ -476,16 +491,14 @@ void ShareUserGroupWidget::activateShareeLineEdit() _ui->shareeLineEdit->setFocus(); } -ShareUserLine::ShareUserLine(AccountPtr account, - QSharedPointer share, - SharePermissions maxSharingPermissions, - bool isFile, - QWidget *parent) +ShareUserLine::ShareUserLine(AccountPtr account, QSharedPointer share, + SharePermissions maxSharingPermissions, bool isFile, QWidget *parent) : QWidget(parent) , _ui(new Ui::ShareUserLine) , _account(account) , _share(share) , _isFile(isFile) + , _profilePageMenu(account, share->getShareWith()->shareWith()) { Q_ASSERT(_share); _ui->setupUi(this); @@ -501,7 +514,6 @@ ShareUserLine::ShareUserLine(AccountPtr account, _ui->permissionsEdit->setEnabled(enabled); connect(_ui->permissionsEdit, &QAbstractButton::clicked, this, &ShareUserLine::slotEditPermissionsChanged); connect(_ui->noteConfirmButton, &QAbstractButton::clicked, this, &ShareUserLine::onNoteConfirmButtonClicked); - connect(_ui->confirmExpirationDate, &QAbstractButton::clicked, this, &ShareUserLine::setExpireDate); connect(_ui->calendar, &QDateTimeEdit::dateChanged, this, &ShareUserLine::setExpireDate); connect(_share.data(), &UserGroupShare::noteSet, this, &ShareUserLine::disableProgessIndicatorAnimation); @@ -521,10 +533,9 @@ ShareUserLine::ShareUserLine(AccountPtr account, showNoteOptions(false); - // email shares do not support notes and expiration dates - const bool isNoteAndExpirationDateSupported = _share->getShareType() != Share::ShareType::TypeEmail; + const bool isNoteSupported = _share->getShareType() != Share::ShareType::TypeEmail && _share->getShareType() != Share::ShareType::TypeRoom; - if (isNoteAndExpirationDateSupported) { + if (isNoteSupported) { _noteLinkAction = new QAction(tr("Note to recipient")); _noteLinkAction->setCheckable(true); menu->addAction(_noteLinkAction); @@ -537,7 +548,9 @@ ShareUserLine::ShareUserLine(AccountPtr account, showExpireDateOptions(false); - if (isNoteAndExpirationDateSupported) { + const bool isExpirationDateSupported = _share->getShareType() != Share::ShareType::TypeEmail; + + if (isExpirationDateSupported) { // email shares do not support expiration dates _expirationDateLinkAction = new QAction(tr("Set expiration date")); _expirationDateLinkAction->setCheckable(true); @@ -545,9 +558,8 @@ ShareUserLine::ShareUserLine(AccountPtr account, connect(_expirationDateLinkAction, &QAction::triggered, this, &ShareUserLine::toggleExpireDateOptions); const auto expireDate = _share->getExpireDate().isValid() ? share.data()->getExpireDate() : QDate(); if (!expireDate.isNull()) { - _ui->calendar->setDate(expireDate); _expirationDateLinkAction->setChecked(true); - showExpireDateOptions(true); + showExpireDateOptions(true, expireDate); } } @@ -630,11 +642,22 @@ ShareUserLine::ShareUserLine(AccountPtr account, _permissionReshare->setVisible(false); } + const auto avatarEventFilter = new AvatarEventFilter(_ui->avatar); + connect(avatarEventFilter, &AvatarEventFilter::contextMenu, this, &ShareUserLine::onAvatarContextMenu); + _ui->avatar->installEventFilter(avatarEventFilter); + loadAvatar(); customizeStyle(); } +void ShareUserLine::onAvatarContextMenu(const QPoint &globalPosition) +{ + if (_share->getShareType() == Share::TypeUser) { + _profilePageMenu.exec(globalPosition); + } +} + void ShareUserLine::loadAvatar() { const int avatarSize = 36; @@ -646,15 +669,28 @@ void ShareUserLine::loadAvatar() _ui->avatar->setMaximumWidth(avatarSize); _ui->avatar->setAlignment(Qt::AlignCenter); + setDefaultAvatar(avatarSize); + + /* Start the network job to fetch the avatar data. + * + * Currently only regular users can have avatars. + */ + if (_share->getShareWith()->type() == Sharee::User) { + auto *job = new AvatarJob(_share->account(), _share->getShareWith()->shareWith(), avatarSize, this); + connect(job, &AvatarJob::avatarPixmap, this, &ShareUserLine::slotAvatarLoaded); + job->start(); + } +} + +void ShareUserLine::setDefaultAvatar(int avatarSize) +{ /* Create the fallback avatar. * * This will be shown until the avatar image data arrives. */ - const QByteArray hash = QCryptographicHash::hash(_ui->sharedWith->text().toUtf8(), QCryptographicHash::Md5); - double hue = static_cast(hash[0]) / 255.; // See core/js/placeholder.js for details on colors and styling - const QColor bg = QColor::fromHslF(hue, 0.7, 0.68); + const auto backgroundColor = backgroundColorForShareeType(_share->getShareWith()->type()); const QString style = QString(R"(* { color: #fff; background-color: %1; @@ -662,21 +698,19 @@ void ShareUserLine::loadAvatar() text-align: center; line-height: %2px; font-size: %2px; - })").arg(bg.name(), QString::number(avatarSize / 2)); + })").arg(backgroundColor.name(), QString::number(avatarSize / 2)); _ui->avatar->setStyleSheet(style); - // The avatar label is the first character of the user name. - const QString text = _share->getShareWith()->displayName(); - _ui->avatar->setText(text.at(0).toUpper()); + const auto pixmap = pixmapForShareeType(_share->getShareWith()->type(), backgroundColor); - /* Start the network job to fetch the avatar data. - * - * Currently only regular users can have avatars. - */ - if (_share->getShareWith()->type() == Sharee::User) { - auto *job = new AvatarJob(_share->account(), _share->getShareWith()->shareWith(), avatarSize, this); - connect(job, &AvatarJob::avatarPixmap, this, &ShareUserLine::slotAvatarLoaded); - job->start(); + if (!pixmap.isNull()) { + _ui->avatar->setPixmap(pixmap); + } else { + qCDebug(lcSharing) << "pixmap is null for share type: " << _share->getShareWith()->type(); + + // The avatar label is the first character of the user name. + const auto text = _share->getShareWith()->displayName(); + _ui->avatar->setText(text.at(0).toUpper()); } } @@ -926,13 +960,57 @@ void ShareUserLine::customizeStyle() _deleteShareButton->setIcon(deleteicon); _ui->noteConfirmButton->setIcon(Theme::createColorAwareIcon(":/client/theme/confirm.svg")); - _ui->confirmExpirationDate->setIcon(Theme::createColorAwareIcon(":/client/theme/confirm.svg")); _ui->progressIndicator->setColor(QGuiApplication::palette().color(QPalette::WindowText)); // make sure to force BackgroundRole to QPalette::WindowText for a lable, because it's parent always has a different role set that applies to children unless customized _ui->errorLabel->setBackgroundRole(QPalette::WindowText); } +QPixmap ShareUserLine::pixmapForShareeType(Sharee::Type type, const QColor &backgroundColor) const +{ + switch (type) { + case Sharee::Room: + return Ui::IconUtils::pixmapForBackground(QStringLiteral("talk-app.svg"), backgroundColor); + case Sharee::Email: + return Ui::IconUtils::pixmapForBackground(QStringLiteral("email.svg"), backgroundColor); + case Sharee::Group: + case Sharee::Federated: + case Sharee::Circle: + case Sharee::User: + break; + } + + return {}; +} + +QColor ShareUserLine::backgroundColorForShareeType(Sharee::Type type) const +{ + switch (type) { + case Sharee::Room: + return Theme::instance()->wizardHeaderBackgroundColor(); + case Sharee::Email: + return Theme::instance()->wizardHeaderTitleColor(); + case Sharee::Group: + case Sharee::Federated: + case Sharee::Circle: + case Sharee::User: + break; + } + + const auto calculateBackgroundBasedOnText = [this]() { + const auto hash = QCryptographicHash::hash(_ui->sharedWith->text().toUtf8(), QCryptographicHash::Md5); + Q_ASSERT(hash.size() > 0); + if (hash.size() == 0) { + qCWarning(lcSharing) << "Failed to calculate hash color for share:" << _share->path(); + return QColor{}; + } + const double hue = static_cast(hash[0]) / 255.; + return QColor::fromHslF(hue, 0.7, 0.68); + }; + + return calculateBackgroundBasedOnText(); +} + void ShareUserLine::showNoteOptions(bool show) { _ui->noteLabel->setVisible(show); @@ -979,17 +1057,21 @@ void ShareUserLine::toggleExpireDateOptions(bool enable) } } -void ShareUserLine::showExpireDateOptions(bool show) +void ShareUserLine::showExpireDateOptions(bool show, const QDate &initialDate) { _ui->expirationLabel->setVisible(show); _ui->calendar->setVisible(show); - _ui->confirmExpirationDate->setVisible(show); if (show) { - const QDate date = QDate::currentDate().addDays(1); - _ui->calendar->setDate(date); - _ui->calendar->setMinimumDate(date); + _ui->calendar->setMinimumDate(QDate::currentDate().addDays(1)); + _ui->calendar->setDate(initialDate.isValid() ? initialDate : _ui->calendar->minimumDate()); _ui->calendar->setFocus(); + + if (enforceExpirationDateForShare(_share->getShareType())) { + _ui->calendar->setMaximumDate(maxExpirationDateForShare(_share->getShareType(), _ui->calendar->maximumDate())); + _expirationDateLinkAction->setChecked(true); + _expirationDateLinkAction->setEnabled(false); + } } emit resizeRequested(); @@ -1031,6 +1113,35 @@ void ShareUserLine::disableProgessIndicatorAnimation() enableProgessIndicatorAnimation(false); } +QDate ShareUserLine::maxExpirationDateForShare(const Share::ShareType type, const QDate &fallbackDate) const +{ + auto daysToExpire = 0; + if (type == Share::ShareType::TypeRemote) { + daysToExpire = _account->capabilities().shareRemoteExpireDateDays(); + } else if (type == Share::ShareType::TypeEmail) { + daysToExpire = _account->capabilities().sharePublicLinkExpireDateDays(); + } else { + daysToExpire = _account->capabilities().shareInternalExpireDateDays(); + } + + if (daysToExpire > 0) { + return QDate::currentDate().addDays(daysToExpire); + } + + return fallbackDate; +} + +bool ShareUserLine::enforceExpirationDateForShare(const Share::ShareType type) const +{ + if (type == Share::ShareType::TypeRemote) { + return _account->capabilities().shareRemoteEnforceExpireDate(); + } else if (type == Share::ShareType::TypeEmail) { + return _account->capabilities().sharePublicLinkEnforceExpireDate(); + } + + return _account->capabilities().shareInternalEnforceExpireDate(); +} + void ShareUserLine::setPasswordConfirmed() { if (_ui->lineEdit_password->text().isEmpty()) { diff --git a/src/gui/shareusergroupwidget.h b/src/gui/shareusergroupwidget.h index bb7f54998f2b..599ab521b557 100644 --- a/src/gui/shareusergroupwidget.h +++ b/src/gui/shareusergroupwidget.h @@ -19,6 +19,7 @@ #include "sharemanager.h" #include "sharepermissions.h" #include "sharee.h" +#include "profilepagewidget.h" #include "QProgressIndicator.h" #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include class QAction; @@ -44,6 +46,21 @@ class SyncResult; class Share; class ShareManager; +class AvatarEventFilter : public QObject +{ + Q_OBJECT + +public: + explicit AvatarEventFilter(QObject *parent = nullptr); + +signals: + void clicked(); + void contextMenu(const QPoint &globalPosition); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; +}; + /** * @brief The ShareDialog (user/group) class * @ingroup gui @@ -59,7 +76,7 @@ class ShareUserGroupWidget : public QWidget SharePermissions maxSharingPermissions, const QString &privateLinkUrl, QWidget *parent = nullptr); - ~ShareUserGroupWidget(); + ~ShareUserGroupWidget() override; signals: void togglePublicLinkShare(bool); @@ -128,7 +145,7 @@ class ShareUserLine : public QWidget SharePermissions maxSharingPermissions, bool isFile, QWidget *parent = nullptr); - ~ShareUserLine(); + ~ShareUserLine() override; QSharedPointer share() const; @@ -166,18 +183,24 @@ private slots: void slotConfirmPasswordClicked(); + void onAvatarContextMenu(const QPoint &globalPosition); + private: void displayPermissions(); void loadAvatar(); + void setDefaultAvatar(int avatarSize); void customizeStyle(); + QPixmap pixmapForShareeType(Sharee::Type type, const QColor &backgroundColor = QColor()) const; + QColor backgroundColorForShareeType(Sharee::Type type) const; + void showNoteOptions(bool show); void toggleNoteOptions(bool enable); void onNoteConfirmButtonClicked(); void setNote(const QString ¬e); void toggleExpireDateOptions(bool enable); - void showExpireDateOptions(bool show); + void showExpireDateOptions(bool show, const QDate &initialDate = QDate()); void setExpireDate(); void togglePasswordSetProgressAnimation(bool show); @@ -185,11 +208,16 @@ private slots: void enableProgessIndicatorAnimation(bool enable); void disableProgessIndicatorAnimation(); + QDate maxExpirationDateForShare(const Share::ShareType type, const QDate &fallbackDate) const; + bool enforceExpirationDateForShare(const Share::ShareType type) const; + Ui::ShareUserLine *_ui; AccountPtr _account; QSharedPointer _share; bool _isFile; + ProfilePageMenu _profilePageMenu; + // _permissionEdit is a checkbox QAction *_permissionReshare; QAction *_deleteShareButton; diff --git a/src/gui/shareuserline.ui b/src/gui/shareuserline.ui index 5c811ed5740f..5067a31201dd 100644 --- a/src/gui/shareuserline.ui +++ b/src/gui/shareuserline.ui @@ -6,8 +6,8 @@ 0 0 - 980 - 239 + 899 + 310 @@ -273,20 +273,6 @@ - - - - - - - - :/client/theme/confirm.svg:/client/theme/confirm.svg - - - true - - - @@ -315,33 +301,519 @@ + + + 255 + 255 + 255 + + + + + + + 65 + 70 + 84 + + + + + + + 95 + 103 + 127 + + + + + 49 + 49 + 49 + + + + + + + 0 + 0 + 0 + + + + + + + 25 + 25 + 25 + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 64 + 69 + 82 + + + + + + + 56 + 60 + 74 + + + + + + + 0 0 0 + + + + 82 + 148 + 226 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 157 + 255 + + + + + + + 158 + 79 + 255 + + + + + + + 60 + 67 + 79 + + + + + + + 0 + 0 + 0 + + + + + + + 238 + 252 + 255 + + + + + + + 255 + 255 + 255 + + + + + + 255 + 255 + 255 + + + + + + + 65 + 70 + 84 + + + + + + + 95 + 103 + 127 + + + + + + + 49 + 49 + 49 + + + + + + + 0 + 0 + 0 + + + + + + + 25 + 25 + 25 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 64 + 69 + 82 + + + + + + + 56 + 60 + 74 + + + + + + + 0 + 0 + 0 + + + + + + + 82 + 149 + 225 + + + + 255 + 255 + 255 + + + + + + + 0 + 157 + 255 + + + + + + + 158 + 79 + 255 + + + + + + + 60 + 67 + 79 + + + + + + + 0 0 0 + + + + 238 + 252 + 255 + + + + + + + 255 + 255 + 255 + + + + + + 255 + 255 + 255 + + + + - 123 - 121 - 134 + 65 + 70 + 84 + + + + + + + 95 + 103 + 127 + + + + + + + 49 + 49 + 49 + + + + + + + 0 + 0 + 0 + + + + + + + 25 + 25 + 25 + + + + + + + 255 + 255 + 255 + + + + + + + 255 + 255 + 255 + + + + + + + 64 + 69 + 82 + + + + + + + 56 + 60 + 74 + + + + + + + 0 + 0 + 0 + + + + + + + 82 + 148 + 226 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 157 + 255 + + + + + + + 158 + 79 + 255 + + + + + + + 60 + 67 + 79 + + + + + + + 0 + 0 + 0 + + + + + + + 238 + 252 + 255 + + + + + + + 255 + 255 + 255 diff --git a/src/gui/socketapi/CMakeLists.txt b/src/gui/socketapi/CMakeLists.txt new file mode 100644 index 000000000000..9290269eedab --- /dev/null +++ b/src/gui/socketapi/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(nextcloudCore PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/socketapi.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/socketuploadjob.cpp +) + +if( APPLE ) + target_sources(nextcloudCore PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/socketapisocket_mac.mm) +endif() diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi/socketapi.cpp similarity index 82% rename from src/gui/socketapi.cpp rename to src/gui/socketapi/socketapi.cpp index 16b618868262..9be00d22fb66 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi/socketapi.cpp @@ -16,9 +16,11 @@ #include "socketapi.h" #include "socketapi_p.h" +#include "socketapi/socketuploadjob.h" #include "conflictdialog.h" #include "conflictsolver.h" + #include "config.h" #include "configfile.h" #include "folderman.h" @@ -32,6 +34,7 @@ #include "account.h" #include "accountstate.h" #include "account.h" +#include "accountmanager.h" #include "capabilities.h" #include "common/asserts.h" #include "guiutility.h" @@ -57,6 +60,7 @@ #include +#include #include #include #include @@ -78,12 +82,25 @@ #define MIRALL_SOCKET_API_VERSION "1.1" namespace { + +const QLatin1Char RecordSeparator() +{ + return QLatin1Char('\x1e'); +} + +QStringList split(const QString &data) +{ + // TODO: string ref? + return data.split(RecordSeparator()); +} + #if GUI_TESTING using namespace OCC; -QList allObjects(const QList &widgets) { - QList objects; +QList allObjects(const QList &widgets) +{ + QList objects; std::copy(widgets.constBegin(), widgets.constEnd(), std::back_inserter(objects)); objects << qApp; @@ -91,11 +108,11 @@ QList allObjects(const QList &widgets) { return objects; } -QObject *findWidget(const QString &queryString, const QList &widgets = QApplication::allWidgets()) +QObject *findWidget(const QString &queryString, const QList &widgets = QApplication::allWidgets()) { auto objects = allObjects(widgets); - QList::const_iterator foundWidget; + QList::const_iterator foundWidget; if (queryString.contains('>')) { qCDebug(lcSocketApi) << "queryString contains >"; @@ -107,33 +124,34 @@ QObject *findWidget(const QString &queryString, const QList &widgets = qCDebug(lcSocketApi) << "Find parent: " << parentQueryString; auto parent = findWidget(parentQueryString); - if(!parent) { + if (!parent) { return nullptr; } auto childQueryString = subQueries[1].trimmed(); - auto child = findWidget(childQueryString, parent->findChildren()); + auto child = findWidget(childQueryString, parent->findChildren()); qCDebug(lcSocketApi) << "found child: " << !!child; return child; - } else if(queryString.startsWith('#')) { + } else if (queryString.startsWith('#')) { auto objectName = queryString.mid(1); qCDebug(lcSocketApi) << "find objectName: " << objectName; foundWidget = std::find_if(objects.constBegin(), objects.constEnd(), [&](QObject *widget) { return widget->objectName() == objectName; }); } else { - QList matches; - std::copy_if(objects.constBegin(), objects.constEnd(), std::back_inserter(matches), [&](QObject* widget) { + QList matches; + std::copy_if(objects.constBegin(), objects.constEnd(), std::back_inserter(matches), [&](QObject *widget) { return widget->inherits(queryString.toLatin1()); }); - std::for_each(matches.constBegin(), matches.constEnd(), [](QObject* w) { - if(!w) return; + std::for_each(matches.constBegin(), matches.constEnd(), [](QObject *w) { + if (!w) + return; qCDebug(lcSocketApi) << "WIDGET: " << w->objectName() << w->metaObject()->className(); }); - if(matches.empty()) { + if (matches.empty()) { return nullptr; } return matches[0]; @@ -200,16 +218,6 @@ void SocketListener::sendMessage(const QString &message, bool doWait) const } } -struct ListenerHasSocketPred -{ - QIODevice *socket; - ListenerHasSocketPred(QIODevice *socket) - : socket(socket) - { - } - bool operator()(const SocketListener &listener) const { return listener.socket == socket; } -}; - SocketApi::SocketApi(QObject *parent) : QObject(parent) { @@ -217,6 +225,7 @@ SocketApi::SocketApi(QObject *parent) qRegisterMetaType("SocketListener*"); qRegisterMetaType>("QSharedPointer"); + qRegisterMetaType>("QSharedPointer"); if (Utility::isWindows()) { socketPath = QLatin1String(R"(\\.\pipe\)") @@ -236,21 +245,20 @@ SocketApi::SocketApi(QObject *parent) CFURLRef url = (CFURLRef)CFAutorelease((CFURLRef)CFBundleCopyBundleURL(CFBundleGetMainBundle())); QString bundlePath = QUrl::fromCFURL(url).path(); - auto _system = [](const QString &cmd, const QStringList &args){ + auto _system = [](const QString &cmd, const QStringList &args) { QProcess process; process.setProcessChannelMode(QProcess::MergedChannels); process.start(cmd, args); - if (!process.waitForFinished()) - { + if (!process.waitForFinished()) { qCWarning(lcSocketApi) << "Failed to load shell extension:" << cmd << args.join(" ") << process.errorString(); } else { - qCInfo(lcSocketApi) << (process.exitCode() != 0 ? "Failed to load" : "Loaded") << "shell extension:" << cmd << args.join(" ") << process.readAll(); + qCInfo(lcSocketApi) << (process.exitCode() != 0 ? "Failed to load" : "Loaded") << "shell extension:" << cmd << args.join(" ") << process.readAll(); } }; // Add it again. This was needed for Mojave to trigger a load. - _system(QStringLiteral("pluginkit"), {QStringLiteral("-a"),QStringLiteral("%1Contents/PlugIns/FinderSyncExt.appex/").arg(bundlePath)}); + _system(QStringLiteral("pluginkit"), { QStringLiteral("-a"), QStringLiteral("%1Contents/PlugIns/FinderSyncExt.appex/").arg(bundlePath) }); // Tell Finder to use the Extension (checking it from System Preferences -> Extensions) - _system(QStringLiteral("pluginkit"), {QStringLiteral("-e"), QStringLiteral("use"), QStringLiteral("-i"), QStringLiteral(APPLICATION_REV_DOMAIN ".FinderSyncExt")}); + _system(QStringLiteral("pluginkit"), { QStringLiteral("-e"), QStringLiteral("use"), QStringLiteral("-i"), QStringLiteral(APPLICATION_REV_DOMAIN ".FinderSyncExt") }); #endif } else if (Utility::isLinux() || Utility::isBSD()) { @@ -288,7 +296,7 @@ SocketApi::~SocketApi() qCDebug(lcSocketApi) << "dtor"; _localServer.close(); // All remaining sockets will be destroyed with _localServer, their parent - ASSERT(_listeners.isEmpty() || _listeners.first().socket->parent() == &_localServer); + ASSERT(_listeners.isEmpty() || _listeners.first()->socket->parent() == &_localServer) _listeners.clear(); } @@ -307,14 +315,13 @@ void SocketApi::slotNewConnection() connect(socket, &QObject::destroyed, this, &SocketApi::slotSocketDestroyed); ASSERT(socket->readAll().isEmpty()); - _listeners.append(SocketListener(socket)); - SocketListener &listener = _listeners.last(); - - foreach (Folder *f, FolderMan::instance()->map()) { + auto listener = QSharedPointer::create(socket); + _listeners.insert(socket, listener); + for (Folder *f : FolderMan::instance()->map()) { if (f->canSync()) { QString message = buildRegisterPathMessage(removeTrailingSlash(f->path())); - qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener.socket; - listener.sendMessage(message); + qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener->socket; + listener->sendMessage(message); } } } @@ -326,13 +333,13 @@ void SocketApi::onLostConnection() auto socket = qobject_cast(sender()); ASSERT(socket); - _listeners.erase(std::remove_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket)), _listeners.end()); + _listeners.remove(socket); } void SocketApi::slotSocketDestroyed(QObject *obj) { auto *socket = static_cast(obj); - _listeners.erase(std::remove_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket)), _listeners.end()); + _listeners.remove(socket); } void SocketApi::slotReadSocket() @@ -346,36 +353,38 @@ void SocketApi::slotReadSocket() // the readyRead() signals are received - in that case there won't be a // valid listener. We execute the handler anyway, but it will work with // a SocketListener that doesn't send any messages. - static auto noListener = SocketListener(nullptr); - SocketListener *listener = &noListener; - auto listenerIt = std::find_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket)); - if (listenerIt != _listeners.end()) { - listener = &*listenerIt; - } - + static auto invalidListener = QSharedPointer::create(nullptr); + const auto listener = _listeners.value(socket, invalidListener); while (socket->canReadLine()) { // Make sure to normalize the input from the socket to // make sure that the path will match, especially on OS X. - QString line = QString::fromUtf8(socket->readLine()).normalized(QString::NormalizationForm_C); - line.chop(1); // remove the '\n' + const QString line = QString::fromUtf8(socket->readLine().trimmed()).normalized(QString::NormalizationForm_C); qCInfo(lcSocketApi) << "Received SocketAPI message <--" << line << "from" << socket; - QByteArray command = line.split(":").value(0).toLatin1(); - - QByteArray functionWithArguments = "command_" + command; - if (command.startsWith("ASYNC_")) { - functionWithArguments += "(QSharedPointer)"; - } else { - functionWithArguments += "(QString,SocketListener*)"; - } - - int indexOfMethod = staticMetaObject.indexOfMethod(functionWithArguments); + const int argPos = line.indexOf(QLatin1Char(':')); + const QByteArray command = line.midRef(0, argPos).toUtf8().toUpper(); + const int indexOfMethod = [&] { + QByteArray functionWithArguments = QByteArrayLiteral("command_"); + if (command.startsWith("ASYNC_")) { + functionWithArguments += command + QByteArrayLiteral("(QSharedPointer)"); + } else if (command.startsWith("V2/")) { + functionWithArguments += QByteArrayLiteral("V2_") + command.mid(3) + QByteArrayLiteral("(QSharedPointer)"); + } else { + functionWithArguments += command + QByteArrayLiteral("(QString,SocketListener*)"); + } + Q_ASSERT(staticQtMetaObject.normalizedSignature(functionWithArguments) == functionWithArguments); + const auto out = staticMetaObject.indexOfMethod(functionWithArguments); + if (out == -1) { + listener->sendError(QStringLiteral("Function %1 not found").arg(QString::fromUtf8(functionWithArguments))); + } + ASSERT(out != -1) + return out; + }(); - QString argument = line.remove(0, command.length() + 1); + const auto argument = argPos != -1 ? line.midRef(argPos + 1) : QStringRef(); if (command.startsWith("ASYNC_")) { - auto arguments = argument.split('|'); if (arguments.size() != 2) { - listener->sendMessage(QLatin1String("argument count is wrong")); + listener->sendError(QStringLiteral("argument count is wrong")); return; } @@ -384,25 +393,41 @@ void SocketApi::slotReadSocket() auto jobId = arguments[0]; auto socketApiJob = QSharedPointer( - new SocketApiJob(jobId, listener, json), &QObject::deleteLater); + new SocketApiJob(jobId.toString(), listener, json), &QObject::deleteLater); if (indexOfMethod != -1) { staticMetaObject.method(indexOfMethod) .invoke(this, Qt::QueuedConnection, - Q_ARG(QSharedPointer, socketApiJob)); + Q_ARG(QSharedPointer, socketApiJob)); } else { qCWarning(lcSocketApi) << "The command is not supported by this version of the client:" << command - << "with argument:" << argument; - socketApiJob->reject("command not found"); + << "with argument:" << argument; + socketApiJob->reject(QStringLiteral("command not found")); + } + } else if (command.startsWith("V2/")) { + QJsonParseError error; + const auto json = QJsonDocument::fromJson(argument.toUtf8(), &error).object(); + if (error.error != QJsonParseError::NoError) { + qCWarning(lcSocketApi()) << "Invalid json" << argument.toString() << error.errorString(); + listener->sendError(error.errorString()); + return; + } + auto socketApiJob = QSharedPointer::create(listener, command, json); + if (indexOfMethod != -1) { + staticMetaObject.method(indexOfMethod) + .invoke(this, Qt::QueuedConnection, + Q_ARG(QSharedPointer, socketApiJob)); + } else { + qCWarning(lcSocketApi) << "The command is not supported by this version of the client:" << command + << "with argument:" << argument; + socketApiJob->failure(QStringLiteral("command not found")); } } else { if (indexOfMethod != -1) { // to ensure that listener is still valid we need to call it with Qt::DirectConnection ASSERT(thread() == QThread::currentThread()) staticMetaObject.method(indexOfMethod) - .invoke(this, Qt::DirectConnection, Q_ARG(QString, argument), - Q_ARG(SocketListener *, listener)); - } else { - qCWarning(lcSocketApi) << "The command is not supported by this version of the client:" << command << "with argument:" << argument; + .invoke(this, Qt::DirectConnection, Q_ARG(QString, argument.toString()), + Q_ARG(SocketListener *, listener.data())); } } } @@ -416,10 +441,10 @@ void SocketApi::slotRegisterPath(const QString &alias) Folder *f = FolderMan::instance()->folder(alias); if (f) { - QString message = buildRegisterPathMessage(removeTrailingSlash(f->path())); - foreach (auto &listener, _listeners) { - qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener.socket; - listener.sendMessage(message); + const QString message = buildRegisterPathMessage(removeTrailingSlash(f->path())); + for (const auto &listener : qAsConst(_listeners)) { + qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener->socket; + listener->sendMessage(message); } } @@ -464,11 +489,17 @@ void SocketApi::slotUpdateFolderView(Folder *f) void SocketApi::broadcastMessage(const QString &msg, bool doWait) { - foreach (auto &listener, _listeners) { - listener.sendMessage(msg, doWait); + for (const auto &listener : qAsConst(_listeners)) { + listener->sendMessage(msg, doWait); } } +void SocketApi::processFileActivityRequest(const QString &localFile) +{ + const auto fileData = FileData::get(localFile); + emit fileActivityCommandReceived(fileData.serverRelativePath, fileData.localPath); +} + void SocketApi::processShareRequest(const QString &localFile, SocketListener *listener, ShareDialogStartPage startPage) { auto theme = Theme::instance(); @@ -515,8 +546,8 @@ void SocketApi::broadcastStatusPushMessage(const QString &systemPath, SyncFileSt QString msg = buildMessage(QLatin1String("STATUS"), systemPath, fileStatus.toSocketAPIString()); Q_ASSERT(!systemPath.endsWith('/')); uint directoryHash = qHash(systemPath.left(systemPath.lastIndexOf('/'))); - foreach (auto &listener, _listeners) { - listener.sendMessageIfDirectoryMonitored(msg, directoryHash); + for (const auto &listener : qAsConst(_listeners)) { + listener->sendMessageIfDirectoryMonitored(msg, directoryHash); } } @@ -553,6 +584,13 @@ void SocketApi::command_SHARE(const QString &localFile, SocketListener *listener processShareRequest(localFile, listener, ShareDialogStartPage::UsersAndGroups); } +void SocketApi::command_ACTIVITY(const QString &localFile, SocketListener *listener) +{ + Q_UNUSED(listener); + + processFileActivityRequest(localFile); +} + void SocketApi::command_MANAGE_PUBLIC_LINKS(const QString &localFile, SocketListener *listener) { processShareRequest(localFile, listener, ShareDialogStartPage::PublicLinks); @@ -592,7 +630,7 @@ void SocketApi::command_EDIT(const QString &localFile, SocketListener *listener) params.addQueryItem("path", fileData.serverRelativePath); params.addQueryItem("editorId", editor->id()); job->addQueryParams(params); - job->usePOST(); + job->setVerb(JsonApiJob::Verb::Post); QObject::connect(job, &JsonApiJob::jsonReceived, [](const QJsonDocument &json){ auto data = json.object().value("ocs").toObject().value("data").toObject(); @@ -612,20 +650,20 @@ class GetOrCreatePublicLinkShare : public QObject Q_OBJECT public: GetOrCreatePublicLinkShare(const AccountPtr &account, const QString &localFile, - std::function targetFun, QObject *parent) + QObject *parent) : QObject(parent) + , _account(account) , _shareManager(account) , _localFile(localFile) - , _targetFun(targetFun) { connect(&_shareManager, &ShareManager::sharesFetched, this, &GetOrCreatePublicLinkShare::sharesFetched); connect(&_shareManager, &ShareManager::linkShareCreated, this, &GetOrCreatePublicLinkShare::linkShareCreated); + connect(&_shareManager, &ShareManager::linkShareRequiresPassword, + this, &GetOrCreatePublicLinkShare::linkShareRequiresPassword); connect(&_shareManager, &ShareManager::serverError, this, &GetOrCreatePublicLinkShare::serverError); - connect(&_shareManager, &ShareManager::linkShareRequiresPassword, - this, &GetOrCreatePublicLinkShare::passwordRequired); } void run() @@ -638,6 +676,7 @@ private slots: void sharesFetched(const QList> &shares) { auto shareName = SocketApi::tr("Context menu share"); + // If there already is a context menu share, reuse it for (const auto &share : shares) { const auto linkShare = qSharedPointerDynamicCast(share); @@ -679,6 +718,13 @@ private slots: _shareManager.createLinkShare(_localFile, QString(), password); } + void linkShareRequiresPassword(const QString &message) + { + qCInfo(lcPublicLink) << "Could not create link share:" << message; + emit error(message); + deleteLater(); + } + void serverError(int code, const QString &message) { qCWarning(lcPublicLink) << "Share fetch/create error" << code << message; @@ -688,19 +734,24 @@ private slots: tr("Could not retrieve or create the public link share. Error:\n\n%1").arg(message), QMessageBox::Ok, QMessageBox::NoButton); + emit error(message); deleteLater(); } +signals: + void done(const QString &link); + void error(const QString &message); + private: void success(const QString &link) { - _targetFun(link); + emit done(link); deleteLater(); } + AccountPtr _account; ShareManager _shareManager; QString _localFile; - std::function _targetFun; }; #else @@ -728,7 +779,11 @@ void SocketApi::command_COPY_PUBLIC_LINK(const QString &localFile, SocketListene return; AccountPtr account = fileData.folder->accountState()->account(); - auto job = new GetOrCreatePublicLinkShare(account, fileData.serverRelativePath, [](const QString &url) { copyUrlToClipboard(url); }, this); + auto job = new GetOrCreatePublicLinkShare(account, fileData.serverRelativePath, this); + connect(job, &GetOrCreatePublicLinkShare::done, this, + [](const QString &url) { copyUrlToClipboard(url); }); + connect(job, &GetOrCreatePublicLinkShare::error, this, + [=]() { emit shareCommandReceived(fileData.serverRelativePath, fileData.localPath, ShareDialogStartPage::PublicLinks); }); job->run(); } @@ -788,7 +843,7 @@ void SocketApi::command_OPEN_PRIVATE_LINK(const QString &localFile, SocketListen void SocketApi::command_MAKE_AVAILABLE_LOCALLY(const QString &filesArg, SocketListener *) { - QStringList files = filesArg.split(QLatin1Char('\x1e')); // Record Separator + const QStringList files = split(filesArg); for (const auto &file : files) { auto data = FileData::get(file); @@ -809,7 +864,7 @@ void SocketApi::command_MAKE_AVAILABLE_LOCALLY(const QString &filesArg, SocketLi /* Go over all the files and replace them by a virtual file */ void SocketApi::command_MAKE_ONLINE_ONLY(const QString &filesArg, SocketListener *) { - QStringList files = filesArg.split(QLatin1Char('\x1e')); // Record Separator + const QStringList files = split(filesArg); for (const auto &file : files) { auto data = FileData::get(file); @@ -903,6 +958,22 @@ void SocketApi::command_MOVE_ITEM(const QString &localFile, SocketListener *) solver.setRemoteVersionFilename(target); } +void SocketApi::command_V2_LIST_ACCOUNTS(const QSharedPointer &job) const +{ + QJsonArray out; + for (auto acc : AccountManager::instance()->accounts()) { + // TODO: Use uuid once https://github.com/owncloud/client/pull/8397 is merged + out << QJsonObject({ { "name", acc->account()->displayName() }, { "id", acc->account()->id() } }); + } + job->success({ { "accounts", out } }); +} + +void SocketApi::command_V2_UPLOAD_FILES_FROM(const QSharedPointer &job) const +{ + auto uploadJob = new SocketUploadJob(job); + uploadJob->start(); +} + void SocketApi::emailPrivateLink(const QString &link) { Utility::openEmailComposer( @@ -918,12 +989,13 @@ void OCC::SocketApi::openPrivateLink(const QString &link) void SocketApi::command_GET_STRINGS(const QString &argument, SocketListener *listener) { - static std::array, 5> strings { { + static std::array, 6> strings { { { "SHARE_MENU_TITLE", tr("Share options") }, + { "FILE_ACTIVITY_MENU_TITLE", tr("Activity") }, { "CONTEXT_MENU_TITLE", Theme::instance()->appNameGUI() }, { "COPY_PRIVATE_LINK_MENU_TITLE", tr("Copy private link to clipboard") }, { "EMAIL_PRIVATE_LINK_MENU_TITLE", tr("Send private link by email …") }, - { "CONTEXT_MENU_ICON", APPLICATION_ICON_NAME}, + { "CONTEXT_MENU_ICON", APPLICATION_ICON_NAME }, } }; listener->sendMessage(QString("GET_STRINGS:BEGIN")); for (const auto& key_value : strings) { @@ -948,8 +1020,7 @@ void SocketApi::sendSharingContextMenuOptions(const FileData &fileData, SocketLi // If sharing is globally disabled, do not show any sharing entries. // If there is no permission to share for this file, add a disabled entry saying so if (isOnTheServer && !record._remotePerm.isNull() && !record._remotePerm.hasPermission(RemotePermissions::CanReshare)) { - listener->sendMessage(QLatin1String("MENU_ITEM:DISABLED:d:") + (!record.isDirectory() - ? tr("Resharing this file is not allowed") : tr("Resharing this folder is not allowed"))); + listener->sendMessage(QLatin1String("MENU_ITEM:DISABLED:d:") + (!record.isDirectory() ? tr("Resharing this file is not allowed") : tr("Resharing this folder is not allowed"))); } else { listener->sendMessage(QLatin1String("MENU_ITEM:SHARE") + flagString + tr("Share options")); @@ -1031,7 +1102,7 @@ SocketApi::FileData SocketApi::FileData::parentFolder() const void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListener *listener) { listener->sendMessage(QString("GET_MENU_ITEMS:BEGIN")); - QStringList files = argument.split(QLatin1Char('\x1e')); // Record Separator + const QStringList files = split(argument); // Find the common sync folder. // syncFolder will be null if files are in different folders. @@ -1061,6 +1132,11 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe const auto isE2eEncryptedPath = fileData.journalRecord()._isE2eEncrypted || !fileData.journalRecord()._e2eMangledName.isEmpty(); auto flagString = isOnTheServer && !isE2eEncryptedPath ? QLatin1String("::") : QLatin1String(":d:"); + const QFileInfo fileInfo(fileData.localPath); + if (!fileInfo.isDir()) { + listener->sendMessage(QLatin1String("MENU_ITEM:ACTIVITY") + flagString + tr("Activity")); + } + DirectEditor* editor = getDirectEditorForLocalFile(fileData.localPath); if (editor) { //listener->sendMessage(QLatin1String("MENU_ITEM:EDIT") + flagString + tr("Edit via ") + editor->name()); @@ -1075,7 +1151,6 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe bool isConflict = Utility::isConflictFile(fileData.folderRelativePath); if (isConflict || !isOnTheServer) { // Check whether this new file is in a read-only directory - QFileInfo fileInfo(fileData.localPath); const auto parentDir = fileData.parentFolder(); const auto parentRecord = parentDir.journalRecord(); const bool canAddToDir = @@ -1149,13 +1224,13 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe // TODO: Should be a submenu, should use icons auto makePinContextMenu = [&](bool makeAvailableLocally, bool freeSpace) { listener->sendMessage(QLatin1String("MENU_ITEM:CURRENT_PIN:d:") - + Utility::vfsCurrentAvailabilityText(*combined)); + + Utility::vfsCurrentAvailabilityText(*combined)); listener->sendMessage(QLatin1String("MENU_ITEM:MAKE_AVAILABLE_LOCALLY:") - + (makeAvailableLocally ? QLatin1String(":") : QLatin1String("d:")) - + Utility::vfsPinActionText()); + + (makeAvailableLocally ? QLatin1String(":") : QLatin1String("d:")) + + Utility::vfsPinActionText()); listener->sendMessage(QLatin1String("MENU_ITEM:MAKE_ONLINE_ONLY:") - + (freeSpace ? QLatin1String(":") : QLatin1String("d:")) - + Utility::vfsFreeSpaceActionText()); + + (freeSpace ? QLatin1String(":") : QLatin1String("d:")) + + Utility::vfsFreeSpaceActionText()); }; if (combined) { @@ -1241,20 +1316,20 @@ void SocketApi::command_ASYNC_GET_WIDGET_PROPERTY(const QSharedPointerproperty(segment.toUtf8().constData()); - if(var.canConvert()) { + if (var.canConvert()) { var.convert(QMetaType::QString); value = var.value(); break; } - auto tmpObject = var.value(); - if(tmpObject) { + auto tmpObject = var.value(); + if (tmpObject) { currentObject = tmpObject; } else { QString message = QString(QLatin1String("Widget not found: 3: %1")).arg(widgetName); @@ -1277,7 +1352,7 @@ void SocketApi::command_ASYNC_SET_WIDGET_PROPERTY(const QSharedPointersetProperty(arguments["property"].toString().toUtf8().constData(), - arguments["value"]); + arguments["value"]); job->resolve(); } @@ -1345,20 +1420,20 @@ void SocketApi::command_ASYNC_ASSERT_ICON_IS_EQUAL(const QSharedPointerproperty(segment.toUtf8().constData()); - if(var.canConvert()) { + if (var.canConvert()) { var.convert(QMetaType::QIcon); value = var.value(); break; } - auto tmpObject = var.value(); - if(tmpObject) { + auto tmpObject = var.value(); + if (tmpObject) { currentObject = tmpObject; } else { job->reject(QString(QLatin1String("Icon not found: %1")).arg(propertyName)); @@ -1366,12 +1441,11 @@ void SocketApi::command_ASYNC_ASSERT_ICON_IS_EQUAL(const QSharedPointerarguments()[QLatin1String("iconName")].toString(); - if (value.name() == iconName) { + if (value.name() == iconName) { job->resolve(); } else { job->reject("iconName " + iconName + " does not match: " + value.name()); } - } #endif @@ -1383,6 +1457,46 @@ QString SocketApi::buildRegisterPathMessage(const QString &path) return message; } +void SocketApiJob::resolve(const QString &response) +{ + _socketListener->sendMessage(QStringLiteral("RESOLVE|") + _jobId + QLatin1Char('|') + response); +} + +void SocketApiJob::resolve(const QJsonObject &response) +{ + resolve(QJsonDocument { response }.toJson()); +} + +void SocketApiJob::reject(const QString &response) +{ + _socketListener->sendMessage(QStringLiteral("REJECT|") + _jobId + QLatin1Char('|') + response); +} + +SocketApiJobV2::SocketApiJobV2(const QSharedPointer &socketListener, const QByteArray &command, const QJsonObject &arguments) + : _socketListener(socketListener) + , _command(command) + , _jobId(arguments[QStringLiteral("id")].toString()) + , _arguments(arguments[QStringLiteral("arguments")].toObject()) +{ + ASSERT(!_jobId.isEmpty()) +} + +void SocketApiJobV2::success(const QJsonObject &response) const +{ + doFinish(response); +} + +void SocketApiJobV2::failure(const QString &error) const +{ + doFinish({ { QStringLiteral("error"), error } }); +} + +void SocketApiJobV2::doFinish(const QJsonObject &obj) const +{ + _socketListener->sendMessage(_command + QStringLiteral("_RESULT:") + QJsonDocument({ { QStringLiteral("id"), _jobId }, { QStringLiteral("arguments"), obj } }).toJson(QJsonDocument::Compact)); + Q_EMIT finished(); +} + } // namespace OCC #include "socketapi.moc" diff --git a/src/gui/socketapi.h b/src/gui/socketapi/socketapi.h similarity index 92% rename from src/gui/socketapi.h rename to src/gui/socketapi/socketapi.h index 1c2ef49f72d4..5183985b5811 100644 --- a/src/gui/socketapi.h +++ b/src/gui/socketapi/socketapi.h @@ -40,6 +40,7 @@ class Folder; class SocketListener; class DirectEditor; class SocketApiJob; +class SocketApiJobV2; Q_DECLARE_LOGGING_CATEGORY(lcSocketApi) @@ -53,7 +54,7 @@ class SocketApi : public QObject public: explicit SocketApi(QObject *parent = nullptr); - virtual ~SocketApi(); + ~SocketApi() override; public slots: void slotUpdateFolderView(Folder *f); @@ -63,6 +64,7 @@ public slots: signals: void shareCommandReceived(const QString &sharePath, const QString &localPath, ShareDialogStartPage startPage); + void fileActivityCommandReceived(const QString &sharePath, const QString &localPath); private slots: void slotNewConnection(); @@ -101,6 +103,7 @@ private slots: // opens share dialog, sends reply void processShareRequest(const QString &localFile, SocketListener *listener, ShareDialogStartPage startPage); + void processFileActivityRequest(const QString &localFile); Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString &argument, SocketListener *listener); Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString &argument, SocketListener *listener); @@ -110,6 +113,7 @@ private slots: Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString &argument, SocketListener *listener); // The context menu actions + Q_INVOKABLE void command_ACTIVITY(const QString &localFile, SocketListener *listener); Q_INVOKABLE void command_SHARE(const QString &localFile, SocketListener *listener); Q_INVOKABLE void command_MANAGE_PUBLIC_LINKS(const QString &localFile, SocketListener *listener); Q_INVOKABLE void command_COPY_PUBLIC_LINK(const QString &localFile, SocketListener *listener); @@ -129,6 +133,10 @@ private slots: Q_INVOKABLE void command_OPEN(const QString &localFile, SocketListener *listener); #endif + // External sync + Q_INVOKABLE void command_V2_LIST_ACCOUNTS(const QSharedPointer &job) const; + Q_INVOKABLE void command_V2_UPLOAD_FILES_FROM(const QSharedPointer &job) const; + // Fetch the private link and call targetFun void fetchPrivateLinkUrlHelper(const QString &localFile, const std::function &targetFun); @@ -164,7 +172,7 @@ private slots: QString buildRegisterPathMessage(const QString &path); QSet _registeredAliases; - QList _listeners; + QMap> _listeners; SocketApiServer _localServer; }; } diff --git a/src/gui/socketapi_p.h b/src/gui/socketapi/socketapi_p.h similarity index 69% rename from src/gui/socketapi_p.h rename to src/gui/socketapi/socketapi_p.h index da3e90b9c19b..91724d6da16d 100644 --- a/src/gui/socketapi_p.h +++ b/src/gui/socketapi/socketapi_p.h @@ -62,12 +62,20 @@ class SocketListener public: QPointer socket; - explicit SocketListener(QIODevice *socket) - : socket(socket) + explicit SocketListener(QIODevice *_socket) + : socket(_socket) { } void sendMessage(const QString &message, bool doWait = false) const; + void sendWarning(const QString &message, bool doWait = false) const + { + sendMessage(QStringLiteral("WARNING:") + message, doWait); + } + void sendError(const QString &message, bool doWait = false) const + { + sendMessage(QStringLiteral("ERROR:") + message, doWait); + } void sendMessageIfDirectoryMonitored(const QString &message, uint systemDirectoryHash) const { @@ -109,30 +117,48 @@ class SocketApiJob : public QObject { Q_OBJECT public: - SocketApiJob(const QString &jobId, SocketListener *socketListener, const QJsonObject &arguments) + explicit SocketApiJob(const QString &jobId, const QSharedPointer &socketListener, const QJsonObject &arguments) : _jobId(jobId) , _socketListener(socketListener) , _arguments(arguments) { } - void resolve(const QString &response = QString()) - { - _socketListener->sendMessage(QLatin1String("RESOLVE|") + _jobId + '|' + response); - } + void resolve(const QString &response = QString()); - void resolve(const QJsonObject &response) { resolve(QJsonDocument{ response }.toJson()); } + void resolve(const QJsonObject &response); const QJsonObject &arguments() { return _arguments; } - void reject(const QString &response) - { - _socketListener->sendMessage(QLatin1String("REJECT|") + _jobId + '|' + response); - } + void reject(const QString &response); + +protected: + QString _jobId; + QSharedPointer _socketListener; + QJsonObject _arguments; +}; + +class SocketApiJobV2 : public QObject +{ + Q_OBJECT +public: + explicit SocketApiJobV2(const QSharedPointer &socketListener, const QByteArray &command, const QJsonObject &arguments); + + void success(const QJsonObject &response) const; + void failure(const QString &error) const; + + const QJsonObject &arguments() const { return _arguments; } + QByteArray command() const { return _command; } + +Q_SIGNALS: + void finished() const; private: + void doFinish(const QJsonObject &obj) const; + + QSharedPointer _socketListener; + const QByteArray _command; QString _jobId; - SocketListener *_socketListener; QJsonObject _arguments; }; } diff --git a/src/gui/socketapisocket_mac.h b/src/gui/socketapi/socketapisocket_mac.h similarity index 100% rename from src/gui/socketapisocket_mac.h rename to src/gui/socketapi/socketapisocket_mac.h diff --git a/src/gui/socketapisocket_mac.mm b/src/gui/socketapi/socketapisocket_mac.mm similarity index 87% rename from src/gui/socketapisocket_mac.mm rename to src/gui/socketapi/socketapisocket_mac.mm index f018ac752b63..926c34d8a6da 100644 --- a/src/gui/socketapisocket_mac.mm +++ b/src/gui/socketapi/socketapisocket_mac.mm @@ -16,7 +16,7 @@ #import @protocol ChannelProtocol -- (void)sendMessage:(NSData*)msg; +- (void)sendMessage:(NSData *)msg; @end @protocol RemoteEndProtocol @@ -31,7 +31,7 @@ - (instancetype)initWithWrapper:(SocketApiSocketPrivate *)wrapper; @interface Server : NSObject @property SocketApiServerPrivate *wrapper; - (instancetype)initWithWrapper:(SocketApiServerPrivate *)wrapper; -- (void)registerClient:(NSDistantObject *)remoteEnd; +- (void)registerClient:(NSDistantObject *)remoteEnd; @end class SocketApiSocketPrivate @@ -39,13 +39,13 @@ - (void)registerClient:(NSDistantObject *)remoteEnd; public: SocketApiSocket *q_ptr; - SocketApiSocketPrivate(NSDistantObject *remoteEnd); + SocketApiSocketPrivate(NSDistantObject *remoteEnd); ~SocketApiSocketPrivate(); // release remoteEnd void disconnectRemote(); - NSDistantObject *remoteEnd; + NSDistantObject *remoteEnd; LocalEnd *localEnd; QByteArray inBuffer; bool isRemoteDisconnected = false; @@ -59,7 +59,7 @@ - (void)registerClient:(NSDistantObject *)remoteEnd; SocketApiServerPrivate(); ~SocketApiServerPrivate(); - QList pendingConnections; + QList pendingConnections; NSConnection *connection; Server *server; }; @@ -73,7 +73,7 @@ - (instancetype)initWithWrapper:(SocketApiSocketPrivate *)wrapper return self; } -- (void)sendMessage:(NSData*)msg +- (void)sendMessage:(NSData *)msg { if (_wrapper) { _wrapper->inBuffer += QByteArray::fromRawNSData(msg); @@ -81,7 +81,7 @@ - (void)sendMessage:(NSData*)msg } } -- (void)connectionDidDie:(NSNotification*)notification +- (void)connectionDidDie:(NSNotification *)notification { #pragma unused(notification) if (_wrapper) { @@ -99,7 +99,7 @@ - (instancetype)initWithWrapper:(SocketApiServerPrivate *)wrapper return self; } -- (void)registerClient:(NSDistantObject *)remoteEnd +- (void)registerClient:(NSDistantObject *)remoteEnd { // This saves a few mach messages that would otherwise be needed to query the interface [remoteEnd setProtocolForProxy:@protocol(RemoteEndProtocol)]; @@ -150,7 +150,7 @@ - (void)registerClient:(NSDistantObject *)remoteEnd // Since FinderSync already runs in a separate process, blocking isn't too critical. [d->remoteEnd sendMessage:[NSData dataWithBytesNoCopy:const_cast(data) length:len freeWhenDone:NO]]; return len; - } @catch(NSException* e) { + } @catch (NSException *e) { // connectionDidDie can be notified too late, also interpret any sending exception as a disconnection. d->disconnectRemote(); emit disconnected(); @@ -170,16 +170,16 @@ - (void)registerClient:(NSDistantObject *)remoteEnd return d->inBuffer.indexOf('\n', int(pos())) != -1 || QIODevice::canReadLine(); } -SocketApiSocketPrivate::SocketApiSocketPrivate(NSDistantObject *remoteEnd) +SocketApiSocketPrivate::SocketApiSocketPrivate(NSDistantObject *remoteEnd) : remoteEnd(remoteEnd) , localEnd([[LocalEnd alloc] initWithWrapper:this]) { [remoteEnd retain]; // (Ab)use our objective-c object just to catch the notification [[NSNotificationCenter defaultCenter] addObserver:localEnd - selector:@selector(connectionDidDie:) - name:NSConnectionDidDieNotification - object:[remoteEnd connectionForProxy]]; + selector:@selector(connectionDidDie:) + name:NSConnectionDidDieNotification + object:[remoteEnd connectionForProxy]]; } SocketApiSocketPrivate::~SocketApiSocketPrivate() diff --git a/src/gui/socketapi/socketuploadjob.cpp b/src/gui/socketapi/socketuploadjob.cpp new file mode 100644 index 000000000000..467a46973e30 --- /dev/null +++ b/src/gui/socketapi/socketuploadjob.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) by Hannah von Reth + * + * 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 "socketuploadjob.h" +#include "socketapi_p.h" + +#include "accountmanager.h" +#include "common/syncjournaldb.h" +#include "syncengine.h" + +#include +#include +#include + +using namespace OCC; + +SocketUploadJob::SocketUploadJob(const QSharedPointer &job) + : _apiJob(job) +{ + connect(job.data(), &SocketApiJobV2::finished, this, &SocketUploadJob::deleteLater); + + _localPath = _apiJob->arguments()[QLatin1String("localPath")].toString(); + _remotePath = _apiJob->arguments()[QLatin1String("remotePath")].toString(); + if (!_remotePath.startsWith(QLatin1Char('/'))) { + _remotePath = QLatin1Char('/') + _remotePath; + } + + _pattern = job->arguments()[QLatin1String("pattern")].toString(); + // TODO: use uuid + const auto accname = job->arguments()[QLatin1String("account")][QLatin1String("name")].toString(); + auto account = AccountManager::instance()->account(accname); + + if (!QFileInfo(_localPath).isAbsolute()) { + job->failure(QStringLiteral("Local path must be a an absolute path")); + return; + } + if (!_tmp.open()) { + job->failure(QStringLiteral("Failed to create temporary database")); + return; + } + + _db = new SyncJournalDb(_tmp.fileName(), this); + _engine = new SyncEngine(account->account(), _localPath.endsWith(QLatin1Char('/')) ? _localPath : _localPath + QLatin1Char('/'), _remotePath, _db); + _engine->setParent(_db); + + connect(_engine, &OCC::SyncEngine::itemCompleted, this, [this](const OCC::SyncFileItemPtr item) { + _syncedFiles.append(item->_file); + }); + + connect(_engine, &OCC::SyncEngine::finished, this, [this](bool ok) { + if (ok) { + _apiJob->success({ { "localPath", _localPath }, { "syncedFiles", QJsonArray::fromStringList(_syncedFiles) } }); + } + }); + connect(_engine, &OCC::SyncEngine::syncError, this, [this](const QString &error, ErrorCategory) { + _apiJob->failure(error); + }); +} + +void SocketUploadJob::start() +{ + auto opt = _engine->syncOptions(); + opt.setFilePattern(_pattern); + if (!opt.fileRegex().isValid()) { + _apiJob->failure(opt.fileRegex().errorString()); + return; + } + _engine->setSyncOptions(opt); + + // create the dir, fail if it already exists + auto mkdir = new OCC::MkColJob(_engine->account(), _remotePath); + connect(mkdir, &OCC::MkColJob::finishedWithoutError, _engine, &OCC::SyncEngine::startSync); + connect(mkdir, &OCC::MkColJob::finishedWithError, this, [this](QNetworkReply *reply) { + if (reply->error() == 202) { + _apiJob->failure(QStringLiteral("Destination %1 already exists").arg(_remotePath)); + } else { + _apiJob->failure(reply->errorString()); + } + }); + mkdir->start(); +} diff --git a/src/gui/socketapi/socketuploadjob.h b/src/gui/socketapi/socketuploadjob.h new file mode 100644 index 000000000000..3b04061d385d --- /dev/null +++ b/src/gui/socketapi/socketuploadjob.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) by Hannah von Reth + * + * 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. + */ + +#pragma once +#include +#include + +#include "socketapi.h" +#include "account.h" + +namespace OCC { + +class SyncJournalDb; +class SyncEngine; + +class SocketUploadJob : public QObject +{ + Q_OBJECT +public: + SocketUploadJob(const QSharedPointer &job); + void start(); + +private: + QSharedPointer _apiJob; + QString _localPath; + QString _remotePath; + QString _pattern; + QTemporaryFile _tmp; + SyncJournalDb *_db; + SyncEngine *_engine; + QStringList _syncedFiles; +}; +} diff --git a/src/gui/sslerrordialog.cpp b/src/gui/sslerrordialog.cpp index 5c148dc85881..7b97a657a6c0 100644 --- a/src/gui/sslerrordialog.cpp +++ b/src/gui/sslerrordialog.cpp @@ -13,6 +13,7 @@ */ #include "configfile.h" #include "sslerrordialog.h" +#include "theme.h" #include #include @@ -68,6 +69,8 @@ SslErrorDialog::SslErrorDialog(AccountPtr account, QWidget *parent) QPushButton *cancelButton = _ui->_dialogButtonBox->button(QDialogButtonBox::Cancel); okButton->setEnabled(false); + + _ui->_cbTrustConnect->setEnabled(!Theme::instance()->forbidBadSSL()); connect(_ui->_cbTrustConnect, &QAbstractButton::clicked, okButton, &QWidget::setEnabled); @@ -105,6 +108,8 @@ bool SslErrorDialog::checkFailingCertsKnown(const QList &errors) QStringList errorStrings; + QStringList additionalErrorStrings; + QList trustedCerts = _account->approvedCerts(); for (int i = 0; i < errors.count(); ++i) { @@ -115,6 +120,8 @@ bool SslErrorDialog::checkFailingCertsKnown(const QList &errors) errorStrings += error.errorString(); if (!error.certificate().isNull()) { _unknownCerts.append(error.certificate()); + } else { + additionalErrorStrings.append(error.errorString()); } } @@ -146,6 +153,17 @@ bool SslErrorDialog::checkFailingCertsKnown(const QList &errors) msg += QL("
"); } } + + if (!additionalErrorStrings.isEmpty()) { + msg += QL("

") + tr("Additional errors:") + QL("

"); + + for (const auto &errorString : additionalErrorStrings) { + msg += QL("
"); + msg += QL("

") + errorString + QL("

"); + msg += QL("
"); + } + } + msg += QL(""); auto *doc = new QTextDocument(nullptr); diff --git a/src/gui/sslerrordialog.h b/src/gui/sslerrordialog.h index 0ef1d3e5a975..3275732609d7 100644 --- a/src/gui/sslerrordialog.h +++ b/src/gui/sslerrordialog.h @@ -49,7 +49,7 @@ class SslErrorDialog : public QDialog Q_OBJECT public: explicit SslErrorDialog(AccountPtr account, QWidget *parent = nullptr); - ~SslErrorDialog(); + ~SslErrorDialog() override; bool checkFailingCertsKnown(const QList &errors); bool trustConnection(); QList unknownCerts() const { return _unknownCerts; } diff --git a/src/gui/syncrunfilelog.cpp b/src/gui/syncrunfilelog.cpp index cb10cef8c7b8..6f75f53cefbf 100644 --- a/src/gui/syncrunfilelog.cpp +++ b/src/gui/syncrunfilelog.cpp @@ -12,7 +12,7 @@ * for more details. */ -#include +#include #include "syncrunfilelog.h" #include "common/utility.h" @@ -104,9 +104,10 @@ void SyncRunFileLog::logItem(const SyncFileItem &item) } QString ts = QString::fromLatin1(item._responseTimeStamp); if (ts.length() > 6) { - QRegExp rx(R"((\d\d:\d\d:\d\d))"); - if (ts.contains(rx)) { - ts = rx.cap(0); + const QRegularExpression rx(R"((\d\d:\d\d:\d\d))"); + const auto rxMatch = rx.match(ts); + if (rxMatch.hasMatch()) { + ts = rxMatch.captured(0); } } diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp index 1f4760b355d4..ed9ed0a71d59 100644 --- a/src/gui/systray.cpp +++ b/src/gui/systray.cpp @@ -17,7 +17,9 @@ #include "theme.h" #include "config.h" #include "common/utility.h" -#include "tray/UserModel.h" +#include "tray/svgimageprovider.h" +#include "tray/usermodel.h" +#include "tray/unifiedsearchresultimageprovider.h" #include "configfile.h" #include @@ -58,6 +60,8 @@ void Systray::setTrayEngine(QQmlApplicationEngine *trayEngine) _trayEngine->addImportPath("qrc:/qml/theme"); _trayEngine->addImageProvider("avatars", new ImageProvider); + _trayEngine->addImageProvider(QLatin1String("svgimage-custom-color"), new OCC::Ui::SvgImageProvider); + _trayEngine->addImageProvider(QLatin1String("unified-search-result-icon"), new UnifiedSearchResultImageProvider); } Systray::Systray() diff --git a/src/gui/systray.h b/src/gui/systray.h index af3739485f54..70917aaabbdc 100644 --- a/src/gui/systray.h +++ b/src/gui/systray.h @@ -18,7 +18,7 @@ #include #include "accountmanager.h" -#include "tray/UserModel.h" +#include "tray/usermodel.h" class QScreen; class QQmlApplicationEngine; @@ -48,7 +48,7 @@ class Systray public: static Systray *instance(); - virtual ~Systray() = default; + ~Systray() override = default; enum class TaskBarPosition { Bottom, Left, Top, Right }; Q_ENUM(TaskBarPosition); @@ -79,6 +79,7 @@ class Systray void hideWindow(); void showWindow(); void openShareDialog(const QString &sharePath, const QString &localPath); + void showFileActivityDialog(const QString &sharePath, const QString &localPath); public slots: void slotNewUserSelected(); diff --git a/src/gui/tray/ActivityItem.qml b/src/gui/tray/ActivityItem.qml index 27bc435e7430..ed85ed9ea79a 100644 --- a/src/gui/tray/ActivityItem.qml +++ b/src/gui/tray/ActivityItem.qml @@ -7,12 +7,17 @@ import com.nextcloud.desktopclient 1.0 MouseArea { id: activityMouseArea + + readonly property int maxActionButtons: 2 + property Flickable flickable + + signal fileActivityButtonClicked(string absolutePath) + enabled: (path !== "" || link !== "") hoverEnabled: true - + Rectangle { anchors.fill: parent - anchors.margins: 2 color: (parent.containsMouse ? Style.lightHover : "transparent") } @@ -35,7 +40,7 @@ MouseArea { Image { id: activityIcon Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter - Layout.leftMargin: 8 + Layout.leftMargin: 20 Layout.preferredWidth: shareButton.icon.width Layout.preferredHeight: shareButton.icon.height verticalAlignment: Qt.AlignCenter @@ -47,13 +52,12 @@ MouseArea { Column { id: activityTextColumn - Layout.leftMargin: 8 + Layout.leftMargin: 14 Layout.topMargin: 4 Layout.bottomMargin: 4 Layout.fillWidth: true - Layout.fillHeight: true spacing: 4 - Layout.alignment: Qt.AlignLeft + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter Text { id: activityTextTitle @@ -106,7 +110,7 @@ MouseArea { } Repeater { - model: activityItem.links.length > activityListView.maxActionButtons ? 1 : activityItem.links.length + model: activityItem.links.length > maxActionButtons ? 1 : activityItem.links.length ActivityActionButton { id: activityActionButton @@ -139,6 +143,31 @@ MouseArea { } } + + Button { + id: shareButton + + Layout.preferredWidth: parent.height + Layout.fillHeight: true + Layout.alignment: Qt.AlignRight + flat: true + hoverEnabled: true + visible: displayActions && (path !== "") + 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 @@ -149,7 +178,7 @@ MouseArea { flat: true hoverEnabled: true - visible: activityItem.links.length > activityListView.maxActionButtons + visible: displayActions && ((path !== "") || (activityItem.links.length > maxActionButtons)) display: AbstractButton.IconOnly icon.source: "qrc:///client/theme/more.svg" icon.color: "transparent" @@ -157,7 +186,7 @@ MouseArea { color: parent.hovered ? Style.lightHover : "transparent" } ToolTip.visible: hovered - ToolTip.delay: 1000 + ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval ToolTip.text: qsTr("Show more actions") Accessible.role: Accessible.Button @@ -167,18 +196,9 @@ MouseArea { onClicked: moreActionsButtonContextMenu.popup(); Connections { - target: trayWindow - onActiveChanged: { - if (!trayWindow.active) { - moreActionsButtonContextMenu.close(); - } - } - } - - Connections { - target: activityListView + target: flickable - onMovementStarted: { + function onMovementStarted() { moreActionsButtonContextMenu.close(); } } @@ -199,7 +219,7 @@ MouseArea { // transform model to contain indexed actions with primary action filtered out function actionListToContextMenuList(actionList) { // early out with non-altered data - if (activityItem.links.length <= activityListView.maxActionButtons) { + if (activityItem.links.length <= maxActionButtons) { return actionList; } @@ -215,6 +235,11 @@ MouseArea { return reducedActionList; } + + MenuItem { + text: qsTr("View activity") + onClicked: fileActivityButtonClicked(absolutePath) + } Repeater { id: moreActionsButtonContextMenuRepeater @@ -230,31 +255,6 @@ MouseArea { } } } - - Button { - id: shareButton - - Layout.preferredWidth: (path === "") ? 0 : parent.height - Layout.preferredHeight: parent.height - Layout.alignment: Qt.AlignRight - flat: true - hoverEnabled: true - visible: (path === "") ? false : true - 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: 1000 - 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() - } } } } diff --git a/src/gui/tray/ActivityList.qml b/src/gui/tray/ActivityList.qml new file mode 100644 index 000000000000..dc3528af954e --- /dev/null +++ b/src/gui/tray/ActivityList.qml @@ -0,0 +1,36 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +import Style 1.0 + +import com.nextcloud.desktopclient 1.0 as NC + +ScrollView { + property alias model: activityList.model + + signal showFileActivity(string displayPath, string absolutePath) + signal activityItemClicked(int index) + + contentWidth: availableWidth + + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + ListView { + id: activityList + + keyNavigationEnabled: true + + Accessible.role: Accessible.List + Accessible.name: qsTr("Activity list") + + clip: true + + delegate: ActivityItem { + width: activityList.contentWidth + height: Style.trayWindowHeaderHeight + flickable: activityList + onClicked: activityItemClicked(model.index) + onFileActivityButtonClicked: showFileActivity(displayPath, absolutePath) + } + } +} diff --git a/src/gui/tray/AutoSizingMenu.qml b/src/gui/tray/AutoSizingMenu.qml new file mode 100644 index 000000000000..fe929eb3c1f9 --- /dev/null +++ b/src/gui/tray/AutoSizingMenu.qml @@ -0,0 +1,15 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.3 + +Menu { + width: { + var result = 0; + var padding = 0; + for (var i = 0; i < count; ++i) { + var item = itemAt(i); + result = Math.max(item.contentItem.implicitWidth, result); + padding = Math.max(item.padding, padding); + } + return result + padding * 2; + } +} diff --git a/src/gui/tray/FileActivityDialog.qml b/src/gui/tray/FileActivityDialog.qml new file mode 100644 index 000000000000..7fcd653d1c10 --- /dev/null +++ b/src/gui/tray/FileActivityDialog.qml @@ -0,0 +1,21 @@ +import QtQuick.Window 2.15 + +import com.nextcloud.desktopclient 1.0 as NC + +Window { + id: dialog + + property alias model: activityModel + + NC.FileActivityListModel { + id: activityModel + } + + width: 500 + height: 500 + + ActivityList { + anchors.fill: parent + model: dialog.model + } +} diff --git a/src/gui/tray/SyncStatus.qml b/src/gui/tray/SyncStatus.qml new file mode 100644 index 000000000000..7bf9a2d5520e --- /dev/null +++ b/src/gui/tray/SyncStatus.qml @@ -0,0 +1,89 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import Style 1.0 + +import com.nextcloud.desktopclient 1.0 as NC + +RowLayout { + id: layout + + property alias model: syncStatus + + spacing: 0 + + NC.SyncStatusSummary { + id: syncStatus + } + + Image { + id: syncIcon + + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter + Layout.topMargin: 16 + Layout.bottomMargin: 16 + Layout.leftMargin: 16 + + source: syncStatus.syncIcon + sourceSize.width: 32 + sourceSize.height: 32 + rotation: syncStatus.syncing ? 0 : 0 + } + + RotationAnimator { + target: syncIcon + running: syncStatus.syncing + from: 0 + to: 360 + loops: Animation.Infinite + duration: 3000 + } + + ColumnLayout { + id: syncProgressLayout + + Layout.alignment: Qt.AlignVCenter + Layout.topMargin: 8 + Layout.rightMargin: 16 + Layout.leftMargin: 10 + Layout.bottomMargin: 8 + Layout.fillWidth: true + Layout.fillHeight: true + + Text { + id: syncProgressText + + Layout.fillWidth: true + + text: syncStatus.syncStatusString + verticalAlignment: Text.AlignVCenter + font.pixelSize: Style.topLinePixelSize + font.bold: true + } + + Loader { + Layout.fillWidth: true + + active: syncStatus.syncing; + visible: syncStatus.syncing + + sourceComponent: ProgressBar { + id: syncProgressBar + + value: syncStatus.syncProgress + } + } + + Text { + id: syncProgressDetailText + + Layout.fillWidth: true + + text: syncStatus.syncStatusDetailString + visible: syncStatus.syncStatusDetailString !== "" + color: "#808080" + font.pixelSize: Style.subLinePixelSize + } + } +} diff --git a/src/gui/tray/UnifiedSearchInputContainer.qml b/src/gui/tray/UnifiedSearchInputContainer.qml new file mode 100644 index 000000000000..2edbfbac6071 --- /dev/null +++ b/src/gui/tray/UnifiedSearchInputContainer.qml @@ -0,0 +1,93 @@ +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.3 +import QtGraphicalEffects 1.0 +import Style 1.0 + +TextField { + id: trayWindowUnifiedSearchTextField + + property bool isSearchInProgress: false + + readonly property color textFieldIconsColor: Style.menuBorder + + readonly property int textFieldIconsOffset: 10 + + readonly property double textFieldIconsScaleFactor: 0.6 + + readonly property int textFieldHorizontalPaddingOffset: 14 + + signal clearText() + + leftPadding: trayWindowUnifiedSearchTextFieldSearchIcon.width + trayWindowUnifiedSearchTextFieldSearchIcon.anchors.leftMargin + textFieldHorizontalPaddingOffset + rightPadding: trayWindowUnifiedSearchTextFieldClearTextButton.width + trayWindowUnifiedSearchTextFieldClearTextButton.anchors.rightMargin + textFieldHorizontalPaddingOffset + + placeholderText: qsTr("Search files, messages, events …") + + selectByMouse: true + + background: Rectangle { + radius: 5 + border.color: parent.activeFocus ? Style.ncBlue : Style.menuBorder + border.width: 1 + } + + Image { + id: trayWindowUnifiedSearchTextFieldSearchIcon + + anchors { + left: parent.left + leftMargin: parent.textFieldIconsOffset + verticalCenter: parent.verticalCenter + } + + visible: !trayWindowUnifiedSearchTextField.isSearchInProgress + + smooth: true; + antialiasing: true + mipmap: true + source: "image://svgimage-custom-color/search.svg" + "/" + trayWindowUnifiedSearchTextField.textFieldIconsColor + sourceSize: Qt.size(parent.height * parent.textFieldIconsScaleFactor, parent.height * parent.textFieldIconsScaleFactor) + } + + BusyIndicator { + id: trayWindowUnifiedSearchTextFieldIconInProgress + running: visible + visible: trayWindowUnifiedSearchTextField.isSearchInProgress + anchors { + left: trayWindowUnifiedSearchTextField.left + bottom: trayWindowUnifiedSearchTextField.bottom + leftMargin: trayWindowUnifiedSearchTextField.textFieldIconsOffset - 4 + topMargin: 4 + bottomMargin: 4 + verticalCenter: trayWindowUnifiedSearchTextField.verticalCenter + } + width: height + } + + Image { + id: trayWindowUnifiedSearchTextFieldClearTextButton + + anchors { + right: parent.right + rightMargin: parent.textFieldIconsOffset + verticalCenter: parent.verticalCenter + } + + smooth: true; + antialiasing: true + mipmap: true + + visible: parent.text + source: "image://svgimage-custom-color/clear.svg" + "/" + trayWindowUnifiedSearchTextField.textFieldIconsColor + sourceSize: Qt.size(parent.height * parent.textFieldIconsScaleFactor, parent.height * parent.textFieldIconsScaleFactor) + + MouseArea { + id: trayWindowUnifiedSearchTextFieldClearTextButtonMouseArea + + anchors.fill: parent + + onClicked: trayWindowUnifiedSearchTextField.clearText() + } + } +} diff --git a/src/gui/tray/UnifiedSearchResultFetchMoreTrigger.qml b/src/gui/tray/UnifiedSearchResultFetchMoreTrigger.qml new file mode 100644 index 000000000000..1af2d42ca7b8 --- /dev/null +++ b/src/gui/tray/UnifiedSearchResultFetchMoreTrigger.qml @@ -0,0 +1,42 @@ +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.2 +import Style 1.0 + +ColumnLayout { + id: unifiedSearchResultItemFetchMore + + property bool isFetchMoreInProgress: false + + property bool isWihinViewPort: false + + property int fontSize: Style.topLinePixelSize + + property string textColor: "grey" + + Accessible.role: Accessible.ListItem + Accessible.name: unifiedSearchResultItemFetchMoreText.text + Accessible.onPressAction: unifiedSearchResultMouseArea.clicked() + + Label { + id: unifiedSearchResultItemFetchMoreText + text: qsTr("Load more results") + visible: !unifiedSearchResultItemFetchMore.isFetchMoreInProgress + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + Layout.fillWidth: true + Layout.fillHeight: true + font.pixelSize: unifiedSearchResultItemFetchMore.fontSize + color: unifiedSearchResultItemFetchMore.textColor + } + + BusyIndicator { + id: unifiedSearchResultItemFetchMoreIconInProgress + running: visible + visible: unifiedSearchResultItemFetchMore.isFetchMoreInProgress && unifiedSearchResultItemFetchMore.isWihinViewPort + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.preferredWidth: parent.height * 0.70 + Layout.preferredHeight: parent.height * 0.70 + } +} diff --git a/src/gui/tray/UnifiedSearchResultItem.qml b/src/gui/tray/UnifiedSearchResultItem.qml new file mode 100644 index 000000000000..0241ed28e73a --- /dev/null +++ b/src/gui/tray/UnifiedSearchResultItem.qml @@ -0,0 +1,107 @@ +import QtQml 2.15 +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.2 +import Style 1.0 +import QtGraphicalEffects 1.0 + +RowLayout { + id: unifiedSearchResultItemDetails + + property string title: "" + property string subline: "" + property string icons: "" + property string iconPlaceholder: "" + property bool isRounded: false + + + property int textLeftMargin: 18 + property int textRightMargin: 16 + property int iconWidth: 24 + property int iconLeftMargin: 12 + + property int titleFontSize: Style.topLinePixelSize + property int sublineFontSize: Style.subLinePixelSize + + property string titleColor: "black" + property string sublineColor: "grey" + + Accessible.role: Accessible.ListItem + Accessible.name: resultTitle + Accessible.onPressAction: unifiedSearchResultMouseArea.clicked() + + ColumnLayout { + id: unifiedSearchResultImageContainer + visible: true + Layout.preferredWidth: unifiedSearchResultItemDetails.iconWidth + 10 + Layout.preferredHeight: unifiedSearchResultItemDetails.height + Image { + id: unifiedSearchResultThumbnail + visible: false + asynchronous: true + source: "image://unified-search-result-icon/" + icons + cache: true + sourceSize.width: imageData.width + sourceSize.height: imageData.height + width: imageData.width + height: imageData.height + } + Rectangle { + id: mask + visible: false + radius: isRounded ? width / 2 : 0 + width: imageData.width + height: imageData.height + } + OpacityMask { + id: imageData + visible: !unifiedSearchResultThumbnailPlaceholder.visible && icons + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.leftMargin: iconLeftMargin + Layout.preferredWidth: unifiedSearchResultItemDetails.iconWidth + Layout.preferredHeight: unifiedSearchResultItemDetails.iconWidth + source: unifiedSearchResultThumbnail + maskSource: mask + } + Image { + id: unifiedSearchResultThumbnailPlaceholder + visible: icons && iconPlaceholder && unifiedSearchResultThumbnail.status !== Image.Ready + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.leftMargin: iconLeftMargin + verticalAlignment: Qt.AlignCenter + cache: true + source: iconPlaceholder + sourceSize.height: unifiedSearchResultItemDetails.iconWidth + sourceSize.width: unifiedSearchResultItemDetails.iconWidth + Layout.preferredWidth: unifiedSearchResultItemDetails.iconWidth + Layout.preferredHeight: unifiedSearchResultItemDetails.iconWidth + } + } + + ColumnLayout { + id: unifiedSearchResultTextContainer + Layout.fillWidth: true + + Label { + id: unifiedSearchResultTitleText + text: title.replace(/[\r\n]+/g, " ") + Layout.leftMargin: textLeftMargin + Layout.rightMargin: textRightMargin + Layout.fillWidth: true + elide: Text.ElideRight + font.pixelSize: unifiedSearchResultItemDetails.titleFontSize + color: unifiedSearchResultItemDetails.titleColor + } + Label { + id: unifiedSearchResultTextSubline + text: subline.replace(/[\r\n]+/g, " ") + elide: Text.ElideRight + font.pixelSize: unifiedSearchResultItemDetails.sublineFontSize + Layout.leftMargin: textLeftMargin + Layout.rightMargin: textRightMargin + Layout.fillWidth: true + color: unifiedSearchResultItemDetails.sublineColor + } + } + +} diff --git a/src/gui/tray/UnifiedSearchResultItemSkeleton.qml b/src/gui/tray/UnifiedSearchResultItemSkeleton.qml new file mode 100644 index 000000000000..3f86c4b9f892 --- /dev/null +++ b/src/gui/tray/UnifiedSearchResultItemSkeleton.qml @@ -0,0 +1,58 @@ +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Layouts 1.2 +import Style 1.0 + +RowLayout { + id: unifiedSearchResultSkeletonItemDetails + + property int textLeftMargin: 18 + property int textRightMargin: 16 + property int iconWidth: 24 + property int iconLeftMargin: 12 + + property int titleFontSize: Style.topLinePixelSize + property int sublineFontSize: Style.subLinePixelSize + + property string titleColor: "black" + property string sublineColor: "grey" + + property string iconColor: "#afafaf" + + property int index: 0 + + Accessible.role: Accessible.ListItem + Accessible.name: qsTr("Search result skeleton.").arg(index) + + Rectangle { + id: unifiedSearchResultSkeletonThumbnail + color: unifiedSearchResultSkeletonItemDetails.iconColor + Layout.preferredWidth: unifiedSearchResultSkeletonItemDetails.iconWidth + Layout.preferredHeight: unifiedSearchResultSkeletonItemDetails.iconWidth + Layout.leftMargin: unifiedSearchResultSkeletonItemDetails.iconLeftMargin + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + } + + ColumnLayout { + id: unifiedSearchResultSkeletonTextContainer + Layout.fillWidth: true + + Rectangle { + id: unifiedSearchResultSkeletonTitleText + color: unifiedSearchResultSkeletonItemDetails.titleColor + Layout.preferredHeight: unifiedSearchResultSkeletonItemDetails.titleFontSize + Layout.leftMargin: unifiedSearchResultSkeletonItemDetails.textLeftMargin + Layout.rightMargin: unifiedSearchResultSkeletonItemDetails.textRightMargin + Layout.fillWidth: true + } + + Rectangle { + id: unifiedSearchResultSkeletonTextSubline + color: unifiedSearchResultSkeletonItemDetails.sublineColor + Layout.preferredHeight: unifiedSearchResultSkeletonItemDetails.sublineFontSize + Layout.leftMargin: unifiedSearchResultSkeletonItemDetails.textLeftMargin + Layout.rightMargin: unifiedSearchResultSkeletonItemDetails.textRightMargin + Layout.fillWidth: true + } + } +} diff --git a/src/gui/tray/UnifiedSearchResultItemSkeletonContainer.qml b/src/gui/tray/UnifiedSearchResultItemSkeletonContainer.qml new file mode 100644 index 000000000000..1b9f8c262a4a --- /dev/null +++ b/src/gui/tray/UnifiedSearchResultItemSkeletonContainer.qml @@ -0,0 +1,49 @@ +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.3 +import Style 1.0 + +Column { + id: unifiedSearchResultsListViewSkeletonColumn + + property int textLeftMargin: 18 + property int textRightMargin: 16 + property int iconWidth: 24 + property int iconLeftMargin: 12 + property int itemHeight: Style.trayWindowHeaderHeight + property int titleFontSize: Style.topLinePixelSize + property int sublineFontSize: Style.subLinePixelSize + property string titleColor: "black" + property string sublineColor: "grey" + property string iconColor: "#afafaf" + + Repeater { + model: 10 + UnifiedSearchResultItemSkeleton { + textLeftMargin: unifiedSearchResultsListViewSkeletonColumn.textLeftMargin + textRightMargin: unifiedSearchResultsListViewSkeletonColumn.textRightMargin + iconWidth: unifiedSearchResultsListViewSkeletonColumn.iconWidth + iconLeftMargin: unifiedSearchResultsListViewSkeletonColumn.iconLeftMargin + width: unifiedSearchResultsListViewSkeletonColumn.width + height: unifiedSearchResultsListViewSkeletonColumn.itemHeight + index: model.index + titleFontSize: unifiedSearchResultsListViewSkeletonColumn.titleFontSize + sublineFontSize: unifiedSearchResultsListViewSkeletonColumn.sublineFontSize + titleColor: unifiedSearchResultsListViewSkeletonColumn.titleColor + sublineColor: unifiedSearchResultsListViewSkeletonColumn.sublineColor + iconColor: unifiedSearchResultsListViewSkeletonColumn.iconColor + } + } + + OpacityAnimator { + target: unifiedSearchResultsListViewSkeletonColumn; + from: 0.5; + to: 1; + duration: 800 + running: unifiedSearchResultsListViewSkeletonColumn.visible + loops: Animation.Infinite; + easing { + type: Easing.InOutBounce; + } + } +} diff --git a/src/gui/tray/UnifiedSearchResultListItem.qml b/src/gui/tray/UnifiedSearchResultListItem.qml new file mode 100644 index 000000000000..33a05f2d561a --- /dev/null +++ b/src/gui/tray/UnifiedSearchResultListItem.qml @@ -0,0 +1,87 @@ +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.3 +import Style 1.0 + +MouseArea { + id: unifiedSearchResultMouseArea + + property int textLeftMargin: 18 + property int textRightMargin: 16 + property int iconWidth: 24 + property int iconLeftMargin: 12 + + property int titleFontSize: Style.topLinePixelSize + property int sublineFontSize: Style.subLinePixelSize + + property string titleColor: "black" + property string sublineColor: "grey" + + property string currentFetchMoreInProgressProviderId: "" + + readonly property bool isFetchMoreTrigger: model.typeAsString === "FetchMoreTrigger" + + property bool isFetchMoreInProgress: currentFetchMoreInProgressProviderId === model.providerId + property bool isSearchInProgress: false + + property bool isPooled: false + + property var fetchMoreTriggerClicked: function(){} + property var resultClicked: function(){} + + enabled: !isFetchMoreTrigger || !isSearchInProgress + hoverEnabled: enabled + + ToolTip { + visible: unifiedSearchResultMouseArea.containsMouse + text: isFetchMoreTrigger ? qsTr("Load more results") : model.resultTitle + "\n\n" + model.subline + delay: Qt.styleHints.mousePressAndHoldInterval + } + + Rectangle { + id: unifiedSearchResultHoverBackground + anchors.fill: parent + color: (parent.containsMouse ? Style.lightHover : "transparent") + } + + Loader { + active: !isFetchMoreTrigger + sourceComponent: UnifiedSearchResultItem { + width: unifiedSearchResultMouseArea.width + height: unifiedSearchResultMouseArea.height + title: model.resultTitle + subline: model.subline + icons: model.icons + iconPlaceholder: model.imagePlaceholder + isRounded: model.isRounded + textLeftMargin: unifiedSearchResultMouseArea.textLeftMargin + textRightMargin: unifiedSearchResultMouseArea.textRightMargin + iconWidth: unifiedSearchResultMouseArea.iconWidth + iconLeftMargin: unifiedSearchResultMouseArea.iconLeftMargin + titleFontSize: unifiedSearchResultMouseArea.titleFontSize + sublineFontSize: unifiedSearchResultMouseArea.sublineFontSize + titleColor: unifiedSearchResultMouseArea.titleColor + sublineColor: unifiedSearchResultMouseArea.sublineColor + } + } + + Loader { + active: isFetchMoreTrigger + sourceComponent: UnifiedSearchResultFetchMoreTrigger { + isFetchMoreInProgress: unifiedSearchResultMouseArea.isFetchMoreInProgress + width: unifiedSearchResultMouseArea.width + height: unifiedSearchResultMouseArea.height + isWihinViewPort: !unifiedSearchResultMouseArea.isPooled + fontSize: unifiedSearchResultMouseArea.titleFontSize + textColor: unifiedSearchResultMouseArea.sublineColor + } + } + + onClicked: { + if (isFetchMoreTrigger) { + unifiedSearchResultMouseArea.fetchMoreTriggerClicked(model.providerId) + } else { + unifiedSearchResultMouseArea.resultClicked(model.providerId, model.resourceUrlRole) + } + } +} diff --git a/src/gui/tray/UnifiedSearchResultNothingFound.qml b/src/gui/tray/UnifiedSearchResultNothingFound.qml new file mode 100644 index 000000000000..36cea93a632e --- /dev/null +++ b/src/gui/tray/UnifiedSearchResultNothingFound.qml @@ -0,0 +1,47 @@ +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.2 +import Style 1.0 + +ColumnLayout { + id: unifiedSearchResultNothingFoundContainer + + required property string text + + spacing: 8 + anchors.leftMargin: 10 + anchors.rightMargin: 10 + + Image { + id: unifiedSearchResultsNoResultsLabelIcon + source: "qrc:///client/theme/magnifying-glass.svg" + sourceSize.width: Style.trayWindowHeaderHeight / 2 + sourceSize.height: Style.trayWindowHeaderHeight / 2 + Layout.alignment: Qt.AlignHCenter + } + + Label { + id: unifiedSearchResultsNoResultsLabel + text: qsTr("No results for") + color: Style.menuBorder + font.pixelSize: Style.subLinePixelSize * 1.25 + wrapMode: Text.Wrap + Layout.fillWidth: true + Layout.preferredHeight: Style.trayWindowHeaderHeight / 2 + horizontalAlignment: Text.AlignHCenter + } + + Label { + id: unifiedSearchResultsNoResultsLabelDetails + text: unifiedSearchResultNothingFoundContainer.text + color: "black" + font.pixelSize: Style.topLinePixelSize * 1.25 + wrapMode: Text.Wrap + maximumLineCount: 2 + elide: Text.ElideRight + Layout.fillWidth: true + Layout.preferredHeight: Style.trayWindowHeaderHeight / 2 + horizontalAlignment: Text.AlignHCenter + } +} diff --git a/src/gui/tray/UnifiedSearchResultSectionItem.qml b/src/gui/tray/UnifiedSearchResultSectionItem.qml new file mode 100644 index 000000000000..a6f9fd591ba8 --- /dev/null +++ b/src/gui/tray/UnifiedSearchResultSectionItem.qml @@ -0,0 +1,20 @@ +import QtQml 2.15 +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.2 +import Style 1.0 + +Label { + required property string section + + topPadding: 8 + bottomPadding: 8 + leftPadding: 16 + + text: section + font.pixelSize: Style.topLinePixelSize + color: Style.ncBlue + + Accessible.role: Accessible.Separator + Accessible.name: qsTr("Search results section %1").arg(section) +} diff --git a/src/gui/tray/UserLine.qml b/src/gui/tray/UserLine.qml index 4143acaeecf3..c418e3c1f1ac 100644 --- a/src/gui/tray/UserLine.qml +++ b/src/gui/tray/UserLine.qml @@ -14,6 +14,11 @@ MenuItem { Accessible.role: Accessible.MenuItem Accessible.name: qsTr("Account entry") + property variant dialog; + property variant comp; + + signal showUserStatusSelectorDialog(int id) + RowLayout { id: userLineLayout spacing: 0 @@ -188,6 +193,29 @@ MenuItem { radius: 2 } + MenuItem { + visible: model.isConnected && model.serverHasUserStatus + height: visible ? implicitHeight : 0 + + text: qsTr("Set status") + font.pixelSize: Style.topLinePixelSize + hoverEnabled: true + onClicked: { + showUserStatusSelectorDialog(index) + accountMenu.close() + } + + background: Item { + height: parent.height + width: parent.menu.width + Rectangle { + anchors.fill: parent + anchors.margins: 1 + color: parent.parent.hovered ? Style.lightHover : "transparent" + } + } + } + MenuItem { text: model.isConnected ? qsTr("Log out") : qsTr("Log in") font.pixelSize: Style.topLinePixelSize diff --git a/src/gui/tray/Window.qml b/src/gui/tray/Window.qml index 39c08ffab256..eab74c981bfe 100644 --- a/src/gui/tray/Window.qml +++ b/src/gui/tray/Window.qml @@ -1,10 +1,11 @@ import QtQml 2.12 import QtQml.Models 2.1 -import QtQuick 2.9 +import QtQuick 2.15 import QtQuick.Window 2.3 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 +import "../" // Custom qml modules are in /theme (and included by resources.qrc) import Style 1.0 @@ -22,8 +23,15 @@ Window { flags: Systray.useNormalWindow ? Qt.Window : Qt.Dialog | Qt.FramelessWindowHint + property var fileActivityDialogAbsolutePath: "" readonly property int maxMenuHeight: Style.trayWindowHeight - Style.trayWindowHeaderHeight - 2 * Style.trayWindowBorderWidth + function openFileActivityDialog(displayPath, absolutePath) { + fileActivityDialogLoader.displayPath = displayPath + fileActivityDialogLoader.absolutePath = absolutePath + fileActivityDialogLoader.refresh() + } + Component.onCompleted: Systray.forceWindowInit(trayWindow) // Close tray window when focus is lost (e.g. click somewhere else on the screen) @@ -43,18 +51,20 @@ Window { // see also id:accountMenu below userLineInstantiator.active = false; userLineInstantiator.active = true; + syncStatus.model.load(); } Connections { target: UserModel - onNewUserSelected: { + function onNewUserSelected() { accountMenu.close(); + syncStatus.model.load(); } } Connections { target: Systray - onShowWindow: { + function onShowWindow() { accountMenu.close(); appsMenu.close(); Systray.positionWindow(trayWindow); @@ -66,10 +76,14 @@ Window { Systray.setOpened(); UserModel.fetchCurrentActivityModel(); } - onHideWindow: { + function onHideWindow() { trayWindow.hide(); Systray.setClosed(); } + + function onShowFileActivityDialog(displayPath, absolutePath) { + openFileActivityDialog(displayPath, absolutePath) + } } OpacityMask { @@ -88,6 +102,11 @@ Window { Rectangle { id: trayWindowBackground + property bool isUnifiedSearchActive: unifiedSearchResultsListViewSkeleton.visible + || unifiedSearchResultNothingFound.visible + || unifiedSearchResultsErrorLabel.visible + || unifiedSearchResultsListView.visible + anchors.fill: parent radius: Systray.useNormalWindow ? 0.0 : Style.trayWindowRadius border.width: Style.trayWindowBorderWidth @@ -140,6 +159,10 @@ Window { } } + Loader { + id: userStatusSelectorDialogLoader + } + Menu { id: accountMenu @@ -167,7 +190,14 @@ Window { Instantiator { id: userLineInstantiator model: UserModel - delegate: UserLine {} + delegate: UserLine { + onShowUserStatusSelectorDialog: { + userStatusSelectorDialogLoader.source = "qrc:/qml/src/gui/UserStatusSelectorDialog.qml" + userStatusSelectorDialogLoader.item.title = qsTr("Set user status") + userStatusSelectorDialogLoader.item.model.load(index) + userStatusSelectorDialogLoader.item.show() + } + } onObjectAdded: accountMenu.insertItem(index, object) onObjectRemoved: accountMenu.removeItem(object) } @@ -396,7 +426,7 @@ Window { visible: UserModel.currentUser.statusMessage !== "" width: Style.currentAccountLabelWidth text: UserModel.currentUser.statusMessage !== "" - ? UserModel.currentUser.statusMessage + ? UserModel.currentUser.statusMessage : UserModel.currentUser.server elide: Text.ElideRight color: Style.ncTextColor @@ -428,20 +458,20 @@ Window { Item { Layout.fillWidth: true } - + RowLayout { id: openLocalFolderRowLayout spacing: 0 Layout.preferredWidth: Style.trayWindowHeaderHeight Layout.preferredHeight: Style.trayWindowHeaderHeight Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - + HeaderButton { id: openLocalFolderButton visible: UserModel.currentUser.hasLocalFolder icon.source: "qrc:///client/theme/white/folder.svg" onClicked: UserModel.openCurrentAccountLocalFolder() - + Rectangle { id: folderStateIndicatorBackground width: Style.folderStateIndicatorSize @@ -452,7 +482,7 @@ Window { radius: width*0.5 z: 1 } - + Image { id: folderStateIndicator visible: UserModel.currentUser.hasLocalFolder @@ -460,19 +490,17 @@ Window { ? Style.stateOnlineImageSource : Style.stateOfflineImageSource cache: false - + anchors.top: openLocalFolderButton.verticalCenter - anchors.left: openLocalFolderButton.horizontalCenter + anchors.left: openLocalFolderButton.horizontalCenter sourceSize.width: Style.folderStateIndicatorSize sourceSize.height: Style.folderStateIndicatorSize - + Accessible.role: Accessible.Indicator Accessible.name: UserModel.currentUser.isConnected ? qsTr("Connected") : qsTr("Disconnected") z: 2 } } - - Accessible.role: Accessible.Button Accessible.name: qsTr("Open local folder of current account") @@ -480,11 +508,11 @@ Window { HeaderButton { id: trayWindowTalkButton - + visible: UserModel.currentUser.serverHasTalk icon.source: "qrc:///client/theme/white/talk-app.svg" onClicked: UserModel.openCurrentAccountTalk() - + Accessible.role: Accessible.Button Accessible.name: qsTr("Open Nextcloud Talk in browser") Accessible.onPressAction: trayWindowTalkButton.clicked() @@ -493,7 +521,7 @@ Window { HeaderButton { id: trayWindowAppsButton icon.source: "qrc:///client/theme/white/more-apps.svg" - + onClicked: { if(appsMenu.count <= 0) { UserModel.openCurrentAccountServer() @@ -508,12 +536,10 @@ Window { Accessible.name: qsTr("More apps") Accessible.onPressAction: trayWindowAppsButton.clicked() - Menu { + AutoSizingMenu { id: appsMenu y: (trayWindowAppsButton.y + trayWindowAppsButton.height + 2) readonly property Item listContentItem: contentItem.contentItem - width: Math.min(listContentItem.childrenRect.width + 4, Style.trayWindowWidth / 2) - height: Math.min(implicitHeight, maxMenuHeight) closePolicy: Menu.CloseOnPressOutsideParent | Menu.CloseOnEscape background: Rectangle { @@ -531,24 +557,9 @@ Window { text: appName font.pixelSize: Style.topLinePixelSize icon.source: appIconUrl - width: contentItem.implicitWidth + leftPadding + rightPadding onTriggered: UserAppsModel.openAppUrl(appUrl) hoverEnabled: true - background: Item { - width: appsMenu.width - height: parent.height - - Rectangle { - anchors.fill: parent - anchors.margins: 1 - color: appEntry.hovered ? Style.lightHover : "transparent" - } - - Accessible.role: Accessible.PopupMenu - Accessible.name: qsTr("Apps menu") - } - Accessible.role: Accessible.MenuItem Accessible.name: qsTr("Open %1 in browser").arg(appName) Accessible.onPressAction: appEntry.triggered() @@ -559,31 +570,187 @@ Window { } } // Rectangle trayWindowHeaderBackground + UnifiedSearchInputContainer { + id: trayWindowUnifiedSearchInputContainer + height: Style.trayWindowHeaderHeight * 0.65 + + anchors { + top: trayWindowHeaderBackground.bottom + left: trayWindowBackground.left + right: trayWindowBackground.right + + margins: { + top: 10 + } + } + + text: UserModel.currentUser.unifiedSearchResultsListModel.searchTerm + readOnly: !UserModel.currentUser.isConnected || UserModel.currentUser.unifiedSearchResultsListModel.currentFetchMoreInProgressProviderId + isSearchInProgress: UserModel.currentUser.unifiedSearchResultsListModel.isSearchInProgress + onTextEdited: { UserModel.currentUser.unifiedSearchResultsListModel.searchTerm = trayWindowUnifiedSearchInputContainer.text } + onClearText: { UserModel.currentUser.unifiedSearchResultsListModel.searchTerm = "" } + } + + ErrorBox { + id: unifiedSearchResultsErrorLabel + visible: UserModel.currentUser.unifiedSearchResultsListModel.errorString && !unifiedSearchResultsListView.visible && ! UserModel.currentUser.unifiedSearchResultsListModel.isSearchInProgress && ! UserModel.currentUser.unifiedSearchResultsListModel.currentFetchMoreInProgressProviderId + text: UserModel.currentUser.unifiedSearchResultsListModel.errorString + color: Style.errorBoxBackgroundColor + backgroundColor: Style.errorBoxTextColor + borderColor: "transparent" + anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.left: trayWindowBackground.left + anchors.right: trayWindowBackground.right + anchors.margins: 10 + } + + UnifiedSearchResultNothingFound { + id: unifiedSearchResultNothingFound + visible: false + anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.left: trayWindowBackground.left + anchors.right: trayWindowBackground.right + anchors.topMargin: 10 + + text: UserModel.currentUser.unifiedSearchResultsListModel.searchTerm + + property bool isSearchRunning: UserModel.currentUser.unifiedSearchResultsListModel.isSearchInProgress + property bool isSearchResultsEmpty: unifiedSearchResultsListView.count === 0 + property bool nothingFound: text && isSearchResultsEmpty && !UserModel.currentUser.unifiedSearchResultsListModel.errorString + + onIsSearchRunningChanged: { + if (unifiedSearchResultNothingFound.isSearchRunning) { + visible = false; + } else { + if (nothingFound) { + visible = true; + } + } + } + + onTextChanged: { + visible = false; + } + + onIsSearchResultsEmptyChanged: { + if (!unifiedSearchResultNothingFound.isSearchResultsEmpty) { + visible = false; + } + } + } + + UnifiedSearchResultItemSkeletonContainer { + id: unifiedSearchResultsListViewSkeleton + visible: !unifiedSearchResultNothingFound.visible && !unifiedSearchResultsListView.visible && ! UserModel.currentUser.unifiedSearchResultsListModel.errorString && UserModel.currentUser.unifiedSearchResultsListModel.searchTerm + anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.left: trayWindowBackground.left + anchors.right: trayWindowBackground.right + anchors.bottom: trayWindowBackground.bottom + textLeftMargin: trayWindowBackground.Style.unifiedSearchResultTextLeftMargin + textRightMargin: trayWindowBackground.Style.unifiedSearchResultTextRightMargin + iconWidth: trayWindowBackground.Style.unifiedSearchResulIconWidth + iconLeftMargin: trayWindowBackground.Style.unifiedSearchResulIconLeftMargin + itemHeight: trayWindowBackground.Style.unifiedSearchItemHeight + titleFontSize: trayWindowBackground.Style.unifiedSearchResulTitleFontSize + sublineFontSize: trayWindowBackground.Style.unifiedSearchResulSublineFontSize + titleColor: trayWindowBackground.Style.unifiedSearchResulTitleColor + sublineColor: trayWindowBackground.Style.unifiedSearchResulSublineColor + iconColor: "#afafaf" + } + ListView { - id: activityListView - anchors.top: trayWindowHeaderBackground.bottom + id: unifiedSearchResultsListView + anchors.top: trayWindowUnifiedSearchInputContainer.bottom anchors.left: trayWindowBackground.left anchors.right: trayWindowBackground.right anchors.bottom: trayWindowBackground.bottom + spacing: 4 + visible: count > 0 clip: true ScrollBar.vertical: ScrollBar { - id: listViewScrollbar + id: unifiedSearchResultsListViewScrollbar } - readonly property int maxActionButtons: 2 - keyNavigationEnabled: true + reuseItems: true + Accessible.role: Accessible.List - Accessible.name: qsTr("Activity list") + Accessible.name: qsTr("Unified search results list") + + model: UserModel.currentUser.unifiedSearchResultsListModel + + delegate: UnifiedSearchResultListItem { + width: unifiedSearchResultsListView.width + height: trayWindowBackground.Style.unifiedSearchItemHeight + isSearchInProgress: unifiedSearchResultsListView.model.isSearchInProgress + textLeftMargin: trayWindowBackground.Style.unifiedSearchResultTextLeftMargin + textRightMargin: trayWindowBackground.Style.unifiedSearchResultTextRightMargin + iconWidth: trayWindowBackground.Style.unifiedSearchResulIconWidth + iconLeftMargin: trayWindowBackground.Style.unifiedSearchResulIconLeftMargin + titleFontSize: trayWindowBackground.Style.unifiedSearchResulTitleFontSize + sublineFontSize: trayWindowBackground.Style.unifiedSearchResulSublineFontSize + titleColor: trayWindowBackground.Style.unifiedSearchResulTitleColor + sublineColor: trayWindowBackground.Style.unifiedSearchResulSublineColor + currentFetchMoreInProgressProviderId: unifiedSearchResultsListView.model.currentFetchMoreInProgressProviderId + fetchMoreTriggerClicked: unifiedSearchResultsListView.model.fetchMoreTriggerClicked + resultClicked: unifiedSearchResultsListView.model.resultClicked + ListView.onPooled: isPooled = true + ListView.onReused: isPooled = false + } + + section.property: "providerName" + section.criteria: ViewSection.FullString + section.delegate: UnifiedSearchResultSectionItem { + width: unifiedSearchResultsListView.width + } + } + + SyncStatus { + id: syncStatus + + visible: !trayWindowBackground.isUnifiedSearchActive + + anchors.top: trayWindowUnifiedSearchInputContainer.bottom + anchors.left: trayWindowBackground.left + anchors.right: trayWindowBackground.right + } + + ActivityList { + visible: !trayWindowBackground.isUnifiedSearchActive + anchors.top: syncStatus.bottom + anchors.left: trayWindowBackground.left + anchors.right: trayWindowBackground.right + anchors.bottom: trayWindowBackground.bottom model: activityModel + onShowFileActivity: { + openFileActivityDialog(displayPath, absolutePath) + } + onActivityItemClicked: { + model.triggerDefaultAction(index) + } + } - delegate: ActivityItem { - width: activityListView.width - height: Style.trayWindowHeaderHeight - onClicked: activityModel.triggerDefaultAction(model.index) + Loader { + id: fileActivityDialogLoader + + property string displayPath: "" + property string absolutePath: "" + + function refresh() { + active = true + item.model.load(activityModel.accountState, absolutePath) + item.show() } + + active: false + sourceComponent: FileActivityDialog { + title: qsTr("%1 - File activity").arg(fileActivityDialogLoader.displayPath) + onClosing: fileActivityDialogLoader.active = false + } + + onLoaded: refresh() } - } // Rectangle trayWindowBackground + } // Rectangle trayWindowBackground } diff --git a/src/gui/tray/ActivityData.cpp b/src/gui/tray/activitydata.cpp similarity index 97% rename from src/gui/tray/ActivityData.cpp rename to src/gui/tray/activitydata.cpp index 9378a6596903..866c97956f97 100644 --- a/src/gui/tray/ActivityData.cpp +++ b/src/gui/tray/activitydata.cpp @@ -14,7 +14,7 @@ #include -#include "ActivityData.h" +#include "activitydata.h" namespace OCC { diff --git a/src/gui/tray/ActivityData.h b/src/gui/tray/activitydata.h similarity index 100% rename from src/gui/tray/ActivityData.h rename to src/gui/tray/activitydata.h diff --git a/src/gui/tray/ActivityListModel.cpp b/src/gui/tray/activitylistmodel.cpp similarity index 90% rename from src/gui/tray/ActivityListModel.cpp rename to src/gui/tray/activitylistmodel.cpp index 1a9a7578ac1e..3d126244df10 100644 --- a/src/gui/tray/ActivityListModel.cpp +++ b/src/gui/tray/activitylistmodel.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "account.h" #include "accountstate.h" @@ -28,9 +29,10 @@ #include "accessmanager.h" #include "owncloudgui.h" #include "guiutility.h" +#include "invalidfilenamedialog.h" -#include "ActivityData.h" -#include "ActivityListModel.h" +#include "activitydata.h" +#include "activitylistmodel.h" #include "theme.h" @@ -38,7 +40,13 @@ namespace OCC { Q_LOGGING_CATEGORY(lcActivity, "nextcloud.gui.activity", QtInfoMsg) -ActivityListModel::ActivityListModel(AccountState *accountState, QObject *parent) +ActivityListModel::ActivityListModel(QObject *parent) + : QAbstractListModel(parent) +{ +} + +ActivityListModel::ActivityListModel(AccountState *accountState, + QObject *parent) : QAbstractListModel(parent) , _accountState(accountState) { @@ -59,9 +67,40 @@ QHash ActivityListModel::roleNames() const roles[ActionTextColorRole] = "activityTextTitleColor"; roles[ObjectTypeRole] = "objectType"; roles[PointInTimeRole] = "dateTime"; + roles[DisplayActions] = "displayActions"; return roles; } +void ActivityListModel::setAccountState(AccountState *state) +{ + _accountState = state; +} + +void ActivityListModel::setCurrentlyFetching(bool value) +{ + _currentlyFetching = value; +} + +bool ActivityListModel::currentlyFetching() const +{ + return _currentlyFetching; +} + +void ActivityListModel::setDoneFetching(bool value) +{ + _doneFetching = value; +} + +void ActivityListModel::setHideOldActivities(bool value) +{ + _hideOldActivities = value; +} + +void ActivityListModel::setDisplayActions(bool value) +{ + _displayActions = value; +} + QVariant ActivityListModel::data(const QModelIndex &index, int role) const { Activity a; @@ -221,6 +260,8 @@ QVariant ActivityListModel::data(const QModelIndex &index, int role) const return a._id == -1 ? "" : Utility::timeAgoInWords(a._dateTime.toLocalTime()); case AccountConnectedRole: return (ast && ast->isConnected()); + case DisplayActions: + return _displayActions; default: return QVariant(); } @@ -252,7 +293,7 @@ void ActivityListModel::startFetchJob() } auto *job = new JsonApiJob(_accountState->account(), QLatin1String("ocs/v2.php/apps/activity/api/v2/activity"), this); QObject::connect(job, &JsonApiJob::jsonReceived, - this, &ActivityListModel::slotActivitiesReceived); + this, &ActivityListModel::activitiesReceived); QUrlQuery params; params.addQueryItem(QLatin1String("since"), QString::number(_currentItem)); @@ -264,7 +305,7 @@ void ActivityListModel::startFetchJob() job->start(); } -void ActivityListModel::slotActivitiesReceived(const QJsonDocument &json, int statusCode) +void ActivityListModel::activitiesReceived(const QJsonDocument &json, int statusCode) { auto activities = json.object().value("ocs").toObject().value("data").toArray(); @@ -303,9 +344,8 @@ void ActivityListModel::slotActivitiesReceived(const QJsonDocument &json, int st _currentItem = list.last()._id; _totalActivitiesFetched++; - if(_totalActivitiesFetched == _maxActivities || - a._dateTime < oldestDate) { - + if (_totalActivitiesFetched == _maxActivities + || (_hideOldActivities && a._dateTime < oldestDate)) { _showMoreActivitiesAvailableEntry = true; _doneFetching = true; break; @@ -446,6 +486,21 @@ void ActivityListModel::triggerDefaultAction(int activityIndex) _currentConflictDialog->open(); ownCloudGui::raiseDialog(_currentConflictDialog); return; + } else if (activity._status == SyncFileItem::FileNameInvalid) { + if (!_currentInvalidFilenameDialog.isNull()) { + _currentInvalidFilenameDialog->close(); + } + + auto folder = FolderMan::instance()->folder(activity._folder); + const auto folderDir = QDir(folder->path()); + _currentInvalidFilenameDialog = new InvalidFilenameDialog(_accountState->account(), folder, + folderDir.filePath(activity._file)); + connect(_currentInvalidFilenameDialog, &InvalidFilenameDialog::accepted, folder, [folder]() { + folder->scheduleThisFolderSoon(); + }); + _currentInvalidFilenameDialog->open(); + ownCloudGui::raiseDialog(_currentInvalidFilenameDialog); + return; } if (path.isValid()) { @@ -480,6 +535,11 @@ void ActivityListModel::triggerAction(int activityIndex, int actionIndex) emit sendNotificationRequest(activity._accName, action._link, action._verb, activityIndex); } +AccountState *ActivityListModel::accountState() const +{ + return _accountState; +} + void ActivityListModel::combineActivityLists() { ActivityList resultList; diff --git a/src/gui/tray/ActivityListModel.h b/src/gui/tray/activitylistmodel.h similarity index 68% rename from src/gui/tray/ActivityListModel.h rename to src/gui/tray/activitylistmodel.h index 554ac320f168..379fc9ba86fc 100644 --- a/src/gui/tray/ActivityListModel.h +++ b/src/gui/tray/activitylistmodel.h @@ -17,7 +17,7 @@ #include -#include "ActivityData.h" +#include "activitydata.h" class QJsonDocument; @@ -27,6 +27,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcActivity) class AccountState; class ConflictDialog; +class InvalidFilenameDialog; /** * @brief The ActivityListModel @@ -38,26 +39,34 @@ class ConflictDialog; class ActivityListModel : public QAbstractListModel { Q_OBJECT + + Q_PROPERTY(AccountState *accountState READ accountState CONSTANT) public: enum DataRole { - ActionIconRole = Qt::UserRole + 1, - UserIconRole, - AccountRole, - ObjectTypeRole, - ActionsLinksRole, - ActionTextRole, - ActionTextColorRole, - ActionRole, - MessageRole, - DisplayPathRole, - PathRole, - AbsolutePathRole, - LinkRole, - PointInTimeRole, - AccountConnectedRole, - SyncFileStatusRole}; - - explicit ActivityListModel(AccountState *accountState, QObject* parent = nullptr); + ActionIconRole = Qt::UserRole + 1, + UserIconRole, + AccountRole, + ObjectTypeRole, + ActionsLinksRole, + ActionTextRole, + ActionTextColorRole, + ActionRole, + MessageRole, + DisplayPathRole, + PathRole, + AbsolutePathRole, + LinkRole, + PointInTimeRole, + AccountConnectedRole, + SyncFileStatusRole, + DisplayActions, + }; + Q_ENUM(DataRole) + + explicit ActivityListModel(QObject *parent = nullptr); + + explicit ActivityListModel(AccountState *accountState, + QObject *parent = nullptr); QVariant data(const QModelIndex &index, int role) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; @@ -78,22 +87,30 @@ class ActivityListModel : public QAbstractListModel Q_INVOKABLE void triggerDefaultAction(int activityIndex); Q_INVOKABLE void triggerAction(int activityIndex, int actionIndex); + AccountState *accountState() const; + public slots: void slotRefreshActivity(); void slotRemoveAccount(); -private slots: - void slotActivitiesReceived(const QJsonDocument &json, int statusCode); - signals: void activityJobStatusCode(int statusCode); void sendNotificationRequest(const QString &accountName, const QString &link, const QByteArray &verb, int row); protected: + void activitiesReceived(const QJsonDocument &json, int statusCode); QHash roleNames() const override; + void setAccountState(AccountState *state); + void setCurrentlyFetching(bool value); + bool currentlyFetching() const; + void setDoneFetching(bool value); + void setHideOldActivities(bool value); + void setDisplayActions(bool value); + + virtual void startFetchJob(); + private: - void startFetchJob(); void combineActivityLists(); bool canFetchActivities() const; @@ -104,17 +121,22 @@ private slots: Activity _notificationIgnoredFiles; ActivityList _notificationErrorsLists; ActivityList _finalList; - AccountState *_accountState; - bool _currentlyFetching = false; - bool _doneFetching = false; int _currentItem = 0; + bool _displayActions = true; + int _totalActivitiesFetched = 0; int _maxActivities = 100; int _maxActivitiesDays = 30; bool _showMoreActivitiesAvailableEntry = false; QPointer _currentConflictDialog; + QPointer _currentInvalidFilenameDialog; + + AccountState *_accountState = nullptr; + bool _currentlyFetching = false; + bool _doneFetching = false; + bool _hideOldActivities = true; }; } diff --git a/src/gui/tray/NotificationCache.cpp b/src/gui/tray/notificationcache.cpp similarity index 94% rename from src/gui/tray/NotificationCache.cpp rename to src/gui/tray/notificationcache.cpp index e2d4f777eef1..f60c2457d668 100644 --- a/src/gui/tray/NotificationCache.cpp +++ b/src/gui/tray/notificationcache.cpp @@ -1,4 +1,4 @@ -#include "NotificationCache.h" +#include "notificationcache.h" namespace OCC { diff --git a/src/gui/tray/NotificationCache.h b/src/gui/tray/notificationcache.h similarity index 100% rename from src/gui/tray/NotificationCache.h rename to src/gui/tray/notificationcache.h diff --git a/src/gui/tray/NotificationHandler.cpp b/src/gui/tray/notificationhandler.cpp similarity index 98% rename from src/gui/tray/NotificationHandler.cpp rename to src/gui/tray/notificationhandler.cpp index d97feed1cdb9..b21f7e8e1758 100644 --- a/src/gui/tray/NotificationHandler.cpp +++ b/src/gui/tray/notificationhandler.cpp @@ -1,4 +1,4 @@ -#include "NotificationHandler.h" +#include "notificationhandler.h" #include "accountstate.h" #include "capabilities.h" @@ -113,7 +113,7 @@ void ServerNotificationHandler::slotNotificationsReceived(const QJsonDocument &j a._icon = json.value("icon").toString(); if (!a._icon.isEmpty()) { - auto *iconJob = new IconJob(QUrl(a._icon)); + auto *iconJob = new IconJob(_accountState->account(), QUrl(a._icon)); iconJob->setProperty("activityId", a._id); connect(iconJob, &IconJob::jobFinished, this, &ServerNotificationHandler::slotIconDownloaded); } diff --git a/src/gui/tray/NotificationHandler.h b/src/gui/tray/notificationhandler.h similarity index 93% rename from src/gui/tray/NotificationHandler.h rename to src/gui/tray/notificationhandler.h index 5bc4692f59bd..5bd824f5cf21 100644 --- a/src/gui/tray/NotificationHandler.h +++ b/src/gui/tray/notificationhandler.h @@ -3,7 +3,7 @@ #include -#include "UserModel.h" +#include "usermodel.h" class QJsonDocument; @@ -34,4 +34,4 @@ private slots: }; } -#endif // NOTIFICATIONHANDLER_H \ No newline at end of file +#endif // NOTIFICATIONHANDLER_H diff --git a/src/gui/tray/svgimageprovider.cpp b/src/gui/tray/svgimageprovider.cpp new file mode 100644 index 000000000000..ab57607004ac --- /dev/null +++ b/src/gui/tray/svgimageprovider.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 "svgimageprovider.h" +#include "iconutils.h" + +#include + +namespace OCC { +namespace Ui { + Q_LOGGING_CATEGORY(lcSvgImageProvider, "nextcloud.gui.svgimageprovider", QtInfoMsg) + + SvgImageProvider::SvgImageProvider() + : QQuickImageProvider(QQuickImageProvider::Image) + { + } + + QImage SvgImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) + { + Q_ASSERT(!id.isEmpty()); + + const auto idSplit = id.split(QStringLiteral("/"), Qt::SkipEmptyParts); + + if (idSplit.isEmpty()) { + qCWarning(lcSvgImageProvider) << "Image id is incorrect!"; + return {}; + } + + const auto pixmapName = idSplit.at(0); + const auto pixmapColor = idSplit.size() > 1 ? QColor(idSplit.at(1)) : QColorConstants::Svg::black; + + if (pixmapName.isEmpty() || !pixmapColor.isValid()) { + qCWarning(lcSvgImageProvider) << "Image id is incorrect!"; + return {}; + } + + return IconUtils::createSvgImageWithCustomColor(pixmapName, pixmapColor, size, requestedSize); + } +} +} diff --git a/src/gui/tray/svgimageprovider.h b/src/gui/tray/svgimageprovider.h new file mode 100644 index 000000000000..ea781b1a77a9 --- /dev/null +++ b/src/gui/tray/svgimageprovider.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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. + */ + +#pragma once + +#include + +namespace OCC { +namespace Ui { + class SvgImageProvider : public QQuickImageProvider + { + public: + SvgImageProvider(); + QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override; + }; +} +} diff --git a/src/gui/tray/syncstatussummary.cpp b/src/gui/tray/syncstatussummary.cpp new file mode 100644 index 000000000000..8f74985c8e6d --- /dev/null +++ b/src/gui/tray/syncstatussummary.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 "syncstatussummary.h" +#include "accountfwd.h" +#include "folderman.h" +#include "navigationpanehelper.h" +#include "networkjobs.h" +#include "syncresult.h" +#include "tray/usermodel.h" + +#include + +namespace { + +OCC::SyncResult::Status determineSyncStatus(const OCC::SyncResult &syncResult) +{ + const auto status = syncResult.status(); + + if (status == OCC::SyncResult::Success || status == OCC::SyncResult::Problem) { + if (syncResult.hasUnresolvedConflicts()) { + return OCC::SyncResult::Problem; + } + return OCC::SyncResult::Success; + } else if (status == OCC::SyncResult::SyncPrepare || status == OCC::SyncResult::Undefined) { + return OCC::SyncResult::SyncRunning; + } + return status; +} +} + +namespace OCC { + +Q_LOGGING_CATEGORY(lcSyncStatusModel, "nextcloud.gui.syncstatusmodel", QtInfoMsg) + +SyncStatusSummary::SyncStatusSummary(QObject *parent) + : QObject(parent) +{ + const auto folderMan = FolderMan::instance(); + connect(folderMan, &FolderMan::folderListChanged, this, &SyncStatusSummary::onFolderListChanged); + connect(folderMan, &FolderMan::folderSyncStateChange, this, &SyncStatusSummary::onFolderSyncStateChanged); +} + +bool SyncStatusSummary::reloadNeeded(AccountState *accountState) const +{ + if (_accountState.data() == accountState) { + return false; + } + return true; +} + +void SyncStatusSummary::load() +{ + const auto currentUser = UserModel::instance()->currentUser(); + if (!currentUser) { + return; + } + setAccountState(currentUser->accountState()); + clearFolderErrors(); + connectToFoldersProgress(FolderMan::instance()->map()); + initSyncState(); +} + +double SyncStatusSummary::syncProgress() const +{ + return _progress; +} + +QUrl SyncStatusSummary::syncIcon() const +{ + return _syncIcon; +} + +bool SyncStatusSummary::syncing() const +{ + return _isSyncing; +} + +void SyncStatusSummary::onFolderListChanged(const OCC::Folder::Map &folderMap) +{ + connectToFoldersProgress(folderMap); +} + +void SyncStatusSummary::markFolderAsError(const Folder *folder) +{ + _foldersWithErrors.insert(folder->alias()); +} + +void SyncStatusSummary::markFolderAsSuccess(const Folder *folder) +{ + _foldersWithErrors.erase(folder->alias()); +} + +bool SyncStatusSummary::folderErrors() const +{ + return _foldersWithErrors.size() != 0; +} + +bool SyncStatusSummary::folderError(const Folder *folder) const +{ + return _foldersWithErrors.find(folder->alias()) != _foldersWithErrors.end(); +} + +void SyncStatusSummary::clearFolderErrors() +{ + _foldersWithErrors.clear(); +} + +void SyncStatusSummary::setSyncStateForFolder(const Folder *folder) +{ + if (_accountState && !_accountState->isConnected()) { + setSyncing(false); + setSyncStatusString(tr("Offline")); + setSyncStatusDetailString(""); + setSyncIcon(Theme::instance()->folderOffline()); + return; + } + + const auto state = determineSyncStatus(folder->syncResult()); + + switch (state) { + case SyncResult::Success: + case SyncResult::SyncPrepare: + // Success should only be shown if all folders were fine + if (!folderErrors() || folderError(folder)) { + setSyncing(false); + setSyncStatusString(tr("All synced!")); + setSyncStatusDetailString(""); + setSyncIcon(Theme::instance()->syncStatusOk()); + markFolderAsSuccess(folder); + } + break; + case SyncResult::Error: + case SyncResult::SetupError: + setSyncing(false); + setSyncStatusString(tr("Some files couldn't be synced!")); + setSyncStatusDetailString(tr("See below for errors")); + setSyncIcon(Theme::instance()->syncStatusError()); + markFolderAsError(folder); + break; + case SyncResult::SyncRunning: + case SyncResult::NotYetStarted: + setSyncing(true); + setSyncStatusString(tr("Syncing")); + setSyncStatusDetailString(""); + setSyncIcon(Theme::instance()->syncStatusRunning()); + break; + case SyncResult::Paused: + case SyncResult::SyncAbortRequested: + setSyncing(false); + setSyncStatusString(tr("Sync paused")); + setSyncStatusDetailString(""); + setSyncIcon(Theme::instance()->syncStatusPause()); + break; + case SyncResult::Problem: + case SyncResult::Undefined: + setSyncing(false); + setSyncStatusString(tr("Some files could not be synced!")); + setSyncStatusDetailString(tr("See below for warnings")); + setSyncIcon(Theme::instance()->syncStatusWarning()); + markFolderAsError(folder); + break; + } +} + +void SyncStatusSummary::onFolderSyncStateChanged(const Folder *folder) +{ + if (!folder) { + return; + } + + if (!_accountState || folder->accountState() != _accountState.data()) { + return; + } + + setSyncStateForFolder(folder); +} + +constexpr double calculateOverallPercent( + qint64 totalFileCount, qint64 completedFile, qint64 totalSize, qint64 completedSize) +{ + int overallPercent = 0; + if (totalFileCount > 0) { + // Add one 'byte' for each file so the percentage is moving when deleting or renaming files + overallPercent = qRound(double(completedSize + completedFile) / double(totalSize + totalFileCount) * 100.0); + } + overallPercent = qBound(0, overallPercent, 100); + return overallPercent / 100.0; +} + +void SyncStatusSummary::onFolderProgressInfo(const ProgressInfo &progress) +{ + const qint64 completedSize = progress.completedSize(); + const qint64 currentFile = progress.currentFile(); + const qint64 completedFile = progress.completedFiles(); + const qint64 totalSize = qMax(completedSize, progress.totalSize()); + const qint64 totalFileCount = qMax(currentFile, progress.totalFiles()); + + setSyncProgress(calculateOverallPercent(totalFileCount, completedFile, totalSize, completedSize)); + + if (totalSize > 0) { + const auto completedSizeString = Utility::octetsToString(completedSize); + const auto totalSizeString = Utility::octetsToString(totalSize); + + if (progress.trustEta()) { + setSyncStatusDetailString( + tr("%1 of %2 · %3 left") + .arg(completedSizeString, totalSizeString) + .arg(Utility::durationToDescriptiveString1(progress.totalProgress().estimatedEta))); + } else { + setSyncStatusDetailString(tr("%1 of %2").arg(completedSizeString, totalSizeString)); + } + } + + if (totalFileCount > 0) { + setSyncStatusString(tr("Syncing file %1 of %2").arg(currentFile).arg(totalFileCount)); + } +} + +void SyncStatusSummary::setSyncing(bool value) +{ + if (value == _isSyncing) { + return; + } + + _isSyncing = value; + emit syncingChanged(); +} + +void SyncStatusSummary::setSyncProgress(double value) +{ + if (_progress == value) { + return; + } + + _progress = value; + emit syncProgressChanged(); +} + +void SyncStatusSummary::setSyncStatusString(const QString &value) +{ + if (_syncStatusString == value) { + return; + } + + _syncStatusString = value; + emit syncStatusStringChanged(); +} + +QString SyncStatusSummary::syncStatusString() const +{ + return _syncStatusString; +} + +QString SyncStatusSummary::syncStatusDetailString() const +{ + return _syncStatusDetailString; +} + +void SyncStatusSummary::setSyncIcon(const QUrl &value) +{ + if (_syncIcon == value) { + return; + } + + _syncIcon = value; + emit syncIconChanged(); +} + +void SyncStatusSummary::setSyncStatusDetailString(const QString &value) +{ + if (_syncStatusDetailString == value) { + return; + } + + _syncStatusDetailString = value; + emit syncStatusDetailStringChanged(); +} + +void SyncStatusSummary::connectToFoldersProgress(const Folder::Map &folderMap) +{ + for (const auto &folder : folderMap) { + if (folder->accountState() == _accountState.data()) { + connect( + folder, &Folder::progressInfo, this, &SyncStatusSummary::onFolderProgressInfo, Qt::UniqueConnection); + } else { + disconnect(folder, &Folder::progressInfo, this, &SyncStatusSummary::onFolderProgressInfo); + } + } +} + +void SyncStatusSummary::onIsConnectedChanged() +{ + setSyncStateToConnectedState(); +} + +void SyncStatusSummary::setSyncStateToConnectedState() +{ + setSyncing(false); + setSyncStatusDetailString(""); + if (_accountState && !_accountState->isConnected()) { + setSyncStatusString(tr("Offline")); + setSyncIcon(Theme::instance()->folderOffline()); + } else { + setSyncStatusString(tr("All synced!")); + setSyncIcon(Theme::instance()->syncStatusOk()); + } +} + +void SyncStatusSummary::setAccountState(AccountStatePtr accountState) +{ + if (!reloadNeeded(accountState.data())) { + return; + } + if (_accountState) { + disconnect( + _accountState.data(), &AccountState::isConnectedChanged, this, &SyncStatusSummary::onIsConnectedChanged); + } + _accountState = accountState; + connect(_accountState.data(), &AccountState::isConnectedChanged, this, &SyncStatusSummary::onIsConnectedChanged); +} + +void SyncStatusSummary::initSyncState() +{ + auto syncStateFallbackNeeded = true; + for (const auto &folder : FolderMan::instance()->map()) { + onFolderSyncStateChanged(folder); + syncStateFallbackNeeded = false; + } + + if (syncStateFallbackNeeded) { + setSyncStateToConnectedState(); + } +} +} diff --git a/src/gui/tray/syncstatussummary.h b/src/gui/tray/syncstatussummary.h new file mode 100644 index 000000000000..b4d1bb91b899 --- /dev/null +++ b/src/gui/tray/syncstatussummary.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +#pragma once + +#include "account.h" +#include "accountfwd.h" +#include "accountstate.h" +#include "folderman.h" + +#include +#include + +#include + +namespace OCC { + +class SyncStatusSummary : public QObject +{ + Q_OBJECT + + Q_PROPERTY(double syncProgress READ syncProgress NOTIFY syncProgressChanged) + Q_PROPERTY(QUrl syncIcon READ syncIcon NOTIFY syncIconChanged) + Q_PROPERTY(bool syncing READ syncing NOTIFY syncingChanged) + Q_PROPERTY(QString syncStatusString READ syncStatusString NOTIFY syncStatusStringChanged) + Q_PROPERTY(QString syncStatusDetailString READ syncStatusDetailString NOTIFY syncStatusDetailStringChanged) + +public: + explicit SyncStatusSummary(QObject *parent = nullptr); + + double syncProgress() const; + QUrl syncIcon() const; + bool syncing() const; + QString syncStatusString() const; + QString syncStatusDetailString() const; + +signals: + void syncProgressChanged(); + void syncIconChanged(); + void syncingChanged(); + void syncStatusStringChanged(); + void syncStatusDetailStringChanged(); + +public slots: + void load(); + +private: + void connectToFoldersProgress(const Folder::Map &map); + + void onFolderListChanged(const OCC::Folder::Map &folderMap); + void onFolderProgressInfo(const ProgressInfo &progress); + void onFolderSyncStateChanged(const Folder *folder); + void onIsConnectedChanged(); + + void setSyncStateForFolder(const Folder *folder); + void markFolderAsError(const Folder *folder); + void markFolderAsSuccess(const Folder *folder); + bool folderErrors() const; + bool folderError(const Folder *folder) const; + void clearFolderErrors(); + void setSyncStateToConnectedState(); + bool reloadNeeded(AccountState *accountState) const; + void initSyncState(); + + void setSyncProgress(double value); + void setSyncing(bool value); + void setSyncStatusString(const QString &value); + void setSyncStatusDetailString(const QString &value); + void setSyncIcon(const QUrl &value); + void setAccountState(AccountStatePtr accountState); + + AccountStatePtr _accountState; + std::set _foldersWithErrors; + + QUrl _syncIcon = Theme::instance()->syncStatusOk(); + double _progress = 1.0; + bool _isSyncing = false; + QString _syncStatusString = tr("All synced!"); + QString _syncStatusDetailString; +}; +} diff --git a/src/gui/tray/unifiedsearchresult.cpp b/src/gui/tray/unifiedsearchresult.cpp new file mode 100644 index 000000000000..768ff3148c22 --- /dev/null +++ b/src/gui/tray/unifiedsearchresult.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 + +#include "unifiedsearchresult.h" + +namespace OCC { + +QString UnifiedSearchResult::typeAsString(UnifiedSearchResult::Type type) +{ + QString result; + + switch (type) { + case Default: + result = QStringLiteral("Default"); + break; + + case FetchMoreTrigger: + result = QStringLiteral("FetchMoreTrigger"); + break; + } + return result; +} +} diff --git a/src/gui/tray/unifiedsearchresult.h b/src/gui/tray/unifiedsearchresult.h new file mode 100644 index 000000000000..bae3158d634b --- /dev/null +++ b/src/gui/tray/unifiedsearchresult.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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. + */ + +#pragma once + +#include + +#include + +namespace OCC { + +/** + * @brief The UnifiedSearchResult class + * @ingroup gui + * Simple data structure that represents single Unified Search result + */ + +struct UnifiedSearchResult +{ + enum Type : quint8 { + Default, + FetchMoreTrigger, + }; + + static QString typeAsString(UnifiedSearchResult::Type type); + + QString _title; + QString _subline; + QString _providerId; + QString _providerName; + bool _isRounded = false; + qint32 _order = std::numeric_limits::max(); + QUrl _resourceUrl; + QString _icons; + Type _type = Type::Default; +}; +} diff --git a/src/gui/tray/unifiedsearchresultimageprovider.cpp b/src/gui/tray/unifiedsearchresultimageprovider.cpp new file mode 100644 index 000000000000..97a57f519dfd --- /dev/null +++ b/src/gui/tray/unifiedsearchresultimageprovider.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 "unifiedsearchresultimageprovider.h" + +#include "usermodel.h" + +#include +#include +#include + +namespace { +class AsyncImageResponse : public QQuickImageResponse +{ +public: + AsyncImageResponse(const QString &id, const QSize &requestedSize) + { + if (id.isEmpty()) { + setImageAndEmitFinished(); + return; + } + + _imagePaths = id.split(QLatin1Char(';'), Qt::SkipEmptyParts); + _requestedImageSize = requestedSize; + + if (_imagePaths.isEmpty()) { + setImageAndEmitFinished(); + } else { + processNextImage(); + } + } + + void setImageAndEmitFinished(const QImage &image = {}) + { + _image = image; + emit finished(); + } + + QQuickTextureFactory *textureFactory() const override + { + return QQuickTextureFactory::textureFactoryForImage(_image); + } + +private: + void processNextImage() + { + if (_index < 0 || _index >= _imagePaths.size()) { + setImageAndEmitFinished(); + return; + } + + if (_imagePaths.at(_index).startsWith(QStringLiteral(":/client"))) { + setImageAndEmitFinished(QIcon(_imagePaths.at(_index)).pixmap(_requestedImageSize).toImage()); + return; + } + + const auto currentUser = OCC::UserModel::instance()->currentUser(); + if (currentUser && currentUser->account()) { + const QUrl iconUrl(_imagePaths.at(_index)); + if (iconUrl.isValid() && !iconUrl.scheme().isEmpty()) { + // fetch the remote resource + const auto reply = currentUser->account()->sendRawRequest(QByteArrayLiteral("GET"), iconUrl); + connect(reply, &QNetworkReply::finished, this, &AsyncImageResponse::slotProcessNetworkReply); + ++_index; + return; + } + } + + setImageAndEmitFinished(); + } + +private slots: + void slotProcessNetworkReply() + { + const auto reply = qobject_cast(sender()); + if (!reply) { + setImageAndEmitFinished(); + return; + } + + const QByteArray imageData = reply->readAll(); + // server returns "[]" for some some file previews (have no idea why), so, we use another image + // from the list if available + if (imageData.isEmpty() || imageData == QByteArrayLiteral("[]")) { + processNextImage(); + } else { + if (imageData.startsWith(QByteArrayLiteral(" + * + * 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. + */ + +#pragma once + +#include +#include + +namespace OCC { + +/** + * @brief The UnifiedSearchResultImageProvider + * @ingroup gui + * Allows to fetch Unified Search result icon from the server or used a local resource + */ + +class UnifiedSearchResultImageProvider : public QQuickAsyncImageProvider +{ +public: + QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override; +}; +} diff --git a/src/gui/tray/unifiedsearchresultslistmodel.cpp b/src/gui/tray/unifiedsearchresultslistmodel.cpp new file mode 100644 index 000000000000..a6cc8569d1fd --- /dev/null +++ b/src/gui/tray/unifiedsearchresultslistmodel.cpp @@ -0,0 +1,708 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 "unifiedsearchresultslistmodel.h" + +#include "account.h" +#include "accountstate.h" +#include "guiutility.h" +#include "folderman.h" +#include "networkjobs.h" + +#include + +#include +#include + +namespace { +QString imagePlaceholderUrlForProviderId(const QString &providerId) +{ + if (providerId.contains(QStringLiteral("message"), Qt::CaseInsensitive) + || providerId.contains(QStringLiteral("talk"), Qt::CaseInsensitive)) { + return QStringLiteral("qrc:///client/theme/black/wizard-talk.svg"); + } else if (providerId.contains(QStringLiteral("file"), Qt::CaseInsensitive)) { + return QStringLiteral("qrc:///client/theme/black/edit.svg"); + } else if (providerId.contains(QStringLiteral("deck"), Qt::CaseInsensitive)) { + return QStringLiteral("qrc:///client/theme/black/deck.svg"); + } else if (providerId.contains(QStringLiteral("calendar"), Qt::CaseInsensitive)) { + return QStringLiteral("qrc:///client/theme/black/calendar.svg"); + } else if (providerId.contains(QStringLiteral("mail"), Qt::CaseInsensitive)) { + return QStringLiteral("qrc:///client/theme/black/email.svg"); + } else if (providerId.contains(QStringLiteral("comment"), Qt::CaseInsensitive)) { + return QStringLiteral("qrc:///client/theme/black/comment.svg"); + } + + return QStringLiteral("qrc:///client/theme/change.svg"); +} + +QString localIconPathFromIconPrefix(const QString &iconNameWithPrefix) +{ + if (iconNameWithPrefix.contains(QStringLiteral("message"), Qt::CaseInsensitive) + || iconNameWithPrefix.contains(QStringLiteral("talk"), Qt::CaseInsensitive)) { + return QStringLiteral(":/client/theme/black/wizard-talk.svg"); + } else if (iconNameWithPrefix.contains(QStringLiteral("folder"), Qt::CaseInsensitive)) { + return QStringLiteral(":/client/theme/black/folder.svg"); + } else if (iconNameWithPrefix.contains(QStringLiteral("deck"), Qt::CaseInsensitive)) { + return QStringLiteral(":/client/theme/black/deck.svg"); + } else if (iconNameWithPrefix.contains(QStringLiteral("contacts"), Qt::CaseInsensitive)) { + return QStringLiteral(":/client/theme/black/wizard-groupware.svg"); + } else if (iconNameWithPrefix.contains(QStringLiteral("calendar"), Qt::CaseInsensitive)) { + return QStringLiteral(":/client/theme/black/calendar.svg"); + } else if (iconNameWithPrefix.contains(QStringLiteral("mail"), Qt::CaseInsensitive)) { + return QStringLiteral(":/client/theme/black/email.svg"); + } + + return QStringLiteral(":/client/theme/change.svg"); +} + +QString iconUrlForDefaultIconName(const QString &defaultIconName) +{ + const QUrl urlForIcon{defaultIconName}; + + if (urlForIcon.isValid() && !urlForIcon.scheme().isEmpty()) { + return defaultIconName; + } + + if (defaultIconName.startsWith(QStringLiteral("icon-"))) { + const auto parts = defaultIconName.split(QLatin1Char('-')); + + if (parts.size() > 1) { + const QString iconFilePath = QStringLiteral(":/client/theme/") + parts[1] + QStringLiteral(".svg"); + + if (QFile::exists(iconFilePath)) { + return iconFilePath; + } + + const QString blackIconFilePath = QStringLiteral(":/client/theme/black/") + parts[1] + QStringLiteral(".svg"); + + if (QFile::exists(blackIconFilePath)) { + return blackIconFilePath; + } + } + + const auto iconNameFromIconPrefix = localIconPathFromIconPrefix(defaultIconName); + + if (!iconNameFromIconPrefix.isEmpty()) { + return iconNameFromIconPrefix; + } + } + + return QStringLiteral(":/client/theme/change.svg"); +} + +QString generateUrlForThumbnail(const QString &thumbnailUrl, const QUrl &serverUrl) +{ + auto serverUrlCopy = serverUrl; + auto thumbnailUrlCopy = thumbnailUrl; + + if (thumbnailUrlCopy.startsWith(QLatin1Char('/')) || thumbnailUrlCopy.startsWith(QLatin1Char('\\'))) { + // relative image resource URL, just needs some concatenation with current server URL + // some icons may contain parameters after (?) + const QStringList thumbnailUrlCopySplitted = thumbnailUrlCopy.contains(QLatin1Char('?')) + ? thumbnailUrlCopy.split(QLatin1Char('?'), Qt::SkipEmptyParts) + : QStringList{thumbnailUrlCopy}; + Q_ASSERT(!thumbnailUrlCopySplitted.isEmpty()); + serverUrlCopy.setPath(thumbnailUrlCopySplitted[0]); + thumbnailUrlCopy = serverUrlCopy.toString(); + if (thumbnailUrlCopySplitted.size() > 1) { + thumbnailUrlCopy += QLatin1Char('?') + thumbnailUrlCopySplitted[1]; + } + } + + return thumbnailUrlCopy; +} + +QString generateUrlForIcon(const QString &fallackIcon, const QUrl &serverUrl) +{ + auto serverUrlCopy = serverUrl; + + auto fallackIconCopy = fallackIcon; + + if (fallackIconCopy.startsWith(QLatin1Char('/')) || fallackIconCopy.startsWith(QLatin1Char('\\'))) { + // relative image resource URL, just needs some concatenation with current server URL + // some icons may contain parameters after (?) + const QStringList fallackIconPathSplitted = + fallackIconCopy.contains(QLatin1Char('?')) ? fallackIconCopy.split(QLatin1Char('?')) : QStringList{fallackIconCopy}; + Q_ASSERT(!fallackIconPathSplitted.isEmpty()); + serverUrlCopy.setPath(fallackIconPathSplitted[0]); + fallackIconCopy = serverUrlCopy.toString(); + if (fallackIconPathSplitted.size() > 1) { + fallackIconCopy += QLatin1Char('?') + fallackIconPathSplitted[1]; + } + } else if (!fallackIconCopy.isEmpty()) { + // could be one of names for standard icons (e.g. icon-mail) + const auto defaultIconUrl = iconUrlForDefaultIconName(fallackIconCopy); + if (!defaultIconUrl.isEmpty()) { + fallackIconCopy = defaultIconUrl; + } + } + + return fallackIconCopy; +} + +QString iconsFromThumbnailAndFallbackIcon(const QString &thumbnailUrl, const QString &fallackIcon, const QUrl &serverUrl) +{ + if (thumbnailUrl.isEmpty() && fallackIcon.isEmpty()) { + return {}; + } + + if (serverUrl.isEmpty()) { + const QStringList listImages = {thumbnailUrl, fallackIcon}; + return listImages.join(QLatin1Char(';')); + } + + const auto urlForThumbnail = generateUrlForThumbnail(thumbnailUrl, serverUrl); + const auto urlForFallackIcon = generateUrlForIcon(fallackIcon, serverUrl); + + if (urlForThumbnail.isEmpty() && !urlForFallackIcon.isEmpty()) { + return urlForFallackIcon; + } + + if (!urlForThumbnail.isEmpty() && urlForFallackIcon.isEmpty()) { + return urlForThumbnail; + } + + const QStringList listImages{urlForThumbnail, urlForFallackIcon}; + return listImages.join(QLatin1Char(';')); +} + +constexpr int searchTermEditingFinishedSearchStartDelay = 800; + +// server-side bug of returning the cursor > 0 and isPaginated == 'true', using '5' as it is done on Android client's end now +constexpr int minimumEntresNumberToShowLoadMore = 5; +} +namespace OCC { +Q_LOGGING_CATEGORY(lcUnifiedSearch, "nextcloud.gui.unifiedsearch", QtInfoMsg) + +UnifiedSearchResultsListModel::UnifiedSearchResultsListModel(AccountState *accountState, QObject *parent) + : QAbstractListModel(parent) + , _accountState(accountState) +{ +} + +QVariant UnifiedSearchResultsListModel::data(const QModelIndex &index, int role) const +{ + Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid)); + + switch (role) { + case ProviderNameRole: + return _results.at(index.row())._providerName; + case ProviderIdRole: + return _results.at(index.row())._providerId; + case ImagePlaceholderRole: + return imagePlaceholderUrlForProviderId(_results.at(index.row())._providerId); + case IconsRole: + return _results.at(index.row())._icons; + case TitleRole: + return _results.at(index.row())._title; + case SublineRole: + return _results.at(index.row())._subline; + case ResourceUrlRole: + return _results.at(index.row())._resourceUrl; + case RoundedRole: + return _results.at(index.row())._isRounded; + case TypeRole: + return _results.at(index.row())._type; + case TypeAsStringRole: + return UnifiedSearchResult::typeAsString(_results.at(index.row())._type); + } + + return {}; +} + +int UnifiedSearchResultsListModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) { + return 0; + } + + return _results.size(); +} + +QHash UnifiedSearchResultsListModel::roleNames() const +{ + auto roles = QAbstractListModel::roleNames(); + roles[ProviderNameRole] = "providerName"; + roles[ProviderIdRole] = "providerId"; + roles[IconsRole] = "icons"; + roles[ImagePlaceholderRole] = "imagePlaceholder"; + roles[TitleRole] = "resultTitle"; + roles[SublineRole] = "subline"; + roles[ResourceUrlRole] = "resourceUrlRole"; + roles[TypeRole] = "type"; + roles[TypeAsStringRole] = "typeAsString"; + roles[RoundedRole] = "isRounded"; + return roles; +} + +QString UnifiedSearchResultsListModel::searchTerm() const +{ + return _searchTerm; +} + +QString UnifiedSearchResultsListModel::errorString() const +{ + return _errorString; +} + +QString UnifiedSearchResultsListModel::currentFetchMoreInProgressProviderId() const +{ + return _currentFetchMoreInProgressProviderId; +} + +void UnifiedSearchResultsListModel::setSearchTerm(const QString &term) +{ + if (term == _searchTerm) { + return; + } + + _searchTerm = term; + emit searchTermChanged(); + + if (!_errorString.isEmpty()) { + _errorString.clear(); + emit errorStringChanged(); + } + + disconnectAndClearSearchJobs(); + + clearCurrentFetchMoreInProgressProviderId(); + + disconnect(&_unifiedSearchTextEditingFinishedTimer, &QTimer::timeout, this, + &UnifiedSearchResultsListModel::slotSearchTermEditingFinished); + + if (_unifiedSearchTextEditingFinishedTimer.isActive()) { + _unifiedSearchTextEditingFinishedTimer.stop(); + } + + if (!_searchTerm.isEmpty()) { + _unifiedSearchTextEditingFinishedTimer.setInterval(searchTermEditingFinishedSearchStartDelay); + connect(&_unifiedSearchTextEditingFinishedTimer, &QTimer::timeout, this, + &UnifiedSearchResultsListModel::slotSearchTermEditingFinished); + _unifiedSearchTextEditingFinishedTimer.start(); + } + + if (!_results.isEmpty()) { + beginResetModel(); + _results.clear(); + endResetModel(); + } +} + +bool UnifiedSearchResultsListModel::isSearchInProgress() const +{ + return !_searchJobConnections.isEmpty(); +} + +void UnifiedSearchResultsListModel::resultClicked(const QString &providerId, const QUrl &resourceUrl) const +{ + const QUrlQuery urlQuery{resourceUrl}; + const auto dir = urlQuery.queryItemValue(QStringLiteral("dir"), QUrl::ComponentFormattingOption::FullyDecoded); + const auto fileName = + urlQuery.queryItemValue(QStringLiteral("scrollto"), QUrl::ComponentFormattingOption::FullyDecoded); + + if (providerId.contains(QStringLiteral("file"), Qt::CaseInsensitive) && !dir.isEmpty() && !fileName.isEmpty()) { + if (!_accountState || !_accountState->account()) { + return; + } + + const QString relativePath = dir + QLatin1Char('/') + fileName; + const auto localFiles = + FolderMan::instance()->findFileInLocalFolders(QFileInfo(relativePath).path(), _accountState->account()); + + if (!localFiles.isEmpty()) { + QDesktopServices::openUrl(localFiles.constFirst()); + return; + } + } + Utility::openBrowser(resourceUrl); +} + +void UnifiedSearchResultsListModel::fetchMoreTriggerClicked(const QString &providerId) +{ + if (isSearchInProgress() || !_currentFetchMoreInProgressProviderId.isEmpty()) { + return; + } + + const auto providerInfo = _providers.value(providerId, {}); + + if (!providerInfo._id.isEmpty() && providerInfo._id == providerId && providerInfo._isPaginated) { + // Load more items + _currentFetchMoreInProgressProviderId = providerId; + emit currentFetchMoreInProgressProviderIdChanged(); + startSearchForProvider(providerId, providerInfo._cursor); + } +} + +void UnifiedSearchResultsListModel::slotSearchTermEditingFinished() +{ + disconnect(&_unifiedSearchTextEditingFinishedTimer, &QTimer::timeout, this, + &UnifiedSearchResultsListModel::slotSearchTermEditingFinished); + + if (!_accountState || !_accountState->account()) { + qCCritical(lcUnifiedSearch) << QString("Account state is invalid. Could not start search!"); + return; + } + + if (_providers.isEmpty()) { + auto job = new JsonApiJob(_accountState->account(), QLatin1String("ocs/v2.php/search/providers")); + QObject::connect(job, &JsonApiJob::jsonReceived, this, &UnifiedSearchResultsListModel::slotFetchProvidersFinished); + job->start(); + } else { + startSearch(); + } +} + +void UnifiedSearchResultsListModel::slotFetchProvidersFinished(const QJsonDocument &json, int statusCode) +{ + const auto job = qobject_cast(sender()); + + if (!job) { + qCCritical(lcUnifiedSearch) << QString("Failed to fetch providers.").arg(_searchTerm); + _errorString += tr("Failed to fetch providers.") + QLatin1Char('\n'); + emit errorStringChanged(); + return; + } + + if (statusCode != 200) { + qCCritical(lcUnifiedSearch) << QString("%1: Failed to fetch search providers for '%2'. Error: %3") + .arg(statusCode) + .arg(_searchTerm) + .arg(job->errorString()); + _errorString += + tr("Failed to fetch search providers for '%1'. Error: %2").arg(_searchTerm).arg(job->errorString()) + + QLatin1Char('\n'); + emit errorStringChanged(); + return; + } + const auto providerList = + json.object().value(QStringLiteral("ocs")).toObject().value(QStringLiteral("data")).toVariant().toList(); + + for (const auto &provider : providerList) { + const auto providerMap = provider.toMap(); + const auto id = providerMap[QStringLiteral("id")].toString(); + const auto name = providerMap[QStringLiteral("name")].toString(); + if (!name.isEmpty() && id != QStringLiteral("talk-message-current")) { + UnifiedSearchProvider newProvider; + newProvider._name = name; + newProvider._id = id; + newProvider._order = providerMap[QStringLiteral("order")].toInt(); + _providers.insert(newProvider._id, newProvider); + } + } + + if (!_providers.empty()) { + startSearch(); + } +} + +void UnifiedSearchResultsListModel::slotSearchForProviderFinished(const QJsonDocument &json, int statusCode) +{ + Q_ASSERT(_accountState && _accountState->account()); + + const auto job = qobject_cast(sender()); + + if (!job) { + qCCritical(lcUnifiedSearch) << QString("Search has failed for '%2'.").arg(_searchTerm); + _errorString += tr("Search has failed for '%2'.").arg(_searchTerm) + QLatin1Char('\n'); + emit errorStringChanged(); + return; + } + + const auto providerId = job->property("providerId").toString(); + + if (providerId.isEmpty()) { + return; + } + + if (!_searchJobConnections.isEmpty()) { + _searchJobConnections.remove(providerId); + + if (_searchJobConnections.isEmpty()) { + emit isSearchInProgressChanged(); + } + } + + if (providerId == _currentFetchMoreInProgressProviderId) { + clearCurrentFetchMoreInProgressProviderId(); + } + + if (statusCode != 200) { + qCCritical(lcUnifiedSearch) << QString("%1: Search has failed for '%2'. Error: %3") + .arg(statusCode) + .arg(_searchTerm) + .arg(job->errorString()); + _errorString += + tr("Search has failed for '%1'. Error: %2").arg(_searchTerm).arg(job->errorString()) + QLatin1Char('\n'); + emit errorStringChanged(); + return; + } + + const auto data = json.object().value(QStringLiteral("ocs")).toObject().value(QStringLiteral("data")).toObject(); + if (!data.isEmpty()) { + parseResultsForProvider(data, providerId, job->property("appendResults").toBool()); + } +} + +void UnifiedSearchResultsListModel::startSearch() +{ + Q_ASSERT(_accountState && _accountState->account()); + + disconnectAndClearSearchJobs(); + + if (!_accountState || !_accountState->account()) { + return; + } + + if (!_results.isEmpty()) { + beginResetModel(); + _results.clear(); + endResetModel(); + } + + for (const auto &provider : _providers) { + startSearchForProvider(provider._id); + } +} + +void UnifiedSearchResultsListModel::startSearchForProvider(const QString &providerId, qint32 cursor) +{ + Q_ASSERT(_accountState && _accountState->account()); + + if (!_accountState || !_accountState->account()) { + return; + } + + auto job = new JsonApiJob(_accountState->account(), + QLatin1String("ocs/v2.php/search/providers/%1/search").arg(providerId)); + + QUrlQuery params; + params.addQueryItem(QStringLiteral("term"), _searchTerm); + if (cursor > 0) { + params.addQueryItem(QStringLiteral("cursor"), QString::number(cursor)); + job->setProperty("appendResults", true); + } + job->setProperty("providerId", providerId); + job->addQueryParams(params); + const auto wasSearchInProgress = isSearchInProgress(); + _searchJobConnections.insert(providerId, + QObject::connect( + job, &JsonApiJob::jsonReceived, this, &UnifiedSearchResultsListModel::slotSearchForProviderFinished)); + if (isSearchInProgress() && !wasSearchInProgress) { + emit isSearchInProgressChanged(); + } + job->start(); +} + +void UnifiedSearchResultsListModel::parseResultsForProvider(const QJsonObject &data, const QString &providerId, bool fetchedMore) +{ + const auto cursor = data.value(QStringLiteral("cursor")).toInt(); + const auto entries = data.value(QStringLiteral("entries")).toVariant().toList(); + + auto &provider = _providers[providerId]; + + if (provider._id.isEmpty() && fetchedMore) { + _providers.remove(providerId); + return; + } + + if (entries.isEmpty()) { + // we may have received false pagination information from the server, such as, we expect more + // results available via pagination, but, there are no more left, so, we need to stop paginating for + // this provider + provider._isPaginated = false; + + if (fetchedMore) { + removeFetchMoreTrigger(provider._id); + } + + return; + } + + provider._isPaginated = data.value(QStringLiteral("isPaginated")).toBool(); + provider._cursor = cursor; + + if (provider._pageSize == -1) { + provider._pageSize = cursor; + } + + if ((provider._pageSize != -1 && entries.size() < provider._pageSize) + || entries.size() < minimumEntresNumberToShowLoadMore) { + // for some providers we are still getting a non-null cursor and isPaginated true even thought + // there are no more results to paginate + provider._isPaginated = false; + } + + QVector newEntries; + + const auto makeResourceUrl = [](const QString &resourceUrl, const QUrl &accountUrl) { + QUrl finalResurceUrl(resourceUrl); + if (finalResurceUrl.scheme().isEmpty() && accountUrl.scheme().isEmpty()) { + finalResurceUrl = accountUrl; + finalResurceUrl.setPath(resourceUrl); + } + return finalResurceUrl; + }; + + for (const auto &entry : entries) { + const auto entryMap = entry.toMap(); + if (entryMap.isEmpty()) { + continue; + } + UnifiedSearchResult result; + result._providerId = provider._id; + result._order = provider._order; + result._providerName = provider._name; + result._isRounded = entryMap.value(QStringLiteral("rounded")).toBool(); + result._title = entryMap.value(QStringLiteral("title")).toString(); + result._subline = entryMap.value(QStringLiteral("subline")).toString(); + + const auto resourceUrl = entryMap.value(QStringLiteral("resourceUrl")).toString(); + const auto accountUrl = (_accountState && _accountState->account()) ? _accountState->account()->url() : QUrl(); + + result._resourceUrl = makeResourceUrl(resourceUrl, accountUrl); + result._icons = iconsFromThumbnailAndFallbackIcon(entryMap.value(QStringLiteral("thumbnailUrl")).toString(), + entryMap.value(QStringLiteral("icon")).toString(), accountUrl); + + newEntries.push_back(result); + } + + if (fetchedMore) { + appendResultsToProvider(newEntries, provider); + } else { + appendResults(newEntries, provider); + } +} + +void UnifiedSearchResultsListModel::appendResults(QVector results, const UnifiedSearchProvider &provider) +{ + if (provider._cursor > 0 && provider._isPaginated) { + UnifiedSearchResult fetchMoreTrigger; + fetchMoreTrigger._providerId = provider._id; + fetchMoreTrigger._providerName = provider._name; + fetchMoreTrigger._order = provider._order; + fetchMoreTrigger._type = UnifiedSearchResult::Type::FetchMoreTrigger; + results.push_back(fetchMoreTrigger); + } + + + if (_results.isEmpty()) { + beginInsertRows({}, 0, results.size() - 1); + _results = results; + endInsertRows(); + return; + } + + // insertion is done with sorting (first -> by order, then -> by name) + const auto itToInsertTo = std::find_if(std::begin(_results), std::end(_results), + [&provider](const UnifiedSearchResult ¤t) { + // insert before other results of higher order when possible + if (current._order > provider._order) { + return true; + } else { + if (current._order == provider._order) { + // insert before results of higher QString value when possible + return current._providerName > provider._name; + } + + return false; + } + }); + + const auto first = static_cast(std::distance(std::begin(_results), itToInsertTo)); + const auto last = first + results.size() - 1; + + beginInsertRows({}, first, last); + std::copy(std::begin(results), std::end(results), std::inserter(_results, itToInsertTo)); + endInsertRows(); +} + +void UnifiedSearchResultsListModel::appendResultsToProvider(const QVector &results, const UnifiedSearchProvider &provider) +{ + if (results.isEmpty()) { + return; + } + + const auto providerId = provider._id; + /* we need to find the last result that is not a fetch-more-trigger or category-separator for the current + provider */ + const auto itLastResultForProviderReverse = + std::find_if(std::rbegin(_results), std::rend(_results), [&providerId](const UnifiedSearchResult &result) { + return result._providerId == providerId && result._type == UnifiedSearchResult::Type::Default; + }); + + if (itLastResultForProviderReverse != std::rend(_results)) { + // #1 Insert rows + // convert reverse_iterator to iterator + const auto itLastResultForProvider = (itLastResultForProviderReverse + 1).base(); + const auto first = static_cast(std::distance(std::begin(_results), itLastResultForProvider + 1)); + const auto last = first + results.size() - 1; + beginInsertRows({}, first, last); + std::copy(std::begin(results), std::end(results), std::inserter(_results, itLastResultForProvider + 1)); + endInsertRows(); + + // #2 Remove the FetchMoreTrigger item if there are no more results to load for this provider + if (!provider._isPaginated) { + removeFetchMoreTrigger(providerId); + } + } +} + +void UnifiedSearchResultsListModel::removeFetchMoreTrigger(const QString &providerId) +{ + const auto itFetchMoreTriggerForProviderReverse = std::find_if( + std::rbegin(_results), + std::rend(_results), + [providerId](const UnifiedSearchResult &result) { + return result._providerId == providerId && result._type == UnifiedSearchResult::Type::FetchMoreTrigger; + }); + + if (itFetchMoreTriggerForProviderReverse != std::rend(_results)) { + // convert reverse_iterator to iterator + const auto itFetchMoreTriggerForProvider = (itFetchMoreTriggerForProviderReverse + 1).base(); + + if (itFetchMoreTriggerForProvider != std::end(_results) + && itFetchMoreTriggerForProvider != std::begin(_results)) { + const auto eraseIndex = static_cast(std::distance(std::begin(_results), itFetchMoreTriggerForProvider)); + Q_ASSERT(eraseIndex >= 0 && eraseIndex < static_cast(_results.size())); + beginRemoveRows({}, eraseIndex, eraseIndex); + _results.erase(itFetchMoreTriggerForProvider); + endRemoveRows(); + } + } +} + +void UnifiedSearchResultsListModel::disconnectAndClearSearchJobs() +{ + for (const auto &connection : _searchJobConnections) { + if (connection) { + QObject::disconnect(connection); + } + } + + if (!_searchJobConnections.isEmpty()) { + _searchJobConnections.clear(); + emit isSearchInProgressChanged(); + } +} + +void UnifiedSearchResultsListModel::clearCurrentFetchMoreInProgressProviderId() +{ + if (!_currentFetchMoreInProgressProviderId.isEmpty()) { + _currentFetchMoreInProgressProviderId.clear(); + emit currentFetchMoreInProgressProviderIdChanged(); + } +} + +} diff --git a/src/gui/tray/unifiedsearchresultslistmodel.h b/src/gui/tray/unifiedsearchresultslistmodel.h new file mode 100644 index 000000000000..5ae811f20572 --- /dev/null +++ b/src/gui/tray/unifiedsearchresultslistmodel.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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. + */ + +#pragma once + +#include "unifiedsearchresult.h" + +#include + +#include + +namespace OCC { +class AccountState; + +/** + * @brief The UnifiedSearchResultsListModel + * @ingroup gui + * Simple list model to provide the list view with data for the Unified Search results. + */ + +class UnifiedSearchResultsListModel : public QAbstractListModel +{ + Q_OBJECT + + Q_PROPERTY(bool isSearchInProgress READ isSearchInProgress NOTIFY isSearchInProgressChanged) + Q_PROPERTY(QString currentFetchMoreInProgressProviderId READ currentFetchMoreInProgressProviderId NOTIFY + currentFetchMoreInProgressProviderIdChanged) + Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged) + Q_PROPERTY(QString searchTerm READ searchTerm WRITE setSearchTerm NOTIFY searchTermChanged) + + struct UnifiedSearchProvider + { + QString _id; + QString _name; + qint32 _cursor = -1; // current pagination value + qint32 _pageSize = -1; // how many max items per step of pagination + bool _isPaginated = false; + qint32 _order = std::numeric_limits::max(); // sorting order (smaller number has bigger priority) + }; + +public: + enum DataRole { + ProviderNameRole = Qt::UserRole + 1, + ProviderIdRole, + ImagePlaceholderRole, + IconsRole, + TitleRole, + SublineRole, + ResourceUrlRole, + RoundedRole, + TypeRole, + TypeAsStringRole, + }; + + explicit UnifiedSearchResultsListModel(AccountState *accountState, QObject *parent = nullptr); + + QVariant data(const QModelIndex &index, int role) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + bool isSearchInProgress() const; + + QString currentFetchMoreInProgressProviderId() const; + QString searchTerm() const; + QString errorString() const; + + Q_INVOKABLE void resultClicked(const QString &providerId, const QUrl &resourceUrl) const; + Q_INVOKABLE void fetchMoreTriggerClicked(const QString &providerId); + + QHash roleNames() const override; + +private: + void startSearch(); + void startSearchForProvider(const QString &providerId, qint32 cursor = -1); + + void parseResultsForProvider(const QJsonObject &data, const QString &providerId, bool fetchedMore = false); + + // append initial search results to the list + void appendResults(QVector results, const UnifiedSearchProvider &provider); + + // append pagination results to existing results from the initial search + void appendResultsToProvider(const QVector &results, const UnifiedSearchProvider &provider); + + void removeFetchMoreTrigger(const QString &providerId); + + void disconnectAndClearSearchJobs(); + + void clearCurrentFetchMoreInProgressProviderId(); + +signals: + void currentFetchMoreInProgressProviderIdChanged(); + void isSearchInProgressChanged(); + void errorStringChanged(); + void searchTermChanged(); + +public slots: + void setSearchTerm(const QString &term); + +private slots: + void slotSearchTermEditingFinished(); + void slotFetchProvidersFinished(const QJsonDocument &json, int statusCode); + void slotSearchForProviderFinished(const QJsonDocument &json, int statusCode); + +private: + QMap _providers; + QVector _results; + + QString _searchTerm; + QString _errorString; + + QString _currentFetchMoreInProgressProviderId; + + QMap _searchJobConnections; + + QTimer _unifiedSearchTextEditingFinishedTimer; + + AccountState *_accountState = nullptr; +}; +} diff --git a/src/gui/tray/UserModel.cpp b/src/gui/tray/usermodel.cpp similarity index 95% rename from src/gui/tray/UserModel.cpp rename to src/gui/tray/usermodel.cpp index 907392571900..36016ead7e13 100644 --- a/src/gui/tray/UserModel.cpp +++ b/src/gui/tray/usermodel.cpp @@ -1,9 +1,10 @@ -#include "NotificationHandler.h" -#include "UserModel.h" +#include "notificationhandler.h" +#include "usermodel.h" #include "accountmanager.h" #include "owncloudgui.h" #include +#include "userstatusselectormodel.h" #include "syncengine.h" #include "ocsjob.h" #include "configfile.h" @@ -11,7 +12,10 @@ #include "logger.h" #include "guiutility.h" #include "syncfileitem.h" -#include "tray/NotificationCache.h" +#include "tray/activitylistmodel.h" +#include "tray/notificationcache.h" +#include "tray/unifiedsearchresultslistmodel.h" +#include "userstatusconnector.h" #include #include @@ -25,8 +29,8 @@ #define NOTIFICATION_REQUEST_FREE_PERIOD 15000 namespace { - constexpr qint64 expiredActivitiesCheckIntervalMsecs = 1000 * 60; - constexpr qint64 activityDefaultExpirationTimeMsecs = 1000 * 60 * 10; +constexpr qint64 expiredActivitiesCheckIntervalMsecs = 1000 * 60; +constexpr qint64 activityDefaultExpirationTimeMsecs = 1000 * 60 * 10; } namespace OCC { @@ -35,7 +39,8 @@ User::User(AccountStatePtr &account, const bool &isCurrent, QObject *parent) : QObject(parent) , _account(account) , _isCurrentUser(isCurrent) - , _activityModel(new ActivityListModel(_account.data())) + , _activityModel(new ActivityListModel(_account.data(), this)) + , _unifiedSearchResultsModel(new UnifiedSearchResultsListModel(_account.data(), this)) , _notificationRequestsRunning(0) { connect(ProgressDispatcher::instance(), &ProgressDispatcher::progressInfo, @@ -65,7 +70,7 @@ User::User(AccountStatePtr &account, const bool &isCurrent, QObject *parent) connect(this, &User::guiLog, Logger::instance(), &Logger::guiLog); connect(_account->account().data(), &Account::accountChangedAvatar, this, &User::avatarChanged); - connect(_account.data(), &AccountState::statusChanged, this, &User::statusChanged); + connect(_account->account().data(), &Account::userStatusChanged, this, &User::statusChanged); connect(_account.data(), &AccountState::desktopNotificationsAllowedChanged, this, &User::desktopNotificationsAllowedChanged); connect(_activityModel, &ActivityListModel::sendNotificationRequest, this, &User::slotSendNotificationRequest); @@ -236,10 +241,10 @@ void User::slotRefreshActivities() _activityModel->slotRefreshActivity(); } -void User::slotRefreshUserStatus() +void User::slotRefreshUserStatus() { if (_account.data() && _account.data()->isConnected()) { - _account.data()->fetchUserStatus(); + _account->account()->userStatusConnector()->fetchUserStatus(); } } @@ -560,6 +565,11 @@ AccountPtr User::account() const return _account->account(); } +AccountStatePtr User::accountState() const +{ + return _account; +} + void User::setCurrentUser(const bool &isCurrent) { _isCurrentUser = isCurrent; @@ -581,6 +591,11 @@ ActivityListModel *User::getActivityModel() return _activityModel; } +UnifiedSearchResultsListModel *User::getUnifiedSearchResultsListModel() const +{ + return _unifiedSearchResultsModel; +} + void User::openLocalFolder() { const auto folder = getFolder(); @@ -621,29 +636,29 @@ QString User::server(bool shortened) const return serverUrl; } -UserStatus::Status User::status() const +UserStatus::OnlineStatus User::status() const { - return _account->status(); + return _account->account()->userStatusConnector()->userStatus().state(); } QString User::statusMessage() const { - return _account->statusMessage(); + return _account->account()->userStatusConnector()->userStatus().message(); } QUrl User::statusIcon() const { - return _account->statusIcon(); + return _account->account()->userStatusConnector()->userStatus().stateIcon(); } QString User::statusEmoji() const { - return _account->statusEmoji(); + return _account->account()->userStatusConnector()->userStatus().icon(); } bool User::serverHasUserStatus() const { - return _account->account()->capabilities().userStatus(); + return _account->account()->capabilities().userStatusNotification(); } QImage User::avatar() const @@ -921,6 +936,15 @@ Q_INVOKABLE void UserModel::removeAccount(const int &id) endRemoveRows(); } +std::shared_ptr UserModel::userStatusConnector(int id) +{ + if (id < 0 || id >= _users.size()) { + return nullptr; + } + + return _users[id]->account()->userStatusConnector(); +} + int UserModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); diff --git a/src/gui/tray/UserModel.h b/src/gui/tray/usermodel.h similarity index 91% rename from src/gui/tray/UserModel.h rename to src/gui/tray/usermodel.h index b1a97da2a9dc..5ec34a916c3f 100644 --- a/src/gui/tray/UserModel.h +++ b/src/gui/tray/usermodel.h @@ -8,13 +8,17 @@ #include #include -#include "ActivityListModel.h" +#include "activitylistmodel.h" +#include "accountfwd.h" #include "accountmanager.h" #include "folderman.h" -#include "NotificationCache.h" +#include "notificationcache.h" +#include "userstatusselectormodel.h" +#include "userstatusconnector.h" #include namespace OCC { +class UnifiedSearchResultsListModel; class User : public QObject { @@ -30,16 +34,19 @@ class User : public QObject Q_PROPERTY(bool serverHasTalk READ serverHasTalk NOTIFY serverHasTalkChanged) Q_PROPERTY(QString avatar READ avatarUrl NOTIFY avatarChanged) Q_PROPERTY(bool isConnected READ isConnected NOTIFY accountStateChanged) + Q_PROPERTY(UnifiedSearchResultsListModel* unifiedSearchResultsListModel READ getUnifiedSearchResultsListModel CONSTANT) public: User(AccountStatePtr &account, const bool &isCurrent = false, QObject *parent = nullptr); AccountPtr account() const; + AccountStatePtr accountState() const; bool isConnected() const; bool isCurrentUser() const; void setCurrentUser(const bool &isCurrent); Folder *getFolder() const; ActivityListModel *getActivityModel(); + UnifiedSearchResultsListModel *getUnifiedSearchResultsListModel() const; void openLocalFolder(); QString name() const; QString server(bool shortened = true) const; @@ -55,7 +62,7 @@ class User : public QObject void removeAccount() const; QString avatarUrl() const; bool isDesktopNotificationsAllowed() const; - UserStatus::Status status() const; + UserStatus::OnlineStatus status() const; QString statusMessage() const; QUrl statusIcon() const; QString statusEmoji() const; @@ -109,6 +116,7 @@ public slots: AccountStatePtr _account; bool _isCurrentUser; ActivityListModel *_activityModel; + UnifiedSearchResultsListModel *_unifiedSearchResultsModel; ActivityList _blacklistedNotifications; QTimer _expiredActivitiesCheckTimer; @@ -130,7 +138,7 @@ class UserModel : public QAbstractListModel Q_PROPERTY(int currentUserId READ currentUserId NOTIFY newUserSelected) public: static UserModel *instance(); - virtual ~UserModel() = default; + ~UserModel() override = default; void addUser(AccountStatePtr &user, const bool &isCurrent = false); int currentUserIndex(); @@ -158,6 +166,8 @@ class UserModel : public QAbstractListModel Q_INVOKABLE void logout(const int &id); Q_INVOKABLE void removeAccount(const int &id); + Q_INVOKABLE std::shared_ptr userStatusConnector(int id); + ActivityListModel *currentActivityModel(); enum UserRoles { @@ -205,7 +215,7 @@ class UserAppsModel : public QAbstractListModel Q_OBJECT public: static UserAppsModel *instance(); - virtual ~UserAppsModel() = default; + ~UserAppsModel() override = default; int rowCount(const QModelIndex &parent = QModelIndex()) const override; diff --git a/src/gui/updater/ocupdater.cpp b/src/gui/updater/ocupdater.cpp index e469fce833bf..6bcf726d0569 100644 --- a/src/gui/updater/ocupdater.cpp +++ b/src/gui/updater/ocupdater.cpp @@ -106,8 +106,8 @@ bool OCUpdater::performUpdate() && !updateSucceeded() /* Someone might have run the updater manually between restarts */) { const auto messageBoxStartInstaller = new QMessageBox(QMessageBox::Information, tr("New %1 update ready").arg(Theme::instance()->appNameGUI()), - tr("A new update for %1 is about to be installed. The updater may ask\n" - "for additional privileges during the process.") + tr("A new update for %1 is about to be installed. The updater may ask " + "for additional privileges during the process. Your computer may reboot to complete the installation.") .arg(Theme::instance()->appNameGUI()), QMessageBox::Ok, nullptr); @@ -144,7 +144,7 @@ void OCUpdater::backgroundCheckForUpdate() } } -QString OCUpdater::statusString() const +QString OCUpdater::statusString(UpdateStatusStringFormat format) const { QString updateVersion = _updateInfo.versionString(); @@ -153,12 +153,20 @@ QString OCUpdater::statusString() const return tr("Downloading %1. Please wait …").arg(updateVersion); case DownloadComplete: return tr("%1 available. Restart application to start the update.").arg(updateVersion); - case DownloadFailed: + case DownloadFailed: { + if (format == UpdateStatusStringFormat::Html) { + return tr("Could not download update. Please open %1 to download the update manually.").arg(_updateInfo.web()); + } return tr("Could not download update. Please open %1 to download the update manually.").arg(_updateInfo.web()); + } case DownloadTimedOut: return tr("Could not check for new updates."); - case UpdateOnlyAvailableThroughSystem: + case UpdateOnlyAvailableThroughSystem: { + if (format == UpdateStatusStringFormat::Html) { + return tr("New %1 is available. Please open %2 to download the update.").arg(updateVersion, _updateInfo.web()); + } return tr("New %1 is available. Please open %2 to download the update.").arg(updateVersion, _updateInfo.web()); + } case CheckingServer: return tr("Checking update server …"); case Unknown: @@ -214,7 +222,7 @@ void OCUpdater::slotStartInstaller() }; QString msiLogFile = cfg.configPath() + "msi.log"; - QString command = QString("&{msiexec /norestart /passive /i '%1' /L*V '%2'| Out-Null ; &'%3'}") + QString command = QString("&{msiexec /promptrestart /passive /i '%1' /L*V '%2'| Out-Null ; &'%3'}") .arg(preparePathForPowershell(updateFile)) .arg(preparePathForPowershell(msiLogFile)) .arg(preparePathForPowershell(QCoreApplication::applicationFilePath())); @@ -453,7 +461,7 @@ void NSISUpdater::showUpdateErrorDialog(const QString &targetVersion) ico->setPixmap(infoIcon.pixmap(iconSize)); auto lbl = new QLabel; QString txt = tr("

A new version of the %1 Client is available but the updating process failed.

" - "

%2 has been downloaded. The installed version is %3.

") + "

%2 has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.

") .arg(Utility::escape(Theme::instance()->appNameGUI()), Utility::escape(targetVersion), Utility::escape(clientVersion())); diff --git a/src/gui/updater/ocupdater.h b/src/gui/updater/ocupdater.h index dbdb6be51774..c6c1ad8dfa22 100644 --- a/src/gui/updater/ocupdater.h +++ b/src/gui/updater/ocupdater.h @@ -97,6 +97,11 @@ class OCUpdater : public Updater DownloadFailed, DownloadTimedOut, UpdateOnlyAvailableThroughSystem }; + + enum UpdateStatusStringFormat { + PlainText, + Html, + }; explicit OCUpdater(const QUrl &url); void setUpdateUrl(const QUrl &url); @@ -105,7 +110,7 @@ class OCUpdater : public Updater void checkForUpdate() override; - QString statusString() const; + QString statusString(UpdateStatusStringFormat format = PlainText) const; int downloadState() const; void setDownloadState(DownloadState state); diff --git a/src/gui/updater/sparkleupdater.h b/src/gui/updater/sparkleupdater.h index d03e76360684..00aa510476fc 100644 --- a/src/gui/updater/sparkleupdater.h +++ b/src/gui/updater/sparkleupdater.h @@ -26,7 +26,7 @@ class SparkleUpdater : public Updater Q_OBJECT public: SparkleUpdater(const QUrl &appCastUrl); - ~SparkleUpdater(); + ~SparkleUpdater() override; void setUpdateUrl(const QUrl &url); diff --git a/src/gui/updater/updater.cpp b/src/gui/updater/updater.cpp index 21fd48b091f2..af8fad47b26c 100644 --- a/src/gui/updater/updater.cpp +++ b/src/gui/updater/updater.cpp @@ -118,7 +118,7 @@ QString Updater::getSystemInfo() { #ifdef Q_OS_LINUX QProcess process; - process.start(QLatin1String("lsb_release -a")); + process.start(QLatin1String("lsb_release"), { QStringLiteral("-a") }); process.waitForFinished(); QByteArray output = process.readAllStandardOutput(); qCDebug(lcUpdater) << "Sys Info size: " << output.length(); diff --git a/src/gui/userstatus.cpp b/src/gui/userstatus.cpp deleted file mode 100644 index 55d929eeeb4f..000000000000 --- a/src/gui/userstatus.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) by Camila - * - * 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 "userstatus.h" -#include "account.h" -#include "accountstate.h" -#include "networkjobs.h" -#include "folderman.h" -#include "creds/abstractcredentials.h" -#include "theme.h" -#include "capabilities.h" - -#include -#include -#include - -namespace OCC { - -Q_LOGGING_CATEGORY(lcUserStatus, "nextcloud.gui.userstatus", QtInfoMsg) - -namespace { - UserStatus::Status stringToEnum(const QString &status) - { - // it needs to match the Status enum - const QHash preDefinedStatus{ - {"online", UserStatus::Status::Online}, - {"dnd", UserStatus::Status::DoNotDisturb}, - {"away", UserStatus::Status::Away}, - {"offline", UserStatus::Status::Offline}, - {"invisible", UserStatus::Status::Invisible} - }; - - // api should return invisible, dnd,... toLower() it is to make sure - // it matches _preDefinedStatus, otherwise the default is online (0) - return preDefinedStatus.value(status.toLower(), UserStatus::Status::Online); - } -} - -UserStatus::UserStatus(QObject *parent) - : QObject(parent) -{ -} - -void UserStatus::fetchUserStatus(AccountPtr account) -{ - if (!account->capabilities().userStatus()) { - return; - } - - if (_job) { - _job->deleteLater(); - } - - _job = new JsonApiJob(account, QStringLiteral("/ocs/v2.php/apps/user_status/api/v1/user_status"), this); - connect(_job.data(), &JsonApiJob::jsonReceived, this, &UserStatus::slotFetchUserStatusFinished); - _job->start(); -} - -void UserStatus::slotFetchUserStatusFinished(const QJsonDocument &json, int statusCode) -{ - const QJsonObject defaultValues { - {"icon", ""}, - {"message", ""}, - {"status", "online"}, - {"messageIsPredefined", "false"}, - {"statusIsUserDefined", "false"} - }; - - if (statusCode != 200) { - qCInfo(lcUserStatus) << "Slot fetch UserStatus finished with status code" << statusCode; - qCInfo(lcUserStatus) << "Using then default values as if user has not set any status" << defaultValues; - } - - const auto retrievedData = json.object().value("ocs").toObject().value("data").toObject(defaultValues); - - _emoji = retrievedData.value("icon").toString().trimmed(); - _status = stringToEnum(retrievedData.value("status").toString()); - _message = retrievedData.value("message").toString().trimmed(); - - emit fetchUserStatusFinished(); -} - -UserStatus::Status UserStatus::status() const -{ - return _status; -} - -QString UserStatus::message() const -{ - return _message; -} - -QString UserStatus::emoji() const -{ - return _emoji; -} - -QUrl UserStatus::icon() const -{ - switch (_status) { - case Status::Away: - return Theme::instance()->statusAwayImageSource(); - case Status::DoNotDisturb: - return Theme::instance()->statusDoNotDisturbImageSource(); - case Status::Invisible: - case Status::Offline: - return Theme::instance()->statusInvisibleImageSource(); - case Status::Online: - return Theme::instance()->statusOnlineImageSource(); - } - - Q_UNREACHABLE(); -} - -} // namespace OCC diff --git a/src/gui/userstatus.h b/src/gui/userstatus.h deleted file mode 100644 index 3e952a50b308..000000000000 --- a/src/gui/userstatus.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) by Camila - * - * 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 USERSTATUS_H -#define USERSTATUS_H - -#include -#include "accountfwd.h" - -namespace OCC { - -class JsonApiJob; - -class UserStatus : public QObject -{ - Q_OBJECT - -public: - explicit UserStatus(QObject *parent = nullptr); - enum class Status { - Online, - DoNotDisturb, - Away, - Offline, - Invisible - }; - Q_ENUM(Status); - void fetchUserStatus(AccountPtr account); - Status status() const; - QString message() const; - QString emoji() const; - QUrl icon() const; - -private slots: - void slotFetchUserStatusFinished(const QJsonDocument &json, int statusCode); - -signals: - void fetchUserStatusFinished(); - -private: - QPointer _job; // the currently running job - Status _status = Status::Online; - QString _message; - QString _emoji; -}; - - -} // namespace OCC - -#endif //USERSTATUS_H diff --git a/src/gui/userstatusselectormodel.cpp b/src/gui/userstatusselectormodel.cpp new file mode 100644 index 000000000000..6ae0dd256f28 --- /dev/null +++ b/src/gui/userstatusselectormodel.cpp @@ -0,0 +1,468 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 "userstatusselectormodel.h" +#include "tray/usermodel.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace OCC { + +Q_LOGGING_CATEGORY(lcUserStatusDialogModel, "nextcloud.gui.userstatusdialogmodel", QtInfoMsg) + +UserStatusSelectorModel::UserStatusSelectorModel(QObject *parent) + : QObject(parent) + , _dateTimeProvider(new DateTimeProvider) +{ + _userStatus.setIcon("😀"); +} + +UserStatusSelectorModel::UserStatusSelectorModel(std::shared_ptr userStatusConnector, QObject *parent) + : QObject(parent) + , _userStatusConnector(userStatusConnector) + , _userStatus("no-id", "", "😀", UserStatus::OnlineStatus::Online, false, {}) + , _dateTimeProvider(new DateTimeProvider) +{ + _userStatus.setIcon("😀"); + init(); +} + +UserStatusSelectorModel::UserStatusSelectorModel(std::shared_ptr userStatusConnector, + std::unique_ptr dateTimeProvider, + QObject *parent) + : QObject(parent) + , _userStatusConnector(userStatusConnector) + , _dateTimeProvider(std::move(dateTimeProvider)) +{ + _userStatus.setIcon("😀"); + init(); +} + +UserStatusSelectorModel::UserStatusSelectorModel(const UserStatus &userStatus, + std::unique_ptr dateTimeProvider, QObject *parent) + : QObject(parent) + , _userStatus(userStatus) + , _dateTimeProvider(std::move(dateTimeProvider)) +{ + _userStatus.setIcon("😀"); +} + +UserStatusSelectorModel::UserStatusSelectorModel(const UserStatus &userStatus, + QObject *parent) + : QObject(parent) + , _userStatus(userStatus) +{ + _userStatus.setIcon("😀"); +} + +void UserStatusSelectorModel::load(int id) +{ + reset(); + _userStatusConnector = UserModel::instance()->userStatusConnector(id); + init(); +} + +void UserStatusSelectorModel::reset() +{ + if (_userStatusConnector) { + disconnect(_userStatusConnector.get(), &UserStatusConnector::userStatusFetched, this, + &UserStatusSelectorModel::onUserStatusFetched); + disconnect(_userStatusConnector.get(), &UserStatusConnector::predefinedStatusesFetched, this, + &UserStatusSelectorModel::onPredefinedStatusesFetched); + disconnect(_userStatusConnector.get(), &UserStatusConnector::error, this, + &UserStatusSelectorModel::onError); + disconnect(_userStatusConnector.get(), &UserStatusConnector::userStatusSet, this, + &UserStatusSelectorModel::onUserStatusSet); + disconnect(_userStatusConnector.get(), &UserStatusConnector::messageCleared, this, + &UserStatusSelectorModel::onMessageCleared); + } + _userStatusConnector = nullptr; +} + +void UserStatusSelectorModel::init() +{ + if (!_userStatusConnector) { + return; + } + + connect(_userStatusConnector.get(), &UserStatusConnector::userStatusFetched, this, + &UserStatusSelectorModel::onUserStatusFetched); + connect(_userStatusConnector.get(), &UserStatusConnector::predefinedStatusesFetched, this, + &UserStatusSelectorModel::onPredefinedStatusesFetched); + connect(_userStatusConnector.get(), &UserStatusConnector::error, this, + &UserStatusSelectorModel::onError); + connect(_userStatusConnector.get(), &UserStatusConnector::userStatusSet, this, + &UserStatusSelectorModel::onUserStatusSet); + connect(_userStatusConnector.get(), &UserStatusConnector::messageCleared, this, + &UserStatusSelectorModel::onMessageCleared); + + _userStatusConnector->fetchUserStatus(); + _userStatusConnector->fetchPredefinedStatuses(); +} + +void UserStatusSelectorModel::onUserStatusSet() +{ + emit finished(); +} + +void UserStatusSelectorModel::onMessageCleared() +{ + emit finished(); +} + +void UserStatusSelectorModel::onError(UserStatusConnector::Error error) +{ + qCWarning(lcUserStatusDialogModel) << "Error:" << error; + + switch (error) { + case UserStatusConnector::Error::CouldNotFetchPredefinedUserStatuses: + setError(tr("Could not fetch predefined statuses. Make sure you are connected to the server.")); + return; + + case UserStatusConnector::Error::CouldNotFetchUserStatus: + setError(tr("Could not fetch user status. Make sure you are connected to the server.")); + return; + + case UserStatusConnector::Error::UserStatusNotSupported: + setError(tr("User status feature is not supported. You will not be able to set your user status.")); + return; + + case UserStatusConnector::Error::EmojisNotSupported: + setError(tr("Emojis feature is not supported. Some user status functionality may not work.")); + return; + + case UserStatusConnector::Error::CouldNotSetUserStatus: + setError(tr("Could not set user status. Make sure you are connected to the server.")); + return; + + case UserStatusConnector::Error::CouldNotClearMessage: + setError(tr("Could not clear user status message. Make sure you are connected to the server.")); + return; + } + + Q_UNREACHABLE(); +} + +void UserStatusSelectorModel::setError(const QString &reason) +{ + _errorMessage = reason; + emit errorMessageChanged(); +} + +void UserStatusSelectorModel::clearError() +{ + setError(""); +} + +void UserStatusSelectorModel::setOnlineStatus(UserStatus::OnlineStatus status) +{ + if (status == _userStatus.state()) { + return; + } + + _userStatus.setState(status); + emit onlineStatusChanged(); +} + +QUrl UserStatusSelectorModel::onlineIcon() const +{ + return Theme::instance()->statusOnlineImageSource(); +} + +QUrl UserStatusSelectorModel::awayIcon() const +{ + return Theme::instance()->statusAwayImageSource(); +} +QUrl UserStatusSelectorModel::dndIcon() const +{ + return Theme::instance()->statusDoNotDisturbImageSource(); +} +QUrl UserStatusSelectorModel::invisibleIcon() const +{ + return Theme::instance()->statusInvisibleImageSource(); +} + +UserStatus::OnlineStatus UserStatusSelectorModel::onlineStatus() const +{ + return _userStatus.state(); +} + +QString UserStatusSelectorModel::userStatusMessage() const +{ + return _userStatus.message(); +} + +void UserStatusSelectorModel::setUserStatusMessage(const QString &message) +{ + _userStatus.setMessage(message); + _userStatus.setMessagePredefined(false); + emit userStatusChanged(); +} + +void UserStatusSelectorModel::setUserStatusEmoji(const QString &emoji) +{ + _userStatus.setIcon(emoji); + _userStatus.setMessagePredefined(false); + emit userStatusChanged(); +} + +QString UserStatusSelectorModel::userStatusEmoji() const +{ + return _userStatus.icon(); +} + +void UserStatusSelectorModel::onUserStatusFetched(const UserStatus &userStatus) +{ + if (userStatus.state() != UserStatus::OnlineStatus::Offline) { + _userStatus.setState(userStatus.state()); + } + _userStatus.setMessage(userStatus.message()); + _userStatus.setMessagePredefined(userStatus.messagePredefined()); + _userStatus.setId(userStatus.id()); + _userStatus.setClearAt(userStatus.clearAt()); + + if (!userStatus.icon().isEmpty()) { + _userStatus.setIcon(userStatus.icon()); + } + + emit userStatusChanged(); + emit onlineStatusChanged(); + emit clearAtChanged(); +} + +Optional UserStatusSelectorModel::clearStageTypeToDateTime(ClearStageType type) const +{ + switch (type) { + case ClearStageType::DontClear: + return {}; + + case ClearStageType::HalfHour: { + ClearAt clearAt; + clearAt._type = ClearAtType::Period; + clearAt._period = 60 * 30; + return clearAt; + } + + case ClearStageType::OneHour: { + ClearAt clearAt; + clearAt._type = ClearAtType::Period; + clearAt._period = 60 * 60; + return clearAt; + } + + case ClearStageType::FourHour: { + ClearAt clearAt; + clearAt._type = ClearAtType::Period; + clearAt._period = 60 * 60 * 4; + return clearAt; + } + + case ClearStageType::Today: { + ClearAt clearAt; + clearAt._type = ClearAtType::EndOf; + clearAt._endof = "day"; + return clearAt; + } + + case ClearStageType::Week: { + ClearAt clearAt; + clearAt._type = ClearAtType::EndOf; + clearAt._endof = "week"; + return clearAt; + } + + default: + Q_UNREACHABLE(); + } +} + +void UserStatusSelectorModel::setUserStatus() +{ + Q_ASSERT(_userStatusConnector); + if (!_userStatusConnector) { + return; + } + + clearError(); + _userStatusConnector->setUserStatus(_userStatus); +} + +void UserStatusSelectorModel::clearUserStatus() +{ + Q_ASSERT(_userStatusConnector); + if (!_userStatusConnector) { + return; + } + + clearError(); + _userStatusConnector->clearMessage(); +} + +void UserStatusSelectorModel::onPredefinedStatusesFetched(const std::vector &statuses) +{ + _predefinedStatuses = statuses; + emit predefinedStatusesChanged(); +} + +UserStatus UserStatusSelectorModel::predefinedStatus(int index) const +{ + Q_ASSERT(0 <= index && index < static_cast(_predefinedStatuses.size())); + return _predefinedStatuses[index]; +} + +int UserStatusSelectorModel::predefinedStatusesCount() const +{ + return static_cast(_predefinedStatuses.size()); +} + +void UserStatusSelectorModel::setPredefinedStatus(int index) +{ + Q_ASSERT(0 <= index && index < static_cast(_predefinedStatuses.size())); + + _userStatus.setMessagePredefined(true); + const auto predefinedStatus = _predefinedStatuses[index]; + _userStatus.setId(predefinedStatus.id()); + _userStatus.setMessage(predefinedStatus.message()); + _userStatus.setIcon(predefinedStatus.icon()); + _userStatus.setClearAt(predefinedStatus.clearAt()); + + emit userStatusChanged(); + emit clearAtChanged(); +} + +QString UserStatusSelectorModel::clearAtStageToString(ClearStageType stage) const +{ + switch (stage) { + case ClearStageType::DontClear: + return tr("Don't clear"); + + case ClearStageType::HalfHour: + return tr("30 minutes"); + + case ClearStageType::OneHour: + return tr("1 hour"); + + case ClearStageType::FourHour: + return tr("4 hours"); + + case ClearStageType::Today: + return tr("Today"); + + case ClearStageType::Week: + return tr("This week"); + + default: + Q_UNREACHABLE(); + } +} + +QStringList UserStatusSelectorModel::clearAtValues() const +{ + QStringList clearAtStages; + std::transform(_clearStages.begin(), _clearStages.end(), + std::back_inserter(clearAtStages), + [this](const ClearStageType &stage) { return clearAtStageToString(stage); }); + + return clearAtStages; +} + +void UserStatusSelectorModel::setClearAt(int index) +{ + Q_ASSERT(0 <= index && index < static_cast(_clearStages.size())); + _userStatus.setClearAt(clearStageTypeToDateTime(_clearStages[index])); + emit clearAtChanged(); +} + +QString UserStatusSelectorModel::errorMessage() const +{ + return _errorMessage; +} + +QString UserStatusSelectorModel::timeDifferenceToString(int differenceSecs) const +{ + if (differenceSecs < 60) { + return tr("Less than a minute"); + } else if (differenceSecs < 60 * 60) { + const auto minutesLeft = std::ceil(differenceSecs / 60.0); + if (minutesLeft == 1) { + return tr("1 minute"); + } else { + return tr("%1 minutes").arg(minutesLeft); + } + } else if (differenceSecs < 60 * 60 * 24) { + const auto hoursLeft = std::ceil(differenceSecs / 60.0 / 60.0); + if (hoursLeft == 1) { + return tr("1 hour"); + } else { + return tr("%1 hours").arg(hoursLeft); + } + } else { + const auto daysLeft = std::ceil(differenceSecs / 60.0 / 60.0 / 24.0); + if (daysLeft == 1) { + return tr("1 day"); + } else { + return tr("%1 days").arg(daysLeft); + } + } +} + +QString UserStatusSelectorModel::clearAtReadable(const Optional &clearAt) const +{ + if (clearAt) { + switch (clearAt->_type) { + case ClearAtType::Period: { + return timeDifferenceToString(clearAt->_period); + } + + case ClearAtType::Timestamp: { + const int difference = static_cast(clearAt->_timestamp - _dateTimeProvider->currentDateTime().toTime_t()); + return timeDifferenceToString(difference); + } + + case ClearAtType::EndOf: { + if (clearAt->_endof == "day") { + return tr("Today"); + } else if (clearAt->_endof == "week") { + return tr("This week"); + } + Q_UNREACHABLE(); + } + + default: + Q_UNREACHABLE(); + } + } + return tr("Don't clear"); +} + +QString UserStatusSelectorModel::predefinedStatusClearAt(int index) const +{ + return clearAtReadable(predefinedStatus(index).clearAt()); +} + +QString UserStatusSelectorModel::clearAt() const +{ + return clearAtReadable(_userStatus.clearAt()); +} +} diff --git a/src/gui/userstatusselectormodel.h b/src/gui/userstatusselectormodel.h new file mode 100644 index 000000000000..c60fc8926aa2 --- /dev/null +++ b/src/gui/userstatusselectormodel.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +#pragma once + +#include "common/result.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace OCC { + +class UserStatusSelectorModel : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString userStatusMessage READ userStatusMessage NOTIFY userStatusChanged) + Q_PROPERTY(QString userStatusEmoji READ userStatusEmoji WRITE setUserStatusEmoji NOTIFY userStatusChanged) + Q_PROPERTY(OCC::UserStatus::OnlineStatus onlineStatus READ onlineStatus WRITE setOnlineStatus NOTIFY onlineStatusChanged) + Q_PROPERTY(int predefinedStatusesCount READ predefinedStatusesCount NOTIFY predefinedStatusesChanged) + Q_PROPERTY(QStringList clearAtValues READ clearAtValues CONSTANT) + Q_PROPERTY(QString clearAt READ clearAt NOTIFY clearAtChanged) + Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) + Q_PROPERTY(QUrl onlineIcon READ onlineIcon CONSTANT) + Q_PROPERTY(QUrl awayIcon READ awayIcon CONSTANT) + Q_PROPERTY(QUrl dndIcon READ dndIcon CONSTANT) + Q_PROPERTY(QUrl invisibleIcon READ invisibleIcon CONSTANT) + +public: + explicit UserStatusSelectorModel(QObject *parent = nullptr); + + explicit UserStatusSelectorModel(std::shared_ptr userStatusConnector, + QObject *parent = nullptr); + + explicit UserStatusSelectorModel(std::shared_ptr userStatusConnector, + std::unique_ptr dateTimeProvider, + QObject *parent = nullptr); + + explicit UserStatusSelectorModel(const UserStatus &userStatus, + std::unique_ptr dateTimeProvider, + QObject *parent = nullptr); + + explicit UserStatusSelectorModel(const UserStatus &userStatus, + QObject *parent = nullptr); + + Q_INVOKABLE void load(int id); + + Q_REQUIRED_RESULT UserStatus::OnlineStatus onlineStatus() const; + Q_INVOKABLE void setOnlineStatus(OCC::UserStatus::OnlineStatus status); + + Q_REQUIRED_RESULT QUrl onlineIcon() const; + Q_REQUIRED_RESULT QUrl awayIcon() const; + Q_REQUIRED_RESULT QUrl dndIcon() const; + Q_REQUIRED_RESULT QUrl invisibleIcon() const; + + Q_REQUIRED_RESULT QString userStatusMessage() const; + Q_INVOKABLE void setUserStatusMessage(const QString &message); + void setUserStatusEmoji(const QString &emoji); + Q_REQUIRED_RESULT QString userStatusEmoji() const; + + Q_INVOKABLE void setUserStatus(); + Q_INVOKABLE void clearUserStatus(); + + Q_REQUIRED_RESULT int predefinedStatusesCount() const; + Q_INVOKABLE UserStatus predefinedStatus(int index) const; + Q_INVOKABLE QString predefinedStatusClearAt(int index) const; + Q_INVOKABLE void setPredefinedStatus(int index); + + Q_REQUIRED_RESULT QStringList clearAtValues() const; + Q_REQUIRED_RESULT QString clearAt() const; + Q_INVOKABLE void setClearAt(int index); + + Q_REQUIRED_RESULT QString errorMessage() const; + +signals: + void errorMessageChanged(); + void userStatusChanged(); + void onlineStatusChanged(); + void clearAtChanged(); + void predefinedStatusesChanged(); + void finished(); + +private: + enum class ClearStageType { + DontClear, + HalfHour, + OneHour, + FourHour, + Today, + Week + }; + + void init(); + void reset(); + void onUserStatusFetched(const UserStatus &userStatus); + void onPredefinedStatusesFetched(const std::vector &statuses); + void onUserStatusSet(); + void onMessageCleared(); + void onError(UserStatusConnector::Error error); + + Q_REQUIRED_RESULT QString clearAtStageToString(ClearStageType stage) const; + Q_REQUIRED_RESULT QString clearAtReadable(const Optional &clearAt) const; + Q_REQUIRED_RESULT QString timeDifferenceToString(int differenceSecs) const; + Q_REQUIRED_RESULT Optional clearStageTypeToDateTime(ClearStageType type) const; + void setError(const QString &reason); + void clearError(); + + std::shared_ptr _userStatusConnector {}; + std::vector _predefinedStatuses; + UserStatus _userStatus; + std::unique_ptr _dateTimeProvider; + + QString _errorMessage; + + std::vector _clearStages = { + ClearStageType::DontClear, + ClearStageType::HalfHour, + ClearStageType::OneHour, + ClearStageType::FourHour, + ClearStageType::Today, + ClearStageType::Week + }; +}; +} diff --git a/src/gui/wizard/flow2authwidget.cpp b/src/gui/wizard/flow2authwidget.cpp index 98b6b74ede62..87f63d59197a 100644 --- a/src/gui/wizard/flow2authwidget.cpp +++ b/src/gui/wizard/flow2authwidget.cpp @@ -108,27 +108,7 @@ void Flow2AuthWidget::slotAuthResult(Flow2Auth::Result r, const QString &errorSt } } - _account->setCredentials(new WebFlowCredentials(user, appPassword)); - const auto fetchUserNameJob = new JsonApiJob(_account->sharedFromThis(), QStringLiteral("/ocs/v1.php/cloud/user")); - connect(fetchUserNameJob, &JsonApiJob::jsonReceived, this, [this, fetchUserNameJob, r, errorString, user, appPassword](const QJsonDocument &json, int statusCode) { - fetchUserNameJob->deleteLater(); - if (statusCode != 100) { - qCWarning(lcFlow2AuthWidget) << "Could not fetch username."; - _account->setDavUser(""); - _account->setDavDisplayName(user); - emit authResult(r, errorString, user, appPassword); - return; - } - - const auto objData = json.object().value("ocs").toObject().value("data").toObject(); - const auto userId = objData.value("id").toString(user); - const auto displayName = objData.value("display-name").toString(); - _account->setDavUser(userId); - _account->setDavDisplayName(displayName); - - emit authResult(r, errorString, user, appPassword); - }); - fetchUserNameJob->start(); + emit authResult(r, errorString, user, appPassword); } void Flow2AuthWidget::setError(const QString &error) { diff --git a/src/gui/wizard/flow2authwidget.h b/src/gui/wizard/flow2authwidget.h index 90095c79c14c..cc1b01d57abb 100644 --- a/src/gui/wizard/flow2authwidget.h +++ b/src/gui/wizard/flow2authwidget.h @@ -31,7 +31,7 @@ class Flow2AuthWidget : public QWidget Q_OBJECT public: Flow2AuthWidget(QWidget *parent = nullptr); - virtual ~Flow2AuthWidget(); + ~Flow2AuthWidget() override; void startAuth(Account *account); void resetAuth(Account *account = nullptr); diff --git a/src/gui/wizard/owncloudadvancedsetuppage.cpp b/src/gui/wizard/owncloudadvancedsetuppage.cpp index 9a7dff87fabd..0d8cb6c1adff 100644 --- a/src/gui/wizard/owncloudadvancedsetuppage.cpp +++ b/src/gui/wizard/owncloudadvancedsetuppage.cpp @@ -57,7 +57,12 @@ OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage(OwncloudWizard *wizard) setupCustomization(); connect(_ui.pbSelectLocalFolder, &QAbstractButton::clicked, this, &OwncloudAdvancedSetupPage::slotSelectFolder); - setButtonText(QWizard::NextButton, tr("Connect")); + setButtonText(QWizard::FinishButton, tr("Connect")); + + if (Theme::instance()->enforceVirtualFilesSyncFolder()) { + _ui.rSyncEverything->setDisabled(true); + _ui.rSelectiveSync->setDisabled(true); + } connect(_ui.rSyncEverything, &QAbstractButton::clicked, this, &OwncloudAdvancedSetupPage::slotSyncEverythingClicked); connect(_ui.rSelectiveSync, &QAbstractButton::clicked, this, &OwncloudAdvancedSetupPage::slotSelectiveSyncClicked); @@ -134,8 +139,8 @@ void OwncloudAdvancedSetupPage::initializePage() } _checking = false; - _ui.lSelectiveSyncSizeLabel->setText(QString()); - _ui.lSyncEverythingSizeLabel->setText(QString()); + _ui.lSelectiveSyncSizeLabel->clear(); + _ui.lSyncEverythingSizeLabel->clear(); // Update the local folder - this is not guaranteed to find a good one QString goodLocalFolder = FolderMan::instance()->findGoodPathForNewSyncFolder(localFolder(), serverUrl()); @@ -145,7 +150,7 @@ void OwncloudAdvancedSetupPage::initializePage() updateStatus(); // ensure "next" gets the focus, not obSelectLocalFolder - QTimer::singleShot(0, wizard()->button(QWizard::NextButton), SLOT(setFocus())); + QTimer::singleShot(0, wizard()->button(QWizard::FinishButton), qOverload<>(&QWidget::setFocus)); auto acc = static_cast(wizard())->account(); auto quotaJob = new PropfindJob(acc, _remoteFolder, this); @@ -327,7 +332,8 @@ QUrl OwncloudAdvancedSetupPage::serverUrl() const int OwncloudAdvancedSetupPage::nextId() const { - return WizardCommon::Page_Result; + // tells the caller that this is the last dialog page + return -1; } QString OwncloudAdvancedSetupPage::localFolder() const diff --git a/src/gui/wizard/owncloudconnectionmethoddialog.h b/src/gui/wizard/owncloudconnectionmethoddialog.h index 9ccccc3f31bb..d82d52e45b9d 100644 --- a/src/gui/wizard/owncloudconnectionmethoddialog.h +++ b/src/gui/wizard/owncloudconnectionmethoddialog.h @@ -36,7 +36,7 @@ class OwncloudConnectionMethodDialog : public QDialog public: explicit OwncloudConnectionMethodDialog(QWidget *parent = nullptr); - ~OwncloudConnectionMethodDialog(); + ~OwncloudConnectionMethodDialog() override; enum { Closed = 0, No_TLS, diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index 0e6e06ca4144..69656ea66b70 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -217,8 +217,10 @@ int OwncloudSetupPage::nextId() const case DetermineAuthTypeJob::WebViewFlow: return WizardCommon::Page_WebView; #endif // WITH_WEBENGINE + case DetermineAuthTypeJob::NoAuthType: + return WizardCommon::Page_HttpCreds; } - return WizardCommon::Page_HttpCreds; + Q_UNREACHABLE(); } QString OwncloudSetupPage::url() const diff --git a/src/gui/wizard/owncloudsetuppage.h b/src/gui/wizard/owncloudsetuppage.h index a03b336398f1..b4cee856da95 100644 --- a/src/gui/wizard/owncloudsetuppage.h +++ b/src/gui/wizard/owncloudsetuppage.h @@ -43,7 +43,7 @@ class OwncloudSetupPage : public QWizardPage Q_OBJECT public: OwncloudSetupPage(QWidget *parent = nullptr); - ~OwncloudSetupPage(); + ~OwncloudSetupPage() override; bool isComplete() const override; void initializePage() override; diff --git a/src/gui/wizard/owncloudwizard.cpp b/src/gui/wizard/owncloudwizard.cpp index 6e8553d39f1d..a41f3cdf4ced 100644 --- a/src/gui/wizard/owncloudwizard.cpp +++ b/src/gui/wizard/owncloudwizard.cpp @@ -29,7 +29,6 @@ #include "wizard/owncloudhttpcredspage.h" #include "wizard/owncloudoauthcredspage.h" #include "wizard/owncloudadvancedsetuppage.h" -#include "wizard/owncloudwizardresultpage.h" #include "wizard/webviewpage.h" #include "wizard/flow2authcredspage.h" @@ -57,7 +56,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent) , _browserCredsPage(new OwncloudOAuthCredsPage) , _flow2CredsPage(new Flow2AuthCredsPage) , _advancedSetupPage(new OwncloudAdvancedSetupPage(this)) - , _resultPage(new OwncloudWizardResultPage) #ifdef WITH_WEBENGINE , _webViewPage(new WebViewPage(this)) #else // WITH_WEBENGINE @@ -77,7 +75,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent) setPage(WizardCommon::Page_OAuthCreds, _browserCredsPage); setPage(WizardCommon::Page_Flow2AuthCreds, _flow2CredsPage); setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage); - setPage(WizardCommon::Page_Result, _resultPage); #ifdef WITH_WEBENGINE setPage(WizardCommon::Page_WebView, _webViewPage); #endif // WITH_WEBENGINE @@ -217,16 +214,9 @@ void OwncloudWizard::setRegistration(bool registration) _registration = registration; } - -void OwncloudWizard::enableFinishOnResultWidget(bool enable) -{ - _resultPage->setComplete(enable); -} - void OwncloudWizard::setRemoteFolder(const QString &remoteFolder) { _advancedSetupPage->setRemoteFolder(remoteFolder); - _resultPage->setRemoteFolder(remoteFolder); } void OwncloudWizard::successfulStep() @@ -257,13 +247,17 @@ void OwncloudWizard::successfulStep() break; case WizardCommon::Page_ServerSetup: - case WizardCommon::Page_Result: qCWarning(lcWizard, "Should not happen at this stage."); break; } ownCloudGui::raiseDialog(this); - next(); + if (nextId() == -1) { + disconnect(this, &QDialog::finished, this, &OwncloudWizard::basicSetupFinished); + emit basicSetupFinished(QDialog::Accepted); + } else { + next(); + } } void OwncloudWizard::setAuthType(DetermineAuthTypeJob::AuthType type) @@ -308,7 +302,7 @@ void OwncloudWizard::slotCurrentPageChanged(int id) id == WizardCommon::Page_Flow2AuthCreds) { setButtonLayout({ QWizard::Stretch, QWizard::BackButton }); } else if (id == WizardCommon::Page_AdvancedSetup) { - setButtonLayout({ QWizard::Stretch, QWizard::CustomButton1, QWizard::BackButton, QWizard::NextButton }); + setButtonLayout({ QWizard::Stretch, QWizard::CustomButton1, QWizard::BackButton, QWizard::FinishButton }); setNextButtonAsDefault(); } else { setButtonLayout({ QWizard::Stretch, QWizard::BackButton, QWizard::NextButton }); @@ -319,14 +313,6 @@ void OwncloudWizard::slotCurrentPageChanged(int id) emit clearPendingRequests(); } - if (id == WizardCommon::Page_Result) { - disconnect(this, &QDialog::finished, this, &OwncloudWizard::basicSetupFinished); - emit basicSetupFinished(QDialog::Accepted); - appendToConfigurationLog(QString()); - // Immediately close on show, we currently don't want this page anymore - done(Accepted); - } - if (id == WizardCommon::Page_AdvancedSetup && (_credentialsPage == _browserCredsPage || _credentialsPage == _flow2CredsPage)) { // For OAuth, disable the back button in the Page_AdvancedSetup because we don't want // to re-open the browser. @@ -443,6 +429,7 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(QWidget *receiver, const acceptButton = msgBox->addButton(tr("Enable experimental placeholder mode"), QMessageBox::AcceptRole); msgBox->addButton(tr("Stay safe"), QMessageBox::RejectRole); break; + case Vfs::XAttr: case Vfs::Off: Q_UNREACHABLE(); } diff --git a/src/gui/wizard/owncloudwizard.h b/src/gui/wizard/owncloudwizard.h index ff253587fca3..4e26925e159e 100644 --- a/src/gui/wizard/owncloudwizard.h +++ b/src/gui/wizard/owncloudwizard.h @@ -68,8 +68,6 @@ class OwncloudWizard : public QWizard bool useVirtualFileSync() const; bool isConfirmBigFolderChecked() const; - void enableFinishOnResultWidget(bool enable); - void displayError(const QString &, bool retryHTTPonly); AbstractCredentials *getCredentials() const; diff --git a/src/gui/wizard/owncloudwizardcommon.h b/src/gui/wizard/owncloudwizardcommon.h index 7c6eef5ab875..093b81bb1908 100644 --- a/src/gui/wizard/owncloudwizardcommon.h +++ b/src/gui/wizard/owncloudwizardcommon.h @@ -50,7 +50,6 @@ namespace WizardCommon { Page_WebView, #endif // WITH_WEBENGINE Page_AdvancedSetup, - Page_Result }; } // ns WizardCommon diff --git a/src/gui/wizard/owncloudwizardresultpage.cpp b/src/gui/wizard/owncloudwizardresultpage.cpp deleted file mode 100644 index d3b1e7268057..000000000000 --- a/src/gui/wizard/owncloudwizardresultpage.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) by Klaas Freitag - * Copyright (C) by Krzesimir Nowak - * - * 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 -#include -#include - -#include "guiutility.h" -#include "wizard/owncloudwizardresultpage.h" -#include "wizard/owncloudwizardcommon.h" -#include "theme.h" - -namespace OCC { - -OwncloudWizardResultPage::OwncloudWizardResultPage() - : QWizardPage() -{ - _ui.setupUi(this); - // no fields to register. - - setTitle(WizardCommon::subTitleTemplate().arg(tr("Everything set up!"))); - // required to show header in QWizard's modern style - setSubTitle(QLatin1String(" ")); - - _ui.pbOpenLocal->setText(tr("Open Local Folder")); - // TODO: File doesn't exist anymore - unneccessary or replacement needed? - _ui.pbOpenLocal->setIcon(QIcon(QLatin1String(":/client/theme/folder-sync.png"))); - _ui.pbOpenLocal->setIconSize(QSize(48, 48)); - _ui.pbOpenLocal->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - connect(_ui.pbOpenLocal, &QAbstractButton::clicked, this, &OwncloudWizardResultPage::slotOpenLocal); - - Theme *theme = Theme::instance(); - QIcon appIcon = theme->applicationIcon(); - _ui.pbOpenServer->setText(tr("Open %1 in Browser").arg(theme->appNameGUI())); - _ui.pbOpenServer->setIcon(appIcon.pixmap(48)); - _ui.pbOpenServer->setIconSize(QSize(48, 48)); - _ui.pbOpenServer->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - connect(_ui.pbOpenServer, &QAbstractButton::clicked, this, &OwncloudWizardResultPage::slotOpenServer); - setupCustomization(); -} - -OwncloudWizardResultPage::~OwncloudWizardResultPage() = default; - -void OwncloudWizardResultPage::setComplete(bool complete) -{ - _complete = complete; - emit completeChanged(); -} - -bool OwncloudWizardResultPage::isComplete() const -{ - return _complete; -} - -void OwncloudWizardResultPage::initializePage() -{ - _ui.localFolderLabel->setText(QString()); -} - -void OwncloudWizardResultPage::setRemoteFolder(const QString &remoteFolder) -{ - _remoteFolder = remoteFolder; -} - -void OwncloudWizardResultPage::setupCustomization() -{ - // set defaults for the customize labels. - _ui.topLabel->setText(QString()); - _ui.topLabel->hide(); - - QVariant variant = Theme::instance()->customMedia(Theme::oCSetupResultTop); - WizardCommon::setupCustomMedia(variant, _ui.topLabel); -} - -void OwncloudWizardResultPage::slotOpenLocal() -{ - const QString localFolder = wizard()->property("localFolder").toString(); - QDesktopServices::openUrl(QUrl::fromLocalFile(localFolder)); -} - -void OwncloudWizardResultPage::slotOpenServer() -{ - Theme *theme = Theme::instance(); - QUrl url = QUrl(field("OCUrl").toString() + theme->wizardUrlPostfix()); - Utility::openBrowser(url); -} - -} // namespace OCC diff --git a/src/gui/wizard/owncloudwizardresultpage.h b/src/gui/wizard/owncloudwizardresultpage.h deleted file mode 100644 index 416f075e00d0..000000000000 --- a/src/gui/wizard/owncloudwizardresultpage.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) by Klaas Freitag - * Copyright (C) by Krzesimir Nowak - * - * 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 MIRALL_OWNCLOUD_WIZARD_RESULT_PAGE_H -#define MIRALL_OWNCLOUD_WIZARD_RESULT_PAGE_H - -#include - -#include "ui_owncloudwizardresultpage.h" - -namespace OCC { - -/** - * @brief The OwncloudWizardResultPage class - * @ingroup gui - */ -class OwncloudWizardResultPage : public QWizardPage -{ - Q_OBJECT -public: - OwncloudWizardResultPage(); - ~OwncloudWizardResultPage(); - - bool isComplete() const override; - void initializePage() override; - void setRemoteFolder(const QString &remoteFolder); - -public slots: - void setComplete(bool complete); - -protected slots: - void slotOpenLocal(); - void slotOpenServer(); - -protected: - void setupCustomization(); - -private: - QString _localFolder; - QString _remoteFolder; - bool _complete = false; - - Ui_OwncloudWizardResultPage _ui; -}; - -} // namespace OCC - -#endif diff --git a/src/gui/wizard/owncloudwizardresultpage.ui b/src/gui/wizard/owncloudwizardresultpage.ui deleted file mode 100644 index 44652f2953ba..000000000000 --- a/src/gui/wizard/owncloudwizardresultpage.ui +++ /dev/null @@ -1,207 +0,0 @@ - - - OwncloudWizardResultPage - - - - 0 - 0 - 473 - 366 - - - - Form - - - - - - TextLabel - - - true - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 48 - 20 - - - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 16 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - - 200 - 80 - - - - PushButton - - - Qt::ToolButtonTextUnderIcon - - - - - - - - 0 - 0 - - - - - 200 - 80 - - - - PushButton - - - Qt::ToolButtonTextUnderIcon - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 16 - - - - - - - - Your entire account is synced to the local folder - - - true - - - - - - - Qt::Vertical - - - - 336 - 13 - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 48 - 20 - - - - - - - - - - - diff --git a/src/gui/wizard/webview.cpp b/src/gui/wizard/webview.cpp index d9cd20922935..9d48397dacfa 100644 --- a/src/gui/wizard/webview.cpp +++ b/src/gui/wizard/webview.cpp @@ -223,7 +223,7 @@ bool WebEnginePage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::Nav Q_UNUSED(type); Q_UNUSED(isMainFrame); - if (_enforceHttps && url.scheme() != QStringLiteral("https")) { + if (_enforceHttps && url.scheme() != QStringLiteral("https") && url.scheme() != QStringLiteral("nc")) { QMessageBox::warning(nullptr, "Security warning", "Can not follow non https link on a https website. This might be a security issue. Please contact your administrator"); return false; } diff --git a/src/gui/wizard/webview.h b/src/gui/wizard/webview.h index 93baf6b59faa..6cfbcb8c0394 100644 --- a/src/gui/wizard/webview.h +++ b/src/gui/wizard/webview.h @@ -21,7 +21,7 @@ class WebView : public QWidget Q_OBJECT public: WebView(QWidget *parent = nullptr); - virtual ~WebView(); + ~WebView() override; void setUrl(const QUrl &url); signals: diff --git a/src/gui/wizard/webviewpage.h b/src/gui/wizard/webviewpage.h index c621e99f1e26..db4febec17f6 100644 --- a/src/gui/wizard/webviewpage.h +++ b/src/gui/wizard/webviewpage.h @@ -14,7 +14,7 @@ class WebViewPage : public AbstractCredentialsWizardPage Q_OBJECT public: WebViewPage(QWidget *parent = nullptr); - ~WebViewPage(); + ~WebViewPage() override; void initializePage() override; void cleanupPage() override; diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index 40a98e1c995b..d58e27d218e4 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -29,6 +29,7 @@ set(libsync_SRCS configfile.cpp abstractnetworkjob.cpp networkjobs.cpp + iconjob.cpp owncloudpropagator.cpp nextcloudtheme.cpp abstractpropagateremotedeleteencrypted.cpp @@ -51,15 +52,25 @@ set(libsync_SRCS syncfilestatustracker.cpp localdiscoverytracker.cpp syncresult.cpp + syncoptions.cpp theme.cpp clientsideencryption.cpp clientsideencryptionjobs.cpp + datetimeprovider.cpp + ocsuserstatusconnector.cpp + userstatusconnector.cpp + ocsprofileconnector.cpp creds/dummycredentials.cpp creds/abstractcredentials.cpp creds/credentialscommon.cpp creds/keychainchunk.cpp ) +if (WIN32) + # to fix warnings from ntstatus.h + add_definitions(-DUMDF_USING_NTSTATUS) +endif() + if(TOKEN_AUTH_ONLY) set (libsync_SRCS ${libsync_SRCS} creds/tokencredentials.cpp) else() @@ -85,19 +96,22 @@ set(creds_HEADERS IF (NOT APPLE) INSTALL( FILES ${owncloudsync_HEADERS} - DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}/mirall + DESTINATION ${INCLUDE_INSTALL_DIR}/nextcloudsync/mirall ) INSTALL( FILES ${creds_HEADERS} - DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}/creds + DESTINATION ${INCLUDE_INSTALL_DIR}/nextcloudsync/creds ) ENDIF(NOT APPLE) find_package(Qt5 REQUIRED COMPONENTS WebSockets) -add_library(${synclib_NAME} SHARED ${libsync_SRCS}) -target_link_libraries(${synclib_NAME} + +add_library(nextcloudsync SHARED ${libsync_SRCS}) +add_library(Nextcloud::sync ALIAS nextcloudsync) + +target_link_libraries(nextcloudsync PUBLIC - "${csync_NAME}" + Nextcloud::csync OpenSSL::Crypto OpenSSL::SSL ${OS_SPECIFIC_LINK_LIBRARIES} @@ -108,38 +122,46 @@ target_link_libraries(${synclib_NAME} if (NOT TOKEN_AUTH_ONLY) find_package(Qt5 REQUIRED COMPONENTS Widgets Svg) - target_link_libraries(${synclib_NAME} PUBLIC Qt5::Widgets Qt5::Svg qt5keychain) + target_link_libraries(nextcloudsync PUBLIC Qt5::Widgets Qt5::Svg qt5keychain) endif() if(Inotify_FOUND) - target_include_directories(${synclib_NAME} PRIVATE ${Inotify_INCLUDE_DIRS}) - target_link_libraries(${synclib_NAME} PUBLIC ${Inotify_LIBRARIES}) + target_include_directories(nextcloudsync PRIVATE ${Inotify_INCLUDE_DIRS}) + target_link_libraries(nextcloudsync PUBLIC ${Inotify_LIBRARIES}) endif() -GENERATE_EXPORT_HEADER( ${synclib_NAME} - BASE_NAME ${synclib_NAME} +GENERATE_EXPORT_HEADER( nextcloudsync + BASE_NAME nextcloudsync EXPORT_MACRO_NAME OWNCLOUDSYNC_EXPORT EXPORT_FILE_NAME owncloudlib.h STATIC_DEFINE OWNCLOUD_BUILT_AS_STATIC ) -target_include_directories(${synclib_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) - - -set_target_properties( ${synclib_NAME} PROPERTIES - VERSION ${MIRALL_VERSION} - SOVERSION ${MIRALL_SOVERSION} - RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} +target_include_directories(nextcloudsync PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +set_target_properties( + nextcloudsync + PROPERTIES + VERSION + ${MIRALL_VERSION} + SOVERSION + ${MIRALL_SOVERSION} + RUNTIME_OUTPUT_DIRECTORY + ${BIN_OUTPUT_DIRECTORY} + LIBRARY_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync + RUNTIME_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync ) if(NOT BUILD_OWNCLOUD_OSX_BUNDLE) - install(TARGETS ${synclib_NAME} + install(TARGETS nextcloudsync RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) else() - install(TARGETS ${synclib_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS) + install(TARGETS nextcloudsync DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS) endif() diff --git a/src/libsync/abstractnetworkjob.cpp b/src/libsync/abstractnetworkjob.cpp index be9c01c9312e..6bb00a6b28ac 100644 --- a/src/libsync/abstractnetworkjob.cpp +++ b/src/libsync/abstractnetworkjob.cpp @@ -139,6 +139,15 @@ QNetworkReply *AbstractNetworkJob::sendRequest(const QByteArray &verb, const QUr return reply; } +QNetworkReply *AbstractNetworkJob::sendRequest(const QByteArray &verb, const QUrl &url, + QNetworkRequest req, const QByteArray &requestBody) +{ + auto reply = _account->sendRawRequest(verb, url, req, requestBody); + _requestBody = nullptr; + adoptRequest(reply); + return reply; +} + void AbstractNetworkJob::adoptRequest(QNetworkReply *reply) { addTimer(reply); diff --git a/src/libsync/abstractnetworkjob.h b/src/libsync/abstractnetworkjob.h index babdffdaa2ce..63391e672e6d 100644 --- a/src/libsync/abstractnetworkjob.h +++ b/src/libsync/abstractnetworkjob.h @@ -41,7 +41,7 @@ class OWNCLOUDSYNC_EXPORT AbstractNetworkJob : public QObject Q_OBJECT public: explicit AbstractNetworkJob(AccountPtr account, const QString &path, QObject *parent = nullptr); - virtual ~AbstractNetworkJob(); + ~AbstractNetworkJob() override; virtual void start(); @@ -128,6 +128,9 @@ public slots: QNetworkRequest req = QNetworkRequest(), QIODevice *requestBody = nullptr); + QNetworkReply *sendRequest(const QByteArray &verb, const QUrl &url, + QNetworkRequest req, const QByteArray &requestBody); + // sendRequest does not take a relative path instead of an url, // but the old API allowed that. We have this undefined overload // to help catch usage errors diff --git a/src/libsync/abstractpropagateremotedeleteencrypted.h b/src/libsync/abstractpropagateremotedeleteencrypted.h index c36fc956d4df..68db266aa078 100644 --- a/src/libsync/abstractpropagateremotedeleteencrypted.h +++ b/src/libsync/abstractpropagateremotedeleteencrypted.h @@ -32,7 +32,7 @@ class AbstractPropagateRemoteDeleteEncrypted : public QObject Q_OBJECT public: AbstractPropagateRemoteDeleteEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item, QObject *parent); - virtual ~AbstractPropagateRemoteDeleteEncrypted() = default; + ~AbstractPropagateRemoteDeleteEncrypted() override = default; QNetworkReply::NetworkError networkError() const; QString errorString() const; diff --git a/src/libsync/accessmanager.cpp b/src/libsync/accessmanager.cpp index da32d912a6e8..fa04e6c6bf3b 100644 --- a/src/libsync/accessmanager.cpp +++ b/src/libsync/accessmanager.cpp @@ -51,9 +51,7 @@ AccessManager::AccessManager(QObject *parent) QByteArray AccessManager::generateRequestId() { - // Use a UUID with the starting and ending curly brace removed. - auto uuid = QUuid::createUuid().toByteArray(); - return uuid.mid(1, uuid.size() - 2); + return QUuid::createUuid().toByteArray(QUuid::WithoutBraces); } QNetworkReply *AccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) diff --git a/src/libsync/account.cpp b/src/libsync/account.cpp index 52a8c1c4d52c..b6be1b1113e5 100644 --- a/src/libsync/account.cpp +++ b/src/libsync/account.cpp @@ -13,6 +13,8 @@ */ #include "account.h" +#include "accountfwd.h" +#include "clientsideencryptionjobs.h" #include "cookiejar.h" #include "networkjobs.h" #include "configfile.h" @@ -27,6 +29,7 @@ #include "common/asserts.h" #include "clientsideencryption.h" +#include "ocsuserstatusconnector.h" #include #include @@ -43,7 +46,9 @@ #include #include #include +#include +#include #include #include "creds/abstractcredentials.h" @@ -86,12 +91,18 @@ Account::~Account() = default; QString Account::davPath() const { - return QLatin1String("/remote.php/dav/files/") + davUser() + QLatin1Char('/'); + return davPathBase() + QLatin1Char('/') + davUser() + QLatin1Char('/'); } void Account::setSharedThis(AccountPtr sharedThis) { _sharedThis = sharedThis.toWeakRef(); + setupUserStatusConnector(); +} + +QString Account::davPathBase() +{ + return QStringLiteral("/remote.php/dav/files"); } AccountPtr Account::sharedFromThis() @@ -331,6 +342,24 @@ QNetworkReply *Account::sendRawRequest(const QByteArray &verb, const QUrl &url, return _am->sendCustomRequest(req, verb, data); } +QNetworkReply *Account::sendRawRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, const QByteArray &data) +{ + req.setUrl(url); + req.setSslConfiguration(this->getOrCreateSslConfig()); + if (verb == "HEAD" && data.isEmpty()) { + return _am->head(req); + } else if (verb == "GET" && data.isEmpty()) { + return _am->get(req); + } else if (verb == "POST") { + return _am->post(req, data); + } else if (verb == "PUT") { + return _am->put(req, data); + } else if (verb == "DELETE" && data.isEmpty()) { + return _am->deleteResource(req); + } + return _am->sendCustomRequest(req, verb, data); +} + SimpleNetworkJob *Account::sendRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data) { auto job = new SimpleNetworkJob(sharedFromThis()); @@ -360,13 +389,15 @@ QSslConfiguration Account::getOrCreateSslConfig() sslConfig.setSslOption(QSsl::SslOptionDisableSessionSharing, false); sslConfig.setSslOption(QSsl::SslOptionDisableSessionPersistence, false); + sslConfig.setOcspStaplingEnabled(Theme::instance()->enableStaplingOCSP()); + return sslConfig; } void Account::setApprovedCerts(const QList certs) { _approvedCerts = certs; - QSslSocket::addDefaultCaCertificates(certs); + QSslConfiguration::defaultConfiguration().addCaCertificates(certs); } void Account::addApprovedCerts(const QList certs) @@ -427,6 +458,9 @@ void Account::slotHandleSslErrors(QNetworkReply *reply, QList errors) << "\n"; } + qCInfo(lcAccount()) << "ssl errors" << out; + qCInfo(lcAccount()) << reply->sslConfiguration().peerCertificateChain(); + bool allPreviouslyRejected = true; foreach (const QSslError &error, errors) { if (!_rejectedCertificates.contains(error.certificate())) { @@ -458,7 +492,7 @@ void Account::slotHandleSslErrors(QNetworkReply *reply, QList errors) return; if (!approvedCerts.isEmpty()) { - QSslSocket::addDefaultCaCertificates(approvedCerts); + QSslConfiguration::defaultConfiguration().addCaCertificates(approvedCerts); addApprovedCerts(approvedCerts); emit wantsAccountSaved(this); @@ -538,9 +572,21 @@ void Account::setCapabilities(const QVariantMap &caps) { _capabilities = Capabilities(caps); + setupUserStatusConnector(); trySetupPushNotifications(); } +void Account::setupUserStatusConnector() +{ + _userStatusConnector = std::make_shared(sharedFromThis()); + connect(_userStatusConnector.get(), &UserStatusConnector::userStatusFetched, this, [this](const UserStatus &) { + emit userStatusChanged(); + }); + connect(_userStatusConnector.get(), &UserStatusConnector::messageCleared, this, [this] { + emit userStatusChanged(); + }); +} + QString Account::serverVersion() const { return _serverVersion; @@ -738,4 +784,9 @@ PushNotifications *Account::pushNotifications() const return _pushNotifications; } +std::shared_ptr Account::userStatusConnector() const +{ + return _userStatusConnector; +} + } // namespace OCC diff --git a/src/libsync/account.h b/src/libsync/account.h index 1b4e2d2e4477..334425853dc4 100644 --- a/src/libsync/account.h +++ b/src/libsync/account.h @@ -55,6 +55,7 @@ using AccountPtr = QSharedPointer; class AccessManager; class SimpleNetworkJob; class PushNotifications; +class UserStatusConnector; /** * @brief Reimplement this to handle SSL errors from libsync @@ -84,7 +85,7 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject public: static AccountPtr create(); - ~Account(); + ~Account() override; AccountPtr sharedFromThis(); @@ -150,6 +151,9 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject QNetworkRequest req = QNetworkRequest(), QIODevice *data = nullptr); + QNetworkReply *sendRawRequest(const QByteArray &verb, + const QUrl &url, QNetworkRequest req, const QByteArray &data); + /** Create and start network job for a simple one-off request. * * More complicated requests typically create their own job types. @@ -251,10 +255,13 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject // Check for the directEditing capability void fetchDirectEditors(const QUrl &directEditingURL, const QString &directEditingETag); + void setupUserStatusConnector(); void trySetupPushNotifications(); PushNotifications *pushNotifications() const; void setPushNotificationsReconnectInterval(int interval); + std::shared_ptr userStatusConnector() const; + public slots: /// Used when forgetting credentials void clearQNAMCache(); @@ -287,6 +294,8 @@ public slots: void pushNotificationsReady(Account *account); void pushNotificationsDisabled(Account *account); + void userStatusChanged(); + protected Q_SLOTS: void slotCredentialsFetched(); void slotCredentialsAsked(); @@ -296,6 +305,8 @@ protected Q_SLOTS: Account(QObject *parent = nullptr); void setSharedThis(AccountPtr sharedThis); + static QString davPathBase(); + QWeakPointer _sharedThis; QString _id; QString _davUser; @@ -341,6 +352,8 @@ protected Q_SLOTS: PushNotifications *_pushNotifications = nullptr; + std::shared_ptr _userStatusConnector; + /* IMPORTANT - remove later - FIXME MS@2019-12-07 --> * TODO: For "Log out" & "Remove account": Remove client CA certs and KEY! * diff --git a/src/libsync/bandwidthmanager.h b/src/libsync/bandwidthmanager.h index 43b4a36b9491..adef4e66881f 100644 --- a/src/libsync/bandwidthmanager.h +++ b/src/libsync/bandwidthmanager.h @@ -35,7 +35,7 @@ class BandwidthManager : public QObject Q_OBJECT public: BandwidthManager(OwncloudPropagator *p); - ~BandwidthManager(); + ~BandwidthManager() override; bool usingAbsoluteUploadLimit() { return _currentUploadLimit > 0; } bool usingRelativeUploadLimit() { return _currentUploadLimit < 0; } diff --git a/src/libsync/capabilities.cpp b/src/libsync/capabilities.cpp index 04db298b142d..d8fa1096a98d 100644 --- a/src/libsync/capabilities.cpp +++ b/src/libsync/capabilities.cpp @@ -90,6 +90,26 @@ int Capabilities::sharePublicLinkExpireDateDays() const return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date"].toMap()["days"].toInt(); } +bool Capabilities::shareInternalEnforceExpireDate() const +{ + return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date_internal"].toMap()["enforced"].toBool(); +} + +int Capabilities::shareInternalExpireDateDays() const +{ + return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date_internal"].toMap()["days"].toInt(); +} + +bool Capabilities::shareRemoteEnforceExpireDate() const +{ + return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date_remote"].toMap()["enforced"].toBool(); +} + +int Capabilities::shareRemoteExpireDateDays() const +{ + return _capabilities["files_sharing"].toMap()["public"].toMap()["expire_date_remote"].toMap()["days"].toInt(); +} + bool Capabilities::sharePublicLinkMultiple() const { return _capabilities["files_sharing"].toMap()["public"].toMap()["multiple"].toBool(); @@ -100,6 +120,15 @@ bool Capabilities::shareResharing() const return _capabilities["files_sharing"].toMap()["resharing"].toBool(); } +int Capabilities::shareDefaultPermissions() const +{ + if(_capabilities["files_sharing"].toMap().contains("default_permissions")) { + return _capabilities["files_sharing"].toMap()["default_permissions"].toInt(); + } + + return {}; +} + bool Capabilities::clientSideEncryptionAvailable() const { auto it = _capabilities.constFind(QStringLiteral("end-to-end-encryption")); @@ -187,13 +216,31 @@ bool Capabilities::chunkingNg() const return _capabilities["dav"].toMap()["chunking"].toByteArray() >= "1.0"; } -bool Capabilities::userStatus() const +bool Capabilities::userStatusNotification() const { return _capabilities.contains("notifications") && _capabilities["notifications"].toMap().contains("ocs-endpoints") && _capabilities["notifications"].toMap()["ocs-endpoints"].toStringList().contains("user-status"); } +bool Capabilities::userStatus() const +{ + if (!_capabilities.contains("user_status")) { + return false; + } + const auto userStatusMap = _capabilities["user_status"].toMap(); + return userStatusMap.value("enabled", false).toBool(); +} + +bool Capabilities::userStatusSupportsEmoji() const +{ + if (!userStatus()) { + return false; + } + const auto userStatusMap = _capabilities["user_status"].toMap(); + return userStatusMap.value("supports_emoji", false).toBool(); +} + PushNotificationTypes Capabilities::availablePushNotifications() const { if (!_capabilities.contains("notify_push")) { diff --git a/src/libsync/capabilities.h b/src/libsync/capabilities.h index 078a0cd35469..fb251e7e3a72 100644 --- a/src/libsync/capabilities.h +++ b/src/libsync/capabilities.h @@ -55,10 +55,17 @@ class OWNCLOUDSYNC_EXPORT Capabilities bool sharePublicLinkEnforcePassword() const; bool sharePublicLinkEnforceExpireDate() const; int sharePublicLinkExpireDateDays() const; + bool shareInternalEnforceExpireDate() const; + int shareInternalExpireDateDays() const; + bool shareRemoteEnforceExpireDate() const; + int shareRemoteExpireDateDays() const; bool sharePublicLinkMultiple() const; bool shareResharing() const; + int shareDefaultPermissions() const; bool chunkingNg() const; + bool userStatusNotification() const; bool userStatus() const; + bool userStatusSupportsEmoji() const; /// Returns which kind of push notfications are available PushNotificationTypes availablePushNotifications() const; diff --git a/src/libsync/clientsideencryption.cpp b/src/libsync/clientsideencryption.cpp index 6c1cfd2cd983..1deada948f94 100644 --- a/src/libsync/clientsideencryption.cpp +++ b/src/libsync/clientsideencryption.cpp @@ -36,7 +36,8 @@ #include #include -#include "common/utility.h" +#include +#include #include "wordlist.h" @@ -55,7 +56,8 @@ Q_LOGGING_CATEGORY(lcCse, "nextcloud.sync.clientsideencryption", QtInfoMsg) Q_LOGGING_CATEGORY(lcCseDecryption, "nextcloud.e2e", QtInfoMsg) Q_LOGGING_CATEGORY(lcCseMetadata, "nextcloud.metadata", QtInfoMsg) -QString baseUrl(){ +QString e2eeBaseUrl() +{ return QStringLiteral("ocs/v2.php/apps/end_to_end_encryption/api/v1/"); } @@ -66,6 +68,8 @@ namespace { const char e2e_private[] = "_e2e-private"; const char e2e_mnemonic[] = "_e2e-mnemonic"; + constexpr qint64 blockSize = 1024; + QList oldCipherFormatSplit(const QByteArray &cipher) { const auto separator = QByteArrayLiteral("fA=="); // BASE64 encoded '|' @@ -295,7 +299,7 @@ namespace { }; QByteArray BIO2ByteArray(Bio &b) { - int pending = BIO_ctrl_pending(b); + auto pending = static_cast(BIO_ctrl_pending(b)); QByteArray res(pending, '\0'); BIO_read(b, unsignedData(res), pending); return res; @@ -423,17 +427,17 @@ QByteArray encryptPrivateKey( } clen += len; - /* Get the tag */ - QByteArray tag(16, '\0'); - if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, unsignedData(tag))) { - qCInfo(lcCse()) << "Error getting the tag"; + /* Get the e2EeTag */ + QByteArray e2EeTag(OCC::Constants::e2EeTagSize, '\0'); + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, OCC::Constants::e2EeTagSize, unsignedData(e2EeTag))) { + qCInfo(lcCse()) << "Error getting the e2EeTag"; handleErrors(); } QByteArray cipherTXT; - cipherTXT.reserve(clen + 16); + cipherTXT.reserve(clen + OCC::Constants::e2EeTagSize); cipherTXT.append(ctext, clen); - cipherTXT.append(tag); + cipherTXT.append(e2EeTag); QByteArray result = cipherTXT.toBase64(); result += '|'; @@ -463,8 +467,8 @@ QByteArray decryptPrivateKey(const QByteArray& key, const QByteArray& data) { QByteArray cipherTXT = QByteArray::fromBase64(cipherTXT64); QByteArray iv = QByteArray::fromBase64(ivB64); - QByteArray tag = cipherTXT.right(16); - cipherTXT.chop(16); + const QByteArray e2EeTag = cipherTXT.right(OCC::Constants::e2EeTagSize); + cipherTXT.chop(OCC::Constants::e2EeTagSize); // Init CipherCtx ctx; @@ -493,7 +497,7 @@ QByteArray decryptPrivateKey(const QByteArray& key, const QByteArray& data) { return QByteArray(); } - QByteArray ptext(cipherTXT.size() + 16, '\0'); + QByteArray ptext(cipherTXT.size() + OCC::Constants::e2EeTagSize, '\0'); int plen = 0; /* Provide the message to be decrypted, and obtain the plaintext output. @@ -504,9 +508,9 @@ QByteArray decryptPrivateKey(const QByteArray& key, const QByteArray& data) { return QByteArray(); } - /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ - if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag.size(), (unsigned char *)tag.constData())) { - qCInfo(lcCse()) << "Could not set tag"; + /* Set expected e2EeTag value. Works in OpenSSL 1.0.1d and later */ + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, e2EeTag.size(), (unsigned char *)e2EeTag.constData())) { + qCInfo(lcCse()) << "Could not set e2EeTag"; return QByteArray(); } @@ -553,8 +557,8 @@ QByteArray decryptStringSymmetric(const QByteArray& key, const QByteArray& data) QByteArray cipherTXT = QByteArray::fromBase64(cipherTXT64); QByteArray iv = QByteArray::fromBase64(ivB64); - QByteArray tag = cipherTXT.right(16); - cipherTXT.chop(16); + const QByteArray e2EeTag = cipherTXT.right(OCC::Constants::e2EeTagSize); + cipherTXT.chop(OCC::Constants::e2EeTagSize); // Init CipherCtx ctx; @@ -583,7 +587,7 @@ QByteArray decryptStringSymmetric(const QByteArray& key, const QByteArray& data) return QByteArray(); } - QByteArray ptext(cipherTXT.size() + 16, '\0'); + QByteArray ptext(cipherTXT.size() + OCC::Constants::e2EeTagSize, '\0'); int plen = 0; /* Provide the message to be decrypted, and obtain the plaintext output. @@ -594,9 +598,9 @@ QByteArray decryptStringSymmetric(const QByteArray& key, const QByteArray& data) return QByteArray(); } - /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ - if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag.size(), (unsigned char *)tag.constData())) { - qCInfo(lcCse()) << "Could not set tag"; + /* Set expected e2EeTag value. Works in OpenSSL 1.0.1d and later */ + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, e2EeTag.size(), (unsigned char *)e2EeTag.constData())) { + qCInfo(lcCse()) << "Could not set e2EeTag"; return QByteArray(); } @@ -686,18 +690,18 @@ QByteArray encryptStringSymmetric(const QByteArray& key, const QByteArray& data) } clen += len; - /* Get the tag */ - QByteArray tag(16, '\0'); - if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, unsignedData(tag))) { - qCInfo(lcCse()) << "Error getting the tag"; + /* Get the e2EeTag */ + QByteArray e2EeTag(OCC::Constants::e2EeTagSize, '\0'); + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, OCC::Constants::e2EeTagSize, unsignedData(e2EeTag))) { + qCInfo(lcCse()) << "Error getting the e2EeTag"; handleErrors(); return {}; } QByteArray cipherTXT; - cipherTXT.reserve(clen + 16); + cipherTXT.reserve(clen + OCC::Constants::e2EeTagSize); cipherTXT.append(ctext, clen); - cipherTXT.append(tag); + cipherTXT.append(e2EeTag); QByteArray result = cipherTXT.toBase64(); result += '|'; @@ -753,7 +757,7 @@ QByteArray decryptStringAsymmetric(EVP_PKEY *privateKey, const QByteArray& data) qCInfo(lcCseDecryption()) << "Size of data is: " << data.size(); } - QByteArray out(outlen, '\0'); + QByteArray out(static_cast(outlen), '\0'); if (EVP_PKEY_decrypt(ctx, unsignedData(out), &outlen, (unsigned char *)data.constData(), data.size()) <= 0) { const auto error = handleErrors(); @@ -804,7 +808,7 @@ QByteArray encryptStringAsymmetric(EVP_PKEY *publicKey, const QByteArray& data) qCInfo(lcCse()) << "Encryption Length:" << outLen; } - QByteArray out(outLen, '\0'); + QByteArray out(static_cast(outLen), '\0'); if (EVP_PKEY_encrypt(ctx, unsignedData(out), &outLen, (unsigned char *)data.constData(), data.size()) != 1) { qCInfo(lcCse()) << "Could not encrypt key." << err; exit(1); @@ -1177,7 +1181,7 @@ void ClientSideEncryption::generateCSR(const AccountPtr &account, EVP_PKEY *keyP qCInfo(lcCse()) << "Returning the certificate"; qCInfo(lcCse()) << output; - auto job = new SignPublicKeyApiJob(account, baseUrl() + "public-key", this); + auto job = new SignPublicKeyApiJob(account, e2eeBaseUrl() + "public-key", this); job->setCsr(output); connect(job, &SignPublicKeyApiJob::jsonReceived, [this, account](const QJsonDocument& json, int retCode) { @@ -1209,7 +1213,7 @@ void ClientSideEncryption::encryptPrivateKey(const AccountPtr &account) auto cryptedText = EncryptionHelper::encryptPrivateKey(secretKey, EncryptionHelper::privateKeyToPem(_privateKey), salt); // Send private key to the server - auto job = new StorePrivateKeyApiJob(account, baseUrl() + "private-key", this); + auto job = new StorePrivateKeyApiJob(account, e2eeBaseUrl() + "private-key", this); job->setPrivateKey(cryptedText); connect(job, &StorePrivateKeyApiJob::jsonReceived, [this, account](const QJsonDocument& doc, int retCode) { Q_UNUSED(doc); @@ -1293,7 +1297,7 @@ void ClientSideEncryption::decryptPrivateKey(const AccountPtr &account, const QB void ClientSideEncryption::getPrivateKeyFromServer(const AccountPtr &account) { qCInfo(lcCse()) << "Retrieving private key from server"; - auto job = new JsonApiJob(account, baseUrl() + "private-key", this); + auto job = new JsonApiJob(account, e2eeBaseUrl() + "private-key", this); connect(job, &JsonApiJob::jsonReceived, [this, account](const QJsonDocument& doc, int retCode) { if (retCode == 200) { QString key = doc.object()["ocs"].toObject()["data"].toObject()["private-key"].toString(); @@ -1312,7 +1316,7 @@ void ClientSideEncryption::getPrivateKeyFromServer(const AccountPtr &account) void ClientSideEncryption::getPublicKeyFromServer(const AccountPtr &account) { qCInfo(lcCse()) << "Retrieving public key from server"; - auto job = new JsonApiJob(account, baseUrl() + "public-key", this); + auto job = new JsonApiJob(account, e2eeBaseUrl() + "public-key", this); connect(job, &JsonApiJob::jsonReceived, [this, account](const QJsonDocument& doc, int retCode) { if (retCode == 200) { QString publicKey = doc.object()["ocs"].toObject()["data"].toObject()["public-keys"].toObject()[account->davUser()].toString(); @@ -1333,7 +1337,7 @@ void ClientSideEncryption::getPublicKeyFromServer(const AccountPtr &account) void ClientSideEncryption::fetchAndValidatePublicKeyFromServer(const AccountPtr &account) { qCInfo(lcCse()) << "Retrieving public key from server"; - auto job = new JsonApiJob(account, baseUrl() + "server-key", this); + auto job = new JsonApiJob(account, e2eeBaseUrl() + "server-key", this); connect(job, &JsonApiJob::jsonReceived, [this, account](const QJsonDocument& doc, int retCode) { if (retCode == 200) { const auto serverPublicKey = doc.object()["ocs"].toObject()["data"].toObject()["public-key"].toString().toLatin1(); @@ -1650,20 +1654,19 @@ bool EncryptionHelper::fileEncryption(const QByteArray &key, const QByteArray &i return false; } - QByteArray out(1024 + 16 - 1, '\0'); + QByteArray out(blockSize + OCC::Constants::e2EeTagSize - 1, '\0'); int len = 0; int total_len = 0; qCDebug(lcCse) << "Starting to encrypt the file" << input->fileName() << input->atEnd(); while(!input->atEnd()) { - QByteArray data = input->read(1024); + const auto data = input->read(blockSize); if (data.size() == 0) { qCInfo(lcCse()) << "Could not read data from file"; return false; } - qCDebug(lcCse) << "Encrypting " << data; if(!EVP_EncryptUpdate(ctx, unsignedData(out), &len, (unsigned char *)data.constData(), data.size())) { qCInfo(lcCse()) << "Could not encrypt"; return false; @@ -1680,15 +1683,15 @@ bool EncryptionHelper::fileEncryption(const QByteArray &key, const QByteArray &i output->write(out, len); total_len += len; - /* Get the tag */ - QByteArray tag(16, '\0'); - if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, unsignedData(tag))) { - qCInfo(lcCse()) << "Could not get tag"; + /* Get the e2EeTag */ + QByteArray e2EeTag(OCC::Constants::e2EeTagSize, '\0'); + if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, OCC::Constants::e2EeTagSize, unsignedData(e2EeTag))) { + qCInfo(lcCse()) << "Could not get e2EeTag"; return false; } - returnTag = tag; - output->write(tag, 16); + returnTag = e2EeTag; + output->write(e2EeTag, OCC::Constants::e2EeTagSize); input->close(); output->close(); @@ -1731,16 +1734,16 @@ bool EncryptionHelper::fileDecryption(const QByteArray &key, const QByteArray& i return false; } - qint64 size = input->size() - 16; + qint64 size = input->size() - OCC::Constants::e2EeTagSize; - QByteArray out(1024 + 16 - 1, '\0'); + QByteArray out(blockSize + OCC::Constants::e2EeTagSize - 1, '\0'); int len = 0; while(input->pos() < size) { auto toRead = size - input->pos(); - if (toRead > 1024) { - toRead = 1024; + if (toRead > blockSize) { + toRead = blockSize; } QByteArray data = input->read(toRead); @@ -1758,11 +1761,11 @@ bool EncryptionHelper::fileDecryption(const QByteArray &key, const QByteArray& i output->write(out, len); } - QByteArray tag = input->read(16); + const QByteArray e2EeTag = input->read(OCC::Constants::e2EeTagSize); - /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ - if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, tag.size(), (unsigned char *)tag.constData())) { - qCInfo(lcCse()) << "Could not set expected tag"; + /* Set expected e2EeTag value. Works in OpenSSL 1.0.1d and later */ + if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, e2EeTag.size(), (unsigned char *)e2EeTag.constData())) { + qCInfo(lcCse()) << "Could not set expected e2EeTag"; return false; } @@ -1777,4 +1780,181 @@ bool EncryptionHelper::fileDecryption(const QByteArray &key, const QByteArray& i return true; } +EncryptionHelper::StreamingDecryptor::StreamingDecryptor(const QByteArray &key, const QByteArray &iv, quint64 totalSize) : _totalSize(totalSize) +{ + if (_ctx && !key.isEmpty() && !iv.isEmpty() && totalSize > 0) { + _isInitialized = true; + + /* Initialize the decryption operation. */ + if(!EVP_DecryptInit_ex(_ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr)) { + qCritical(lcCse()) << "Could not init cipher"; + _isInitialized = false; + } + + EVP_CIPHER_CTX_set_padding(_ctx, 0); + + /* Set IV length. */ + if(!EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_SET_IVLEN, iv.size(), nullptr)) { + qCritical(lcCse()) << "Could not set iv length"; + _isInitialized = false; + } + + /* Initialize key and IV */ + if(!EVP_DecryptInit_ex(_ctx, nullptr, nullptr, reinterpret_cast(key.constData()), reinterpret_cast(iv.constData()))) { + qCritical(lcCse()) << "Could not set key and iv"; + _isInitialized = false; + } + } +} + +QByteArray EncryptionHelper::StreamingDecryptor::chunkDecryption(const char *input, quint64 chunkSize) +{ + QByteArray byteArray; + QBuffer buffer(&byteArray); + buffer.open(QIODevice::WriteOnly); + + Q_ASSERT(isInitialized()); + if (!isInitialized()) { + qCritical(lcCse()) << "Decryption failed. Decryptor is not initialized!"; + return QByteArray(); + } + + Q_ASSERT(buffer.isOpen() && buffer.isWritable()); + if (!buffer.isOpen() || !buffer.isWritable()) { + qCritical(lcCse()) << "Decryption failed. Incorrect output device!"; + return QByteArray(); + } + + Q_ASSERT(input); + if (!input) { + qCritical(lcCse()) << "Decryption failed. Incorrect input!"; + return QByteArray(); + } + + Q_ASSERT(chunkSize > 0); + if (chunkSize <= 0) { + qCritical(lcCse()) << "Decryption failed. Incorrect chunkSize!"; + return QByteArray(); + } + + if (_decryptedSoFar == 0) { + qCDebug(lcCse()) << "Decryption started"; + } + + Q_ASSERT(_decryptedSoFar + chunkSize <= _totalSize); + if (_decryptedSoFar + chunkSize > _totalSize) { + qCritical(lcCse()) << "Decryption failed. Chunk is out of range!"; + return QByteArray(); + } + + Q_ASSERT(_decryptedSoFar + chunkSize < OCC::Constants::e2EeTagSize || _totalSize - OCC::Constants::e2EeTagSize >= _decryptedSoFar + chunkSize - OCC::Constants::e2EeTagSize); + if (_decryptedSoFar + chunkSize > OCC::Constants::e2EeTagSize && _totalSize - OCC::Constants::e2EeTagSize < _decryptedSoFar + chunkSize - OCC::Constants::e2EeTagSize) { + qCritical(lcCse()) << "Decryption failed. Incorrect chunk!"; + return QByteArray(); + } + + const bool isLastChunk = _decryptedSoFar + chunkSize == _totalSize; + + // last OCC::Constants::e2EeTagSize bytes is ALWAYS a e2EeTag!!! + const qint64 size = isLastChunk ? chunkSize - OCC::Constants::e2EeTagSize : chunkSize; + + // either the size is more than 0 and an e2EeTag is at the end of chunk, or, chunk is the e2EeTag itself + Q_ASSERT(size > 0 || chunkSize == OCC::Constants::e2EeTagSize); + if (size <= 0 && chunkSize != OCC::Constants::e2EeTagSize) { + qCritical(lcCse()) << "Decryption failed. Invalid input size: " << size << " !"; + return QByteArray(); + } + + qint64 bytesWritten = 0; + qint64 inputPos = 0; + + QByteArray decryptedBlock(blockSize + OCC::Constants::e2EeTagSize - 1, '\0'); + + while(inputPos < size) { + // read blockSize or less bytes + const QByteArray encryptedBlock(input + inputPos, qMin(size - inputPos, blockSize)); + + if (encryptedBlock.size() == 0) { + qCritical(lcCse()) << "Could not read data from the input buffer."; + return QByteArray(); + } + + int outLen = 0; + + if(!EVP_DecryptUpdate(_ctx, unsignedData(decryptedBlock), &outLen, reinterpret_cast(encryptedBlock.data()), encryptedBlock.size())) { + qCritical(lcCse()) << "Could not decrypt"; + return QByteArray(); + } + + const auto writtenToOutput = buffer.write(decryptedBlock, outLen); + + Q_ASSERT(writtenToOutput == outLen); + if (writtenToOutput != outLen) { + qCritical(lcCse()) << "Failed to write decrypted data to device."; + return QByteArray(); + } + + bytesWritten += writtenToOutput; + + // advance input position for further read + inputPos += encryptedBlock.size(); + + _decryptedSoFar += encryptedBlock.size(); + } + + if (isLastChunk) { + // if it's a last chunk, we'd need to read a e2EeTag at the end and finalize the decryption + + Q_ASSERT(chunkSize - inputPos == OCC::Constants::e2EeTagSize); + if (chunkSize - inputPos != OCC::Constants::e2EeTagSize) { + qCritical(lcCse()) << "Decryption failed. e2EeTag is missing!"; + return QByteArray(); + } + + int outLen = 0; + + QByteArray e2EeTag = QByteArray(input + inputPos, OCC::Constants::e2EeTagSize); + + /* Set expected e2EeTag value. Works in OpenSSL 1.0.1d and later */ + if(!EVP_CIPHER_CTX_ctrl(_ctx, EVP_CTRL_GCM_SET_TAG, e2EeTag.size(), reinterpret_cast(e2EeTag.data()))) { + qCritical(lcCse()) << "Could not set expected e2EeTag"; + return QByteArray(); + } + + if(1 != EVP_DecryptFinal_ex(_ctx, unsignedData(decryptedBlock), &outLen)) { + qCritical(lcCse()) << "Could finalize decryption"; + return QByteArray(); + } + + const auto writtenToOutput = buffer.write(decryptedBlock, outLen); + + Q_ASSERT(writtenToOutput == outLen); + if (writtenToOutput != outLen) { + qCritical(lcCse()) << "Failed to write decrypted data to device."; + return QByteArray(); + } + + bytesWritten += writtenToOutput; + + _decryptedSoFar += OCC::Constants::e2EeTagSize; + + _isFinished = true; + } + + if (isFinished()) { + qCDebug(lcCse()) << "Decryption complete"; + } + + return byteArray; +} + +bool EncryptionHelper::StreamingDecryptor::isInitialized() const +{ + return _isInitialized; +} + +bool EncryptionHelper::StreamingDecryptor::isFinished() const +{ + return _isFinished; +} } diff --git a/src/libsync/clientsideencryption.h b/src/libsync/clientsideencryption.h index 8ea5834ab19d..751c7d4c824f 100644 --- a/src/libsync/clientsideencryption.h +++ b/src/libsync/clientsideencryption.h @@ -23,11 +23,11 @@ class ReadPasswordJob; namespace OCC { -QString baseUrl(); +QString e2eeBaseUrl(); namespace EncryptionHelper { QByteArray generateRandomFilename(); - QByteArray generateRandom(int size); + OWNCLOUDSYNC_EXPORT QByteArray generateRandom(int size); QByteArray generatePassword(const QString &wordlist, const QByteArray& salt); OWNCLOUDSYNC_EXPORT QByteArray encryptPrivateKey( const QByteArray& key, @@ -60,11 +60,57 @@ namespace EncryptionHelper { const QByteArray& data ); - bool fileEncryption(const QByteArray &key, const QByteArray &iv, + OWNCLOUDSYNC_EXPORT bool fileEncryption(const QByteArray &key, const QByteArray &iv, QFile *input, QFile *output, QByteArray& returnTag); - bool fileDecryption(const QByteArray &key, const QByteArray& iv, + OWNCLOUDSYNC_EXPORT bool fileDecryption(const QByteArray &key, const QByteArray &iv, QFile *input, QFile *output); + +// +// Simple classes for safe (RAII) handling of OpenSSL +// data structures +// +class CipherCtx { +public: + CipherCtx() : _ctx(EVP_CIPHER_CTX_new()) + { + } + + ~CipherCtx() + { + EVP_CIPHER_CTX_free(_ctx); + } + + operator EVP_CIPHER_CTX*() + { + return _ctx; + } + +private: + Q_DISABLE_COPY(CipherCtx) + EVP_CIPHER_CTX *_ctx; +}; + +class OWNCLOUDSYNC_EXPORT StreamingDecryptor +{ +public: + StreamingDecryptor(const QByteArray &key, const QByteArray &iv, quint64 totalSize); + ~StreamingDecryptor() = default; + + QByteArray chunkDecryption(const char *input, quint64 chunkSize); + + bool isInitialized() const; + bool isFinished() const; + +private: + Q_DISABLE_COPY(StreamingDecryptor) + + CipherCtx _ctx; + bool _isInitialized = false; + bool _isFinished = false; + quint64 _decryptedSoFar = 0; + quint64 _totalSize = 0; +}; } class OWNCLOUDSYNC_EXPORT ClientSideEncryption : public QObject { diff --git a/src/libsync/clientsideencryptionjobs.cpp b/src/libsync/clientsideencryptionjobs.cpp index ad8e30c66d29..71bb8a510609 100644 --- a/src/libsync/clientsideencryptionjobs.cpp +++ b/src/libsync/clientsideencryptionjobs.cpp @@ -27,7 +27,7 @@ namespace OCC { GetMetadataApiJob::GetMetadataApiJob(const AccountPtr& account, const QByteArray& fileId, QObject* parent) -: AbstractNetworkJob(account, baseUrl() + QStringLiteral("meta-data/") + fileId, parent), _fileId(fileId) +: AbstractNetworkJob(account, e2eeBaseUrl() + QStringLiteral("meta-data/") + fileId, parent), _fileId(fileId) { } @@ -63,7 +63,7 @@ StoreMetaDataApiJob::StoreMetaDataApiJob(const AccountPtr& account, const QByteArray& fileId, const QByteArray& b64Metadata, QObject* parent) -: AbstractNetworkJob(account, baseUrl() + QStringLiteral("meta-data/") + fileId, parent), _fileId(fileId), _b64Metadata(b64Metadata) +: AbstractNetworkJob(account, e2eeBaseUrl() + QStringLiteral("meta-data/") + fileId, parent), _fileId(fileId), _b64Metadata(b64Metadata) { } @@ -104,8 +104,8 @@ UpdateMetadataApiJob::UpdateMetadataApiJob(const AccountPtr& account, const QByteArray& b64Metadata, const QByteArray& token, QObject* parent) -: AbstractNetworkJob(account, baseUrl() + QStringLiteral("meta-data/") + fileId, parent), -_fileId(fileId), +: AbstractNetworkJob(account, e2eeBaseUrl() + QStringLiteral("meta-data/") + fileId, parent) +, _fileId(fileId), _b64Metadata(b64Metadata), _token(token) { @@ -154,7 +154,7 @@ UnlockEncryptFolderApiJob::UnlockEncryptFolderApiJob(const AccountPtr& account, const QByteArray& fileId, const QByteArray& token, QObject* parent) -: AbstractNetworkJob(account, baseUrl() + QStringLiteral("lock/") + fileId, parent), _fileId(fileId), _token(token) +: AbstractNetworkJob(account, e2eeBaseUrl() + QStringLiteral("lock/") + fileId, parent), _fileId(fileId), _token(token) { } @@ -185,11 +185,10 @@ bool UnlockEncryptFolderApiJob::finished() } - DeleteMetadataApiJob::DeleteMetadataApiJob(const AccountPtr& account, const QByteArray& fileId, QObject* parent) -: AbstractNetworkJob(account, baseUrl() + QStringLiteral("meta-data/") + fileId, parent), _fileId(fileId) +: AbstractNetworkJob(account, e2eeBaseUrl() + QStringLiteral("meta-data/") + fileId, parent), _fileId(fileId) { } @@ -219,7 +218,7 @@ bool DeleteMetadataApiJob::finished() } LockEncryptFolderApiJob::LockEncryptFolderApiJob(const AccountPtr& account, const QByteArray& fileId, QObject* parent) -: AbstractNetworkJob(account, baseUrl() + QStringLiteral("lock/") + fileId, parent), _fileId(fileId) +: AbstractNetworkJob(account, e2eeBaseUrl() + QStringLiteral("lock/") + fileId, parent), _fileId(fileId) { } @@ -258,7 +257,7 @@ bool LockEncryptFolderApiJob::finished() } SetEncryptionFlagApiJob::SetEncryptionFlagApiJob(const AccountPtr& account, const QByteArray& fileId, FlagAction flagAction, QObject* parent) -: AbstractNetworkJob(account, baseUrl() + QStringLiteral("encrypted/") + fileId, parent), _fileId(fileId), _flagAction(flagAction) +: AbstractNetworkJob(account, e2eeBaseUrl() + QStringLiteral("encrypted/") + fileId, parent), _fileId(fileId), _flagAction(flagAction) { } diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp index fddd5ed88e65..0f2059be2669 100644 --- a/src/libsync/configfile.cpp +++ b/src/libsync/configfile.cpp @@ -645,7 +645,7 @@ int ConfigFile::updateSegment() const // Invalid? (Unset at the very first launch) if(segment < 0 || segment > 99) { // Save valid segment value, normally has to be done only once. - segment = qrand() % 99; + segment = Utility::rand() % 99; settings.setValue(QLatin1String(updateSegmentC), segment); } diff --git a/src/libsync/cookiejar.h b/src/libsync/cookiejar.h index ecdd69971c59..6d3703aaa1ff 100644 --- a/src/libsync/cookiejar.h +++ b/src/libsync/cookiejar.h @@ -30,7 +30,7 @@ class OWNCLOUDSYNC_EXPORT CookieJar : public QNetworkCookieJar Q_OBJECT public: explicit CookieJar(QObject *parent = nullptr); - ~CookieJar(); + ~CookieJar() override; bool setCookiesFromUrl(const QList &cookieList, const QUrl &url) override; QList cookiesForUrl(const QUrl &url) const override; diff --git a/src/libsync/creds/credentialscommon.cpp b/src/libsync/creds/credentialscommon.cpp index b56b8193dee1..edc17ff830bf 100644 --- a/src/libsync/creds/credentialscommon.cpp +++ b/src/libsync/creds/credentialscommon.cpp @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/libsync/creds/keychainchunk.h b/src/libsync/creds/keychainchunk.h index 0a08b8f2f54e..0e86843728e7 100644 --- a/src/libsync/creds/keychainchunk.h +++ b/src/libsync/creds/keychainchunk.h @@ -45,7 +45,7 @@ class OWNCLOUDSYNC_EXPORT Job : public QObject public: Job(QObject *parent = nullptr); - virtual ~Job(); + ~Job() override; QKeychain::Error error() const; QString errorString() const; diff --git a/src/libsync/datetimeprovider.cpp b/src/libsync/datetimeprovider.cpp new file mode 100644 index 000000000000..08407231208e --- /dev/null +++ b/src/libsync/datetimeprovider.cpp @@ -0,0 +1,17 @@ +#include "datetimeprovider.h" + +namespace OCC { + +DateTimeProvider::~DateTimeProvider() = default; + +QDateTime DateTimeProvider::currentDateTime() const +{ + return QDateTime::currentDateTime(); +} + +QDate DateTimeProvider::currentDate() const +{ + return QDate::currentDate(); +} + +} diff --git a/src/libsync/datetimeprovider.h b/src/libsync/datetimeprovider.h new file mode 100644 index 000000000000..1525a2e3d85e --- /dev/null +++ b/src/libsync/datetimeprovider.h @@ -0,0 +1,18 @@ +#pragma once + +#include "owncloudlib.h" + +#include + +namespace OCC { + +class OWNCLOUDSYNC_EXPORT DateTimeProvider +{ +public: + virtual ~DateTimeProvider(); + + virtual QDateTime currentDateTime() const; + + virtual QDate currentDate() const; +}; +} diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 2e6771319c52..ee0ce489cd53 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -15,16 +15,20 @@ #include "discovery.h" #include "common/filesystembase.h" #include "common/syncjournaldb.h" +#include "filesystem.h" #include "syncfileitem.h" #include #include +#include +#include #include #include #include "vio/csync_vio_local.h" #include #include #include -#include "common/checksums.h" +#include +#include #include "csync_exclude.h" #include "csync.h" @@ -33,6 +37,50 @@ namespace OCC { Q_LOGGING_CATEGORY(lcDisco, "sync.discovery", QtInfoMsg) + +bool ProcessDirectoryJob::checkForInvalidFileName(const PathTuple &path, + const std::map &entries, Entries &entry) +{ + const auto originalFileName = entry.localEntry.name; + const auto newFileName = originalFileName.trimmed(); + + if (originalFileName == newFileName) { + return true; + } + + const auto entriesIter = entries.find(newFileName); + if (entriesIter != entries.end()) { + QString errorMessage; + const auto newFileNameEntry = entriesIter->second; + if (newFileNameEntry.serverEntry.isValid()) { + errorMessage = tr("File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server."); + } + if (newFileNameEntry.localEntry.isValid()) { + errorMessage = tr("File contains trailing spaces and could not be renamed, because a file with the same name already exists locally."); + } + + if (!errorMessage.isEmpty()) { + auto item = SyncFileItemPtr::create(); + if (entry.localEntry.isDirectory) { + item->_type = CSyncEnums::ItemTypeDirectory; + } else { + item->_type = CSyncEnums::ItemTypeFile; + } + item->_file = path._target; + item->_originalFile = path._target; + item->_instruction = CSYNC_INSTRUCTION_ERROR; + item->_status = SyncFileItem::NormalError; + item->_errorString = errorMessage; + emit _discoveryData->itemDiscovered(item); + return false; + } + } + + entry.localEntry.renameName = newFileName; + + return true; +} + void ProcessDirectoryJob::start() { qCInfo(lcDisco) << "STARTING" << _currentFolder._server << _queryServer << _currentFolder._local << _queryLocal; @@ -66,20 +114,12 @@ void ProcessDirectoryJob::process() { ASSERT(_localQueryDone && _serverQueryDone); - QString localDir; - // Build lookup tables for local, remote and db entries. // For suffix-virtual files, the key will normally be the base file name // without the suffix. // However, if foo and foo.owncloud exists locally, there'll be "foo" // with local, db, server entries and "foo.owncloud" with only a local // entry. - struct Entries { - QString nameOverride; - SyncJournalFileRecord dbEntry; - RemoteInfo serverEntry; - LocalInfo localEntry; - }; std::map entries; for (auto &e : _serverNormalQueryEntries) { entries[e.name].serverEntry = std::move(e); @@ -137,8 +177,8 @@ void ProcessDirectoryJob::process() // // Iterate over entries and process them // - for (const auto &f : entries) { - const auto &e = f.second; + for (auto &f : entries) { + auto &e = f.second; PathTuple path; path = _currentFolder.addName(e.nameOverride.isEmpty() ? f.first : e.nameOverride); @@ -193,6 +233,9 @@ void ProcessDirectoryJob::process() processBlacklisted(path, e.localEntry, e.dbEntry); continue; } + if (!checkForInvalidFileName(path, entries, e)) { + continue; + } processFile(std::move(path), e.localEntry, e.serverEntry, e.dbEntry); } QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs); @@ -204,7 +247,7 @@ bool ProcessDirectoryJob::handleExcluded(const QString &path, const QString &loc // FIXME: move to ExcludedFiles 's regexp ? bool isInvalidPattern = false; - if (excluded == CSYNC_NOT_EXCLUDED && !_discoveryData->_invalidFilenameRx.isEmpty()) { + if (excluded == CSYNC_NOT_EXCLUDED && !_discoveryData->_invalidFilenameRx.pattern().isEmpty()) { if (path.contains(_discoveryData->_invalidFilenameRx)) { excluded = CSYNC_FILE_EXCLUDE_INVALID_CHAR; isInvalidPattern = true; @@ -346,6 +389,7 @@ void ProcessDirectoryJob::processFile(PathTuple path, item->_originalFile = path._original; item->_previousSize = dbEntry._fileSize; item->_previousModtime = dbEntry._modtime; + item->_renameTarget = localEntry.renameName; if (dbEntry._modtime == localEntry.modtime && dbEntry._type == ItemTypeVirtualFile && localEntry.type == ItemTypeFile) { item->_type = ItemTypeFile; @@ -443,7 +487,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( if (serverEntry.size == -1) missingData.append(tr("size")); if (serverEntry.remotePerm.isNull()) - missingData.append(tr("permissions")); + missingData.append(tr("permission")); if (serverEntry.etag.isEmpty()) missingData.append("ETag"); if (serverEntry.fileId.isEmpty()) @@ -451,7 +495,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( if (!missingData.isEmpty()) { item->_instruction = CSYNC_INSTRUCTION_ERROR; _childIgnored = true; - item->_errorString = tr("server reported no %1").arg(missingData.join(QLatin1String(", "))); + item->_errorString = tr("Server reported no %1").arg(missingData.join(QLatin1String(", "))); emit _discoveryData->itemDiscovered(item); return; } @@ -459,13 +503,19 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( // The file is known in the db already if (dbEntry.isValid()) { + const bool isDbEntryAnE2EePlaceholder = dbEntry.isVirtualFile() && !dbEntry.e2eMangledName().isEmpty(); + Q_ASSERT(!isDbEntryAnE2EePlaceholder || serverEntry.size >= Constants::e2EeTagSize); + const bool isVirtualE2EePlaceholder = isDbEntryAnE2EePlaceholder && serverEntry.size >= Constants::e2EeTagSize; + const qint64 sizeOnServer = isVirtualE2EePlaceholder ? serverEntry.size - Constants::e2EeTagSize : serverEntry.size; + const bool metaDataSizeNeedsUpdateForE2EeFilePlaceholder = isVirtualE2EePlaceholder && dbEntry._fileSize == serverEntry.size; + if (serverEntry.isDirectory != dbEntry.isDirectory()) { // If the type of the entity changed, it's like NEW, but // needs to delete the other entity first. item->_instruction = CSYNC_INSTRUCTION_TYPE_CHANGE; item->_direction = SyncFileItem::Down; item->_modtime = serverEntry.modtime; - item->_size = serverEntry.size; + item->_size = sizeOnServer; } else if ((dbEntry._type == ItemTypeVirtualFileDownload || localEntry.type == ItemTypeVirtualFileDownload) && (localEntry.isValid() || _queryLocal == ParentNotChanged)) { // The above check for the localEntry existing is important. Otherwise it breaks @@ -476,7 +526,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( } else if (dbEntry._etag != serverEntry.etag) { item->_direction = SyncFileItem::Down; item->_modtime = serverEntry.modtime; - item->_size = serverEntry.size; + item->_size = sizeOnServer; if (serverEntry.isDirectory) { ENFORCE(dbEntry.isDirectory()); item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA; @@ -486,11 +536,43 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( } else { item->_instruction = CSYNC_INSTRUCTION_SYNC; } - } else if (dbEntry._remotePerm != serverEntry.remotePerm || dbEntry._fileId != serverEntry.fileId) { + } else if (dbEntry._remotePerm != serverEntry.remotePerm || dbEntry._fileId != serverEntry.fileId || metaDataSizeNeedsUpdateForE2EeFilePlaceholder) { + if (metaDataSizeNeedsUpdateForE2EeFilePlaceholder) { + // we are updating placeholder sizes after migrating from older versions with VFS + E2EE implicit hydration not supported + qCDebug(lcDisco) << "Migrating the E2EE VFS placeholder " << dbEntry.path() << " from older version. The old size is " << item->_size << ". The new size is " << sizeOnServer; + item->_size = sizeOnServer; + } item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA; item->_direction = SyncFileItem::Down; } else { - processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, ParentNotChanged); + // if (is virtual mode enabled and folder is encrypted - check if the size is the same as on the server and then - trigger server query + // to update a placeholder with corrected size (-16 Bytes) + // or, maybe, add a flag to the database - vfsE2eeSizeCorrected? if it is not set - subtract it from the placeholder's size and re-create/update a placeholder? + const QueryMode serverQueryMode = [this, &dbEntry, &serverEntry]() { + const bool isVfsModeOn = _discoveryData && _discoveryData->_syncOptions._vfs && _discoveryData->_syncOptions._vfs->mode() != Vfs::Off; + if (isVfsModeOn && dbEntry.isDirectory() && dbEntry._isE2eEncrypted) { + qint64 localFolderSize = 0; + const auto listFilesCallback = [&localFolderSize](const OCC::SyncJournalFileRecord &record) { + if (record.isFile()) { + // add Constants::e2EeTagSize so we will know the size of E2EE file on the server + localFolderSize += record._fileSize + Constants::e2EeTagSize; + } else if (record.isVirtualFile()) { + // just a virtual file, so, the size must contain Constants::e2EeTagSize if it was not corrected already + localFolderSize += record._fileSize; + } + }; + + const bool listFilesSucceeded = _discoveryData->_statedb->listFilesInPath(dbEntry.path().toUtf8(), listFilesCallback); + + if (listFilesSucceeded && localFolderSize != 0 && localFolderSize == serverEntry.sizeOfFolder) { + qCInfo(lcDisco) << "Migration of E2EE folder " << dbEntry.path() << " from older version to the one, supporting the implicit VFS hydration."; + return NormalQuery; + } + } + return ParentNotChanged; + }(); + + processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, serverQueryMode); return; } @@ -506,15 +588,14 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( item->_modtime = serverEntry.modtime; item->_size = serverEntry.size; - auto postProcessServerNew = [=] () { - auto tmp_path = path; + auto postProcessServerNew = [=]() mutable { if (item->isDirectory()) { _pendingAsyncJobs++; - _discoveryData->checkSelectiveSyncNewFolder(tmp_path._server, serverEntry.remotePerm, + _discoveryData->checkSelectiveSyncNewFolder(path._server, serverEntry.remotePerm, [=](bool result) { --_pendingAsyncJobs; if (!result) { - processFileAnalyzeLocalInfo(item, tmp_path, localEntry, serverEntry, dbEntry, _queryServer); + processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, _queryServer); } QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs); }); @@ -529,9 +610,18 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( && !FileSystem::isExcludeFile(item->_file)) { item->_type = ItemTypeVirtualFile; if (isVfsWithSuffix()) - addVirtualFileSuffix(tmp_path._original); + addVirtualFileSuffix(path._original); + } + + if (opts._vfs->mode() != Vfs::Off && !item->_encryptedFileName.isEmpty()) { + // We are syncing a file for the first time (local entry is invalid) and it is encrypted file that will be virtual once synced + // to avoid having error of "file has changed during sync" when trying to hydrate it excplicitly - we must remove Constants::e2EeTagSize bytes from the end + // as explicit hydration does not care if these bytes are present in the placeholder or not, but, the size must not change in the middle of the sync + // this way it works for both implicit and explicit hydration by making a placeholder size that does not includes encryption tag Constants::e2EeTagSize bytes + // another scenario - we are syncing a file which is on disk but not in the database (database was removed or file was not written there yet) + item->_size = serverEntry.size - Constants::e2EeTagSize; } - processFileAnalyzeLocalInfo(item, tmp_path, localEntry, serverEntry, dbEntry, _queryServer); + processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, _queryServer); }; // Potential NEW/NEW conflict is handled in AnalyzeLocal @@ -649,9 +739,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( } else { // we need to make a request to the server to know that the original file is deleted on the server _pendingAsyncJobs++; - auto job = new RequestEtagJob(_discoveryData->_account, originalPath, this); - connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult &etag) { - auto tmp_path = path; + auto job = new RequestEtagJob(_discoveryData->_account, _discoveryData->_remoteFolder + originalPath, this); + connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult &etag) mutable { _pendingAsyncJobs--; QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs); if (etag || etag.error().code != 404 || @@ -667,8 +756,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo( // In case the deleted item was discovered in parallel _discoveryData->findAndCancelDeletedJob(originalPath); - postProcessRename(tmp_path); - processFileFinalize(item, tmp_path, item->isDirectory(), item->_instruction == CSYNC_INSTRUCTION_RENAME ? NormalQuery : ParentDontExist, _queryServer); + postProcessRename(path); + processFileFinalize(item, path, item->isDirectory(), item->_instruction == CSYNC_INSTRUCTION_RENAME ? NormalQuery : ParentDontExist, _queryServer); }); job->start(); done = true; // Ideally, if the origin still exist on the server, we should continue searching... but that'd be difficult @@ -935,7 +1024,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo( const auto isfolderPlaceHolderAvailabilityOnlineOnly = (folderPlaceHolderAvailability.isValid() && *folderPlaceHolderAvailability == VfsItemAvailability::OnlineOnly); // a folder is considered online-only if: no files are hydrated, or, if it's an empty folder - const auto isOnlineOnlyFolder = isfolderPlaceHolderAvailabilityOnlineOnly || !folderPlaceHolderAvailability && isFolderPinStateOnlineOnly; + const auto isOnlineOnlyFolder = isfolderPlaceHolderAvailabilityOnlineOnly || (!folderPlaceHolderAvailability && isFolderPinStateOnlineOnly); if (!isFilePlaceHolder && !isOnlineOnlyFolder) { if (localEntry.isDirectory && folderPlaceHolderAvailability.isValid() && !isOnlineOnlyFolder) { @@ -1114,8 +1203,8 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo( if (base.isVirtualFile() && isVfsWithSuffix()) chopVirtualFileSuffix(serverOriginalPath); auto job = new RequestEtagJob(_discoveryData->_account, serverOriginalPath, this); - connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult &etag) mutable { - if (!etag || (*etag != base._etag && !item->isDirectory()) || _discoveryData->isRenamed(originalPath)) { + connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult &etag) mutable { + if (!etag || (etag.get() != base._etag && !item->isDirectory()) || _discoveryData->isRenamed(originalPath)) { qCInfo(lcDisco) << "Can't rename because the etag has changed or the directory is gone" << originalPath; // Can't be a rename, leave it as a new. postProcessLocalNew(); @@ -1123,7 +1212,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo( // In case the deleted item was discovered in parallel _discoveryData->findAndCancelDeletedJob(originalPath); processRename(path); - recurseQueryServer = *etag == base._etag ? ParentNotChanged : NormalQuery; + recurseQueryServer = etag.get() == base._etag ? ParentNotChanged : NormalQuery; } processFileFinalize(item, path, item->isDirectory(), NormalQuery, recurseQueryServer); _pendingAsyncJobs--; diff --git a/src/libsync/discovery.h b/src/libsync/discovery.h index fd70f31390b7..661315916ee5 100644 --- a/src/libsync/discovery.h +++ b/src/libsync/discovery.h @@ -78,11 +78,11 @@ class ProcessDirectoryJob : public QObject ProcessDirectoryJob *parent) : QObject(parent) , _dirItem(dirItem) + , _lastSyncTimestamp(lastSyncTimestamp) , _queryServer(queryServer) , _queryLocal(queryLocal) , _discoveryData(parent->_discoveryData) , _currentFolder(path) - , _lastSyncTimestamp(lastSyncTimestamp) { computePinState(parent->_pinState); } @@ -104,6 +104,13 @@ class ProcessDirectoryJob : public QObject SyncFileItemPtr _dirItem; private: + struct Entries + { + QString nameOverride; + SyncJournalFileRecord dbEntry; + RemoteInfo serverEntry; + LocalInfo localEntry; + }; /** Structure representing a path during discovery. A same path may have different value locally * or on the server in case of renames. @@ -143,6 +150,8 @@ class ProcessDirectoryJob : public QObject } }; + bool checkForInvalidFileName(const PathTuple &path, const std::map &entries, Entries &entry); + /** Iterate over entries inside the directory (non-recursively). * * Called once _serverEntries and _localEntries are filled @@ -293,6 +302,6 @@ class ProcessDirectoryJob : public QObject signals: void finished(); // The root etag of this directory was fetched - void etag(const QString &, const QDateTime &time); + void etag(const QByteArray &, const QDateTime &time); }; } diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp index 6a7837708b2b..5206f7e90848 100644 --- a/src/libsync/discoveryphase.cpp +++ b/src/libsync/discoveryphase.cpp @@ -349,7 +349,9 @@ void DiscoverySingleDirectoryJob::start() << "getlastmodified" << "getcontentlength" << "getetag" + << "http://owncloud.org/ns:size" << "http://owncloud.org/ns:id" + << "http://owncloud.org/ns:fileid" << "http://owncloud.org/ns:downloadURL" << "http://owncloud.org/ns:dDC" << "http://owncloud.org/ns:permissions" @@ -429,6 +431,10 @@ static void propertyMapToRemoteInfo(const QMap &map, RemoteInf result.isE2eEncrypted = true; } } + + if (result.isDirectory && map.contains("size")) { + result.sizeOfFolder = map.value("size").toInt(); + } } void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &file, const QMap &map) @@ -448,6 +454,9 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi _dataFingerprint = "[empty]"; } } + if (map.contains(QStringLiteral("fileid"))) { + _localFileId = map.value(QStringLiteral("fileid")).toUtf8(); + } if (map.contains("id")) { _fileId = map.value("id").toUtf8(); } @@ -455,6 +464,9 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi _isE2eEncrypted = true; Q_ASSERT(!_fileId.isEmpty()); } + if (map.contains("size")) { + _size = map.value("size").toInt(); + } } else { RemoteInfo result; @@ -478,7 +490,7 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi //This works in concerto with the RequestEtagJob and the Folder object to check if the remote folder changed. if (map.contains("getetag")) { if (_firstEtag.isEmpty()) { - _firstEtag = parseEtag(map.value("getetag").toUtf8()); // for directory itself + _firstEtag = parseEtag(map.value(QStringLiteral("getetag")).toUtf8()); // for directory itself } } } @@ -521,7 +533,7 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithErrorSlot(QNetworkReply *r) void DiscoverySingleDirectoryJob::fetchE2eMetadata() { - auto job = new GetMetadataApiJob(_account, _fileId); + const auto job = new GetMetadataApiJob(_account, _localFileId); connect(job, &GetMetadataApiJob::jsonReceived, this, &DiscoverySingleDirectoryJob::metadataReceived); connect(job, &GetMetadataApiJob::error, diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h index 9868e3ec66c1..c894cfc2a52b 100644 --- a/src/libsync/discoveryphase.h +++ b/src/libsync/discoveryphase.h @@ -55,6 +55,7 @@ struct RemoteInfo OCC::RemotePermissions remotePerm; time_t modtime = 0; int64_t size = 0; + int64_t sizeOfFolder = 0; bool isDirectory = false; bool isE2eEncrypted = false; QString e2eMangledName; @@ -69,6 +70,7 @@ struct LocalInfo { /** FileName of the entry (this does not contains any directory or path, just the plain name */ QString name; + QString renameName; time_t modtime = 0; int64_t size = 0; uint64_t inode = 0; @@ -91,7 +93,7 @@ class DiscoverySingleLocalDirectoryJob : public QObject, public QRunnable public: explicit DiscoverySingleLocalDirectoryJob(const AccountPtr &account, const QString &localPath, OCC::Vfs *vfs, QObject *parent = nullptr); - void run() Q_DECL_OVERRIDE; + void run() override; signals: void finished(QVector result); void finishedFatalError(QString errorString); @@ -126,7 +128,7 @@ class DiscoverySingleDirectoryJob : public QObject // This is not actually a network job, it is just a job signals: void firstDirectoryPermissions(RemotePermissions); - void etag(const QString &, const QDateTime &time); + void etag(const QByteArray &, const QDateTime &time); void finished(const HttpResult> &result); private slots: @@ -140,8 +142,9 @@ private slots: private: QVector _results; QString _subPath; - QString _firstEtag; + QByteArray _firstEtag; QByteArray _fileId; + QByteArray _localFileId; AccountPtr _account; // The first result is for the directory itself and need to be ignored. // This flag is true if it was already ignored. @@ -153,6 +156,7 @@ private slots: // If this directory is e2ee bool _isE2eEncrypted; // If set, the discovery will finish with an error + int64_t _size = 0; QString _error; QPointer _lsColJob; @@ -252,7 +256,7 @@ class DiscoveryPhase : public QObject AccountPtr _account; SyncOptions _syncOptions; ExcludedFiles *_excludes; - QRegExp _invalidFilenameRx; // FIXME: maybe move in ExcludedFiles + QRegularExpression _invalidFilenameRx; // FIXME: maybe move in ExcludedFiles QStringList _serverBlacklistedFiles; // The blacklist from the capabilities bool _ignoreHiddenFiles = false; std::function _shouldDiscoverLocaly; diff --git a/src/libsync/filesystem.cpp b/src/libsync/filesystem.cpp index af84f4d2fe2e..5c6cd4610061 100644 --- a/src/libsync/filesystem.cpp +++ b/src/libsync/filesystem.cpp @@ -63,9 +63,9 @@ time_t FileSystem::getModTime(const QString &filename) && (stat.modtime != 0)) { result = stat.modtime; } else { - qCWarning(lcFileSystem) << "Could not get modification time for" << filename - << "with csync, using QFileInfo"; result = Utility::qDateTimeToTime_t(QFileInfo(filename).lastModified()); + qCWarning(lcFileSystem) << "Could not get modification time for" << filename + << "with csync, using QFileInfo:" << result; } return result; } @@ -115,7 +115,7 @@ static qint64 getSizeWithCsync(const QString &filename) if (csync_vio_local_stat(filename, &stat) != -1) { result = stat.size; } else { - qCWarning(lcFileSystem) << "Could not get size for" << filename << "with csync"; + qCWarning(lcFileSystem) << "Could not get size for" << filename << "with csync" << Utility::formatWinError(errno); } return result; } diff --git a/src/gui/iconjob.cpp b/src/libsync/iconjob.cpp similarity index 61% rename from src/gui/iconjob.cpp rename to src/libsync/iconjob.cpp index 2eaed5d0b820..23a7ace7fb17 100644 --- a/src/gui/iconjob.cpp +++ b/src/libsync/iconjob.cpp @@ -16,26 +16,31 @@ namespace OCC { -IconJob::IconJob(const QUrl &url, QObject *parent) : - QObject(parent) +IconJob::IconJob(AccountPtr account, const QUrl &url, QObject *parent) + : QObject(parent) { - connect(&_accessManager, &QNetworkAccessManager::finished, - this, &IconJob::finished); - QNetworkRequest request(url); #if (QT_VERSION >= 0x050600) request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); #endif - _accessManager.get(request); + const auto reply = account->sendRawRequest(QByteArrayLiteral("GET"), url, request); + connect(reply, &QNetworkReply::finished, this, &IconJob::finished); } -void IconJob::finished(QNetworkReply *reply) +void IconJob::finished() { - if (reply->error() != QNetworkReply::NoError) + const auto reply = qobject_cast(sender()); + if (!reply) { return; - - reply->deleteLater(); + } deleteLater(); + + const auto networkError = reply->error(); + if (networkError != QNetworkReply::NoError) { + emit error(networkError); + return; + } + emit jobFinished(reply->readAll()); } } diff --git a/src/gui/iconjob.h b/src/libsync/iconjob.h similarity index 76% rename from src/gui/iconjob.h rename to src/libsync/iconjob.h index efbbeb3bd261..dcb036956330 100644 --- a/src/gui/iconjob.h +++ b/src/libsync/iconjob.h @@ -15,6 +15,10 @@ #ifndef ICONJOB_H #define ICONJOB_H +#include "account.h" +#include "accountfwd.h" +#include "owncloudlib.h" + #include #include #include @@ -27,20 +31,18 @@ namespace OCC { * @brief Job to fetch a icon * @ingroup gui */ -class IconJob : public QObject +class OWNCLOUDSYNC_EXPORT IconJob : public QObject { Q_OBJECT public: - explicit IconJob(const QUrl &url, QObject *parent = nullptr); + explicit IconJob(AccountPtr account, const QUrl &url, QObject *parent = nullptr); signals: void jobFinished(QByteArray iconData); + void error(QNetworkReply::NetworkError errorType); private slots: - void finished(QNetworkReply *reply); - -private: - QNetworkAccessManager _accessManager; + void finished(); }; } diff --git a/src/libsync/logger.cpp b/src/libsync/logger.cpp index 8eb4908ade13..2a90c976b3f2 100644 --- a/src/libsync/logger.cpp +++ b/src/libsync/logger.cpp @@ -17,6 +17,7 @@ #include "config.h" #include +#include #include #include #include @@ -32,35 +33,10 @@ #include // for stdout #endif -namespace OCC { - -QtMessageHandler s_originalMessageHandler = nullptr; - -static void mirallLogCatcher(QtMsgType type, const QMessageLogContext &ctx, const QString &message) -{ - auto logger = Logger::instance(); - if (type == QtDebugMsg && !logger->logDebug()) { - if (s_originalMessageHandler) { - s_originalMessageHandler(type, ctx, message); - } - } else if (!logger->isNoop()) { - logger->doLog(qFormatLogMessage(type, ctx, message)); - } - if(type == QtCriticalMsg || type == QtFatalMsg) { - std::cerr << qPrintable(qFormatLogMessage(type, ctx, message)) << std::endl; - } - - if(type == QtFatalMsg) { - if (!logger->isNoop()) { - logger->close(); - } -#if defined(Q_OS_WIN) - // Make application terminate in a way that can be caught by the crash reporter - Utility::crash(); -#endif - } +namespace { +constexpr int CrashLogSize = 20; } - +namespace OCC { Logger *Logger::instance() { @@ -71,11 +47,13 @@ Logger *Logger::instance() Logger::Logger(QObject *parent) : QObject(parent) { - qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss:zzz} [ %{type} %{category} ]%{if-debug}\t[ %{function} ]%{endif}:\t%{message}"); + qSetMessagePattern(QStringLiteral("%{time yyyy-MM-dd hh:mm:ss:zzz} [ %{type} %{category} %{file}:%{line} " + "]%{if-debug}\t[ %{function} ]%{endif}:\t%{message}")); + _crashLog.resize(CrashLogSize); #ifndef NO_MSG_HANDLER - s_originalMessageHandler = qInstallMessageHandler(mirallLogCatcher); -#else - Q_UNUSED(mirallLogCatcher) + qInstallMessageHandler([](QtMsgType type, const QMessageLogContext &ctx, const QString &message) { + Logger::instance()->doLog(type, ctx, message); + }); #endif } @@ -102,51 +80,38 @@ void Logger::postGuiMessage(const QString &title, const QString &message) emit guiMessage(title, message); } -void Logger::log(Log log) -{ - QString msg; - if (_showTime) { - msg = log.timeStamp.toString(QLatin1String("MM-dd hh:mm:ss:zzz")) + QLatin1Char(' '); - } - - msg += log.message; - // _logs.append(log); - // std::cout << qPrintable(log.message) << std::endl; - - doLog(msg); -} - -/** - * Returns true if doLog does nothing and need not to be called - */ -bool Logger::isNoop() const -{ - QMutexLocker lock(&_mutex); - return !_logstream; -} - bool Logger::isLoggingToFile() const { QMutexLocker lock(&_mutex); return _logstream; } -void Logger::doLog(const QString &msg) +void Logger::doLog(QtMsgType type, const QMessageLogContext &ctx, const QString &message) { + const QString msg = qFormatLogMessage(type, ctx, message); { QMutexLocker lock(&_mutex); + _crashLogIndex = (_crashLogIndex + 1) % CrashLogSize; + _crashLog[_crashLogIndex] = msg; if (_logstream) { - (*_logstream) << msg << endl; + (*_logstream) << msg << Qt::endl; if (_doFileFlush) _logstream->flush(); } + if (type == QtFatalMsg) { + close(); +#if defined(Q_OS_WIN) + // Make application terminate in a way that can be caught by the crash reporter + Utility::crash(); +#endif + } } emit logWindowLog(msg); } void Logger::close() { - QMutexLocker lock(&_mutex); + dumpCrashLog(); if (_logstream) { _logstream->flush(); @@ -155,15 +120,6 @@ void Logger::close() } } -void Logger::mirallLog(const QString &message) -{ - Log log_; - log_.timeStamp = QDateTime::currentDateTimeUtc(); - log_.message = message; - - Logger::instance()->log(log_); -} - QString Logger::logFile() const { return _logFile.fileName(); @@ -264,7 +220,24 @@ void Logger::disableTemporaryFolderLogDir() void Logger::setLogRules(const QSet &rules) { _logRules = rules; - QLoggingCategory::setFilterRules(rules.toList().join(QLatin1Char('\n'))); + QString tmp; + QTextStream out(&tmp); + for (const auto &p : rules) { + out << p << QLatin1Char('\n'); + } + qDebug() << tmp; + QLoggingCategory::setFilterRules(tmp); +} + +void Logger::dumpCrashLog() +{ + QFile logFile(QDir::tempPath() + QStringLiteral("/" APPLICATION_NAME "-crash.log")); + if (logFile.open(QFile::WriteOnly)) { + QTextStream out(&logFile); + for (int i = 1; i <= CrashLogSize; ++i) { + out << _crashLog[(_crashLogIndex + i) % CrashLogSize] << QLatin1Char('\n'); + } + } } static bool compressLog(const QString &originalName, const QString &targetName) @@ -309,7 +282,7 @@ void Logger::enterNextLogFile() // Expire old log files and deal with conflicts QStringList files = dir.entryList(QStringList("*owncloud.log.*"), QDir::Files, QDir::Name); - QRegExp rx(R"(.*owncloud\.log\.(\d+).*)"); + const QRegularExpression rx(QRegularExpression::anchoredPattern(R"(.*owncloud\.log\.(\d+).*)")); int maxNumber = -1; foreach (const QString &s, files) { if (_logExpire > 0) { @@ -318,8 +291,9 @@ void Logger::enterNextLogFile() dir.remove(s); } } - if (s.startsWith(newLogName) && rx.exactMatch(s)) { - maxNumber = qMax(maxNumber, rx.cap(1).toInt()); + const auto rxMatch = rx.match(s); + if (s.startsWith(newLogName) && rxMatch.hasMatch()) { + maxNumber = qMax(maxNumber, rxMatch.captured(1).toInt()); } } newLogName.append("." + QString::number(maxNumber + 1)); diff --git a/src/libsync/logger.h b/src/libsync/logger.h index 2796409a91f7..c37da97faa63 100644 --- a/src/libsync/logger.h +++ b/src/libsync/logger.h @@ -27,12 +27,6 @@ namespace OCC { -struct Log -{ - QDateTime timeStamp; - QString message; -}; - /** * @brief The Logger class * @ingroup libsync @@ -41,16 +35,9 @@ class OWNCLOUDSYNC_EXPORT Logger : public QObject { Q_OBJECT public: - bool isNoop() const; bool isLoggingToFile() const; - void log(Log log); - void doLog(const QString &log); - void close(); - - static void mirallLog(const QString &message); - - const QList &logs() const { return _logs; } + void doLog(QtMsgType type, const QMessageLogContext &ctx, const QString &message); static Logger *instance(); @@ -107,9 +94,11 @@ public slots: private: Logger(QObject *parent = nullptr); - ~Logger(); - QList _logs; - bool _showTime = true; + ~Logger() override; + + void close(); + void dumpCrashLog(); + QFile _logFile; bool _doFileFlush = false; int _logExpire = 0; @@ -119,6 +108,8 @@ public slots: QString _logDirectory; bool _temporaryFolderLogDir = false; QSet _logRules; + QVector _crashLog; + int _crashLogIndex = 0; }; } // namespace OCC diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index 763367988177..f2ba661e44e2 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -113,8 +113,8 @@ bool RequestEtagJob::finished() if (httpCode == 207) { // Parse DAV response QXmlStreamReader reader(reply()); - reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:")); - QString etag; + reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration(QStringLiteral("d"), QStringLiteral("DAV:"))); + QByteArray etag; while (!reader.atEnd()) { QXmlStreamReader::TokenType type = reader.readNext(); if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) { @@ -123,9 +123,9 @@ bool RequestEtagJob::finished() auto etagText = reader.readElementText(); auto parsedTag = parseEtag(etagText.toUtf8()); if (!parsedTag.isEmpty()) { - etag += QString::fromUtf8(parsedTag); + etag += parsedTag; } else { - etag += etagText; + etag += etagText.toUtf8(); } } } @@ -182,7 +182,11 @@ bool MkColJob::finished() qCInfo(lcMkColJob) << "MKCOL of" << reply()->request().url() << "FINISHED WITH STATUS" << replyStatusString(); - emit finished(reply()->error()); + if (reply()->error() != QNetworkReply::NoError) { + Q_EMIT finishedWithError(reply()); + } else { + Q_EMIT finishedWithoutError(); + } return true; } @@ -826,13 +830,49 @@ void JsonApiJob::addRawHeader(const QByteArray &headerName, const QByteArray &va _request.setRawHeader(headerName, value); } +void JsonApiJob::setBody(const QJsonDocument &body) +{ + _body = body.toJson(); + qCDebug(lcJsonApiJob) << "Set body for request:" << _body; + if (!_body.isEmpty()) { + _request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + } +} + + +void JsonApiJob::setVerb(Verb value) +{ + _verb = value; +} + + +QByteArray JsonApiJob::verbToString() const +{ + switch (_verb) { + case Verb::Get: + return "GET"; + case Verb::Post: + return "POST"; + case Verb::Put: + return "PUT"; + case Verb::Delete: + return "DELETE"; + } + return "GET"; +} + void JsonApiJob::start() { addRawHeader("OCS-APIREQUEST", "true"); auto query = _additionalParams; query.addQueryItem(QLatin1String("format"), QLatin1String("json")); QUrl url = Utility::concatUrlPath(account()->url(), path(), query); - sendRequest(_usePOST ? "POST" : "GET", url, _request); + const auto httpVerb = verbToString(); + if (!_body.isEmpty()) { + sendRequest(httpVerb, url, _request, _body); + } else { + sendRequest(httpVerb, url, _request); + } AbstractNetworkJob::start(); } @@ -852,19 +892,21 @@ bool JsonApiJob::finished() QString jsonStr = QString::fromUtf8(reply()->readAll()); if (jsonStr.contains("")) { - QRegExp rex("(\\d+)"); - if (jsonStr.contains(rex)) { + const QRegularExpression rex("(\\d+)"); + const auto rexMatch = rex.match(jsonStr); + if (rexMatch.hasMatch()) { // this is a error message coming back from ocs. - statusCode = rex.cap(1).toInt(); + statusCode = rexMatch.captured(1).toInt(); } } else if(jsonStr.isEmpty() && httpStatusCode == notModifiedStatusCode){ qCWarning(lcJsonApiJob) << "Nothing changed so nothing to retrieve - status code: " << httpStatusCode; statusCode = httpStatusCode; } else { - QRegExp rex(R"("statuscode":(\d+),)"); + const QRegularExpression rex(R"("statuscode":(\d+))"); // example: "{"ocs":{"meta":{"status":"ok","statuscode":100,"message":null},"data":{"version":{"major":8,"minor":"... (504) - if (jsonStr.contains(rex)) { - statusCode = rex.cap(1).toInt(); + const auto rxMatch = rex.match(jsonStr); + if (rxMatch.hasMatch()) { + statusCode = rxMatch.captured(1).toInt(); } } @@ -926,7 +968,10 @@ void DetermineAuthTypeJob::start() oldFlowRequired->setIgnoreCredentialFailure(true); connect(get, &SimpleNetworkJob::finishedSignal, this, [this, get]() { - if (get->reply()->error() == QNetworkReply::AuthenticationRequiredError) { + const auto reply = get->reply(); + const auto wwwAuthenticateHeader = reply->rawHeader("WWW-Authenticate"); + if (reply->error() == QNetworkReply::AuthenticationRequiredError + && (wwwAuthenticateHeader.startsWith("Basic") || wwwAuthenticateHeader.startsWith("Bearer"))) { _resultGet = Basic; } else { _resultGet = LoginFlowV2; diff --git a/src/libsync/networkjobs.h b/src/libsync/networkjobs.h index 8e88853bc61e..01cfcdedd7ed 100644 --- a/src/libsync/networkjobs.h +++ b/src/libsync/networkjobs.h @@ -22,6 +22,7 @@ #include #include +#include #include class QUrl; @@ -273,9 +274,10 @@ class OWNCLOUDSYNC_EXPORT MkColJob : public AbstractNetworkJob void start() override; signals: - void finished(QNetworkReply::NetworkError); + void finishedWithError(QNetworkReply *reply); + void finishedWithoutError(); -private slots: +private: bool finished() override; }; @@ -348,8 +350,8 @@ class OWNCLOUDSYNC_EXPORT RequestEtagJob : public AbstractNetworkJob void start() override; signals: - void etagRetrieved(const QString &etag, const QDateTime &time); - void finishedWithResult(const HttpResult &etag); + void etagRetrieved(const QByteArray &etag, const QDateTime &time); + void finishedWithResult(const HttpResult &etag); private slots: bool finished() override; @@ -374,6 +376,13 @@ class OWNCLOUDSYNC_EXPORT JsonApiJob : public AbstractNetworkJob { Q_OBJECT public: + enum class Verb { + Get, + Post, + Put, + Delete, + }; + explicit JsonApiJob(const AccountPtr &account, const QString &path, QObject *parent = nullptr); /** @@ -389,15 +398,9 @@ class OWNCLOUDSYNC_EXPORT JsonApiJob : public AbstractNetworkJob void addQueryParams(const QUrlQuery ¶ms); void addRawHeader(const QByteArray &headerName, const QByteArray &value); - /** - * @brief usePOST - allow job to do an anonymous POST request instead of GET - * @param params: (optional) true for POST, false for GET (default). - * - * This function needs to be called before start() obviously. - */ - void usePOST(bool usePOST = true) { - _usePOST = usePOST; - } + void setBody(const QJsonDocument &body); + + void setVerb(Verb value); public slots: void start() override; @@ -420,18 +423,21 @@ public slots: * @param statusCode - the OCS status code: 100 (!) for success */ void etagResponseHeaderReceived(const QByteArray &value, int statusCode); - + /** * @brief desktopNotificationStatusReceived - signal to report if notifications are allowed - * @param status - set desktop notifications allowed status + * @param status - set desktop notifications allowed status */ void allowDesktopNotificationsChanged(bool isAllowed); private: + QByteArray _body; QUrlQuery _additionalParams; QNetworkRequest _request; - bool _usePOST = false; + Verb _verb = Verb::Get; + + QByteArray verbToString() const; }; /** diff --git a/src/libsync/ocsprofileconnector.cpp b/src/libsync/ocsprofileconnector.cpp new file mode 100644 index 000000000000..c24d5f85f59e --- /dev/null +++ b/src/libsync/ocsprofileconnector.cpp @@ -0,0 +1,168 @@ +#include "ocsprofileconnector.h" +#include "accountfwd.h" +#include "common/result.h" +#include "networkjobs.h" +#include "iconjob.h" +#include "theme.h" +#include "account.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +Q_LOGGING_CATEGORY(lcOcsProfileConnector, "nextcloud.gui.ocsprofileconnector", QtInfoMsg) + +OCC::HovercardAction jsonToAction(const QJsonObject &jsonActionObject) +{ + const auto iconUrl = jsonActionObject.value(QStringLiteral("icon")).toString(QStringLiteral("no-icon")); + QPixmap iconPixmap; + OCC::HovercardAction hovercardAction{ + jsonActionObject.value(QStringLiteral("title")).toString(QStringLiteral("No title")), iconUrl, + jsonActionObject.value(QStringLiteral("hyperlink")).toString(QStringLiteral("no-link"))}; + if (QPixmapCache::find(iconUrl, &iconPixmap)) { + hovercardAction._icon = iconPixmap; + } + return hovercardAction; +} + +OCC::Hovercard jsonToHovercard(const QJsonArray &jsonDataArray) +{ + OCC::Hovercard hovercard; + hovercard._actions.reserve(jsonDataArray.size()); + for (const auto &jsonEntry : jsonDataArray) { + Q_ASSERT(jsonEntry.isObject()); + if (!jsonEntry.isObject()) { + continue; + } + hovercard._actions.push_back(jsonToAction(jsonEntry.toObject())); + } + return hovercard; +} + +OCC::Optional createPixmapFromSvgData(const QByteArray &iconData) +{ + QSvgRenderer svgRenderer; + if (!svgRenderer.load(iconData)) { + return {}; + } + QSize imageSize{16, 16}; + if (OCC::Theme::isHidpi()) { + imageSize = QSize{32, 32}; + } + QImage scaledSvg(imageSize, QImage::Format_ARGB32); + scaledSvg.fill("transparent"); + QPainter svgPainter{&scaledSvg}; + svgRenderer.render(&svgPainter); + return QPixmap::fromImage(scaledSvg); +} + +OCC::Optional iconDataToPixmap(const QByteArray iconData) +{ + if (!iconData.startsWith("serverVersionInt() < Account::makeServerVersion(23, 0, 0)) { + qInfo(lcOcsProfileConnector) << "Server version" << _account->serverVersion() + << "does not support profile page"; + emit error(); + return; + } + const QString url = QStringLiteral("/ocs/v2.php/hovercard/v1/%1").arg(userId); + const auto job = new JsonApiJob(_account, url, this); + connect(job, &JsonApiJob::jsonReceived, this, &OcsProfileConnector::onHovercardFetched); + job->start(); +} + +void OcsProfileConnector::onHovercardFetched(const QJsonDocument &json, int statusCode) +{ + qCDebug(lcOcsProfileConnector) << "Hovercard fetched:" << json; + + if (statusCode != 200) { + qCInfo(lcOcsProfileConnector) << "Fetching of hovercard finished with status code" << statusCode; + return; + } + const auto jsonData = json.object().value("ocs").toObject().value("data").toObject().value("actions"); + Q_ASSERT(jsonData.isArray()); + _currentHovercard = jsonToHovercard(jsonData.toArray()); + fetchIcons(); + emit hovercardFetched(); +} + +void OcsProfileConnector::setHovercardActionIcon(const std::size_t index, const QPixmap &pixmap) +{ + auto &hovercardAction = _currentHovercard._actions[index]; + QPixmapCache::insert(hovercardAction._iconUrl.toString(), pixmap); + hovercardAction._icon = pixmap; + emit iconLoaded(index); +} + +void OcsProfileConnector::loadHovercardActionIcon(const std::size_t hovercardActionIndex, const QByteArray &iconData) +{ + if (hovercardActionIndex >= _currentHovercard._actions.size()) { + // Note: Probably could do more checking, like checking if the url is still the same. + return; + } + const auto icon = iconDataToPixmap(iconData); + if (icon.isValid()) { + setHovercardActionIcon(hovercardActionIndex, icon.get()); + return; + } + qCWarning(lcOcsProfileConnector) << "Could not load Svg icon from data" << iconData; +} + +void OcsProfileConnector::startFetchIconJob(const std::size_t hovercardActionIndex) +{ + const auto hovercardAction = _currentHovercard._actions[hovercardActionIndex]; + const auto iconJob = new IconJob{_account, hovercardAction._iconUrl, this}; + connect(iconJob, &IconJob::jobFinished, + [this, hovercardActionIndex](QByteArray iconData) { loadHovercardActionIcon(hovercardActionIndex, iconData); }); + connect(iconJob, &IconJob::error, this, [](QNetworkReply::NetworkError errorType) { + qCWarning(lcOcsProfileConnector) << "Could not fetch icon:" << errorType; + }); +} + +void OcsProfileConnector::fetchIcons() +{ + for (auto hovercardActionIndex = 0u; hovercardActionIndex < _currentHovercard._actions.size(); + ++hovercardActionIndex) { + startFetchIconJob(hovercardActionIndex); + } +} + +const Hovercard &OcsProfileConnector::hovercard() const +{ + return _currentHovercard; +} +} diff --git a/src/libsync/ocsprofileconnector.h b/src/libsync/ocsprofileconnector.h new file mode 100644 index 000000000000..69cd60116d6e --- /dev/null +++ b/src/libsync/ocsprofileconnector.h @@ -0,0 +1,58 @@ +#pragma once + +#include "accountfwd.h" +#include "owncloudlib.h" + +#include +#include +#include +#include + +namespace OCC { + +struct OWNCLOUDSYNC_EXPORT HovercardAction +{ +public: + HovercardAction(); + HovercardAction(QString title, QUrl iconUrl, QUrl link); + + QString _title; + QUrl _iconUrl; + QPixmap _icon; + QUrl _link; +}; + +struct OWNCLOUDSYNC_EXPORT Hovercard +{ + std::vector _actions; +}; + +class OWNCLOUDSYNC_EXPORT OcsProfileConnector : public QObject +{ + Q_OBJECT +public: + explicit OcsProfileConnector(AccountPtr account, QObject *parent = nullptr); + + void fetchHovercard(const QString &userId); + const Hovercard &hovercard() const; + +signals: + void error(); + void hovercardFetched(); + void iconLoaded(const std::size_t hovercardActionIndex); + +private: + void onHovercardFetched(const QJsonDocument &json, int statusCode); + + void fetchIcons(); + void startFetchIconJob(const std::size_t hovercardActionIndex); + void setHovercardActionIcon(const std::size_t index, const QPixmap &pixmap); + void loadHovercardActionIcon(const std::size_t hovercardActionIndex, const QByteArray &iconData); + + AccountPtr _account; + Hovercard _currentHovercard; +}; +} + +Q_DECLARE_METATYPE(OCC::HovercardAction) +Q_DECLARE_METATYPE(OCC::Hovercard) diff --git a/src/libsync/ocsuserstatusconnector.cpp b/src/libsync/ocsuserstatusconnector.cpp new file mode 100644 index 000000000000..95f3810e272f --- /dev/null +++ b/src/libsync/ocsuserstatusconnector.cpp @@ -0,0 +1,455 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 "ocsuserstatusconnector.h" +#include "account.h" +#include "userstatusconnector.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + +Q_LOGGING_CATEGORY(lcOcsUserStatusConnector, "nextcloud.gui.ocsuserstatusconnector", QtInfoMsg) + +OCC::UserStatus::OnlineStatus stringToUserOnlineStatus(const QString &status) +{ + // it needs to match the Status enum + const QHash preDefinedStatus { + { "online", OCC::UserStatus::OnlineStatus::Online }, + { "dnd", OCC::UserStatus::OnlineStatus::DoNotDisturb }, + { "away", OCC::UserStatus::OnlineStatus::Away }, + { "offline", OCC::UserStatus::OnlineStatus::Offline }, + { "invisible", OCC::UserStatus::OnlineStatus::Invisible } + }; + + // api should return invisible, dnd,... toLower() it is to make sure + // it matches _preDefinedStatus, otherwise the default is online (0) + return preDefinedStatus.value(status.toLower(), OCC::UserStatus::OnlineStatus::Online); +} + +QString onlineStatusToString(OCC::UserStatus::OnlineStatus status) +{ + switch (status) { + case OCC::UserStatus::OnlineStatus::Online: + return QStringLiteral("online"); + case OCC::UserStatus::OnlineStatus::DoNotDisturb: + return QStringLiteral("dnd"); + case OCC::UserStatus::OnlineStatus::Away: + return QStringLiteral("offline"); + case OCC::UserStatus::OnlineStatus::Offline: + return QStringLiteral("offline"); + case OCC::UserStatus::OnlineStatus::Invisible: + return QStringLiteral("invisible"); + } + return QStringLiteral("online"); +} + +OCC::Optional jsonExtractClearAt(QJsonObject jsonObject) +{ + OCC::Optional clearAt {}; + if (jsonObject.contains("clearAt") && !jsonObject.value("clearAt").isNull()) { + OCC::ClearAt clearAtValue; + clearAtValue._type = OCC::ClearAtType::Timestamp; + clearAtValue._timestamp = jsonObject.value("clearAt").toInt(); + clearAt = clearAtValue; + } + return clearAt; +} + +OCC::UserStatus jsonExtractUserStatus(QJsonObject json) +{ + const auto clearAt = jsonExtractClearAt(json); + + const OCC::UserStatus userStatus(json.value("messageId").toString(), + json.value("message").toString().trimmed(), + json.value("icon").toString().trimmed(), stringToUserOnlineStatus(json.value("status").toString()), + json.value("messageIsPredefined").toBool(false), clearAt); + + return userStatus; +} + +OCC::UserStatus jsonToUserStatus(const QJsonDocument &json) +{ + const QJsonObject defaultValues { + { "icon", "" }, + { "message", "" }, + { "status", "online" }, + { "messageIsPredefined", "false" }, + { "statusIsUserDefined", "false" } + }; + const auto retrievedData = json.object().value("ocs").toObject().value("data").toObject(defaultValues); + return jsonExtractUserStatus(retrievedData); +} + +quint64 clearAtEndOfToTimestamp(const OCC::ClearAt &clearAt) +{ + Q_ASSERT(clearAt._type == OCC::ClearAtType::EndOf); + + if (clearAt._endof == "day") { + return QDate::currentDate().addDays(1).startOfDay().toTime_t(); + } else if (clearAt._endof == "week") { + const auto days = Qt::Sunday - QDate::currentDate().dayOfWeek(); + return QDate::currentDate().addDays(days + 1).startOfDay().toTime_t(); + } + qCWarning(lcOcsUserStatusConnector) << "Can not handle clear at endof day type" << clearAt._endof; + return QDateTime::currentDateTime().toTime_t(); +} + +quint64 clearAtPeriodToTimestamp(const OCC::ClearAt &clearAt) +{ + return QDateTime::currentDateTime().addSecs(clearAt._period).toTime_t(); +} + +quint64 clearAtToTimestamp(const OCC::ClearAt &clearAt) +{ + switch (clearAt._type) { + case OCC::ClearAtType::Period: { + return clearAtPeriodToTimestamp(clearAt); + } + + case OCC::ClearAtType::EndOf: { + return clearAtEndOfToTimestamp(clearAt); + } + + case OCC::ClearAtType::Timestamp: { + return clearAt._timestamp; + } + } + + return 0; +} + +quint64 clearAtToTimestamp(const OCC::Optional &clearAt) +{ + if (clearAt) { + return clearAtToTimestamp(*clearAt); + } + return 0; +} + +OCC::Optional jsonToClearAt(QJsonObject jsonObject) +{ + OCC::Optional clearAt; + + if (jsonObject.value("clearAt").isObject() && !jsonObject.value("clearAt").isNull()) { + OCC::ClearAt clearAtValue; + const auto clearAtObject = jsonObject.value("clearAt").toObject(); + const auto typeValue = clearAtObject.value("type").toString("period"); + if (typeValue == "period") { + const auto timeValue = clearAtObject.value("time").toInt(0); + clearAtValue._type = OCC::ClearAtType::Period; + clearAtValue._period = timeValue; + } else if (typeValue == "end-of") { + const auto timeValue = clearAtObject.value("time").toString("day"); + clearAtValue._type = OCC::ClearAtType::EndOf; + clearAtValue._endof = timeValue; + } else { + qCWarning(lcOcsUserStatusConnector) << "Can not handle clear type value" << typeValue; + } + clearAt = clearAtValue; + } + + return clearAt; +} + +OCC::UserStatus jsonToUserStatus(QJsonObject jsonObject) +{ + const auto clearAt = jsonToClearAt(jsonObject); + + OCC::UserStatus userStatus( + jsonObject.value("id").toString("no-id"), + jsonObject.value("message").toString("No message"), + jsonObject.value("icon").toString("no-icon"), + OCC::UserStatus::OnlineStatus::Online, + true, + clearAt); + + return userStatus; +} + +std::vector jsonToPredefinedStatuses(QJsonArray jsonDataArray) +{ + std::vector statuses; + for (const auto &jsonEntry : jsonDataArray) { + Q_ASSERT(jsonEntry.isObject()); + if (!jsonEntry.isObject()) { + continue; + } + statuses.push_back(jsonToUserStatus(jsonEntry.toObject())); + } + + return statuses; +} + + +const QString baseUrl("/ocs/v2.php/apps/user_status/api/v1"); +const QString userStatusBaseUrl = baseUrl + QStringLiteral("/user_status"); +} + +namespace OCC { + +OcsUserStatusConnector::OcsUserStatusConnector(AccountPtr account, QObject *parent) + : UserStatusConnector(parent) + , _account(account) +{ + Q_ASSERT(_account); + _userStatusSupported = _account->capabilities().userStatus(); + _userStatusEmojisSupported = _account->capabilities().userStatusSupportsEmoji(); +} + +void OcsUserStatusConnector::fetchUserStatus() +{ + qCDebug(lcOcsUserStatusConnector) << "Try to fetch user status"; + + if (!_userStatusSupported) { + qCDebug(lcOcsUserStatusConnector) << "User status not supported"; + emit error(Error::UserStatusNotSupported); + return; + } + + startFetchUserStatusJob(); +} + +void OcsUserStatusConnector::startFetchUserStatusJob() +{ + if (_getUserStatusJob) { + qCDebug(lcOcsUserStatusConnector) << "Get user status job is already running."; + return; + } + + _getUserStatusJob = new JsonApiJob(_account, userStatusBaseUrl, this); + connect(_getUserStatusJob, &JsonApiJob::jsonReceived, this, &OcsUserStatusConnector::onUserStatusFetched); + _getUserStatusJob->start(); +} + +void OcsUserStatusConnector::onUserStatusFetched(const QJsonDocument &json, int statusCode) +{ + logResponse("user status fetched", json, statusCode); + + if (statusCode != 200) { + qCInfo(lcOcsUserStatusConnector) << "Slot fetch UserStatus finished with status code" << statusCode; + emit error(Error::CouldNotFetchUserStatus); + return; + } + + _userStatus = jsonToUserStatus(json); + emit userStatusFetched(_userStatus); +} + +void OcsUserStatusConnector::startFetchPredefinedStatuses() +{ + if (_getPredefinedStausesJob) { + qCDebug(lcOcsUserStatusConnector) << "Get predefined statuses job is already running"; + return; + } + + _getPredefinedStausesJob = new JsonApiJob(_account, + baseUrl + QStringLiteral("/predefined_statuses"), this); + connect(_getPredefinedStausesJob, &JsonApiJob::jsonReceived, this, + &OcsUserStatusConnector::onPredefinedStatusesFetched); + _getPredefinedStausesJob->start(); +} + +void OcsUserStatusConnector::fetchPredefinedStatuses() +{ + if (!_userStatusSupported) { + emit error(Error::UserStatusNotSupported); + return; + } + startFetchPredefinedStatuses(); +} + +void OcsUserStatusConnector::onPredefinedStatusesFetched(const QJsonDocument &json, int statusCode) +{ + logResponse("predefined statuses", json, statusCode); + + if (statusCode != 200) { + qCInfo(lcOcsUserStatusConnector) << "Slot predefined user statuses finished with status code" << statusCode; + emit error(Error::CouldNotFetchPredefinedUserStatuses); + return; + } + const auto jsonData = json.object().value("ocs").toObject().value("data"); + Q_ASSERT(jsonData.isArray()); + if (!jsonData.isArray()) { + return; + } + const auto statuses = jsonToPredefinedStatuses(jsonData.toArray()); + emit predefinedStatusesFetched(statuses); +} + +void OcsUserStatusConnector::logResponse(const QString &message, const QJsonDocument &json, int statusCode) +{ + qCDebug(lcOcsUserStatusConnector) << "Response from:" << message << "Status:" << statusCode << "Json:" << json; +} + +void OcsUserStatusConnector::setUserStatusOnlineStatus(UserStatus::OnlineStatus onlineStatus) +{ + _setOnlineStatusJob = new JsonApiJob(_account, + userStatusBaseUrl + QStringLiteral("/status"), this); + _setOnlineStatusJob->setVerb(JsonApiJob::Verb::Put); + // Set body + QJsonObject dataObject; + dataObject.insert("statusType", onlineStatusToString(onlineStatus)); + QJsonDocument body; + body.setObject(dataObject); + _setOnlineStatusJob->setBody(body); + connect(_setOnlineStatusJob, &JsonApiJob::jsonReceived, this, &OcsUserStatusConnector::onUserStatusOnlineStatusSet); + _setOnlineStatusJob->start(); +} + +void OcsUserStatusConnector::setUserStatusMessagePredefined(const UserStatus &userStatus) +{ + Q_ASSERT(userStatus.messagePredefined()); + if (!userStatus.messagePredefined()) { + return; + } + + _setMessageJob = new JsonApiJob(_account, userStatusBaseUrl + QStringLiteral("/message/predefined"), this); + _setMessageJob->setVerb(JsonApiJob::Verb::Put); + // Set body + QJsonObject dataObject; + dataObject.insert("messageId", userStatus.id()); + if (userStatus.clearAt()) { + dataObject.insert("clearAt", static_cast(clearAtToTimestamp(userStatus.clearAt()))); + } else { + dataObject.insert("clearAt", QJsonValue()); + } + QJsonDocument body; + body.setObject(dataObject); + _setMessageJob->setBody(body); + connect(_setMessageJob, &JsonApiJob::jsonReceived, this, &OcsUserStatusConnector::onUserStatusMessageSet); + _setMessageJob->start(); +} + +void OcsUserStatusConnector::setUserStatusMessageCustom(const UserStatus &userStatus) +{ + Q_ASSERT(!userStatus.messagePredefined()); + if (userStatus.messagePredefined()) { + return; + } + + if (!_userStatusEmojisSupported) { + emit error(Error::EmojisNotSupported); + return; + } + _setMessageJob = new JsonApiJob(_account, userStatusBaseUrl + QStringLiteral("/message/custom"), this); + _setMessageJob->setVerb(JsonApiJob::Verb::Put); + // Set body + QJsonObject dataObject; + dataObject.insert("statusIcon", userStatus.icon()); + dataObject.insert("message", userStatus.message()); + const auto clearAt = userStatus.clearAt(); + if (clearAt) { + dataObject.insert("clearAt", static_cast(clearAtToTimestamp(*clearAt))); + } else { + dataObject.insert("clearAt", QJsonValue()); + } + QJsonDocument body; + body.setObject(dataObject); + _setMessageJob->setBody(body); + connect(_setMessageJob, &JsonApiJob::jsonReceived, this, &OcsUserStatusConnector::onUserStatusMessageSet); + _setMessageJob->start(); +} + +void OcsUserStatusConnector::setUserStatusMessage(const UserStatus &userStatus) +{ + if (userStatus.messagePredefined()) { + setUserStatusMessagePredefined(userStatus); + return; + } + setUserStatusMessageCustom(userStatus); +} + +void OcsUserStatusConnector::setUserStatus(const UserStatus &userStatus) +{ + if (!_userStatusSupported) { + emit error(Error::UserStatusNotSupported); + return; + } + + if (_setOnlineStatusJob || _setMessageJob) { + qCDebug(lcOcsUserStatusConnector) << "Set online status job or set message job are already running."; + return; + } + + setUserStatusOnlineStatus(userStatus.state()); + setUserStatusMessage(userStatus); +} + +void OcsUserStatusConnector::onUserStatusOnlineStatusSet(const QJsonDocument &json, int statusCode) +{ + logResponse("Online status set", json, statusCode); + + if (statusCode != 200) { + emit error(Error::CouldNotSetUserStatus); + return; + } +} + +void OcsUserStatusConnector::onUserStatusMessageSet(const QJsonDocument &json, int statusCode) +{ + logResponse("Message set", json, statusCode); + + if (statusCode != 200) { + emit error(Error::CouldNotSetUserStatus); + return; + } + + // We fetch the user status again because json does not contain + // the new message when user status was set from a predefined + // message + fetchUserStatus(); + + emit userStatusSet(); +} + +void OcsUserStatusConnector::clearMessage() +{ + _clearMessageJob = new JsonApiJob(_account, userStatusBaseUrl + QStringLiteral("/message")); + _clearMessageJob->setVerb(JsonApiJob::Verb::Delete); + connect(_clearMessageJob, &JsonApiJob::jsonReceived, this, &OcsUserStatusConnector::onMessageCleared); + _clearMessageJob->start(); +} + +UserStatus OcsUserStatusConnector::userStatus() const +{ + return _userStatus; +} + +void OcsUserStatusConnector::onMessageCleared(const QJsonDocument &json, int statusCode) +{ + logResponse("Message cleared", json, statusCode); + + if (statusCode != 200) { + emit error(Error::CouldNotClearMessage); + return; + } + + _userStatus = {}; + emit messageCleared(); +} +} diff --git a/src/libsync/ocsuserstatusconnector.h b/src/libsync/ocsuserstatusconnector.h new file mode 100644 index 000000000000..0d366419fe04 --- /dev/null +++ b/src/libsync/ocsuserstatusconnector.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +#pragma once + +#include "accountfwd.h" +#include "userstatusconnector.h" + +#include + +namespace OCC { + +class JsonApiJob; +class SimpleNetworkJob; + +class OWNCLOUDSYNC_EXPORT OcsUserStatusConnector : public UserStatusConnector +{ +public: + explicit OcsUserStatusConnector(AccountPtr account, QObject *parent = nullptr); + + void fetchUserStatus() override; + + void fetchPredefinedStatuses() override; + + void setUserStatus(const UserStatus &userStatus) override; + + void clearMessage() override; + + UserStatus userStatus() const override; + +private: + void onUserStatusFetched(const QJsonDocument &json, int statusCode); + void onPredefinedStatusesFetched(const QJsonDocument &json, int statusCode); + void onUserStatusOnlineStatusSet(const QJsonDocument &json, int statusCode); + void onUserStatusMessageSet(const QJsonDocument &json, int statusCode); + void onMessageCleared(const QJsonDocument &json, int statusCode); + + void logResponse(const QString &message, const QJsonDocument &json, int statusCode); + void startFetchUserStatusJob(); + void startFetchPredefinedStatuses(); + void setUserStatusOnlineStatus(UserStatus::OnlineStatus onlineStatus); + void setUserStatusMessage(const UserStatus &userStatus); + void setUserStatusMessagePredefined(const UserStatus &userStatus); + void setUserStatusMessageCustom(const UserStatus &userStatus); + + AccountPtr _account; + + bool _userStatusSupported = false; + bool _userStatusEmojisSupported = false; + + QPointer _clearMessageJob {}; + QPointer _setMessageJob {}; + QPointer _setOnlineStatusJob {}; + QPointer _getPredefinedStausesJob {}; + QPointer _getUserStatusJob {}; + + UserStatus _userStatus; +}; +} diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index e2f3b69509b4..9a4ceae54595 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -27,6 +27,7 @@ #include "account.h" #include "common/asserts.h" #include "discoveryphase.h" +#include "syncfileitem.h" #ifdef Q_OS_WIN #include @@ -40,12 +41,14 @@ #include #include #include +#include #include namespace OCC { Q_LOGGING_CATEGORY(lcPropagator, "nextcloud.sync.propagator", QtInfoMsg) Q_LOGGING_CATEGORY(lcDirectory, "nextcloud.sync.propagator.directory", QtInfoMsg) +Q_LOGGING_CATEGORY(lcRootDirectory, "nextcloud.sync.propagator.root.directory", QtInfoMsg) Q_LOGGING_CATEGORY(lcCleanupPolls, "nextcloud.sync.propagator.cleanuppolls", QtInfoMsg) qint64 criticalFreeSpaceLimit() @@ -268,6 +271,7 @@ void PropagateItemJob::done(SyncFileItem::Status statusArg, const QString &error case SyncFileItem::NoStatus: case SyncFileItem::BlacklistedError: case SyncFileItem::FileLocked: + case SyncFileItem::FileNameInvalid: // nothing break; } @@ -356,15 +360,13 @@ PropagateItemJob *OwncloudPropagator::createJob(const SyncFileItemPtr &item) job->setDeleteExistingFolder(deleteExisting); return job; } else { - PropagateUploadFileCommon *job = nullptr; - if (item->_size > syncOptions()._initialChunkSize && account()->capabilities().chunkingNg()) { - // Item is above _initialChunkSize, thus will be classified as to be chunked - job = new PropagateUploadFileNG(this, item); + if (deleteExisting || !isDelayedUploadItem(item)) { + auto job = createUploadJob(item, deleteExisting); + return job.release(); } else { - job = new PropagateUploadFileV1(this, item); + pushDelayedUploadTask(item); + return nullptr; } - job->setDeleteExisting(deleteExisting); - return job; } case CSYNC_INSTRUCTION_RENAME: if (item->_direction == SyncFileItem::Up) { @@ -381,13 +383,40 @@ PropagateItemJob *OwncloudPropagator::createJob(const SyncFileItemPtr &item) return nullptr; } +std::unique_ptr OwncloudPropagator::createUploadJob(SyncFileItemPtr item, bool deleteExisting) +{ + auto job = std::unique_ptr{}; + + if (item->_size > syncOptions()._initialChunkSize && account()->capabilities().chunkingNg()) { + // Item is above _initialChunkSize, thus will be classified as to be chunked + job = std::make_unique(this, item); + } else { + job = std::make_unique(this, item); + } + + job->setDeleteExisting(deleteExisting); + + return job; +} + +void OwncloudPropagator::pushDelayedUploadTask(SyncFileItemPtr item) +{ + _delayedTasks.push_back(item); +} + +void OwncloudPropagator::resetDelayedUploadTasks() +{ + _scheduleDelayedTasks = false; + _delayedTasks.clear(); +} + qint64 OwncloudPropagator::smallFileSize() { const qint64 smallFileSize = 100 * 1024; //default to 1 MB. Not dynamic right now. return smallFileSize; } -void OwncloudPropagator::start(const SyncFileItemVector &items) +void OwncloudPropagator::start(SyncFileItemVector &&items) { Q_ASSERT(std::is_sorted(items.begin(), items.end())); @@ -396,6 +425,27 @@ void OwncloudPropagator::start(const SyncFileItemVector &items) * In order to do that we loop over the items. (which are sorted by destination) * When we enter a directory, we can create the directory job and push it on the stack. */ + const auto regex = syncOptions().fileRegex(); + if (regex.isValid()) { + QSet names; + for (auto &i : items) { + if (regex.match(i->_file).hasMatch()) { + int index = -1; + QStringRef ref; + do { + ref = i->_file.midRef(0, index); + names.insert(ref); + index = ref.lastIndexOf(QLatin1Char('/')); + } while (index > 0); + } + } + items.erase(std::remove_if(items.begin(), items.end(), [&names](auto i) { + return !names.contains(QStringRef { &i->_file }); + }), + items.end()); + } + + resetDelayedUploadTasks(); _rootJob.reset(new PropagateRootDirectory(this)); QStack> directories; directories.push(qMakePair(QString(), _rootJob.data())); @@ -451,56 +501,17 @@ void OwncloudPropagator::start(const SyncFileItemVector &items) } if (item->isDirectory()) { - auto *dir = new PropagateDirectory(this, item); - - if (item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE - && item->_direction == SyncFileItem::Up) { - // Skip all potential uploads to the new folder. - // Processing them now leads to problems with permissions: - // checkForPermissions() has already run and used the permissions - // of the file we're about to delete to decide whether uploading - // to the new dir is ok... - foreach (const SyncFileItemPtr &item2, items) { - if (item2->destination().startsWith(item->destination() + "/")) { - item2->_instruction = CSYNC_INSTRUCTION_NONE; - _anotherSyncNeeded = true; - } - } - } - - if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) { - // We do the removal of directories at the end, because there might be moves from - // these directories that will happen later. - directoriesToRemove.prepend(dir); - removedDirectory = item->_file + "/"; - - // We should not update the etag of parent directories of the removed directory - // since it would be done before the actual remove (issue #1845) - // NOTE: Currently this means that we don't update those etag at all in this sync, - // but it should not be a problem, they will be updated in the next sync. - for (int i = 0; i < directories.size(); ++i) { - if (directories[i].second->_item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) - directories[i].second->_item->_instruction = CSYNC_INSTRUCTION_NONE; - } - } else { - PropagateDirectory *currentDirJob = directories.top().second; - currentDirJob->appendJob(dir); - } - directories.push(qMakePair(item->destination() + "/", dir)); + startDirectoryPropagation(item, + directories, + directoriesToRemove, + removedDirectory, + items); } else { - if (item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE) { - // will delete directories, so defer execution - directoriesToRemove.prepend(createJob(item)); - removedDirectory = item->_file + "/"; - } else { - directories.top().second->appendTask(item); - } - - if (item->_instruction == CSYNC_INSTRUCTION_CONFLICT) { - // This might be a file or a directory on the local side. If it's a - // directory we want to skip processing items inside it. - maybeConflictDirectory = item->_file + "/"; - } + startFilePropagation(item, + directories, + directoriesToRemove, + removedDirectory, + maybeConflictDirectory); } } @@ -514,6 +525,75 @@ void OwncloudPropagator::start(const SyncFileItemVector &items) scheduleNextJob(); } +void OwncloudPropagator::startDirectoryPropagation(const SyncFileItemPtr &item, + QStack> &directories, + QVector &directoriesToRemove, + QString &removedDirectory, + const SyncFileItemVector &items) +{ + auto directoryPropagationJob = std::make_unique(this, item); + + if (item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE + && item->_direction == SyncFileItem::Up) { + // Skip all potential uploads to the new folder. + // Processing them now leads to problems with permissions: + // checkForPermissions() has already run and used the permissions + // of the file we're about to delete to decide whether uploading + // to the new dir is ok... + foreach (const SyncFileItemPtr &dirItem, items) { + if (dirItem->destination().startsWith(item->destination() + "/")) { + dirItem->_instruction = CSYNC_INSTRUCTION_NONE; + _anotherSyncNeeded = true; + } + } + } + + if (item->_instruction == CSYNC_INSTRUCTION_REMOVE) { + // We do the removal of directories at the end, because there might be moves from + // these directories that will happen later. + directoriesToRemove.prepend(directoryPropagationJob.get()); + removedDirectory = item->_file + "/"; + + // We should not update the etag of parent directories of the removed directory + // since it would be done before the actual remove (issue #1845) + // NOTE: Currently this means that we don't update those etag at all in this sync, + // but it should not be a problem, they will be updated in the next sync. + for (int i = 0; i < directories.size(); ++i) { + if (directories[i].second->_item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) { + directories[i].second->_item->_instruction = CSYNC_INSTRUCTION_NONE; + } + } + } else { + const auto currentDirJob = directories.top().second; + currentDirJob->appendJob(directoryPropagationJob.get()); + } + directories.push(qMakePair(item->destination() + "/", directoryPropagationJob.release())); +} + +void OwncloudPropagator::startFilePropagation(const SyncFileItemPtr &item, + QStack > &directories, + QVector &directoriesToRemove, + QString &removedDirectory, + QString &maybeConflictDirectory) +{ + if (item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE) { + // will delete directories, so defer execution + auto job = createJob(item); + if (job) { + directoriesToRemove.prepend(job); + } + removedDirectory = item->_file + "/"; + } else { + directories.top().second->appendTask(item); + } + + if (item->_instruction == CSYNC_INSTRUCTION_CONFLICT) { + // This might be a file or a directory on the local side. If it's a + // directory we want to skip processing items inside it. + maybeConflictDirectory = item->_file + "/"; + } +} + const SyncOptions &OwncloudPropagator::syncOptions() const { return _syncOptions; @@ -535,7 +615,6 @@ bool OwncloudPropagator::localFileNameClash(const QString &relFile) #ifdef Q_OS_MAC const QFileInfo fileInfo(file); if (!fileInfo.exists()) { - qCWarning(lcPropagator) << "No valid fileinfo"; return false; } else { // Need to normalize to composited form because of QTBUG-39622/QTBUG-55896 @@ -780,6 +859,21 @@ Result OwncloudPropagator::staticUpdat return Vfs::ConvertToPlaceholderResult::Ok; } +bool OwncloudPropagator::isDelayedUploadItem(const SyncFileItemPtr &item) const +{ + return !_scheduleDelayedTasks && !item->_isEncrypted; +} + +void OwncloudPropagator::setScheduleDelayedTasks(bool active) +{ + _scheduleDelayedTasks = active; +} + +void OwncloudPropagator::clearDelayedTasks() +{ + _delayedTasks.clear(); +} + // ================================================================================ PropagatorJob::PropagatorJob(OwncloudPropagator *propagator) @@ -990,6 +1084,7 @@ void PropagateDirectory::slotFirstJobFinished(SyncFileItem::Status status) // Synchronously abort abort(AbortType::Synchronous); _state = Finished; + qCInfo(lcPropagator) << "PropagateDirectory::slotFirstJobFinished" << "emit finished" << status; emit finished(status); } return; @@ -1032,6 +1127,7 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status) } } _state = Finished; + qCInfo(lcPropagator) << "PropagateDirectory::slotSubJobsFinished" << "emit finished" << status; emit finished(status); } @@ -1084,21 +1180,37 @@ qint64 PropagateRootDirectory::committedDiskSpace() const bool PropagateRootDirectory::scheduleSelfOrChild() { - if (_state == Finished) + qCInfo(lcRootDirectory()) << "scheduleSelfOrChild" << _state << "pending uploads" << propagator()->delayedTasks().size() << "subjobs state" << _subJobs._state; + + if (_state == Finished) { return false; + } - if (PropagateDirectory::scheduleSelfOrChild()) + if (PropagateDirectory::scheduleSelfOrChild() && propagator()->delayedTasks().empty()) { return true; + } // Important: Finish _subJobs before scheduling any deletes. - if (_subJobs._state != Finished) + if (_subJobs._state != Finished) { return false; + } + + if (!propagator()->delayedTasks().empty()) { + return scheduleDelayedJobs(); + } return _dirDeletionJobs.scheduleSelfOrChild(); } void PropagateRootDirectory::slotSubJobsFinished(SyncFileItem::Status status) { + qCInfo(lcRootDirectory()) << status << "slotSubJobsFinished" << _state << "pending uploads" << propagator()->delayedTasks().size() << "subjobs state" << _subJobs._state; + + if (!propagator()->delayedTasks().empty()) { + scheduleDelayedJobs(); + return; + } + if (status != SyncFileItem::Success && status != SyncFileItem::Restoration && status != SyncFileItem::Conflict) { @@ -1106,6 +1218,7 @@ void PropagateRootDirectory::slotSubJobsFinished(SyncFileItem::Status status) // Synchronously abort abort(AbortType::Synchronous); _state = Finished; + qCInfo(lcPropagator) << "PropagateRootDirectory::slotSubJobsFinished" << "emit finished" << status; emit finished(status); } return; @@ -1117,9 +1230,21 @@ void PropagateRootDirectory::slotSubJobsFinished(SyncFileItem::Status status) void PropagateRootDirectory::slotDirDeletionJobsFinished(SyncFileItem::Status status) { _state = Finished; + qCInfo(lcPropagator) << "PropagateRootDirectory::slotDirDeletionJobsFinished" << "emit finished" << status; emit finished(status); } +bool PropagateRootDirectory::scheduleDelayedJobs() +{ + qCInfo(lcPropagator) << "PropagateRootDirectory::scheduleDelayedJobs"; + propagator()->setScheduleDelayedTasks(true); + auto bulkPropagatorJob = std::make_unique(propagator(), propagator()->delayedTasks()); + propagator()->clearDelayedTasks(); + _subJobs.appendJob(bulkPropagatorJob.release()); + _subJobs._state = Running; + return _subJobs.scheduleSelfOrChild(); +} + // ================================================================================ CleanupPollsJob::~CleanupPollsJob() = default; @@ -1178,4 +1303,14 @@ QString OwncloudPropagator::remotePath() const { return _remoteFolder; } + +BulkPropagatorJob::BulkPropagatorJob(OwncloudPropagator *propagator, const QVector &items) + : PropagatorCompositeJob(propagator) + , _items(items) +{ + for(const auto &oneItemJob : _items) { + appendTask(oneItemJob); + } + _items.clear(); +} } diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index c2df7749f970..98bbbfeab94b 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -70,6 +70,8 @@ class PropagatorJob : public QObject Asynchronous }; + Q_ENUM(AbortType) + enum JobState { NotYetStarted, Running, @@ -77,6 +79,8 @@ class PropagatorJob : public QObject }; JobState _state; + Q_ENUM(JobState) + enum JobParallelism { /** Jobs can be run in parallel to this job */ @@ -88,6 +92,8 @@ class PropagatorJob : public QObject WaitForFinished, }; + Q_ENUM(JobParallelism) + virtual JobParallelism parallelism() { return FullParallelism; } /** @@ -183,8 +189,8 @@ protected slots: public: PropagateItemJob(OwncloudPropagator *propagator, const SyncFileItemPtr &item) : PropagatorJob(propagator) - , _item(item) , _parallelism(FullParallelism) + , _item(item) { // we should always execute jobs that process the E2EE API calls as sequential jobs // TODO: In fact, we must make sure Lock/Unlock are not colliding and always wait for each other to complete. So, we could refactor this "_parallelism" later @@ -192,7 +198,7 @@ protected slots: // As an alternative, we could optimize Lock/Unlock calls, so we do a batch-write on one folder and only lock and unlock a folder once per batch. _parallelism = (_item->_isEncrypted || hasEncryptedAncestor()) ? WaitForFinished : FullParallelism; } - ~PropagateItemJob(); + ~PropagateItemJob() override; bool scheduleSelfOrChild() override { @@ -206,7 +212,7 @@ protected slots: return true; } - virtual JobParallelism parallelism() override { return _parallelism; } + JobParallelism parallelism() override { return _parallelism; } SyncFileItemPtr _item; @@ -237,7 +243,7 @@ class PropagatorCompositeJob : public PropagatorJob // Don't delete jobs in _jobsToDo and _runningJobs: they have parents // that will be responsible for cleanup. Deleting them here would risk // deleting something that has already been deleted by a shared parent. - virtual ~PropagatorCompositeJob() = default; + ~PropagatorCompositeJob() override = default; void appendJob(PropagatorJob *job); void appendTask(const SyncFileItemPtr &item) @@ -368,6 +374,23 @@ class OWNCLOUDSYNC_EXPORT PropagateRootDirectory : public PropagateDirectory private slots: void slotSubJobsFinished(SyncFileItem::Status status) override; void slotDirDeletionJobsFinished(SyncFileItem::Status status); + +private: + + bool scheduleDelayedJobs(); +}; + +class BulkPropagatorJob : public PropagatorCompositeJob +{ + Q_OBJECT +public: + + explicit BulkPropagatorJob(OwncloudPropagator *propagator, + const QVector &items); + +private: + + QVector _items; }; /** @@ -397,6 +420,8 @@ class PropagateIgnoreJob : public PropagateItemJob } }; +class PropagateUploadFileCommon; + class OWNCLOUDSYNC_EXPORT OwncloudPropagator : public QObject { Q_OBJECT @@ -407,21 +432,33 @@ class OWNCLOUDSYNC_EXPORT OwncloudPropagator : public QObject public: OwncloudPropagator(AccountPtr account, const QString &localDir, const QString &remoteFolder, SyncJournalDb *progressDb) - : _localDir((localDir.endsWith(QChar('/'))) ? localDir : localDir + '/') - , _remoteFolder((remoteFolder.endsWith(QChar('/'))) ? remoteFolder : remoteFolder + '/') - , _journal(progressDb) + : _journal(progressDb) , _finishedEmited(false) , _bandwidthManager(this) , _anotherSyncNeeded(false) , _chunkSize(10 * 1000 * 1000) // 10 MB, overridden in setSyncOptions , _account(account) + , _localDir((localDir.endsWith(QChar('/'))) ? localDir : localDir + '/') + , _remoteFolder((remoteFolder.endsWith(QChar('/'))) ? remoteFolder : remoteFolder + '/') { qRegisterMetaType("PropagatorJob::AbortType"); } - ~OwncloudPropagator(); + ~OwncloudPropagator() override; - void start(const SyncFileItemVector &_syncedItems); + void start(SyncFileItemVector &&_syncedItems); + + void startDirectoryPropagation(const SyncFileItemPtr &item, + QStack> &directories, + QVector &directoriesToRemove, + QString &removedDirectory, + const SyncFileItemVector &items); + + void startFilePropagation(const SyncFileItemPtr &item, + QStack> &directories, + QVector &directoriesToRemove, + QString &removedDirectory, + QString &maybeConflictDirectory); const SyncOptions &syncOptions() const; void setSyncOptions(const SyncOptions &syncOptions); @@ -572,6 +609,17 @@ class OWNCLOUDSYNC_EXPORT OwncloudPropagator : public QObject static Result staticUpdateMetadata(const SyncFileItem &item, const QString localDir, Vfs *vfs, SyncJournalDb * const journal); + Q_REQUIRED_RESULT bool isDelayedUploadItem(const SyncFileItemPtr &item) const; + + Q_REQUIRED_RESULT const QVector& delayedTasks() const + { + return _delayedTasks; + } + + void setScheduleDelayedTasks(bool active); + + void clearDelayedTasks(); + private slots: void abortTimeout() @@ -611,6 +659,13 @@ private slots: void insufficientRemoteStorage(); private: + std::unique_ptr createUploadJob(SyncFileItemPtr item, + bool deleteExisting); + + void pushDelayedUploadTask(SyncFileItemPtr item); + + void resetDelayedUploadTasks(); + AccountPtr _account; QScopedPointer _rootJob; SyncOptions _syncOptions; @@ -618,6 +673,9 @@ private slots: const QString _localDir; // absolute path to the local directory. ends with '/' const QString _remoteFolder; // remote folder, ends with '/' + + QVector _delayedTasks; + bool _scheduleDelayedTasks = false; }; @@ -646,7 +704,7 @@ class CleanupPollsJob : public QObject { } - ~CleanupPollsJob(); + ~CleanupPollsJob() override; /** * Start the job. After the job is completed, it will emit either finished or aborted, and it diff --git a/src/libsync/progressdispatcher.h b/src/libsync/progressdispatcher.h index 99415d544def..3e34fdd8f4ef 100644 --- a/src/libsync/progressdispatcher.h +++ b/src/libsync/progressdispatcher.h @@ -269,7 +269,7 @@ class OWNCLOUDSYNC_EXPORT ProgressDispatcher : public QObject friend class Folder; // only allow Folder class to access the setting slots. public: static ProgressDispatcher *instance(); - ~ProgressDispatcher(); + ~ProgressDispatcher() override; signals: /** diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 64773953a3be..10ccd97db45d 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -22,8 +22,9 @@ #include "common/utility.h" #include "filesystem.h" #include "propagatorjobs.h" -#include "common/checksums.h" -#include "common/asserts.h" +#include +#include +#include #include "clientsideencryptionjobs.h" #include "propagatedownloadencrypted.h" #include "common/vfs.h" @@ -62,9 +63,9 @@ QString OWNCLOUDSYNC_EXPORT createDownloadTmpFileName(const QString &previous) int overhead = 1 + 1 + 2 + 8; // slash dot dot-tilde ffffffff" int spaceForFileName = qMin(254, tmpFileName.length() + overhead) - overhead; if (tmpPath.length() > 0) { - return tmpPath + '/' + '.' + tmpFileName.left(spaceForFileName) + ".~" + (QString::number(uint(qrand() % 0xFFFFFFFF), 16)); + return tmpPath + '/' + '.' + tmpFileName.left(spaceForFileName) + ".~" + (QString::number(uint(Utility::rand() % 0xFFFFFFFF), 16)); } else { - return '.' + tmpFileName.left(spaceForFileName) + ".~" + (QString::number(uint(qrand() % 0xFFFFFFFF), 16)); + return '.' + tmpFileName.left(spaceForFileName) + ".~" + (QString::number(uint(Utility::rand() % 0xFFFFFFFF), 16)); } } @@ -77,7 +78,6 @@ GETFileJob::GETFileJob(AccountPtr account, const QString &path, QIODevice *devic , _headers(headers) , _expectedEtagForResume(expectedEtagForResume) , _expectedContentLength(-1) - , _contentLength(-1) , _resumeStart(resumeStart) , _errorStatus(SyncFileItem::NoStatus) , _bandwidthLimited(false) @@ -86,6 +86,7 @@ GETFileJob::GETFileJob(AccountPtr account, const QString &path, QIODevice *devic , _bandwidthManager(nullptr) , _hasEmittedFinishedSignal(false) , _lastModified() + , _contentLength(-1) { } @@ -97,7 +98,6 @@ GETFileJob::GETFileJob(AccountPtr account, const QUrl &url, QIODevice *device, , _headers(headers) , _expectedEtagForResume(expectedEtagForResume) , _expectedContentLength(-1) - , _contentLength(-1) , _resumeStart(resumeStart) , _errorStatus(SyncFileItem::NoStatus) , _directDownloadUrl(url) @@ -107,6 +107,7 @@ GETFileJob::GETFileJob(AccountPtr account, const QUrl &url, QIODevice *device, , _bandwidthManager(nullptr) , _hasEmittedFinishedSignal(false) , _lastModified() + , _contentLength(-1) { } @@ -219,9 +220,10 @@ void GETFileJob::slotMetaDataChanged() qint64 start = 0; QByteArray ranges = reply()->rawHeader("Content-Range"); if (!ranges.isEmpty()) { - QRegExp rx("bytes (\\d+)-"); - if (rx.indexIn(ranges) >= 0) { - start = rx.cap(1).toLongLong(); + const QRegularExpression rx("bytes (\\d+)-"); + const auto rxMatch = rx.match(ranges); + if (rxMatch.hasMatch()) { + start = rxMatch.captured(1).toLongLong(); } } if (start != _resumeStart) { @@ -284,6 +286,11 @@ qint64 GETFileJob::currentDownloadPosition() return _resumeStart; } +qint64 GETFileJob::writeToDevice(const QByteArray &data) +{ + return _device->write(data); +} + void GETFileJob::slotReadyRead() { if (!reply()) @@ -306,8 +313,8 @@ void GETFileJob::slotReadyRead() _bandwidthQuota -= toRead; } - qint64 r = reply()->read(buffer.data(), toRead); - if (r < 0) { + const qint64 readBytes = reply()->read(buffer.data(), toRead); + if (readBytes < 0) { _errorString = networkReplyErrorString(*reply()); _errorStatus = SyncFileItem::NormalError; qCWarning(lcGetJob) << "Error while reading from device: " << _errorString; @@ -315,11 +322,11 @@ void GETFileJob::slotReadyRead() return; } - qint64 w = _device->write(buffer.constData(), r); - if (w != r) { + const qint64 writtenBytes = writeToDevice(QByteArray::fromRawData(buffer.constData(), readBytes)); + if (writtenBytes != readBytes) { _errorString = _device->errorString(); _errorStatus = SyncFileItem::NormalError; - qCWarning(lcGetJob) << "Error while writing to file" << w << r << _errorString; + qCWarning(lcGetJob) << "Error while writing to file" << writtenBytes << readBytes << _errorString; reply()->abort(); return; } @@ -371,6 +378,75 @@ QString GETFileJob::errorString() const return AbstractNetworkJob::errorString(); } +GETEncryptedFileJob::GETEncryptedFileJob(AccountPtr account, const QString &path, QIODevice *device, + const QMap &headers, const QByteArray &expectedEtagForResume, + qint64 resumeStart, EncryptedFile encryptedInfo, QObject *parent) + : GETFileJob(account, path, device, headers, expectedEtagForResume, resumeStart, parent) + , _encryptedFileInfo(encryptedInfo) +{ +} + +GETEncryptedFileJob::GETEncryptedFileJob(AccountPtr account, const QUrl &url, QIODevice *device, + const QMap &headers, const QByteArray &expectedEtagForResume, + qint64 resumeStart, EncryptedFile encryptedInfo, QObject *parent) + : GETFileJob(account, url, device, headers, expectedEtagForResume, resumeStart, parent) + , _encryptedFileInfo(encryptedInfo) +{ +} + +qint64 GETEncryptedFileJob::writeToDevice(const QByteArray &data) +{ + if (!_decryptor) { + // only initialize the decryptor once, because, according to Qt documentation, metadata might get changed during the processing of the data sometimes + // https://doc.qt.io/qt-5/qnetworkreply.html#metaDataChanged + _decryptor.reset(new EncryptionHelper::StreamingDecryptor(_encryptedFileInfo.encryptionKey, _encryptedFileInfo.initializationVector, _contentLength)); + } + + if (!_decryptor->isInitialized()) { + return -1; + } + + const auto bytesRemaining = _contentLength - _processedSoFar - data.length(); + + if (bytesRemaining != 0 && bytesRemaining < OCC::Constants::e2EeTagSize) { + // decryption is going to fail if last chunk does not include or does not equal to OCC::Constants::e2EeTagSize bytes tag + // we may end up receiving packets beyond OCC::Constants::e2EeTagSize bytes tag at the end + // in that case, we don't want to try and decrypt less than OCC::Constants::e2EeTagSize ending bytes of tag, we will accumulate all the incoming data till the end + // and then, we are going to decrypt the entire chunk containing OCC::Constants::e2EeTagSize bytes at the end + _pendingBytes += QByteArray(data.constData(), data.length()); + _processedSoFar += data.length(); + if (_processedSoFar != _contentLength) { + return data.length(); + } + } + + if (!_pendingBytes.isEmpty()) { + const auto decryptedChunk = _decryptor->chunkDecryption(_pendingBytes.constData(), _pendingBytes.size()); + + if (decryptedChunk.isEmpty()) { + qCCritical(lcPropagateDownload) << "Decryption failed!"; + return -1; + } + + GETFileJob::writeToDevice(decryptedChunk); + + return data.length(); + } + + const auto decryptedChunk = _decryptor->chunkDecryption(data.constData(), data.length()); + + if (decryptedChunk.isEmpty()) { + qCCritical(lcPropagateDownload) << "Decryption failed!"; + return -1; + } + + GETFileJob::writeToDevice(decryptedChunk); + + _processedSoFar += data.length(); + + return data.length(); +} + void PropagateDownloadFile::start() { if (propagator()->_abortRequested) diff --git a/src/libsync/propagatedownload.h b/src/libsync/propagatedownload.h index 31f1749286a6..fc4942c4e773 100644 --- a/src/libsync/propagatedownload.h +++ b/src/libsync/propagatedownload.h @@ -36,7 +36,6 @@ class OWNCLOUDSYNC_EXPORT GETFileJob : public AbstractNetworkJob QString _errorString; QByteArray _expectedEtagForResume; qint64 _expectedContentLength; - qint64 _contentLength; qint64 _resumeStart; SyncFileItem::Status _errorStatus; QUrl _directDownloadUrl; @@ -51,6 +50,9 @@ class OWNCLOUDSYNC_EXPORT GETFileJob : public AbstractNetworkJob /// Will be set to true once we've seen a 2xx response header bool _saveBodyToFile = false; +protected: + qint64 _contentLength; + public: // DOES NOT take ownership of the device. explicit GETFileJob(AccountPtr account, const QString &path, QIODevice *device, @@ -60,7 +62,7 @@ class OWNCLOUDSYNC_EXPORT GETFileJob : public AbstractNetworkJob explicit GETFileJob(AccountPtr account, const QUrl &url, QIODevice *device, const QMap &headers, const QByteArray &expectedEtagForResume, qint64 resumeStart, QObject *parent = nullptr); - virtual ~GETFileJob() + ~GETFileJob() override { if (_bandwidthManager) { _bandwidthManager->unregisterDownloadJob(this); @@ -110,6 +112,9 @@ class OWNCLOUDSYNC_EXPORT GETFileJob : public AbstractNetworkJob qint64 expectedContentLength() const { return _expectedContentLength; } void setExpectedContentLength(qint64 size) { _expectedContentLength = size; } +protected: + virtual qint64 writeToDevice(const QByteArray &data); + signals: void finishedSignal(); void downloadProgress(qint64, qint64); @@ -118,6 +123,34 @@ private slots: void slotMetaDataChanged(); }; +/** + * @brief The GETEncryptedFileJob class that provides file decryption on the fly while the download is running + * @ingroup libsync + */ +class OWNCLOUDSYNC_EXPORT GETEncryptedFileJob : public GETFileJob +{ + Q_OBJECT + +public: + // DOES NOT take ownership of the device. + explicit GETEncryptedFileJob(AccountPtr account, const QString &path, QIODevice *device, + const QMap &headers, const QByteArray &expectedEtagForResume, + qint64 resumeStart, EncryptedFile encryptedInfo, QObject *parent = nullptr); + explicit GETEncryptedFileJob(AccountPtr account, const QUrl &url, QIODevice *device, + const QMap &headers, const QByteArray &expectedEtagForResume, + qint64 resumeStart, EncryptedFile encryptedInfo, QObject *parent = nullptr); + ~GETEncryptedFileJob() override = default; + +protected: + qint64 writeToDevice(const QByteArray &data) override; + +private: + QSharedPointer _decryptor; + EncryptedFile _encryptedFileInfo = {}; + QByteArray _pendingBytes; + qint64 _processedSoFar = 0; +}; + /** * @brief The PropagateDownloadFile class * @ingroup libsync @@ -219,6 +252,6 @@ private slots: QElapsedTimer _stopwatch; - PropagateDownloadEncrypted *_downloadEncryptedHelper; + PropagateDownloadEncrypted *_downloadEncryptedHelper = nullptr; }; } diff --git a/src/libsync/propagateremotedeleteencrypted.h b/src/libsync/propagateremotedeleteencrypted.h index f29ae1939034..85bad2094247 100644 --- a/src/libsync/propagateremotedeleteencrypted.h +++ b/src/libsync/propagateremotedeleteencrypted.h @@ -24,7 +24,7 @@ class PropagateRemoteDeleteEncrypted : public AbstractPropagateRemoteDeleteEncry public: PropagateRemoteDeleteEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item, QObject *parent); - virtual void start() Q_DECL_OVERRIDE; + void start() override; private: void slotFolderUnLockedSuccessfully(const QByteArray &folderId) override; diff --git a/src/libsync/propagateremotedeleteencryptedrootfolder.h b/src/libsync/propagateremotedeleteencryptedrootfolder.h index 6cb083a5dcea..d0210f7f350f 100644 --- a/src/libsync/propagateremotedeleteencryptedrootfolder.h +++ b/src/libsync/propagateremotedeleteencryptedrootfolder.h @@ -27,7 +27,7 @@ class PropagateRemoteDeleteEncryptedRootFolder : public AbstractPropagateRemoteD public: PropagateRemoteDeleteEncryptedRootFolder(OwncloudPropagator *propagator, SyncFileItemPtr item, QObject *parent); - virtual void start() Q_DECL_OVERRIDE; + void start() override; private: void slotFolderUnLockedSuccessfully(const QByteArray &folderId) override; diff --git a/src/libsync/propagateremotemkdir.cpp b/src/libsync/propagateremotemkdir.cpp index 0809617dc98a..ac1b5b62a859 100644 --- a/src/libsync/propagateremotemkdir.cpp +++ b/src/libsync/propagateremotemkdir.cpp @@ -61,8 +61,7 @@ void PropagateRemoteMkdir::start() _job = new DeleteJob(propagator()->account(), propagator()->fullRemotePath(_item->_file), this); - connect(static_cast(_job.data()), &DeleteJob::finishedSignal, - this, &PropagateRemoteMkdir::slotMkdir); + connect(qobject_cast(_job), &DeleteJob::finishedSignal, this, &PropagateRemoteMkdir::slotMkdir); _job->start(); } @@ -76,7 +75,8 @@ void PropagateRemoteMkdir::slotStartMkcolJob() _job = new MkColJob(propagator()->account(), propagator()->fullRemotePath(_item->_file), this); - connect(_job, SIGNAL(finished(QNetworkReply::NetworkError)), this, SLOT(slotMkcolJobFinished())); + connect(qobject_cast(_job), &MkColJob::finishedWithError, this, &PropagateRemoteMkdir::slotMkcolJobFinished); + connect(qobject_cast(_job), &MkColJob::finishedWithoutError, this, &PropagateRemoteMkdir::slotMkcolJobFinished); _job->start(); } @@ -95,8 +95,8 @@ void PropagateRemoteMkdir::slotStartEncryptedMkcolJob(const QString &path, const propagator()->fullRemotePath(filename), {{"e2e-token", _uploadEncryptedHelper->folderToken() }}, this); - connect(job, qOverload(&MkColJob::finished), - this, &PropagateRemoteMkdir::slotMkcolJobFinished); + connect(job, &MkColJob::finishedWithError, this, &PropagateRemoteMkdir::slotMkcolJobFinished); + connect(job, &MkColJob::finishedWithoutError, this, &PropagateRemoteMkdir::slotMkcolJobFinished); _job = job; _job->start(); } @@ -137,36 +137,34 @@ void PropagateRemoteMkdir::finalizeMkColJob(QNetworkReply::NetworkError err, con return; } - if (_item->_fileId.isEmpty()) { - // Owncloud 7.0.0 and before did not have a header with the file id. - // (https://github.com/owncloud/core/issues/9000) - // So we must get the file id using a PROPFIND - // This is required so that we can detect moves even if the folder is renamed on the server - // while files are still uploading - propagator()->_activeJobList.append(this); - auto propfindJob = new PropfindJob(propagator()->account(), jobPath, this); - propfindJob->setProperties(QList() << "http://owncloud.org/ns:id"); - QObject::connect(propfindJob, &PropfindJob::result, this, &PropagateRemoteMkdir::propfindResult); - QObject::connect(propfindJob, &PropfindJob::finishedWithError, this, &PropagateRemoteMkdir::propfindError); - propfindJob->start(); - _job = propfindJob; - return; - } - - if (!_uploadEncryptedHelper && !_item->_isEncrypted) { - success(); - } else { - // We still need to mark that folder encrypted in case we were uploading it as encrypted one - // Another scenario, is we are creating a new folder because of move operation on an encrypted folder that works via remove + re-upload - propagator()->_activeJobList.append(this); - - // We're expecting directory path in /Foo/Bar convention... - Q_ASSERT(jobPath.startsWith('/') && !jobPath.endsWith('/')); - // But encryption job expect it in Foo/Bar/ convention - auto job = new OCC::EncryptFolderJob(propagator()->account(), propagator()->_journal, jobPath.mid(1), _item->_fileId, this); - connect(job, &OCC::EncryptFolderJob::finished, this, &PropagateRemoteMkdir::slotEncryptFolderFinished); - job->start(); - } + propagator()->_activeJobList.append(this); + auto propfindJob = new PropfindJob(propagator()->account(), jobPath, this); + propfindJob->setProperties({"http://owncloud.org/ns:permissions"}); + connect(propfindJob, &PropfindJob::result, this, [this, jobPath](const QVariantMap &result){ + propagator()->_activeJobList.removeOne(this); + _item->_remotePerm = RemotePermissions::fromServerString(result.value(QStringLiteral("permissions")).toString()); + + if (!_uploadEncryptedHelper && !_item->_isEncrypted) { + success(); + } else { + // We still need to mark that folder encrypted in case we were uploading it as encrypted one + // Another scenario, is we are creating a new folder because of move operation on an encrypted folder that works via remove + re-upload + propagator()->_activeJobList.append(this); + + // We're expecting directory path in /Foo/Bar convention... + Q_ASSERT(jobPath.startsWith('/') && !jobPath.endsWith('/')); + // But encryption job expect it in Foo/Bar/ convention + auto job = new OCC::EncryptFolderJob(propagator()->account(), propagator()->_journal, jobPath.mid(1), _item->_fileId, this); + connect(job, &OCC::EncryptFolderJob::finished, this, &PropagateRemoteMkdir::slotEncryptFolderFinished); + job->start(); + } + }); + connect(propfindJob, &PropfindJob::finishedWithError, this, [this]{ + // ignore the PROPFIND error + propagator()->_activeJobList.removeOne(this); + done(SyncFileItem::NormalError); + }); + propfindJob->start(); } void PropagateRemoteMkdir::slotMkdir() @@ -235,22 +233,6 @@ void PropagateRemoteMkdir::slotEncryptFolderFinished() success(); } -void PropagateRemoteMkdir::propfindResult(const QVariantMap &result) -{ - propagator()->_activeJobList.removeOne(this); - if (result.contains("id")) { - _item->_fileId = result["id"].toByteArray(); - } - success(); -} - -void PropagateRemoteMkdir::propfindError() -{ - // ignore the PROPFIND error - propagator()->_activeJobList.removeOne(this); - done(SyncFileItem::Success); -} - void PropagateRemoteMkdir::success() { // Never save the etag on first mkdir. diff --git a/src/libsync/propagateremotemkdir.h b/src/libsync/propagateremotemkdir.h index fe646b3c7c38..a48fad0e98dc 100644 --- a/src/libsync/propagateremotemkdir.h +++ b/src/libsync/propagateremotemkdir.h @@ -54,8 +54,6 @@ private slots: void slotStartEncryptedMkcolJob(const QString &path, const QString &filename, quint64 size); void slotMkcolJobFinished(); void slotEncryptFolderFinished(); - void propfindResult(const QVariantMap &); - void propfindError(); void success(); private: diff --git a/src/libsync/propagateremotemove.h b/src/libsync/propagateremotemove.h index 567896dd8e31..64ee0842e372 100644 --- a/src/libsync/propagateremotemove.h +++ b/src/libsync/propagateremotemove.h @@ -22,7 +22,7 @@ namespace OCC { * @brief The MoveJob class * @ingroup libsync */ -class MoveJob : public AbstractNetworkJob +class OWNCLOUDSYNC_EXPORT MoveJob : public AbstractNetworkJob { Q_OBJECT const QString _destination; diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 3136603cd48d..cd9e9db1c0fb 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -217,6 +217,20 @@ void PropagateUploadFileCommon::start() const auto slashPosition = path.lastIndexOf('/'); const auto parentPath = slashPosition >= 0 ? path.left(slashPosition) : QString(); + + if (!_item->_renameTarget.isEmpty() && _item->_file != _item->_renameTarget) { + // Try to rename the file + const auto originalFilePathAbsolute = propagator()->fullLocalPath(_item->_file); + const auto newFilePathAbsolute = propagator()->fullLocalPath(_item->_renameTarget); + const auto renameSuccess = QFile::rename(originalFilePathAbsolute, newFilePathAbsolute); + if (!renameSuccess) { + done(SyncFileItem::NormalError, "File contains trailing spaces and couldn't be renamed"); + return; + } + _item->_file = _item->_renameTarget; + _item->_modtime = FileSystem::getModTime(newFilePathAbsolute); + } + SyncJournalFileRecord parentRec; bool ok = propagator()->_journal->getFileRecord(parentPath, &parentRec); if (!ok) { diff --git a/src/libsync/propagateupload.h b/src/libsync/propagateupload.h index 33d1f209b30e..1a547a3b6884 100644 --- a/src/libsync/propagateupload.h +++ b/src/libsync/propagateupload.h @@ -39,7 +39,7 @@ class UploadDevice : public QIODevice Q_OBJECT public: UploadDevice(const QString &fileName, qint64 start, qint64 size, BandwidthManager *bwm); - ~UploadDevice(); + ~UploadDevice() override; bool open(QIODevice::OpenMode mode) override; void close() override; @@ -118,7 +118,7 @@ class PUTFileJob : public AbstractNetworkJob { _device->setParent(this); } - ~PUTFileJob(); + ~PUTFileJob() override; int _chunk; @@ -418,7 +418,7 @@ private slots: void slotPropfindFinishedWithError(); void slotPropfindIterate(const QString &name, const QMap &properties); void slotDeleteJobFinished(); - void slotMkColFinished(QNetworkReply::NetworkError); + void slotMkColFinished(); void slotPutFinished(); void slotMoveJobFinished(); void slotUploadProgress(qint64, qint64); diff --git a/src/libsync/propagateuploadencrypted.h b/src/libsync/propagateuploadencrypted.h index 6f5b25ba1207..246b32cac52a 100644 --- a/src/libsync/propagateuploadencrypted.h +++ b/src/libsync/propagateuploadencrypted.h @@ -33,7 +33,7 @@ class PropagateUploadEncrypted : public QObject Q_OBJECT public: PropagateUploadEncrypted(OwncloudPropagator *propagator, const QString &remoteParentPath, SyncFileItemPtr item, QObject *parent = nullptr); - ~PropagateUploadEncrypted() = default; + ~PropagateUploadEncrypted() override = default; void start(); diff --git a/src/libsync/propagateuploadng.cpp b/src/libsync/propagateuploadng.cpp index 62d1fca03893..0b4b40a861e5 100644 --- a/src/libsync/propagateuploadng.cpp +++ b/src/libsync/propagateuploadng.cpp @@ -229,7 +229,7 @@ void PropagateUploadFileNG::slotDeleteJobFinished() void PropagateUploadFileNG::startNewUpload() { ASSERT(propagator()->_activeJobList.count(this) == 1); - _transferId = uint(qrand() ^ uint(_item->_modtime) ^ (uint(_fileToUpload._size) << 16) ^ qHash(_fileToUpload._file)); + _transferId = uint(Utility::rand() ^ uint(_item->_modtime) ^ (uint(_fileToUpload._size) << 16) ^ qHash(_fileToUpload._file)); _sent = 0; _currentChunk = 0; @@ -249,13 +249,15 @@ void PropagateUploadFileNG::startNewUpload() headers["OC-Total-Length"] = QByteArray::number(_fileToUpload._size); auto job = new MkColJob(propagator()->account(), chunkUrl(), headers, this); - connect(job, SIGNAL(finished(QNetworkReply::NetworkError)), - this, SLOT(slotMkColFinished(QNetworkReply::NetworkError))); + connect(job, &MkColJob::finishedWithError, + this, &PropagateUploadFileNG::slotMkColFinished); + connect(job, &MkColJob::finishedWithoutError, + this, &PropagateUploadFileNG::slotMkColFinished); connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed); job->start(); } -void PropagateUploadFileNG::slotMkColFinished(QNetworkReply::NetworkError) +void PropagateUploadFileNG::slotMkColFinished() { propagator()->_activeJobList.removeOne(this); auto job = qobject_cast(sender()); diff --git a/src/libsync/propagateuploadv1.cpp b/src/libsync/propagateuploadv1.cpp index 8e4ec1e05e6e..40662fa20792 100644 --- a/src/libsync/propagateuploadv1.cpp +++ b/src/libsync/propagateuploadv1.cpp @@ -39,7 +39,7 @@ void PropagateUploadFileV1::doStartUpload() { _chunkCount = int(std::ceil(_fileToUpload._size / double(chunkSize()))); _startChunk = 0; - _transferId = uint(qrand()) ^ uint(_item->_modtime) ^ (uint(_fileToUpload._size) << 16); + _transferId = uint(Utility::rand()) ^ uint(_item->_modtime) ^ (uint(_fileToUpload._size) << 16); const SyncJournalDb::UploadInfo progressInfo = propagator()->_journal->getUploadInfo(_item->_file); diff --git a/src/libsync/pushnotifications.cpp b/src/libsync/pushnotifications.cpp index fcae8e985b04..8febf024dd87 100644 --- a/src/libsync/pushnotifications.cpp +++ b/src/libsync/pushnotifications.cpp @@ -76,6 +76,9 @@ void PushNotifications::closeWebSocket() _reconnectTimer->stop(); } + disconnect(_webSocket, QOverload::of(&QWebSocket::error), this, &PushNotifications::onWebSocketError); + disconnect(_webSocket, &QWebSocket::sslErrors, this, &PushNotifications::onWebSocketSslErrors); + _webSocket->close(); } @@ -171,6 +174,8 @@ void PushNotifications::openWebSocket() const auto webSocketUrl = capabilities.pushNotificationsWebSocketUrl(); qCInfo(lcPushNotifications) << "Open connection to websocket on" << webSocketUrl << "for account" << _account->url(); + connect(_webSocket, QOverload::of(&QWebSocket::error), this, &PushNotifications::onWebSocketError); + connect(_webSocket, &QWebSocket::sslErrors, this, &PushNotifications::onWebSocketSslErrors); _webSocket->open(webSocketUrl); } diff --git a/src/libsync/pushnotifications.h b/src/libsync/pushnotifications.h index 9d6b8445d233..1409c92a0e79 100644 --- a/src/libsync/pushnotifications.h +++ b/src/libsync/pushnotifications.h @@ -31,7 +31,7 @@ class OWNCLOUDSYNC_EXPORT PushNotifications : public QObject public: explicit PushNotifications(Account *account, QObject *parent = nullptr); - ~PushNotifications(); + ~PushNotifications() override; /** * Setup push notifications diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 7f480913dd7a..25a2826bb4ac 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -15,6 +15,7 @@ #include "syncengine.h" #include "account.h" +#include "common/filesystembase.h" #include "owncloudpropagator.h" #include "common/syncjournaldb.h" #include "common/syncjournalfilerecord.h" @@ -53,6 +54,7 @@ #include #include #include +#include #include namespace OCC { @@ -434,7 +436,7 @@ void SyncEngine::startSync() } if (s_anySyncRunning || _syncRunning) { - ASSERT(false); + ASSERT(false) return; } @@ -452,7 +454,7 @@ void SyncEngine::startSync() if (!QDir(_localPath).exists()) { _anotherSyncNeeded = DelayedFollowUp; // No _tr, it should only occur in non-mirall - syncError("Unable to find local sync folder."); + Q_EMIT syncError(QStringLiteral("Unable to find local sync folder.")); finalize(false); return; } @@ -465,11 +467,11 @@ void SyncEngine::startSync() qCWarning(lcEngine()) << "Too little space available at" << _localPath << ". Have" << freeBytes << "bytes and require at least" << minFree << "bytes"; _anotherSyncNeeded = DelayedFollowUp; - syncError(tr("Only %1 are available, need at least %2 to start", + Q_EMIT syncError(tr("Only %1 are available, need at least %2 to start", "Placeholders are postfixed with file sizes using Utility::octetsToString()") - .arg( - Utility::octetsToString(freeBytes), - Utility::octetsToString(minFree))); + .arg( + Utility::octetsToString(freeBytes), + Utility::octetsToString(minFree))); finalize(false); return; } else { @@ -498,7 +500,7 @@ void SyncEngine::startSync() // This creates the DB if it does not exist yet. if (!_journal->open()) { qCWarning(lcEngine) << "No way to create a sync journal!"; - syncError(tr("Unable to open or create the local sync database. Make sure you have write access in the sync folder.")); + Q_EMIT syncError(tr("Unable to open or create the local sync database. Make sure you have write access in the sync folder.")); finalize(false); return; // database creation error! @@ -514,7 +516,7 @@ void SyncEngine::startSync() _lastLocalDiscoveryStyle = _localDiscoveryStyle; if (_syncOptions._vfs->mode() == Vfs::WithSuffix && _syncOptions._vfs->fileSuffix().isEmpty()) { - syncError(tr("Using virtual files with suffix, but suffix is not set")); + Q_EMIT syncError(tr("Using virtual files with suffix, but suffix is not set")); finalize(false); return; } @@ -526,7 +528,7 @@ void SyncEngine::startSync() qCInfo(lcEngine) << (usingSelectiveSync ? "Using Selective Sync" : "NOT Using Selective Sync"); } else { qCWarning(lcEngine) << "Could not retrieve selective sync list from DB"; - syncError(tr("Unable to read the blacklist from the local database")); + Q_EMIT syncError(tr("Unable to read the blacklist from the local database")); finalize(false); return; } @@ -544,6 +546,11 @@ void SyncEngine::startSync() _discoveryPhase.reset(new DiscoveryPhase); _discoveryPhase->_account = _account; _discoveryPhase->_excludes = _excludedFiles.data(); + const QString excludeFilePath = _localPath + QStringLiteral(".sync-exclude.lst"); + if (QFile::exists(excludeFilePath)) { + _discoveryPhase->_excludes->addExcludeFilePath(excludeFilePath); + _discoveryPhase->_excludes->reloadExcludeFiles(); + } _discoveryPhase->_statedb = _journal; _discoveryPhase->_localDir = _localPath; if (!_discoveryPhase->_localDir.endsWith('/')) @@ -557,7 +564,7 @@ void SyncEngine::startSync() _discoveryPhase->setSelectiveSyncWhiteList(_journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, &ok)); if (!ok) { qCWarning(lcEngine) << "Unable to read selective sync list, aborting."; - syncError(tr("Unable to read from the sync journal.")); + Q_EMIT syncError(tr("Unable to read from the sync journal.")); finalize(false); return; } @@ -574,14 +581,14 @@ void SyncEngine::startSync() invalidFilenamePattern = R"([\\:?*"<>|])"; } if (!invalidFilenamePattern.isEmpty()) - _discoveryPhase->_invalidFilenameRx = QRegExp(invalidFilenamePattern); + _discoveryPhase->_invalidFilenameRx = QRegularExpression(invalidFilenamePattern); _discoveryPhase->_serverBlacklistedFiles = _account->capabilities().blacklistedFiles(); _discoveryPhase->_ignoreHiddenFiles = ignoreHiddenFiles(); connect(_discoveryPhase.data(), &DiscoveryPhase::itemDiscovered, this, &SyncEngine::slotItemDiscovered); connect(_discoveryPhase.data(), &DiscoveryPhase::newBigFolder, this, &SyncEngine::newBigFolder); connect(_discoveryPhase.data(), &DiscoveryPhase::fatalError, this, [this](const QString &errorString) { - syncError(errorString); + Q_EMIT syncError(errorString); finalize(false); }); connect(_discoveryPhase.data(), &DiscoveryPhase::finished, this, &SyncEngine::slotDiscoveryFinished); @@ -614,7 +621,7 @@ void SyncEngine::slotFolderDiscovered(bool local, const QString &folder) emit transmissionProgress(*_progressInfo); } -void SyncEngine::slotRootEtagReceived(const QString &e, const QDateTime &time) +void SyncEngine::slotRootEtagReceived(const QByteArray &e, const QDateTime &time) { if (_remoteRootEtag.isEmpty()) { qCDebug(lcEngine) << "Root etag:" << e; @@ -640,7 +647,7 @@ void SyncEngine::slotDiscoveryFinished() // Sanity check if (!_journal->open()) { qCWarning(lcEngine) << "Bailing out, DB failure"; - syncError(tr("Cannot open the sync journal")); + Q_EMIT syncError(tr("Cannot open the sync journal")); finalize(false); return; } else { @@ -690,8 +697,12 @@ void SyncEngine::slotDiscoveryFinished() const QString script = qEnvironmentVariable("OWNCLOUD_POST_UPDATE_SCRIPT"); qCDebug(lcEngine) << "Post Update Script: " << script; - QProcess::execute(script); - #else + auto scriptArgs = script.split(QRegularExpression("\\s+"), Qt::SkipEmptyParts); + if (scriptArgs.size() > 0) { + const auto scriptExecutable = scriptArgs.takeFirst(); + QProcess::execute(scriptExecutable, scriptArgs); + } +#else qCWarning(lcEngine) << "**** Attention: POST_UPDATE_SCRIPT installed, but not executed because compiled with NDEBUG"; #endif } @@ -723,10 +734,9 @@ void SyncEngine::slotDiscoveryFinished() // Emit the started signal only after the propagator has been set up. if (_needsUpdate) - emit(started()); + Q_EMIT started(); - _propagator->start(_syncItems); - _syncItems.clear(); + _propagator->start(std::move(_syncItems)); qCInfo(lcEngine) << "#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QStringLiteral("Post-Reconcile Finished")) << "ms"; }; @@ -799,55 +809,8 @@ void SyncEngine::slotPropagationFinished(bool success) _anotherSyncNeeded = ImmediateFollowUp; } - // TODO: Remove this when the file restoration problem is fixed for a user - bool shouldStartSyncAgain = false; - const auto checkAndOverrideSetDataFingerprint = [this, &shouldStartSyncAgain] { - const int dataFingerprintOverrideThreshold = 9; - const QString dataFingerprintOverrideHostHash = QStringLiteral("63debc9ef6d217649ea70632ca573a1db7a237ba61c48cdd2bf797f7060233db"); - const auto accountHost = account()->url().host(); - const auto accountDisplayName = account()->displayName(); - - if (_dataFingerprintSetFailCount >= 0) { - qCWarning(lcEngine) << "setDataFingerprint has failed for account" << accountDisplayName << "on host" << accountHost << "due to sync errors. Checking the possibility for override..."; - - if (_dataFingerprintSetFailCount > 0) { - if (_dataFingerprintSetFailCount >= dataFingerprintOverrideThreshold) { - qCWarning(lcEngine) << "All sync attempts failed for account" << accountDisplayName << "on host" << accountHost << "setting the dataFingerprint anyway."; - _journal->setDataFingerprint(_discoveryPhase->_dataFingerprint); - // this mechanism should only run once per app launch - _dataFingerprintSetFailCount = -1; - } else { - ++_dataFingerprintSetFailCount; - // request to start sync again as it won't happen by itself unless the file has changed on the server or in the local folder - shouldStartSyncAgain = true; - } - } else { - // only compare hash once - // if it matches - we don't need to calculate it again while _dataFingerprintSetFailCount is greater than 0 - const auto accountHostHash = QString::fromUtf8(QCryptographicHash::hash(accountHost.toUtf8(), QCryptographicHash::Sha256).toHex()); - - if (accountHostHash == dataFingerprintOverrideHostHash) { - qCInfo(lcEngine) << "accountHostHash" << accountHostHash << "equals to dataFingerprintOverrideHostHash" << dataFingerprintOverrideHostHash << "_dataFingerprintSetFailCount" << _dataFingerprintSetFailCount; - ++_dataFingerprintSetFailCount; - // request to start sync again as it won't happen by itself unless the file has changed on the server or in the local folder - shouldStartSyncAgain = true; - } else { - qCInfo(lcEngine) << "accountHostHash" << accountHostHash << "differs from dataFingerprintOverrideHostHash" << dataFingerprintOverrideHostHash; - // give up on calculating the has next time, as it's not the host we are looking for - _dataFingerprintSetFailCount = -1; - } - } - } else { - qCWarning(lcEngine) << "setDataFingerprint was overridden already for account" << accountDisplayName << "on host" << accountHost << "but is failing again! Or, it's not the host that we are looking for."; - } - }; - // - if (success && _discoveryPhase) { _journal->setDataFingerprint(_discoveryPhase->_dataFingerprint); - } else if (_discoveryPhase) { - // TODO: Remove this when the file restoration problem is fixed for a user - checkAndOverrideSetDataFingerprint(); } conflictRecordMaintenance(); @@ -863,12 +826,6 @@ void SyncEngine::slotPropagationFinished(bool success) emit transmissionProgress(*_progressInfo); finalize(success); - - if (shouldStartSyncAgain) { - // TODO: Remove this when the file restoration problem is fixed for a user - qCWarning(lcEngine) << "Starting sync again for account" << account()->displayName() << "on host" << account()->url().host() << "due to setDataFingerprint override is running."; - startSync(); - } } void SyncEngine::finalize(bool success) @@ -1064,6 +1021,24 @@ void SyncEngine::wipeVirtualFiles(const QString &localPath, SyncJournalDb &journ // But hydrated placeholders may still be around. } +void SyncEngine::switchToVirtualFiles(const QString &localPath, SyncJournalDb &journal, Vfs &vfs) +{ + qCInfo(lcEngine) << "Convert to virtual files inside" << localPath; + journal.getFilesBelowPath({}, [&](const SyncJournalFileRecord &rec) { + const auto path = rec.path(); + const auto fileName = QFileInfo(path).fileName(); + if (FileSystem::isExcludeFile(fileName)) { + return; + } + SyncFileItem item; + QString localFile = localPath + path; + const auto result = vfs.convertToPlaceholder(localFile, item, localFile); + if (!result.isValid()) { + qCWarning(lcEngine) << "Could not convert file to placeholder" << result.error(); + } + }); +} + void SyncEngine::abort() { if (_propagator) @@ -1078,7 +1053,7 @@ void SyncEngine::abort() disconnect(_discoveryPhase.data(), nullptr, this, nullptr); _discoveryPhase.take()->deleteLater(); - syncError(tr("Aborted")); + Q_EMIT syncError(tr("Synchronization will resume shortly.")); finalize(false); } } diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h index a9e50a19798d..9d0bada92df4 100644 --- a/src/libsync/syncengine.h +++ b/src/libsync/syncengine.h @@ -59,7 +59,7 @@ class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject public: SyncEngine(AccountPtr account, const QString &localPath, const QString &remotePath, SyncJournalDb *journal); - ~SyncEngine(); + ~SyncEngine() override; Q_INVOKABLE void startSync(); void setNetworkLimits(int upload, int download); @@ -134,11 +134,13 @@ class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject */ static void wipeVirtualFiles(const QString &localPath, SyncJournalDb &journal, Vfs &vfs); + static void switchToVirtualFiles(const QString &localPath, SyncJournalDb &journal, Vfs &vfs); + auto getPropagator() { return _propagator; } // for the test signals: // During update, before reconcile - void rootEtag(const QString &, const QDateTime &); + void rootEtag(const QByteArray &, const QDateTime &); // after the above signals. with the items that actually need propagating void aboutToPropagate(SyncFileItemVector &); @@ -174,7 +176,7 @@ class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject private slots: void slotFolderDiscovered(bool local, const QString &folder); - void slotRootEtagReceived(const QString &, const QDateTime &time); + void slotRootEtagReceived(const QByteArray &, const QDateTime &time); /** When the discovery phase discovers an item */ void slotItemDiscovered(const SyncFileItemPtr &item); @@ -234,7 +236,7 @@ private slots: bool _syncRunning; QString _localPath; QString _remotePath; - QString _remoteRootEtag; + QByteArray _remoteRootEtag; SyncJournalDb *_journal; QScopedPointer _discoveryPhase; QSharedPointer _propagator; @@ -291,9 +293,6 @@ private slots: LocalDiscoveryStyle _lastLocalDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly; LocalDiscoveryStyle _localDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly; std::set _localDiscoveryPaths; - - // TODO: Remove this when the file restoration problem is fixed for a user - int _dataFingerprintSetFailCount = 0; }; } diff --git a/src/libsync/syncfilestatustracker.cpp b/src/libsync/syncfilestatustracker.cpp index 276bc4f8d050..9c4ae0e8ca88 100644 --- a/src/libsync/syncfilestatustracker.cpp +++ b/src/libsync/syncfilestatustracker.cpp @@ -339,7 +339,7 @@ SyncFileStatus SyncFileStatusTracker::resolveSyncAndErrorStatus(const QString &r void SyncFileStatusTracker::invalidateParentPaths(const QString &path) { - QStringList splitPath = path.split('/', QString::SkipEmptyParts); + QStringList splitPath = path.split('/', Qt::SkipEmptyParts); for (int i = 0; i < splitPath.size(); ++i) { QString parentPath = QStringList(splitPath.mid(0, i)).join(QLatin1String("/")); emit fileStatusChanged(getSystemDestination(parentPath), fileStatus(parentPath)); diff --git a/src/libsync/syncoptions.cpp b/src/libsync/syncoptions.cpp new file mode 100644 index 000000000000..c6312d4b41be --- /dev/null +++ b/src/libsync/syncoptions.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) by Olivier Goffart + * + * 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 "syncoptions.h" +#include "common/utility.h" + +#include + +using namespace OCC; + +SyncOptions::SyncOptions() + : _vfs(new VfsOff) +{ +} + +SyncOptions::~SyncOptions() = default; + +void SyncOptions::fillFromEnvironmentVariables() +{ + QByteArray chunkSizeEnv = qgetenv("OWNCLOUD_CHUNK_SIZE"); + if (!chunkSizeEnv.isEmpty()) + _initialChunkSize = chunkSizeEnv.toUInt(); + + QByteArray minChunkSizeEnv = qgetenv("OWNCLOUD_MIN_CHUNK_SIZE"); + if (!minChunkSizeEnv.isEmpty()) + _minChunkSize = minChunkSizeEnv.toUInt(); + + QByteArray maxChunkSizeEnv = qgetenv("OWNCLOUD_MAX_CHUNK_SIZE"); + if (!maxChunkSizeEnv.isEmpty()) + _maxChunkSize = maxChunkSizeEnv.toUInt(); + + QByteArray targetChunkUploadDurationEnv = qgetenv("OWNCLOUD_TARGET_CHUNK_UPLOAD_DURATION"); + if (!targetChunkUploadDurationEnv.isEmpty()) + _targetChunkUploadDuration = std::chrono::milliseconds(targetChunkUploadDurationEnv.toUInt()); + + int maxParallel = qgetenv("OWNCLOUD_MAX_PARALLEL").toInt(); + if (maxParallel > 0) + _parallelNetworkJobs = maxParallel; +} + +void SyncOptions::verifyChunkSizes() +{ + _minChunkSize = qMin(_minChunkSize, _initialChunkSize); + _maxChunkSize = qMax(_maxChunkSize, _initialChunkSize); +} + +QRegularExpression SyncOptions::fileRegex() const +{ + return _fileRegex; +} + +void SyncOptions::setFilePattern(const QString &pattern) +{ + // full match or a path ending with this pattern + setPathPattern(QStringLiteral("(^|/|\\\\)") + pattern + QLatin1Char('$')); +} + +void SyncOptions::setPathPattern(const QString &pattern) +{ + _fileRegex.setPatternOptions(Utility::fsCasePreserving() ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption); + _fileRegex.setPattern(pattern); +} diff --git a/src/libsync/syncoptions.h b/src/libsync/syncoptions.h index cc792aa9b120..f109ec7fc248 100644 --- a/src/libsync/syncoptions.h +++ b/src/libsync/syncoptions.h @@ -15,21 +15,25 @@ #pragma once #include "owncloudlib.h" -#include +#include "common/vfs.h" + +#include #include +#include + #include -#include "common/vfs.h" + namespace OCC { /** * Value class containing the options given to the sync engine */ -struct OWNCLOUDSYNC_EXPORT SyncOptions +class OWNCLOUDSYNC_EXPORT SyncOptions { - SyncOptions() - : _vfs(new VfsOff) - {} +public: + SyncOptions(); + ~SyncOptions(); /** Maximum size (in Bytes) a folder can have without asking for confirmation. * -1 means infinite */ @@ -67,7 +71,45 @@ struct OWNCLOUDSYNC_EXPORT SyncOptions /** The maximum number of active jobs in parallel */ int _parallelNetworkJobs = 6; -}; + /** Reads settings from env vars where available. + * + * Currently reads _initialChunkSize, _minChunkSize, _maxChunkSize, + * _targetChunkUploadDuration, _parallelNetworkJobs. + */ + void fillFromEnvironmentVariables(); + + /** Ensure min <= initial <= max + * + * Previously min/max chunk size values didn't exist, so users might + * have setups where the chunk size exceeds the new min/max default + * values. To cope with this, adjust min/max to always include the + * initial chunk size value. + */ + void verifyChunkSizes(); + + + /** A regular expression to match file names + * If no pattern is provided the default is an invalid regular expression. + */ + QRegularExpression fileRegex() const; + + /** + * A pattern like *.txt, matching only file names + */ + void setFilePattern(const QString &pattern); + + /** + * A pattern like /own.*\/.*txt matching the full path + */ + void setPathPattern(const QString &pattern); + +private: + /** + * Only sync files that mathc the expression + * Invalid pattern by default. + */ + QRegularExpression _fileRegex = QRegularExpression(QStringLiteral("(")); +}; } diff --git a/src/libsync/theme.cpp b/src/libsync/theme.cpp index aaaf0774a59a..ff7f58e607ff 100644 --- a/src/libsync/theme.cpp +++ b/src/libsync/theme.cpp @@ -156,7 +156,37 @@ QUrl Theme::statusAwayImageSource() const QUrl Theme::statusInvisibleImageSource() const { - return imagePathToUrl(themeImagePath("user-status-invisible", 16)); + return imagePathToUrl(themeImagePath("user-status-invisible", 64)); +} + +QUrl Theme::syncStatusOk() const +{ + return imagePathToUrl(themeImagePath("state-ok", 16)); +} + +QUrl Theme::syncStatusError() const +{ + return imagePathToUrl(themeImagePath("state-error", 16)); +} + +QUrl Theme::syncStatusRunning() const +{ + return imagePathToUrl(themeImagePath("state-sync", 16)); +} + +QUrl Theme::syncStatusPause() const +{ + return imagePathToUrl(themeImagePath("state-pause", 16)); +} + +QUrl Theme::syncStatusWarning() const +{ + return imagePathToUrl(themeImagePath("state-warning", 16)); +} + +QUrl Theme::folderOffline() const +{ + return imagePathToUrl(themeImagePath("state-offline")); } QString Theme::version() const @@ -197,7 +227,7 @@ QIcon Theme::themeIcon(const QString &name, bool sysTray) const return cached = QIcon::fromTheme(name); } - const auto svgName = QString::fromLatin1(":/client/theme/%1/%2.svg").arg(flavor).arg(name); + const QString svgName = QString(Theme::themePrefix) + QString::fromLatin1("%1/%2.svg").arg(flavor).arg(name); QSvgRenderer renderer(svgName); const auto createPixmapFromSvg = [&renderer] (int size) { QImage img(size, size, QImage::Format_ARGB32); @@ -208,7 +238,7 @@ QIcon Theme::themeIcon(const QString &name, bool sysTray) const }; const auto loadPixmap = [flavor, name] (int size) { - const auto pixmapName = QString::fromLatin1(":/client/theme/%1/%2-%3.png").arg(flavor).arg(name).arg(size); + const QString pixmapName = QString(Theme::themePrefix) + QString::fromLatin1("%1/%2-%3.png").arg(flavor).arg(name).arg(size); return QPixmap(pixmapName); }; @@ -249,8 +279,8 @@ QString Theme::themeImagePath(const QString &name, int size, bool sysTray) const // branded client may have several sizes of the same icon const QString filePath = (useSvg || size <= 0) - ? QString::fromLatin1(":/client/theme/%1/%2").arg(flavor).arg(name) - : QString::fromLatin1(":/client/theme/%1/%2-%3").arg(flavor).arg(name).arg(size); + ? QString(Theme::themePrefix) + QString::fromLatin1("%1/%2").arg(flavor).arg(name) + : QString(Theme::themePrefix) + QString::fromLatin1("%1/%2-%3").arg(flavor).arg(name).arg(size); const QString svgPath = filePath + ".svg"; if (useSvg) { @@ -274,8 +304,7 @@ bool Theme::isHidpi(QPaintDevice *dev) QIcon Theme::uiThemeIcon(const QString &iconName, bool uiHasDarkBg) const { - QString themeResBasePath = ":/client/theme/"; - QString iconPath = themeResBasePath + (uiHasDarkBg?"white/":"black/") + iconName; + QString iconPath = QString(Theme::themePrefix) + (uiHasDarkBg ? "white/" : "black/") + iconName; std::string icnPath = iconPath.toUtf8().constData(); return QIcon(QPixmap(iconPath)); } @@ -303,8 +332,7 @@ QString Theme::hidpiFileName(const QString &iconName, const QColor &backgroundCo { const auto isDarkBackground = Theme::isDarkColor(backgroundColor); - const QString themeResBasePath = ":/client/theme/"; - const QString iconPath = themeResBasePath + (isDarkBackground ? "white/" : "black/") + iconName; + const QString iconPath = QString(Theme::themePrefix) + (isDarkBackground ? "white/" : "black/") + iconName; return Theme::hidpiFileName(iconPath, dev); } @@ -371,6 +399,24 @@ bool Theme::forceOverrideServerUrl() const #endif } +bool Theme::enableStaplingOCSP() const +{ +#ifdef APPLICATION_OCSP_STAPLING_ENABLED + return true; +#else + return false; +#endif +} + +bool Theme::forbidBadSSL() const +{ +#ifdef APPLICATION_FORBID_BAD_SSL + return true; +#else + return false; +#endif +} + QString Theme::forceConfigAuthType() const { return QString(); @@ -406,7 +452,7 @@ bool Theme::systrayUseMonoIcons() const bool Theme::monoIconsAvailable() const { - QString themeDir = QString::fromLatin1(":/client/theme/%1/").arg(Theme::instance()->systrayIconFlavor(true)); + QString themeDir = QString(Theme::themePrefix) + QString::fromLatin1("%1/").arg(Theme::instance()->systrayIconFlavor(true)); return QDir(themeDir).exists(); } @@ -468,6 +514,8 @@ QString Theme::about() const devString += tr("

Using virtual files plugin: %1

") .arg(Vfs::modeToString(bestAvailableVfsMode())); + devString += QStringLiteral("
%1") + .arg(QSysInfo::productType() % QLatin1Char('-') % QSysInfo::kernelVersion()); return devString; } @@ -508,7 +556,7 @@ QVariant Theme::customMedia(CustomMediaType type) break; } - QString imgPath = QString::fromLatin1(":/client/theme/colored/%1.png").arg(key); + QString imgPath = QString(Theme::themePrefix) + QString::fromLatin1("colored/%1.png").arg(key); if (QFile::exists(imgPath)) { QPixmap pix(imgPath); if (pix.isNull()) { @@ -579,11 +627,11 @@ QColor Theme::wizardHeaderBackgroundColor() const QPixmap Theme::wizardApplicationLogo() const { if (!Theme::isBranded()) { - return QPixmap(Theme::hidpiFileName(":/client/theme/colored/wizard-nextcloud.png")); + return QPixmap(Theme::hidpiFileName(QString(Theme::themePrefix) + "colored/wizard-nextcloud.png")); } #ifdef APPLICATION_WIZARD_USE_CUSTOM_LOGO const auto useSvg = shouldPreferSvg(); - const auto logoBasePath = QStringLiteral(":/client/theme/colored/wizard_logo"); + const QString logoBasePath = QString(Theme::themePrefix) + QStringLiteral("colored/wizard_logo"); if (useSvg) { const auto maxHeight = Theme::isHidpi() ? 200 : 100; const auto maxWidth = 2 * maxHeight; @@ -603,7 +651,7 @@ QPixmap Theme::wizardHeaderLogo() const { #ifdef APPLICATION_WIZARD_USE_CUSTOM_LOGO const auto useSvg = shouldPreferSvg(); - const auto logoBasePath = QStringLiteral(":/client/theme/colored/wizard_logo"); + const QString logoBasePath = QString(Theme::themePrefix) + QStringLiteral("colored/wizard_logo"); if (useSvg) { const auto maxHeight = 64; const auto maxWidth = 2 * maxHeight; @@ -705,17 +753,17 @@ QString Theme::versionSwitchOutput() const QTextStream stream(&helpText); stream << appName() << QLatin1String(" version ") - << version() << endl; + << version() << Qt::endl; #ifdef GIT_SHA1 - stream << "Git revision " << GIT_SHA1 << endl; + stream << "Git revision " << GIT_SHA1 << Qt::endl; #endif - stream << "Using Qt " << qVersion() << ", built against Qt " << QT_VERSION_STR << endl; + stream << "Using Qt " << qVersion() << ", built against Qt " << QT_VERSION_STR << Qt::endl; if(!QGuiApplication::platformName().isEmpty()) - stream << "Using Qt platform plugin '" << QGuiApplication::platformName() << "'" << endl; + stream << "Using Qt platform plugin '" << QGuiApplication::platformName() << "'" << Qt::endl; - stream << "Using '" << QSslSocket::sslLibraryVersionString() << "'" << endl; - stream << "Running on " << Utility::platformName() << ", " << QSysInfo::currentCpuArchitecture() << endl; + stream << "Using '" << QSslSocket::sslLibraryVersionString() << "'" << Qt::endl; + stream << "Running on " << Utility::platformName() << ", " << QSysInfo::currentCpuArchitecture() << Qt::endl; return helpText; } @@ -811,4 +859,25 @@ bool Theme::showVirtualFilesOption() const return ConfigFile().showExperimentalOptions() || vfsMode == Vfs::WindowsCfApi; } +bool Theme::enforceVirtualFilesSyncFolder() const +{ + const auto vfsMode = bestAvailableVfsMode(); + return ENFORCE_VIRTUAL_FILES_SYNC_FOLDER && vfsMode != OCC::Vfs::Off; +} + +QColor Theme::errorBoxTextColor() const +{ + return QColor{"white"}; +} + +QColor Theme::errorBoxBackgroundColor() const +{ + return QColor{"red"}; +} + +QColor Theme::errorBoxBorderColor() const +{ + return QColor{"black"}; +} + } // end namespace client diff --git a/src/libsync/theme.h b/src/libsync/theme.h index c40cdb0b6847..6b9aefb255a7 100644 --- a/src/libsync/theme.h +++ b/src/libsync/theme.h @@ -61,6 +61,10 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject Q_PROPERTY(QColor wizardHeaderBackgroundColor READ wizardHeaderBackgroundColor CONSTANT) #endif Q_PROPERTY(QString updateCheckUrl READ updateCheckUrl CONSTANT) + + Q_PROPERTY(QColor errorBoxTextColor READ errorBoxTextColor CONSTANT) + Q_PROPERTY(QColor errorBoxBackgroundColor READ errorBoxBackgroundColor CONSTANT) + Q_PROPERTY(QColor errorBoxBorderColor READ errorBoxBorderColor CONSTANT) public: enum CustomMediaType { oCSetupTop, // ownCloud connect page @@ -72,7 +76,7 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject /* returns a singleton instance. */ static Theme *instance(); - ~Theme(); + ~Theme() override; /** * @brief isBranded indicates if the current application is branded @@ -151,6 +155,18 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject */ QUrl statusInvisibleImageSource() const; + QUrl syncStatusOk() const; + + QUrl syncStatusError() const; + + QUrl syncStatusRunning() const; + + QUrl syncStatusPause() const; + + QUrl syncStatusWarning() const; + + QUrl folderOffline() const; + /** * @brief configFileName * @return the name of the config file. @@ -223,6 +239,20 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject * When true, the respective UI controls will be disabled */ virtual bool forceOverrideServerUrl() const; + + /** + * Enable OCSP stapling for SSL handshakes + * + * When true, peer will be requested for Online Certificate Status Protocol response + */ + virtual bool enableStaplingOCSP() const; + + /** + * Enforce SSL validity + * + * When true, trusting the untrusted certificate is not allowed + */ + virtual bool forbidBadSSL() const; /** * This is only usefull when previous version had a different overrideServerUrl @@ -535,6 +565,19 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject */ virtual bool showVirtualFilesOption() const; + virtual bool enforceVirtualFilesSyncFolder() const; + + /** @return color for the ErrorBox text. */ + virtual QColor errorBoxTextColor() const; + + /** @return color for the ErrorBox background. */ + virtual QColor errorBoxBackgroundColor() const; + + /** @return color for the ErrorBox border. */ + virtual QColor errorBoxBorderColor() const; + + static constexpr const char *themePrefix = ":/client/theme/"; + protected: #ifndef TOKEN_AUTH_ONLY QIcon themeIcon(const QString &name, bool sysTray = false) const; diff --git a/src/libsync/userstatusconnector.cpp b/src/libsync/userstatusconnector.cpp new file mode 100644 index 000000000000..178e8d7948cc --- /dev/null +++ b/src/libsync/userstatusconnector.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 "userstatusconnector.h" +#include "theme.h" + +namespace OCC { + +UserStatus::UserStatus() = default; + +UserStatus::UserStatus( + const QString &id, const QString &message, const QString &icon, + OnlineStatus state, bool messagePredefined, const Optional &clearAt) + : _id(id) + , _message(message) + , _icon(icon) + , _state(state) + , _messagePredefined(messagePredefined) + , _clearAt(clearAt) +{ +} + +QString UserStatus::id() const +{ + return _id; +} + +QString UserStatus::message() const +{ + return _message; +} + +QString UserStatus::icon() const +{ + return _icon; +} + +auto UserStatus::state() const -> OnlineStatus +{ + return _state; +} + +bool UserStatus::messagePredefined() const +{ + return _messagePredefined; +} + +QUrl UserStatus::stateIcon() const +{ + switch (_state) { + case UserStatus::OnlineStatus::Away: + return Theme::instance()->statusAwayImageSource(); + + case UserStatus::OnlineStatus::DoNotDisturb: + return Theme::instance()->statusDoNotDisturbImageSource(); + + case UserStatus::OnlineStatus::Invisible: + case UserStatus::OnlineStatus::Offline: + return Theme::instance()->statusInvisibleImageSource(); + + case UserStatus::OnlineStatus::Online: + return Theme::instance()->statusOnlineImageSource(); + } + + Q_UNREACHABLE(); +} + +Optional UserStatus::clearAt() const +{ + return _clearAt; +} + +void UserStatus::setId(const QString &id) +{ + _id = id; +} + +void UserStatus::setMessage(const QString &message) +{ + _message = message; +} + +void UserStatus::setState(OnlineStatus state) +{ + _state = state; +} + +void UserStatus::setIcon(const QString &icon) +{ + _icon = icon; +} + +void UserStatus::setMessagePredefined(bool value) +{ + _messagePredefined = value; +} + +void UserStatus::setClearAt(const Optional &dateTime) +{ + _clearAt = dateTime; +} + + +UserStatusConnector::UserStatusConnector(QObject *parent) + : QObject(parent) +{ +} + +UserStatusConnector::~UserStatusConnector() = default; +} diff --git a/src/libsync/userstatusconnector.h b/src/libsync/userstatusconnector.h new file mode 100644 index 000000000000..d5593fe9e50c --- /dev/null +++ b/src/libsync/userstatusconnector.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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. + */ + +#pragma once + +#include "common/result.h" +#include "owncloudlib.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + + +namespace OCC { + +enum class OWNCLOUDSYNC_EXPORT ClearAtType { + Period, + EndOf, + Timestamp +}; + +// TODO: If we can use C++17 make it a std::variant +struct OWNCLOUDSYNC_EXPORT ClearAt +{ + ClearAtType _type = ClearAtType::Period; + + quint64 _timestamp; + int _period; + QString _endof; +}; + +class OWNCLOUDSYNC_EXPORT UserStatus +{ + Q_GADGET + + Q_PROPERTY(QString id MEMBER _id) + Q_PROPERTY(QString message MEMBER _message) + Q_PROPERTY(QString icon MEMBER _icon) + Q_PROPERTY(OnlineStatus state MEMBER _state) + +public: + enum class OnlineStatus : quint8 { + Online, + DoNotDisturb, + Away, + Offline, + Invisible + }; + Q_ENUM(OnlineStatus); + + UserStatus(); + + UserStatus(const QString &id, const QString &message, const QString &icon, + OnlineStatus state, bool messagePredefined, const Optional &clearAt = {}); + + Q_REQUIRED_RESULT QString id() const; + Q_REQUIRED_RESULT QString message() const; + Q_REQUIRED_RESULT QString icon() const; + Q_REQUIRED_RESULT OnlineStatus state() const; + Q_REQUIRED_RESULT Optional clearAt() const; + + void setId(const QString &id); + void setMessage(const QString &message); + void setState(OnlineStatus state); + void setIcon(const QString &icon); + void setMessagePredefined(bool value); + void setClearAt(const Optional &dateTime); + + Q_REQUIRED_RESULT bool messagePredefined() const; + + Q_REQUIRED_RESULT QUrl stateIcon() const; + +private: + QString _id; + QString _message; + QString _icon; + OnlineStatus _state = OnlineStatus::Online; + bool _messagePredefined; + Optional _clearAt; +}; + +class OWNCLOUDSYNC_EXPORT UserStatusConnector : public QObject +{ + Q_OBJECT + +public: + enum class Error { + CouldNotFetchUserStatus, + CouldNotFetchPredefinedUserStatuses, + UserStatusNotSupported, + EmojisNotSupported, + CouldNotSetUserStatus, + CouldNotClearMessage + }; + Q_ENUM(Error) + + explicit UserStatusConnector(QObject *parent = nullptr); + + ~UserStatusConnector() override; + + virtual void fetchUserStatus() = 0; + + virtual void fetchPredefinedStatuses() = 0; + + virtual void setUserStatus(const UserStatus &userStatus) = 0; + + virtual void clearMessage() = 0; + + virtual UserStatus userStatus() const = 0; + +signals: + void userStatusFetched(const UserStatus &userStatus); + void predefinedStatusesFetched(const std::vector &statuses); + void userStatusSet(); + void messageCleared(); + void error(Error error); +}; +} + +Q_DECLARE_METATYPE(OCC::UserStatusConnector *) +Q_DECLARE_METATYPE(OCC::UserStatus) diff --git a/src/libsync/vfs/cfapi/CMakeLists.txt b/src/libsync/vfs/cfapi/CMakeLists.txt index 77392c21f96d..a6ac662d3173 100644 --- a/src/libsync/vfs/cfapi/CMakeLists.txt +++ b/src/libsync/vfs/cfapi/CMakeLists.txt @@ -1,35 +1,44 @@ if (WIN32) add_definitions(-D_WIN32_WINNT=_WIN32_WINNT_WIN10) - add_library("${synclib_NAME}_vfs_cfapi" SHARED + add_library(nextcloudsync_vfs_cfapi SHARED cfapiwrapper.cpp hydrationjob.cpp vfs_cfapi.cpp ) - target_link_libraries("${synclib_NAME}_vfs_cfapi" - "${synclib_NAME}" + target_link_libraries(nextcloudsync_vfs_cfapi PRIVATE + Nextcloud::sync cldapi ) - set_target_properties("${synclib_NAME}_vfs_cfapi" PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} - PREFIX "" - AUTOMOC TRUE + set_target_properties(nextcloudsync_vfs_cfapi + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY + ${BIN_OUTPUT_DIRECTORY} + RUNTIME_OUTPUT_DIRECTORY + ${BIN_OUTPUT_DIRECTORY} + PREFIX + "" + AUTOMOC + TRUE + LIBRARY_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync_vfs_cfapi + RUNTIME_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync_vfs_cfapi ) - target_include_directories("${synclib_NAME}_vfs_cfapi" BEFORE PUBLIC ${CMAKE_CURRENT_BINARY_DIR} INTERFACE ${CMAKE_BINARY_DIR}) + target_include_directories("nextcloudsync_vfs_cfapi" BEFORE PUBLIC ${CMAKE_CURRENT_BINARY_DIR} INTERFACE ${CMAKE_BINARY_DIR}) set(vfs_installdir "${PLUGINDIR}") - GENERATE_EXPORT_HEADER( "${synclib_NAME}_vfs_cfapi" - BASE_NAME "${synclib_NAME}_vfs_cfapi" + generate_export_header(nextcloudsync_vfs_cfapi + BASE_NAME nextcloudsync_vfs_cfapi EXPORT_MACRO_NAME NEXTCLOUD_CFAPI_EXPORT EXPORT_FILE_NAME cfapiexport.h ) - INSTALL(TARGETS "${synclib_NAME}_vfs_cfapi" + install(TARGETS nextcloudsync_vfs_cfapi LIBRARY DESTINATION "${vfs_installdir}" RUNTIME DESTINATION "${vfs_installdir}" ) diff --git a/src/libsync/vfs/cfapi/cfapiwrapper.cpp b/src/libsync/vfs/cfapi/cfapiwrapper.cpp index 02ed7d362db0..8046cb18a412 100644 --- a/src/libsync/vfs/cfapi/cfapiwrapper.cpp +++ b/src/libsync/vfs/cfapi/cfapiwrapper.cpp @@ -499,7 +499,7 @@ OCC::Result OCC::CfApiWrapper::registerSyncRoot(const QString &pa const auto version = std::wstring(providerVersion.toStdWString().data()); CF_SYNC_REGISTRATION info; - info.StructSize = sizeof(info) + (name.length() + version.length()) * sizeof(wchar_t); + info.StructSize = static_cast(sizeof(info) + (name.length() + version.length()) * sizeof(wchar_t)); info.ProviderName = name.data(); info.ProviderVersion = version.data(); info.SyncRootIdentity = nullptr; @@ -618,6 +618,7 @@ OCC::CfApiWrapper::PlaceHolderInfo OCC::CfApiWrapper::findPlaceholderInfo(const if (result == S_OK) { return info; } else { + qCWarning(lcCfApiWrapper()) << "Couldn't get placeholder info" << QString::fromWCharArray(_com_error(result).ErrorMessage()); return {}; } } diff --git a/src/libsync/vfs/cfapi/hydrationjob.cpp b/src/libsync/vfs/cfapi/hydrationjob.cpp index 2031a8a01c38..12570ebe92f2 100644 --- a/src/libsync/vfs/cfapi/hydrationjob.cpp +++ b/src/libsync/vfs/cfapi/hydrationjob.cpp @@ -17,6 +17,9 @@ #include "common/syncjournaldb.h" #include "propagatedownload.h" #include "vfs/cfapi/vfs_cfapi.h" +#include + +#include "filesystem.h" #include #include @@ -88,6 +91,26 @@ void OCC::HydrationJob::setFolderPath(const QString &folderPath) _folderPath = folderPath; } +bool OCC::HydrationJob::isEncryptedFile() const +{ + return _isEncryptedFile; +} + +void OCC::HydrationJob::setIsEncryptedFile(bool isEncrypted) +{ + _isEncryptedFile = isEncrypted; +} + +QString OCC::HydrationJob::e2eMangledName() const +{ + return _e2eMangledName; +} + +void OCC::HydrationJob::setE2eMangledName(const QString &e2eMangledName) +{ + _e2eMangledName = e2eMangledName; +} + OCC::HydrationJob::Status OCC::HydrationJob::status() const { return _status; @@ -137,6 +160,70 @@ void OCC::HydrationJob::start() connect(_transferDataServer, &QLocalServer::newConnection, this, &HydrationJob::onNewConnection); } +void OCC::HydrationJob::slotFolderIdError() +{ + // TODO: the following code is borrowed from PropagateDownloadEncrypted (see HydrationJob::onNewConnection() for explanation of next steps) + qCCritical(lcHydration) << "Failed to get encrypted metadata of folder" << _requestId << _localPath << _folderPath; + emitFinished(Error); +} + +void OCC::HydrationJob::slotCheckFolderId(const QStringList &list) +{ + // TODO: the following code is borrowed from PropagateDownloadEncrypted (see HydrationJob::onNewConnection() for explanation of next steps) + auto job = qobject_cast(sender()); + const QString folderId = list.first(); + qCDebug(lcHydration) << "Received id of folder" << folderId; + + const ExtraFolderInfo &folderInfo = job->_folderInfos.value(folderId); + + // Now that we have the folder-id we need it's JSON metadata + auto metadataJob = new GetMetadataApiJob(_account, folderInfo.fileId); + connect(metadataJob, &GetMetadataApiJob::jsonReceived, + this, &HydrationJob::slotCheckFolderEncryptedMetadata); + connect(metadataJob, &GetMetadataApiJob::error, + this, &HydrationJob::slotFolderEncryptedMetadataError); + + metadataJob->start(); +} + +void OCC::HydrationJob::slotFolderEncryptedMetadataError(const QByteArray & /*fileId*/, int /*httpReturnCode*/) +{ + // TODO: the following code is borrowed from PropagateDownloadEncrypted (see HydrationJob::onNewConnection() for explanation of next steps) + qCCritical(lcHydration) << "Failed to find encrypted metadata information of remote file" << e2eMangledName(); + emitFinished(Error); + return; +} + +void OCC::HydrationJob::slotCheckFolderEncryptedMetadata(const QJsonDocument &json) +{ + // TODO: the following code is borrowed from PropagateDownloadEncrypted (see HydrationJob::onNewConnection() for explanation of next steps) + qCDebug(lcHydration) << "Metadata Received reading" << e2eMangledName(); + const QString filename = e2eMangledName(); + auto meta = new FolderMetadata(_account, json.toJson(QJsonDocument::Compact)); + const QVector files = meta->files(); + + EncryptedFile encryptedInfo = {}; + + const QString encryptedFileExactName = e2eMangledName().section(QLatin1Char('/'), -1); + for (const EncryptedFile &file : files) { + if (encryptedFileExactName == file.encryptedFilename) { + EncryptedFile encryptedInfo = file; + encryptedInfo = file; + + qCDebug(lcHydration) << "Found matching encrypted metadata for file, starting download" << _requestId << _folderPath; + _transferDataSocket = _transferDataServer->nextPendingConnection(); + _job = new GETEncryptedFileJob(_account, _remotePath + e2eMangledName(), _transferDataSocket, {}, {}, 0, encryptedInfo, this); + + connect(qobject_cast(_job), &GETEncryptedFileJob::finishedSignal, this, &HydrationJob::onGetFinished); + _job->start(); + return; + } + } + + qCCritical(lcHydration) << "Failed to find encrypted metadata information of a remote file" << filename; + emitFinished(Error); +} + void OCC::HydrationJob::cancel() { Q_ASSERT(_signalSocket); @@ -184,11 +271,11 @@ void OCC::HydrationJob::onNewConnection() Q_ASSERT(!_transferDataSocket); Q_ASSERT(!_job); - qCInfo(lcHydration) << "Got new connection starting GETFileJob" << _requestId << _folderPath; - _transferDataSocket = _transferDataServer->nextPendingConnection(); - _job = new GETFileJob(_account, _remotePath + _folderPath, _transferDataSocket, {}, {}, 0, this); - connect(_job, &GETFileJob::finishedSignal, this, &HydrationJob::onGetFinished); - _job->start(); + if (isEncryptedFile()) { + handleNewConnectionForEncryptedFile(); + } else { + handleNewConnection(); + } } void OCC::HydrationJob::finalize(OCC::VfsCfApi *vfs) @@ -214,6 +301,9 @@ void OCC::HydrationJob::finalize(OCC::VfsCfApi *vfs) } record._type = ItemTypeFile; + // store the actual size of a file that has been decrypted as we will need its actual size when dehydrating it if requested + record._fileSize = FileSystem::getSize(localPath() + folderPath()); + _journal->setFileRecord(record); } @@ -234,3 +324,38 @@ void OCC::HydrationJob::onGetFinished() } emitFinished(Success); } + +void OCC::HydrationJob::handleNewConnection() +{ + qCInfo(lcHydration) << "Got new connection starting GETFileJob" << _requestId << _folderPath; + _transferDataSocket = _transferDataServer->nextPendingConnection(); + _job = new GETFileJob(_account, _remotePath + _folderPath, _transferDataSocket, {}, {}, 0, this); + connect(_job, &GETFileJob::finishedSignal, this, &HydrationJob::onGetFinished); + _job->start(); +} + +void OCC::HydrationJob::handleNewConnectionForEncryptedFile() +{ + // TODO: the following code is borrowed from PropagateDownloadEncrypted (should we factor it out and reuse? YES! Should we do it now? Probably not, as, this would imply modifying PropagateDownloadEncrypted, so we need a separate PR) + qCInfo(lcHydration) << "Got new connection for encrypted file. Getting required info for decryption..."; + const auto rootPath = [=]() { + const auto result = _remotePath; + if (result.startsWith('/')) { + return result.mid(1); + } else { + return result; + } + }(); + + const auto remoteFilename = e2eMangledName(); + const auto remotePath = QString(rootPath + remoteFilename); + const auto remoteParentPath = remotePath.left(remotePath.lastIndexOf('/')); + + auto job = new LsColJob(_account, remoteParentPath, this); + job->setProperties({ "resourcetype", "http://owncloud.org/ns:fileid" }); + connect(job, &LsColJob::directoryListingSubfolders, + this, &HydrationJob::slotCheckFolderId); + connect(job, &LsColJob::finishedWithError, + this, &HydrationJob::slotFolderIdError); + job->start(); +} diff --git a/src/libsync/vfs/cfapi/hydrationjob.h b/src/libsync/vfs/cfapi/hydrationjob.h index 2425881209f1..c13cd7b5021a 100644 --- a/src/libsync/vfs/cfapi/hydrationjob.h +++ b/src/libsync/vfs/cfapi/hydrationjob.h @@ -25,6 +25,10 @@ class GETFileJob; class SyncJournalDb; class VfsCfApi; +namespace EncryptionHelper { + class StreamingDecryptor; +}; + class HydrationJob : public QObject { Q_OBJECT @@ -56,12 +60,27 @@ class HydrationJob : public QObject QString folderPath() const; void setFolderPath(const QString &folderPath); + bool isEncryptedFile() const; + void setIsEncryptedFile(bool isEncrypted); + + QString e2eMangledName() const; + void setE2eMangledName(const QString &e2eMangledName); + + qint64 fileTotalSize() const; + void setFileTotalSize(qint64 totalSize); + Status status() const; void start(); void cancel(); void finalize(OCC::VfsCfApi *vfs); +public slots: + void slotCheckFolderId(const QStringList &list); + void slotFolderIdError(); + void slotCheckFolderEncryptedMetadata(const QJsonDocument &json); + void slotFolderEncryptedMetadataError(const QByteArray &fileId, int httpReturnCode); + signals: void finished(HydrationJob *job); @@ -72,6 +91,11 @@ class HydrationJob : public QObject void onCancellationServerNewConnection(); void onGetFinished(); + void handleNewConnection(); + void handleNewConnectionForEncryptedFile(); + + void startServerAndWaitForConnections(); + AccountPtr _account; QString _remotePath; QString _localPath; @@ -81,6 +105,9 @@ class HydrationJob : public QObject QString _requestId; QString _folderPath; + bool _isEncryptedFile = false; + QString _e2eMangledName; + QLocalServer *_transferDataServer = nullptr; QLocalServer *_signalServer = nullptr; QLocalSocket *_transferDataSocket = nullptr; diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.cpp b/src/libsync/vfs/cfapi/vfs_cfapi.cpp index d332480afd89..76e3c446d53c 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.cpp +++ b/src/libsync/vfs/cfapi/vfs_cfapi.cpp @@ -16,7 +16,6 @@ #include #include -#include #include "cfapiwrapper.h" #include "hydrationjob.h" @@ -323,28 +322,8 @@ void VfsCfApi::requestHydration(const QString &requestId, const QString &path) return; } - // This is impossible to handle with CfAPI since the file size is generally different - // between the encrypted and the decrypted file which would make CfAPI reject the hydration - // of the placeholder with decrypted data - if (record._isE2eEncrypted || !record._e2eMangledName.isEmpty()) { - qCInfo(lcCfApi) << "Couldn't hydrate, the file is E2EE this is not supported"; - - QMessageBox e2eeFileDownloadRequestWarningMsgBox; - e2eeFileDownloadRequestWarningMsgBox.setText(tr("Download of end-to-end encrypted file failed")); - e2eeFileDownloadRequestWarningMsgBox.setInformativeText(tr("It seems that you are trying to download a virtual file that" - " is end-to-end encrypted. Implicitly downloading such files is not" - " supported at the moment. To workaround this issue, go to the" - " settings and mark the encrypted folder with \"Make always available" - " locally\".")); - e2eeFileDownloadRequestWarningMsgBox.setIcon(QMessageBox::Warning); - e2eeFileDownloadRequestWarningMsgBox.exec(); - - emit hydrationRequestFailed(requestId); - return; - } - // All good, let's hydrate now - scheduleHydrationJob(requestId, relativePath); + scheduleHydrationJob(requestId, relativePath, record); } void VfsCfApi::fileStatusChanged(const QString &systemFileName, SyncFileStatus fileStatus) @@ -353,7 +332,7 @@ void VfsCfApi::fileStatusChanged(const QString &systemFileName, SyncFileStatus f Q_UNUSED(fileStatus); } -void VfsCfApi::scheduleHydrationJob(const QString &requestId, const QString &folderPath) +void VfsCfApi::scheduleHydrationJob(const QString &requestId, const QString &folderPath, const SyncJournalFileRecord &record) { const auto jobAlreadyScheduled = std::any_of(std::cbegin(d->hydrationJobs), std::cend(d->hydrationJobs), [=](HydrationJob *job) { return job->requestId() == requestId || job->folderPath() == folderPath; @@ -376,6 +355,8 @@ void VfsCfApi::scheduleHydrationJob(const QString &requestId, const QString &fol job->setJournal(params().journal); job->setRequestId(requestId); job->setFolderPath(folderPath); + job->setIsEncryptedFile(record._isE2eEncrypted); + job->setE2eMangledName(record._e2eMangledName); connect(job, &HydrationJob::finished, this, &VfsCfApi::onHydrationJobFinished); d->hydrationJobs << job; job->start(); diff --git a/src/libsync/vfs/cfapi/vfs_cfapi.h b/src/libsync/vfs/cfapi/vfs_cfapi.h index faa15d559a22..23053415a6ab 100644 --- a/src/libsync/vfs/cfapi/vfs_cfapi.h +++ b/src/libsync/vfs/cfapi/vfs_cfapi.h @@ -22,6 +22,7 @@ namespace OCC { class HydrationJob; class VfsCfApiPrivate; +class SyncJournalFileRecord; class VfsCfApi : public Vfs { @@ -71,7 +72,7 @@ public slots: void startImpl(const VfsSetupParams ¶ms) override; private: - void scheduleHydrationJob(const QString &requestId, const QString &folderPath); + void scheduleHydrationJob(const QString &requestId, const QString &folderPath, const SyncJournalFileRecord &record); void onHydrationJobFinished(HydrationJob *job); HydrationJob *findHydrationJob(const QString &requestId) const; diff --git a/src/libsync/vfs/suffix/CMakeLists.txt b/src/libsync/vfs/suffix/CMakeLists.txt index 92426a5fb9dd..bb326c4ad146 100644 --- a/src/libsync/vfs/suffix/CMakeLists.txt +++ b/src/libsync/vfs/suffix/CMakeLists.txt @@ -1,22 +1,29 @@ -add_library("${synclib_NAME}_vfs_suffix" SHARED +add_library(nextcloudsync_vfs_suffix SHARED vfs_suffix.cpp ) -target_link_libraries("${synclib_NAME}_vfs_suffix" - "${synclib_NAME}" -) +target_link_libraries(nextcloudsync_vfs_suffix PRIVATE Nextcloud::sync) -set_target_properties("${synclib_NAME}_vfs_suffix" PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} - PREFIX "" - AUTOMOC TRUE +set_target_properties(nextcloudsync_vfs_suffix + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY + ${BIN_OUTPUT_DIRECTORY} + RUNTIME_OUTPUT_DIRECTORY + ${BIN_OUTPUT_DIRECTORY} + PREFIX + "" + AUTOMOC + TRUE + LIBRARY_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync_vfs_suffix + RUNTIME_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync_vfs_suffix ) if(APPLE) # for being loadable when client run from build dir set(vfs_buildoutputdir "${BIN_OUTPUT_DIRECTORY}/${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns/") - set_target_properties("${synclib_NAME}_vfs_suffix" + set_target_properties(nextcloudsync_vfs_suffix PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${vfs_buildoutputdir} RUNTIME_OUTPUT_DIRECTORY ${vfs_buildoutputdir} @@ -27,7 +34,7 @@ else() set(vfs_installdir "${PLUGINDIR}") endif() -INSTALL(TARGETS "${synclib_NAME}_vfs_suffix" +install(TARGETS nextcloudsync_vfs_suffix LIBRARY DESTINATION "${vfs_installdir}" RUNTIME DESTINATION "${vfs_installdir}" ) diff --git a/src/libsync/vfs/suffix/vfs_suffix.h b/src/libsync/vfs/suffix/vfs_suffix.h index 8ac8c1217a00..e3ddaed69350 100644 --- a/src/libsync/vfs/suffix/vfs_suffix.h +++ b/src/libsync/vfs/suffix/vfs_suffix.h @@ -27,7 +27,7 @@ class VfsSuffix : public Vfs public: explicit VfsSuffix(QObject *parent = nullptr); - ~VfsSuffix(); + ~VfsSuffix() override; Mode mode() const override; QString fileSuffix() const override; diff --git a/src/libsync/vfs/xattr/CMakeLists.txt b/src/libsync/vfs/xattr/CMakeLists.txt index ae6fe7abfcb1..877d2635a8bf 100644 --- a/src/libsync/vfs/xattr/CMakeLists.txt +++ b/src/libsync/vfs/xattr/CMakeLists.txt @@ -4,27 +4,34 @@ if (LINUX) xattrwrapper_linux.cpp ) - add_library("${synclib_NAME}_vfs_xattr" SHARED + add_library(nextcloudsync_vfs_xattr SHARED ${vfs_xattr_SRCS} ) - target_link_libraries("${synclib_NAME}_vfs_xattr" - "${synclib_NAME}" - ) + target_link_libraries(nextcloudsync_vfs_xattr PRIVATE Nextcloud::sync) - set_target_properties("${synclib_NAME}_vfs_xattr" PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} - RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} - PREFIX "" - AUTOMOC TRUE + set_target_properties(nextcloudsync_vfs_xattr + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY + ${BIN_OUTPUT_DIRECTORY} + RUNTIME_OUTPUT_DIRECTORY + ${BIN_OUTPUT_DIRECTORY} + PREFIX + "" + AUTOMOC + TRUE + LIBRARY_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync_vfs_xattr + RUNTIME_OUTPUT_NAME + ${APPLICATION_EXECUTABLE}sync_vfs_xattr ) - target_include_directories("${synclib_NAME}_vfs_xattr" BEFORE PUBLIC ${CMAKE_CURRENT_BINARY_DIR} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) + target_include_directories(nextcloudsync_vfs_xattr BEFORE PUBLIC ${CMAKE_CURRENT_BINARY_DIR} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}) if(APPLE) # for being loadable when client run from build dir set(vfs_buildoutputdir "${BIN_OUTPUT_DIRECTORY}/${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns/") - set_target_properties("${synclib_NAME}_vfs_xattr" + set_target_properties(nextcloudsync_vfs_xattr PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${vfs_buildoutputdir} RUNTIME_OUTPUT_DIRECTORY ${vfs_buildoutputdir} @@ -35,13 +42,13 @@ if (LINUX) set(vfs_installdir "${PLUGINDIR}") endif() - GENERATE_EXPORT_HEADER( "${synclib_NAME}_vfs_xattr" - BASE_NAME "${synclib_NAME}_vfs_xattr" + generate_export_header(nextcloudsync_vfs_xattr + BASE_NAME nextcloudsync_vfs_xattr EXPORT_MACRO_NAME NEXTCLOUD_XATTR_EXPORT EXPORT_FILE_NAME xattrexport.h ) - INSTALL(TARGETS "${synclib_NAME}_vfs_xattr" + install(TARGETS nextcloudsync_vfs_xattr LIBRARY DESTINATION "${vfs_installdir}" RUNTIME DESTINATION "${vfs_installdir}" ) diff --git a/src/libsync/vfs/xattr/vfs_xattr.h b/src/libsync/vfs/xattr/vfs_xattr.h index 745ad8ef95c4..2170a42a775b 100644 --- a/src/libsync/vfs/xattr/vfs_xattr.h +++ b/src/libsync/vfs/xattr/vfs_xattr.h @@ -27,7 +27,7 @@ class VfsXAttr : public Vfs public: explicit VfsXAttr(QObject *parent = nullptr); - ~VfsXAttr(); + ~VfsXAttr() override; Mode mode() const override; QString fileSuffix() const override; diff --git a/sync-exclude.lst b/sync-exclude.lst index 0c56e7b6731d..f54d68776f0e 100644 --- a/sync-exclude.lst +++ b/sync-exclude.lst @@ -22,6 +22,7 @@ System Volume Information ].Trash-* .fseventd .apdisk +.Spotlight-V100 .directory diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b5272134acf7..987fb8c9f4f5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,7 +12,7 @@ add_library(testutils testhelper.cpp ) -target_link_libraries(testutils PUBLIC ${APPLICATION_EXECUTABLE}sync Qt5::Test) +target_link_libraries(testutils PUBLIC Nextcloud::sync Qt5::Test) target_include_directories(testutils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties(testutils PROPERTIES FOLDER Tests) @@ -57,7 +57,10 @@ nextcloud_add_test(FolderWatcher) nextcloud_add_test(Capabilities) nextcloud_add_test(PushNotifications) nextcloud_add_test(Theme) +nextcloud_add_test(IconUtils) nextcloud_add_test(NotificationCache) +nextcloud_add_test(SetUserStatusDialog) +nextcloud_add_test(UnifiedSearchListmodel) if( UNIX AND NOT APPLE ) nextcloud_add_test(InotifyWatcher) @@ -68,12 +71,12 @@ if (WIN32) ${CMAKE_BINARY_DIR}/src/libsync/vfs/cfapi ) - nextcloud_add_test(LongWinPath) nextcloud_add_test(SyncCfApi) elseif(LINUX) # elseif(LINUX OR APPLE) nextcloud_add_test(SyncXAttr) endif() +nextcloud_add_test(LongPath) nextcloud_add_benchmark(LargeSync) nextcloud_add_test(Account) diff --git a/test/csync/CMakeLists.txt b/test/csync/CMakeLists.txt index e2b7796b8625..a621e5f95840 100644 --- a/test/csync/CMakeLists.txt +++ b/test/csync/CMakeLists.txt @@ -14,7 +14,7 @@ include_directories( add_library(${TORTURE_LIBRARY} STATIC torture.c cmdline.c) target_link_libraries(${TORTURE_LIBRARY} ${CMOCKA_LIBRARIES}) -set(TEST_TARGET_LIBRARIES ${TORTURE_LIBRARY} Qt5::Core "${csync_NAME}") +set(TEST_TARGET_LIBRARIES ${TORTURE_LIBRARY} Qt5::Core Nextcloud::csync) # create tests diff --git a/test/mockserver/httpserver.cpp b/test/mockserver/httpserver.cpp index fbc24e8474ca..43a4c81ce06b 100644 --- a/test/mockserver/httpserver.cpp +++ b/test/mockserver/httpserver.cpp @@ -24,7 +24,7 @@ void HttpServer::readClient() { QTcpSocket* socket = (QTcpSocket*)sender(); if (socket->canReadLine()) { - QStringList tokens = QString(socket->readLine()).split(QRegExp("[ \r\n][ \r\n]*")); + QStringList tokens = QString(socket->readLine()).split(QRegularExpression("[ \r\n][ \r\n]*")); if (tokens[0] == "GET") { QTextStream os(socket); os.setAutoDetectUnicode(true); diff --git a/test/nextcloud_add_test.cmake b/test/nextcloud_add_test.cmake index f7a6572b3f73..98f3ef7673cd 100644 --- a/test/nextcloud_add_test.cmake +++ b/test/nextcloud_add_test.cmake @@ -8,8 +8,8 @@ macro(nextcloud_add_test test_class) add_executable(${OWNCLOUD_TEST_CLASS}Test test${OWNCLOUD_TEST_CLASS_LOWERCASE}.cpp) set_target_properties(${OWNCLOUD_TEST_CLASS}Test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) - target_link_libraries(${OWNCLOUD_TEST_CLASS}Test - ${APPLICATION_EXECUTABLE}sync + target_link_libraries(${OWNCLOUD_TEST_CLASS}Test PRIVATE + Nextcloud::sync testutils nextcloudCore cmdCore @@ -18,19 +18,19 @@ macro(nextcloud_add_test test_class) ) if (WIN32) - target_link_libraries(${OWNCLOUD_TEST_CLASS}Test - "${synclib_NAME}_vfs_cfapi" + target_link_libraries(${OWNCLOUD_TEST_CLASS}Test PRIVATE + nextcloudsync_vfs_cfapi ) endif() - if (UNIX) - target_link_libraries(${OWNCLOUD_TEST_CLASS}Test - "${synclib_NAME}_vfs_xattr" + if (LINUX) + target_link_libraries(${OWNCLOUD_TEST_CLASS}Test PRIVATE + nextcloudsync_vfs_xattr ) endif() IF(BUILD_UPDATER) - target_link_libraries(${OWNCLOUD_TEST_CLASS}Test + target_link_libraries(${OWNCLOUD_TEST_CLASS}Test PRIVATE updater ) endif() @@ -58,7 +58,7 @@ macro(nextcloud_add_benchmark test_class) set_target_properties(${OWNCLOUD_TEST_CLASS}Bench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}) target_link_libraries(${OWNCLOUD_TEST_CLASS}Bench - ${APPLICATION_EXECUTABLE}sync + Nextcloud::sync testutils nextcloudCore cmdCore diff --git a/test/pushnotificationstestutils.h b/test/pushnotificationstestutils.h index f1eca050f904..57e56831e05e 100644 --- a/test/pushnotificationstestutils.h +++ b/test/pushnotificationstestutils.h @@ -29,7 +29,7 @@ class FakeWebSocketServer : public QObject public: explicit FakeWebSocketServer(quint16 port = 12345, QObject *parent = nullptr); - ~FakeWebSocketServer(); + ~FakeWebSocketServer() override; QWebSocket *authenticateAccount( const OCC::AccountPtr account, std::function beforeAuthentication = [](OCC::PushNotifications *) {}, std::function afterAuthentication = [] {}); @@ -70,18 +70,18 @@ class CredentialsStub : public OCC::AbstractCredentials public: CredentialsStub(const QString &user, const QString &password); - virtual QString authType() const; - virtual QString user() const; - virtual QString password() const; - virtual QNetworkAccessManager *createQNAM() const; - virtual bool ready() const; - virtual void fetchFromKeychain(); - virtual void askFromUser(); - - virtual bool stillValid(QNetworkReply *reply); - virtual void persist(); - virtual void invalidateToken(); - virtual void forgetSensitiveData(); + QString authType() const override; + QString user() const override; + QString password() const override; + QNetworkAccessManager *createQNAM() const override; + bool ready() const override; + void fetchFromKeychain() override; + void askFromUser() override; + + bool stillValid(QNetworkReply *reply) override; + void persist() override; + void invalidateToken() override; + void forgetSensitiveData() override; private: QString _user; diff --git a/test/syncenginetestutils.cpp b/test/syncenginetestutils.cpp index 19a87dd35ffb..8b8f58871b20 100644 --- a/test/syncenginetestutils.cpp +++ b/test/syncenginetestutils.cpp @@ -20,7 +20,7 @@ PathComponents::PathComponents(const char *path) } PathComponents::PathComponents(const QString &path) - : QStringList { path.split(QLatin1Char('/'), QString::SkipEmptyParts) } + : QStringList { path.split(QLatin1Char('/'), Qt::SkipEmptyParts) } { } @@ -243,6 +243,15 @@ QString FileInfo::path() const return (parentPath.isEmpty() ? QString() : (parentPath + QLatin1Char('/'))) + name; } +QString FileInfo::absolutePath() const +{ + if (parentPath.endsWith(QLatin1Char('/'))) { + return parentPath + name; + } else { + return parentPath + QLatin1Char('/') + name; + } +} + void FileInfo::fixupParentPathRecursively() { auto p = path(); @@ -273,7 +282,7 @@ FakePropfindReply::FakePropfindReply(FileInfo &remoteRootFileInfo, QNetworkAcces QMetaObject::invokeMethod(this, "respond404", Qt::QueuedConnection); return; } - QString prefix = request.url().path().left(request.url().path().size() - fileName.size()); + const QString prefix = request.url().path().left(request.url().path().size() - fileName.size()); // Don't care about the request and just return a full propfind const QString davUri { QStringLiteral("DAV:") }; @@ -288,11 +297,12 @@ FakePropfindReply::FakePropfindReply(FileInfo &remoteRootFileInfo, QNetworkAcces auto writeFileResponse = [&](const FileInfo &fileInfo) { xml.writeStartElement(davUri, QStringLiteral("response")); - QString url = prefix + QString::fromUtf8(QUrl::toPercentEncoding(fileInfo.path(), "/")); + auto url = QString::fromUtf8(QUrl::toPercentEncoding(fileInfo.absolutePath(), "/")); if (!url.endsWith(QChar('/'))) { url.append(QChar('/')); } - xml.writeTextElement(davUri, QStringLiteral("href"), url); + const auto href = OCC::Utility::concatUrlPath(prefix, url).path(); + xml.writeTextElement(davUri, QStringLiteral("href"), href); xml.writeStartElement(davUri, QStringLiteral("propstat")); xml.writeStartElement(davUri, QStringLiteral("prop")); @@ -488,9 +498,11 @@ FakeGetReply::FakeGetReply(FileInfo &remoteRootFileInfo, QNetworkAccessManager:: QString fileName = getFilePathFromUrl(request.url()); Q_ASSERT(!fileName.isEmpty()); fileInfo = remoteRootFileInfo.find(fileName); - if (!fileInfo) - qWarning() << "Could not find file" << fileName << "on the remote"; - QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection); + if (!fileInfo) { + qDebug() << "meh;"; + } + Q_ASSERT_X(fileInfo, Q_FUNC_INFO, "Could not find file on the remote"); + QMetaObject::invokeMethod(this, &FakeGetReply::respond, Qt::QueuedConnection); } void FakeGetReply::respond() @@ -697,14 +709,20 @@ void FakeChunkMoveReply::abort() } FakePayloadReply::FakePayloadReply(QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &body, QObject *parent) - : FakeReply { parent } + : FakePayloadReply(op, request, body, FakePayloadReply::defaultDelay, parent) +{ +} + +FakePayloadReply::FakePayloadReply( + QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &body, int delay, QObject *parent) + : FakeReply{parent} , _body(body) { setRequest(request); setUrl(request.url()); setOperation(op); open(QIODevice::ReadOnly); - QTimer::singleShot(10, this, &FakePayloadReply::respond); + QTimer::singleShot(delay, this, &FakePayloadReply::respond); } void FakePayloadReply::respond() @@ -740,7 +758,7 @@ FakeErrorReply::FakeErrorReply(QNetworkAccessManager::Operation op, const QNetwo open(QIODevice::ReadOnly); setAttribute(QNetworkRequest::HttpStatusCodeAttribute, httpErrorCode); setError(InternalServerError, QStringLiteral("Internal Server Fake Error")); - QMetaObject::invokeMethod(this, "respond", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, &FakeErrorReply::respond, Qt::QueuedConnection); } void FakeErrorReply::respond() @@ -784,7 +802,7 @@ void FakeHangingReply::abort() // Follow more or less the implementation of QNetworkReplyImpl::abort close(); setError(OperationCanceledError, tr("Operation canceled")); - emit error(OperationCanceledError); + emit errorOccurred(OperationCanceledError); setFinished(true); emit finished(); } @@ -1041,6 +1059,19 @@ OCC::SyncFileItemPtr ItemCompletedSpy::findItem(const QString &path) const return OCC::SyncFileItemPtr::create(); } +OCC::SyncFileItemPtr ItemCompletedSpy::findItemWithExpectedRank(const QString &path, int rank) const +{ + Q_ASSERT(size() > rank); + Q_ASSERT(!(*this)[rank].isEmpty()); + + auto item = (*this)[rank][0].value(); + if (item->destination() == path) { + return item; + } else { + return OCC::SyncFileItemPtr::create(); + } +} + FakeReply::FakeReply(QObject *parent) : QNetworkReply(parent) { diff --git a/test/syncenginetestutils.h b/test/syncenginetestutils.h index 2c2051eec50e..0fdfb22dffe6 100644 --- a/test/syncenginetestutils.h +++ b/test/syncenginetestutils.h @@ -52,10 +52,10 @@ inline QString getFilePathFromUrl(const QUrl &url) inline QByteArray generateEtag() { - return QByteArray::number(QDateTime::currentDateTimeUtc().toMSecsSinceEpoch(), 16) + QByteArray::number(qrand(), 16); + return QByteArray::number(QDateTime::currentDateTimeUtc().toMSecsSinceEpoch(), 16) + QByteArray::number(OCC::Utility::rand(), 16); } inline QByteArray generateFileId() { - return QByteArray::number(qrand(), 16); + return QByteArray::number(OCC::Utility::rand(), 16); } class PathComponents : public QStringList { @@ -143,6 +143,7 @@ class FileInfo : public FileModifier } QString path() const; + QString absolutePath() const; void fixupParentPathRecursively(); @@ -174,7 +175,7 @@ class FakeReply : public QNetworkReply Q_OBJECT public: FakeReply(QObject *parent); - virtual ~FakeReply(); + ~FakeReply() override; // useful to be public for testing using QNetworkReply::setRawHeader; @@ -315,12 +316,17 @@ class FakePayloadReply : public FakeReply FakePayloadReply(QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &body, QObject *parent); + FakePayloadReply(QNetworkAccessManager::Operation op, const QNetworkRequest &request, + const QByteArray &body, int delay, QObject *parent); + void respond(); void abort() override {} qint64 readData(char *buf, qint64 max) override; qint64 bytesAvailable() const override; QByteArray _body; + + static const int defaultDelay = 10; }; @@ -413,17 +419,17 @@ class FakeCredentials : public OCC::AbstractCredentials QNetworkAccessManager *_qnam; public: FakeCredentials(QNetworkAccessManager *qnam) : _qnam{qnam} { } - virtual QString authType() const { return "test"; } - virtual QString user() const { return "admin"; } - virtual QString password() const { return "password"; } - virtual QNetworkAccessManager *createQNAM() const { return _qnam; } - virtual bool ready() const { return true; } - virtual void fetchFromKeychain() { } - virtual void askFromUser() { } - virtual bool stillValid(QNetworkReply *) { return true; } - virtual void persist() { } - virtual void invalidateToken() { } - virtual void forgetSensitiveData() { } + QString authType() const override { return "test"; } + QString user() const override { return "admin"; } + QString password() const override { return "password"; } + QNetworkAccessManager *createQNAM() const override { return _qnam; } + bool ready() const override { return true; } + void fetchFromKeychain() override { } + void askFromUser() override { } + bool stillValid(QNetworkReply *) override { return true; } + void persist() override { } + void invalidateToken() override { } + void forgetSensitiveData() override { } }; class FakeFolder @@ -510,6 +516,8 @@ struct ItemCompletedSpy : QSignalSpy { {} OCC::SyncFileItemPtr findItem(const QString &path) const; + + OCC::SyncFileItemPtr findItemWithExpectedRank(const QString &path, int rank) const; }; // QTest::toString overloads diff --git a/test/testcapabilities.cpp b/test/testcapabilities.cpp index 1d85d0a375a8..1c8e9bac2861 100644 --- a/test/testcapabilities.cpp +++ b/test/testcapabilities.cpp @@ -138,6 +138,111 @@ private slots: QCOMPARE(capabilities.pushNotificationsWebSocketUrl(), websocketUrl); } + + void testUserStatus_userStatusAvailable_returnTrue() + { + QVariantMap userStatusMap; + userStatusMap["enabled"] = true; + + QVariantMap capabilitiesMap; + capabilitiesMap["user_status"] = userStatusMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + + QVERIFY(capabilities.userStatus()); + } + + void testUserStatus_userStatusNotAvailable_returnFalse() + { + QVariantMap userStatusMap; + userStatusMap["enabled"] = false; + + QVariantMap capabilitiesMap; + capabilitiesMap["user_status"] = userStatusMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + + QVERIFY(!capabilities.userStatus()); + } + + void testUserStatus_userStatusNotInCapabilites_returnFalse() + { + QVariantMap capabilitiesMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + + QVERIFY(!capabilities.userStatus()); + } + + void testUserStatusSupportsEmoji_supportsEmojiAvailable_returnTrue() + { + QVariantMap userStatusMap; + userStatusMap["enabled"] = true; + userStatusMap["supports_emoji"] = true; + + QVariantMap capabilitiesMap; + capabilitiesMap["user_status"] = userStatusMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + + QVERIFY(capabilities.userStatus()); + } + + void testUserStatusSupportsEmoji_supportsEmojiNotAvailable_returnFalse() + { + QVariantMap userStatusMap; + userStatusMap["enabled"] = true; + userStatusMap["supports_emoji"] = false; + + QVariantMap capabilitiesMap; + capabilitiesMap["user_status"] = userStatusMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + + QVERIFY(!capabilities.userStatusSupportsEmoji()); + } + + void testUserStatusSupportsEmoji_supportsEmojiNotInCapabilites_returnFalse() + { + QVariantMap userStatusMap; + userStatusMap["enabled"] = true; + + QVariantMap capabilitiesMap; + capabilitiesMap["user_status"] = userStatusMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + + QVERIFY(!capabilities.userStatusSupportsEmoji()); + } + + void testShareDefaultPermissions_defaultSharePermissionsNotInCapabilities_returnZero() + { + QVariantMap filesSharingMap; + filesSharingMap["api_enabled"] = false; + + QVariantMap capabilitiesMap; + capabilitiesMap["files_sharing"] = filesSharingMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + const auto defaultSharePermissionsNotInCapabilities = capabilities.shareDefaultPermissions(); + + QCOMPARE(defaultSharePermissionsNotInCapabilities, {}); + } + + void testShareDefaultPermissions_defaultSharePermissionsAvailable_returnPermissions() + { + QVariantMap filesSharingMap; + filesSharingMap["api_enabled"] = true; + filesSharingMap["default_permissions"] = 31; + + QVariantMap capabilitiesMap; + capabilitiesMap["files_sharing"] = filesSharingMap; + + const OCC::Capabilities capabilities(capabilitiesMap); + const auto defaultSharePermissionsAvailable = capabilities.shareDefaultPermissions(); + + QCOMPARE(defaultSharePermissionsAvailable, 31); + } }; QTEST_GUILESS_MAIN(TestCapabilities) diff --git a/test/testclientsideencryption.cpp b/test/testclientsideencryption.cpp index 2b0ea5a2cde2..a2115561d909 100644 --- a/test/testclientsideencryption.cpp +++ b/test/testclientsideencryption.cpp @@ -6,6 +6,11 @@ #include +#include +#include + +#include + #include "clientsideencryption.h" using namespace OCC; @@ -132,6 +137,116 @@ private slots: // THEN QCOMPARE(data, originalData); } + + void testStreamingDecryptor_data() + { + QTest::addColumn("totalBytes"); + QTest::addColumn("bytesToRead"); + + QTest::newRow("data1") << 64 << 2; + QTest::newRow("data2") << 32 << 8; + QTest::newRow("data3") << 76 << 64; + QTest::newRow("data4") << 272 << 256; + } + + void testStreamingDecryptor() + { + QFETCH(int, totalBytes); + + QTemporaryFile dummyInputFile; + + QVERIFY(dummyInputFile.open()); + + const auto dummyFileRandomContents = EncryptionHelper::generateRandom(totalBytes); + + QCOMPARE(dummyInputFile.write(dummyFileRandomContents), dummyFileRandomContents.size()); + + const auto generateHash = [](const QByteArray &data) { + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(data); + return hash.result(); + }; + + const QByteArray originalFileHash = generateHash(dummyFileRandomContents); + + QVERIFY(!originalFileHash.isEmpty()); + + dummyInputFile.close(); + QVERIFY(!dummyInputFile.isOpen()); + + const auto encryptionKey = EncryptionHelper::generateRandom(16); + const auto initializationVector = EncryptionHelper::generateRandom(16); + + // test normal file encryption/decryption + QTemporaryFile dummyEncryptionOutputFile; + + QByteArray tag; + + QVERIFY(EncryptionHelper::fileEncryption(encryptionKey, initializationVector, &dummyInputFile, &dummyEncryptionOutputFile, tag)); + dummyInputFile.close(); + QVERIFY(!dummyInputFile.isOpen()); + + dummyEncryptionOutputFile.close(); + QVERIFY(!dummyEncryptionOutputFile.isOpen()); + + QTemporaryFile dummyDecryptionOutputFile; + + QVERIFY(EncryptionHelper::fileDecryption(encryptionKey, initializationVector, &dummyEncryptionOutputFile, &dummyDecryptionOutputFile)); + QVERIFY(dummyDecryptionOutputFile.open()); + const auto dummyDecryptionOutputFileHash = generateHash(dummyDecryptionOutputFile.readAll()); + QCOMPARE(dummyDecryptionOutputFileHash, originalFileHash); + + // test streaming decryptor + EncryptionHelper::StreamingDecryptor streamingDecryptor(encryptionKey, initializationVector, dummyEncryptionOutputFile.size()); + QVERIFY(streamingDecryptor.isInitialized()); + + QBuffer chunkedOutputDecrypted; + QVERIFY(chunkedOutputDecrypted.open(QBuffer::WriteOnly)); + + QVERIFY(dummyEncryptionOutputFile.open()); + + QByteArray pendingBytes; + + QFETCH(int, bytesToRead); + + while (dummyEncryptionOutputFile.pos() < dummyEncryptionOutputFile.size()) { + const auto bytesRemaining = dummyEncryptionOutputFile.size() - dummyEncryptionOutputFile.pos(); + auto toRead = bytesRemaining > bytesToRead ? bytesToRead : bytesRemaining; + + if (dummyEncryptionOutputFile.pos() + toRead > dummyEncryptionOutputFile.size()) { + toRead = dummyEncryptionOutputFile.size() - dummyEncryptionOutputFile.pos(); + } + + if (bytesRemaining - toRead != 0 && bytesRemaining - toRead < OCC::Constants::e2EeTagSize) { + // decryption is going to fail if last chunk does not include or does not equal to OCC::Constants::e2EeTagSize bytes tag + // since we are emulating random size of network packets, we may end up reading beyond OCC::Constants::e2EeTagSize bytes tag at the end + // in that case, we don't want to try and decrypt less than OCC::Constants::e2EeTagSize ending bytes of tag, we will accumulate all the incoming data till the end + // and then, we are going to decrypt the entire chunk containing OCC::Constants::e2EeTagSize bytes at the end + pendingBytes += dummyEncryptionOutputFile.read(bytesRemaining); + continue; + } + + const auto decryptedChunk = streamingDecryptor.chunkDecryption(dummyEncryptionOutputFile.read(toRead).constData(), toRead); + + QVERIFY(decryptedChunk.size() == toRead || streamingDecryptor.isFinished() || !pendingBytes.isEmpty()); + + chunkedOutputDecrypted.write(decryptedChunk); + } + + if (!pendingBytes.isEmpty()) { + const auto decryptedChunk = streamingDecryptor.chunkDecryption(pendingBytes.constData(), pendingBytes.size()); + + QVERIFY(decryptedChunk.size() == pendingBytes.size() || streamingDecryptor.isFinished()); + + chunkedOutputDecrypted.write(decryptedChunk); + } + + chunkedOutputDecrypted.close(); + + QVERIFY(chunkedOutputDecrypted.open(QBuffer::ReadOnly)); + QCOMPARE(generateHash(chunkedOutputDecrypted.readAll()), originalFileHash); + chunkedOutputDecrypted.close(); + } }; QTEST_APPLESS_MAIN(TestClientSideEncryption) diff --git a/test/testcookies.cpp b/test/testcookies.cpp index a5053abd9c1b..eead47953384 100644 --- a/test/testcookies.cpp +++ b/test/testcookies.cpp @@ -21,7 +21,7 @@ private slots: const QString nonexistingPath = tmp.filePath("someNonexistingDir/test.db"); QNetworkCookie cookieA = QNetworkCookie("foo", "bar"); // tomorrow rounded - cookieA.setExpirationDate(QDateTime(QDateTime::currentDateTimeUtc().addDays(1).date())); + cookieA.setExpirationDate(QDateTime::currentDateTimeUtc().addDays(1).date().startOfDay()); const QList cookies = {cookieA, QNetworkCookie("foo2", "bar")}; CookieJar jar; jar.setAllCookies(cookies); diff --git a/test/testexcludedfiles.cpp b/test/testexcludedfiles.cpp index ba48e5c2c813..c044f5e59964 100644 --- a/test/testexcludedfiles.cpp +++ b/test/testexcludedfiles.cpp @@ -265,7 +265,7 @@ private slots: QCOMPARE(excludeList.write("bar"), 3); excludeList.close(); - excludedFiles->addInTreeExcludeFilePath(fooExcludeList); + excludedFiles->addExcludeFilePath(fooExcludeList); excludedFiles->reloadExcludeFiles(); QCOMPARE(check_file_full(QByteArray(fooDir.toUtf8() + "/bar")), CSYNC_FILE_EXCLUDE_LIST); QCOMPARE(check_file_full(QByteArray(fooDir.toUtf8() + "/baz")), CSYNC_NOT_EXCLUDED); @@ -322,7 +322,7 @@ private slots: QCOMPARE(check_file_traversal("subdir/.sync_5bdd60bdfcfa.db"), CSYNC_FILE_SILENTLY_EXCLUDED); /* Other builtin excludes */ - QCOMPARE(check_file_traversal("foo/Desktop.ini"), CSYNC_NOT_EXCLUDED); + QCOMPARE(check_file_traversal("foo/Desktop.ini"), CSYNC_FILE_SILENTLY_EXCLUDED); QCOMPARE(check_file_traversal("Desktop.ini"), CSYNC_FILE_SILENTLY_EXCLUDED); /* pattern ]*.directory - ignore and remove */ @@ -700,7 +700,77 @@ private slots: QVERIFY(excludes.versionDirectiveKeepNextLine(test.first) == test.second); } } - + + void testAddExcludeFilePath_addSameFilePath_listSizeDoesNotIncrease() + { + excludedFiles.reset(new ExcludedFiles()); + const auto filePath = QString("exclude/.sync-exclude.lst"); + + excludedFiles->addExcludeFilePath(filePath); + excludedFiles->addExcludeFilePath(filePath); + + QCOMPARE(excludedFiles->_excludeFiles.size(), 1); + } + + void testAddExcludeFilePath_addDifferentFilePaths_listSizeIncrease() + { + excludedFiles.reset(new ExcludedFiles()); + + const auto filePath1 = QString("exclude1/.sync-exclude.lst"); + const auto filePath2 = QString("exclude2/.sync-exclude.lst"); + + excludedFiles->addExcludeFilePath(filePath1); + excludedFiles->addExcludeFilePath(filePath2); + + QCOMPARE(excludedFiles->_excludeFiles.size(), 2); + } + + void testAddExcludeFilePath_addDefaultExcludeFile_returnCorrectMap() + { + const QString basePath("syncFolder/"); + const QString folder1("syncFolder/folder1/"); + const QString folder2(folder1 + "folder2/"); + excludedFiles.reset(new ExcludedFiles(basePath)); + + const QString defaultExcludeList("desktop-client/config-folder/sync-exclude.lst"); + const QString folder1ExcludeList(folder1 + ".sync-exclude.lst"); + const QString folder2ExcludeList(folder2 + ".sync-exclude.lst"); + + excludedFiles->addExcludeFilePath(defaultExcludeList); + excludedFiles->addExcludeFilePath(folder1ExcludeList); + excludedFiles->addExcludeFilePath(folder2ExcludeList); + + QCOMPARE(excludedFiles->_excludeFiles.size(), 3); + QCOMPARE(excludedFiles->_excludeFiles[basePath].first(), defaultExcludeList); + QCOMPARE(excludedFiles->_excludeFiles[folder1].first(), folder1ExcludeList); + QCOMPARE(excludedFiles->_excludeFiles[folder2].first(), folder2ExcludeList); + } + + void testReloadExcludeFiles_fileDoesNotExist_returnFalse() { + excludedFiles.reset(new ExcludedFiles()); + const QString nonExistingFile("directory/.sync-exclude.lst"); + excludedFiles->addExcludeFilePath(nonExistingFile); + QCOMPARE(excludedFiles->reloadExcludeFiles(), false); + QCOMPARE(excludedFiles->_allExcludes.size(), 0); + } + + void testReloadExcludeFiles_fileExists_returnTrue() + { + const auto tempDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation); + excludedFiles.reset(new ExcludedFiles(tempDir + "/")); + + const auto subTempDir = QStringLiteral("exclude"); + QVERIFY(QDir(tempDir).mkpath(subTempDir)); + + const auto existingFilePath = QString(tempDir + '/' + subTempDir + "/.sync-exclude.lst"); + QFile excludeList(existingFilePath); + QVERIFY(excludeList.open(QFile::WriteOnly)); + excludeList.close(); + + excludedFiles->addExcludeFilePath(existingFilePath); + QCOMPARE(excludedFiles->reloadExcludeFiles(), true); + QCOMPARE(excludedFiles->_allExcludes.size(), 1); + } }; QTEST_APPLESS_MAIN(TestExcludedFiles) diff --git a/test/testfolderwatcher.cpp b/test/testfolderwatcher.cpp index 7345e645025d..d8c7da0924f7 100644 --- a/test/testfolderwatcher.cpp +++ b/test/testfolderwatcher.cpp @@ -103,8 +103,8 @@ class TestFolderWatcher : public QObject #endif public: - TestFolderWatcher() { - qsrand(QTime::currentTime().msec()); + TestFolderWatcher() + { QDir rootDir(_root.path()); _rootPath = rootDir.canonicalPath(); qDebug() << "creating test directory tree in " << _rootPath; diff --git a/test/testhelper.h b/test/testhelper.h index 5eaa2c5912a1..40379577cb3a 100644 --- a/test/testhelper.h +++ b/test/testhelper.h @@ -11,7 +11,7 @@ class HttpCredentialsTest : public OCC::HttpCredentials : HttpCredentials(user, password) {} - void askFromUser() Q_DECL_OVERRIDE { + void askFromUser() override { } }; diff --git a/test/testiconutils.cpp b/test/testiconutils.cpp new file mode 100644 index 000000000000..9f16acd7f7f5 --- /dev/null +++ b/test/testiconutils.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 + +#include "theme.h" +#include "iconutils.h" + +class TestIconUtils : public QObject +{ + Q_OBJECT + +public: + TestIconUtils() + { + Q_INIT_RESOURCE(resources); + Q_INIT_RESOURCE(theme); + } + +private slots: + void testDrawSvgWithCustomFillColor() + { + const QString blackSvgDirPath{QString{OCC::Theme::themePrefix} + QStringLiteral("black")}; + const QDir blackSvgDir(blackSvgDirPath); + const QStringList blackImages = blackSvgDir.entryList(QStringList("*.svg")); + + Q_ASSERT(!blackImages.isEmpty()); + + QVERIFY(!OCC::Ui::IconUtils::drawSvgWithCustomFillColor(blackSvgDirPath + QStringLiteral("/") + blackImages.at(0), QColorConstants::Svg::red).isNull()); + + QVERIFY(!OCC::Ui::IconUtils::drawSvgWithCustomFillColor(blackSvgDirPath + QStringLiteral("/") + blackImages.at(0), QColorConstants::Svg::green).isNull()); + + const QString whiteSvgDirPath{QString{OCC::Theme::themePrefix} + QStringLiteral("white")}; + const QDir whiteSvgDir(whiteSvgDirPath); + const QStringList whiteImages = whiteSvgDir.entryList(QStringList("*.svg")); + + Q_ASSERT(!whiteImages.isEmpty()); + + QVERIFY(!OCC::Ui::IconUtils::drawSvgWithCustomFillColor(whiteSvgDirPath + QStringLiteral("/") + whiteImages.at(0), QColorConstants::Svg::blue).isNull()); + } + + void testCreateSvgPixmapWithCustomColor() + { + const QDir blackSvgDir(QString(QString{OCC::Theme::themePrefix}) + QStringLiteral("black")); + const QStringList blackImages = blackSvgDir.entryList(QStringList("*.svg")); + + QVERIFY(!blackImages.isEmpty()); + + QVERIFY(!OCC::Ui::IconUtils::createSvgImageWithCustomColor(blackImages.at(0), QColorConstants::Svg::red).isNull()); + + QVERIFY(!OCC::Ui::IconUtils::createSvgImageWithCustomColor(blackImages.at(0), QColorConstants::Svg::green).isNull()); + + const QDir whiteSvgDir(QString(QString{OCC::Theme::themePrefix}) + QStringLiteral("white")); + const QStringList whiteImages = whiteSvgDir.entryList(QStringList("*.svg")); + + QVERIFY(!whiteImages.isEmpty()); + + QVERIFY(!OCC::Ui::IconUtils::createSvgImageWithCustomColor(whiteImages.at(0), QColorConstants::Svg::blue).isNull()); + } + + void testPixmapForBackground() + { + const QDir blackSvgDir(QString(QString{OCC::Theme::themePrefix}) + QStringLiteral("black")); + const QStringList blackImages = blackSvgDir.entryList(QStringList("*.svg")); + + const QDir whiteSvgDir(QString(QString{OCC::Theme::themePrefix}) + QStringLiteral("white")); + const QStringList whiteImages = whiteSvgDir.entryList(QStringList("*.svg")); + + QVERIFY(!blackImages.isEmpty()); + + QVERIFY(!OCC::Ui::IconUtils::pixmapForBackground(whiteImages.at(0), QColor("blue")).isNull()); + + QVERIFY(!whiteImages.isEmpty()); + + QVERIFY(!OCC::Ui::IconUtils::pixmapForBackground(blackImages.at(0), QColor("yellow")).isNull()); + } +}; + +QTEST_MAIN(TestIconUtils) +#include "testiconutils.moc" diff --git a/test/testinotifywatcher.cpp b/test/testinotifywatcher.cpp index 2d8cf937d10b..204939f9132c 100644 --- a/test/testinotifywatcher.cpp +++ b/test/testinotifywatcher.cpp @@ -19,10 +19,9 @@ class TestInotifyWatcher: public FolderWatcherPrivate QString _root; private slots: - void initTestCase() { - qsrand(QTime::currentTime().msec()); - - _root = QDir::tempPath() + "/" + "test_" + QString::number(qrand()); + void initTestCase() + { + _root = QDir::tempPath() + "/" + "test_" + QString::number(OCC::Utility::rand()); qDebug() << "creating test directory tree in " << _root; QDir rootDir(_root); @@ -31,7 +30,6 @@ private slots: rootDir.mkpath(_root + "/a1/b2/c1"); rootDir.mkpath(_root + "/a1/b3/c3"); rootDir.mkpath(_root + "/a2/b3/c3"); - } // Test the recursive path listing function findFoldersBelow diff --git a/test/testlocaldiscovery.cpp b/test/testlocaldiscovery.cpp index d1831a56da0e..1933993328d8 100644 --- a/test/testlocaldiscovery.cpp +++ b/test/testlocaldiscovery.cpp @@ -204,6 +204,71 @@ private slots: QVERIFY(!fakeFolder.currentRemoteState().find("C/.foo")); QVERIFY(!fakeFolder.currentRemoteState().find("C/bar")); } + + void testCreateFileWithTrailingSpaces_localAndRemoteTrimmedDoNotExist_renameAndUploadFile() + { + FakeFolder fakeFolder { FileInfo::A12_B12_C12_S12() }; + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + const QString fileWithSpaces1(" foo"); + const QString fileWithSpaces2(" bar "); + const QString fileWithSpaces3("bla "); + + fakeFolder.localModifier().insert(fileWithSpaces1); + fakeFolder.localModifier().insert(fileWithSpaces2); + fakeFolder.localModifier().insert(fileWithSpaces3); + + QVERIFY(fakeFolder.syncOnce()); + + QVERIFY(fakeFolder.currentRemoteState().find(fileWithSpaces1.trimmed())); + QVERIFY(!fakeFolder.currentRemoteState().find(fileWithSpaces1)); + QVERIFY(fakeFolder.currentLocalState().find(fileWithSpaces1.trimmed())); + QVERIFY(!fakeFolder.currentLocalState().find(fileWithSpaces1)); + + QVERIFY(fakeFolder.currentRemoteState().find(fileWithSpaces2.trimmed())); + QVERIFY(!fakeFolder.currentRemoteState().find(fileWithSpaces2)); + QVERIFY(fakeFolder.currentLocalState().find(fileWithSpaces2.trimmed())); + QVERIFY(!fakeFolder.currentLocalState().find(fileWithSpaces2)); + + QVERIFY(fakeFolder.currentRemoteState().find(fileWithSpaces3.trimmed())); + QVERIFY(!fakeFolder.currentRemoteState().find(fileWithSpaces3)); + QVERIFY(fakeFolder.currentLocalState().find(fileWithSpaces3.trimmed())); + QVERIFY(!fakeFolder.currentLocalState().find(fileWithSpaces3)); + } + + void testCreateFileWithTrailingSpaces_localTrimmedDoesExist_dontRenameAndUploadFile() + { + FakeFolder fakeFolder { FileInfo::A12_B12_C12_S12() }; + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + const QString fileWithSpaces(" foo"); + const QString fileTrimmed("foo"); + + fakeFolder.localModifier().insert(fileTrimmed); + QVERIFY(fakeFolder.syncOnce()); + fakeFolder.localModifier().insert(fileWithSpaces); + QVERIFY(!fakeFolder.syncOnce()); + + QVERIFY(fakeFolder.currentRemoteState().find(fileTrimmed)); + QVERIFY(!fakeFolder.currentRemoteState().find(fileWithSpaces)); + QVERIFY(fakeFolder.currentLocalState().find(fileWithSpaces)); + QVERIFY(fakeFolder.currentLocalState().find(fileTrimmed)); + } + + void testCreateFileWithTrailingSpaces_localTrimmedAlsoCreated_dontRenameAndUploadFile() + { + FakeFolder fakeFolder { FileInfo::A12_B12_C12_S12() }; + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + const QString fileWithSpaces(" foo"); + const QString fileTrimmed("foo"); + + fakeFolder.localModifier().insert(fileTrimmed); + fakeFolder.localModifier().insert(fileWithSpaces); + QVERIFY(!fakeFolder.syncOnce()); + + QVERIFY(fakeFolder.currentRemoteState().find(fileTrimmed)); + QVERIFY(!fakeFolder.currentRemoteState().find(fileWithSpaces)); + QVERIFY(fakeFolder.currentLocalState().find(fileWithSpaces)); + QVERIFY(fakeFolder.currentLocalState().find(fileTrimmed)); + } }; QTEST_GUILESS_MAIN(TestLocalDiscovery) diff --git a/test/testlockedfiles.cpp b/test/testlockedfiles.cpp index df1e8f8d04c9..cae7fb11c4ef 100644 --- a/test/testlockedfiles.cpp +++ b/test/testlockedfiles.cpp @@ -17,7 +17,8 @@ using namespace OCC; // pass combination of FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE HANDLE makeHandle(const QString &file, int shareMode) { - const wchar_t *wuri = reinterpret_cast(file.utf16()); + const auto fName = FileSystem::longWinPath(file); + const wchar_t *wuri = reinterpret_cast(fName.utf16()); auto handle = CreateFileW( wuri, GENERIC_READ | GENERIC_WRITE, @@ -39,6 +40,7 @@ class TestLockedFiles : public QObject private slots: void testBasicLockFileWatcher() { + QTemporaryDir tmp; int count = 0; QString file; @@ -46,12 +48,16 @@ private slots: watcher.setCheckInterval(std::chrono::milliseconds(50)); connect(&watcher, &LockWatcher::fileUnlocked, &watcher, [&](const QString &f) { ++count; file = f; }); - QString tmpFile; + const QString tmpFile = tmp.path() + QString::fromUtf8("/alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/file🐷.txt"); { - QTemporaryFile tmp; - tmp.setAutoRemove(false); - tmp.open(); - tmpFile = tmp.fileName(); + // use a long file path to ensure we handle that correctly + QVERIFY(QFileInfo(tmpFile).dir().mkpath(".")); + QFile tmp(tmpFile); + QVERIFY(tmp.open(QFile::WriteOnly)); + QVERIFY(tmp.write("ownCLoud")); } QVERIFY(QFile::exists(tmpFile)); @@ -91,7 +97,7 @@ private slots: QCOMPARE(file, tmpFile); QVERIFY(!watcher.contains(tmpFile)); #endif - QFile::remove(tmpFile); + QVERIFY(tmp.remove()); } #ifdef Q_OS_WIN diff --git a/test/testlongwinpath.cpp b/test/testlongpath.cpp similarity index 51% rename from test/testlongwinpath.cpp rename to test/testlongpath.cpp index 16933813cb0f..7e912ae15780 100644 --- a/test/testlongwinpath.cpp +++ b/test/testlongpath.cpp @@ -18,7 +18,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "common/filesystembase.h" +#include "csync/csync.h" +#include "csync/vio/csync_vio_local.h" +#include #include @@ -27,6 +30,7 @@ class TestLongWindowsPath : public QObject Q_OBJECT private Q_SLOTS: +#ifdef Q_OS_WIN void check_long_win_path() { { @@ -81,7 +85,58 @@ private Q_SLOTS: // printf( "YYYYYYYYYYYY %ld\n", strlen(new_long)); QCOMPARE(new_long.length(), 286); } +#endif + + + void testLongPathStat_data() + { + QTest::addColumn("name"); + + QTest::newRow("long") << QStringLiteral("/alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/file.txt"); + QTest::newRow("long emoji") << QString::fromUtf8("/alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/file🐷.txt"); + QTest::newRow("long russian") << QString::fromUtf8("/alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/собственное.txt"); + QTest::newRow("long arabic") << QString::fromUtf8("/alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/السحاب.txt"); + QTest::newRow("long chinese") << QString::fromUtf8("/alonglonglonglong/blonglonglonglong/clonglonglonglong/dlonglonglonglong/" + "elonglonglonglong/flonglonglonglong/glonglonglonglong/hlonglonglonglong/ilonglonglonglong/" + "jlonglonglonglong/klonglonglonglong/llonglonglonglong/mlonglonglonglong/nlonglonglonglong/" + "olonglonglonglong/自己的云.txt"); + } + + void testLongPathStat() + { + QTemporaryDir tmp; + QFETCH(QString, name); + const QFileInfo longPath(tmp.path() + name); + + const auto data = QByteArrayLiteral("hello"); + qDebug() << longPath; + QVERIFY(longPath.dir().mkpath(".")); + + QFile file(longPath.filePath()); + QVERIFY(file.open(QFile::WriteOnly)); + QVERIFY(file.write(data.constData()) == data.size()); + file.close(); + + csync_file_stat_t buf; + QVERIFY(csync_vio_local_stat(longPath.filePath(), &buf) != -1); + QVERIFY(buf.size == data.size()); + QVERIFY(buf.size == longPath.size()); + + QVERIFY(tmp.remove()); + } }; QTEST_GUILESS_MAIN(TestLongWindowsPath) -#include "testlongwinpath.moc" +#include "testlongpath.moc" diff --git a/test/testnotificationcache.cpp b/test/testnotificationcache.cpp index 6ee05e3d7983..eba7e3f4d526 100644 --- a/test/testnotificationcache.cpp +++ b/test/testnotificationcache.cpp @@ -1,6 +1,6 @@ #include -#include "tray/NotificationCache.h" +#include "tray/notificationcache.h" class TestNotificationCache : public QObject { diff --git a/test/testownsql.cpp b/test/testownsql.cpp index abfb72db01ac..167c53be88ab 100644 --- a/test/testownsql.cpp +++ b/test/testownsql.cpp @@ -136,8 +136,6 @@ private slots: q2.prepare("SELECT * FROM addresses"); SqlQuery q3("SELECT * FROM addresses", _db); SqlQuery q4; - SqlQuery q5; - PreparedSqlQueryRAII testQuery(&q5, "SELECT * FROM addresses", _db); db.reset(); } diff --git a/test/testpushnotifications.cpp b/test/testpushnotifications.cpp index b7e00583f4d5..9345918e5011 100644 --- a/test/testpushnotifications.cpp +++ b/test/testpushnotifications.cpp @@ -65,6 +65,20 @@ class TestPushNotifications : public QObject Q_OBJECT private slots: + void testTryReconnect_capabilitesReportPushNotificationsAvailable_reconnectForEver() + { + FakeWebSocketServer fakeServer; + auto account = FakeWebSocketServer::createAccount(); + account->setPushNotificationsReconnectInterval(0); + + // Let if fail a few times + QVERIFY(failThreeAuthenticationAttempts(fakeServer, account)); + QVERIFY(failThreeAuthenticationAttempts(fakeServer, account)); + + // Push notifications should try to reconnect + QVERIFY(fakeServer.authenticateAccount(account)); + } + void testSetup_correctCredentials_authenticateAndEmitReady() { FakeWebSocketServer fakeServer; @@ -272,20 +286,6 @@ private slots: QVERIFY(verifyCalledOnceWithAccount(*activitiesChangedSpy, account)); })); } - - void testTryReconnect_capabilitesReportPushNotificationsAvailable_reconnectForEver() - { - FakeWebSocketServer fakeServer; - auto account = FakeWebSocketServer::createAccount(); - account->setPushNotificationsReconnectInterval(0); - - // Let if fail a few times - QVERIFY(failThreeAuthenticationAttempts(fakeServer, account)); - QVERIFY(failThreeAuthenticationAttempts(fakeServer, account)); - - // Push notifications should try to reconnect - QVERIFY(fakeServer.authenticateAccount(account)); - } }; QTEST_GUILESS_MAIN(TestPushNotifications) diff --git a/test/testremotediscovery.cpp b/test/testremotediscovery.cpp index 2df07b0db2ac..c4a8f4def92e 100644 --- a/test/testremotediscovery.cpp +++ b/test/testremotediscovery.cpp @@ -169,7 +169,7 @@ private slots: QCOMPARE(completeSpy.findItem("nopermissions/A")->_instruction, CSYNC_INSTRUCTION_ERROR); QVERIFY(completeSpy.findItem("noetag")->_errorString.contains("ETag")); QVERIFY(completeSpy.findItem("nofileid")->_errorString.contains("file id")); - QVERIFY(completeSpy.findItem("nopermissions/A")->_errorString.contains("permissions")); + QVERIFY(completeSpy.findItem("nopermissions/A")->_errorString.contains("permission")); } }; diff --git a/test/testsetuserstatusdialog.cpp b/test/testsetuserstatusdialog.cpp new file mode 100644 index 000000000000..0454638566ee --- /dev/null +++ b/test/testsetuserstatusdialog.cpp @@ -0,0 +1,747 @@ +/* + * Copyright (C) by Felix Weilbach + * + * 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 "userstatusconnector.h" +#include "userstatusselectormodel.h" + +#include +#include +#include + +#include + +class FakeUserStatusConnector : public OCC::UserStatusConnector +{ +public: + void fetchUserStatus() override + { + if (_couldNotFetchUserStatus) { + emit error(Error::CouldNotFetchUserStatus); + return; + } else if (_userStatusNotSupported) { + emit error(Error::UserStatusNotSupported); + return; + } else if (_emojisNotSupported) { + emit error(Error::EmojisNotSupported); + return; + } + + emit userStatusFetched(_userStatus); + } + + void fetchPredefinedStatuses() override + { + if (_couldNotFetchPredefinedUserStatuses) { + emit error(Error::CouldNotFetchPredefinedUserStatuses); + return; + } + emit predefinedStatusesFetched(_predefinedStatuses); + } + + void setUserStatus(const OCC::UserStatus &userStatus) override + { + if (_couldNotSetUserStatusMessage) { + emit error(Error::CouldNotSetUserStatus); + return; + } + + _userStatusSetByCallerOfSetUserStatus = userStatus; + emit UserStatusConnector::userStatusSet(); + } + + void clearMessage() override + { + if (_couldNotClearUserStatusMessage) { + emit error(Error::CouldNotClearMessage); + } else { + _isMessageCleared = true; + } + } + + OCC::UserStatus userStatus() const override + { + return {}; // Not implemented + } + + void setFakeUserStatus(const OCC::UserStatus &userStatus) + { + _userStatus = userStatus; + } + + void setFakePredefinedStatuses( + const std::vector &statuses) + { + _predefinedStatuses = statuses; + } + + OCC::UserStatus userStatusSetByCallerOfSetUserStatus() const { return _userStatusSetByCallerOfSetUserStatus; } + + bool messageCleared() const { return _isMessageCleared; } + + void setErrorCouldNotFetchPredefinedUserStatuses(bool value) + { + _couldNotFetchPredefinedUserStatuses = value; + } + + void setErrorCouldNotFetchUserStatus(bool value) + { + _couldNotFetchUserStatus = value; + } + + void setErrorCouldNotSetUserStatusMessage(bool value) + { + _couldNotSetUserStatusMessage = value; + } + + void setErrorUserStatusNotSupported(bool value) + { + _userStatusNotSupported = value; + } + + void setErrorEmojisNotSupported(bool value) + { + _emojisNotSupported = value; + } + + void setErrorCouldNotClearUserStatusMessage(bool value) + { + _couldNotClearUserStatusMessage = value; + } + +private: + OCC::UserStatus _userStatusSetByCallerOfSetUserStatus; + OCC::UserStatus _userStatus; + std::vector _predefinedStatuses; + bool _isMessageCleared = false; + bool _couldNotFetchPredefinedUserStatuses = false; + bool _couldNotFetchUserStatus = false; + bool _couldNotSetUserStatusMessage = false; + bool _userStatusNotSupported = false; + bool _emojisNotSupported = false; + bool _couldNotClearUserStatusMessage = false; +}; + +class FakeDateTimeProvider : public OCC::DateTimeProvider +{ +public: + void setCurrentDateTime(const QDateTime &dateTime) { _dateTime = dateTime; } + + QDateTime currentDateTime() const override { return _dateTime; } + + QDate currentDate() const override { return _dateTime.date(); } + +private: + QDateTime _dateTime; +}; + +static std::vector +createFakePredefinedStatuses(const QDateTime ¤tTime) +{ + std::vector statuses; + + const QString userStatusId("fake-id"); + const QString userStatusMessage("Predefined status"); + const QString userStatusIcon("🏖"); + const OCC::UserStatus::OnlineStatus userStatusState(OCC::UserStatus::OnlineStatus::Online); + const bool userStatusMessagePredefined(true); + OCC::Optional userStatusClearAt; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addSecs(60 * 60).toTime_t(); + userStatusClearAt = clearAt; + + statuses.emplace_back(userStatusId, userStatusMessage, userStatusIcon, + userStatusState, userStatusMessagePredefined, userStatusClearAt); + + return statuses; +} + +static QDateTime createDateTime(int year = 2021, int month = 7, int day = 27, + int hour = 12, int minute = 0, int second = 0) +{ + QDate fakeDate(year, month, day); + QTime fakeTime(hour, minute, second); + QDateTime fakeDateTime; + + fakeDateTime.setDate(fakeDate); + fakeDateTime.setTime(fakeTime); + + return fakeDateTime; +} + +class TestSetUserStatusDialog : public QObject +{ + Q_OBJECT + +private slots: + void testCtor_fetchStatusAndPredefinedStatuses() + { + const QDateTime currentDateTime(QDateTime::currentDateTime()); + + const QString userStatusId("fake-id"); + const QString userStatusMessage("Some status"); + const QString userStatusIcon("❤"); + const OCC::UserStatus::OnlineStatus userStatusState(OCC::UserStatus::OnlineStatus::DoNotDisturb); + const bool userStatusMessagePredefined(false); + OCC::Optional userStatusClearAt; + { + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentDateTime.addDays(1).toTime_t(); + userStatusClearAt = clearAt; + } + + const OCC::UserStatus userStatus(userStatusId, userStatusMessage, + userStatusIcon, userStatusState, userStatusMessagePredefined, userStatusClearAt); + + const auto fakePredefinedStatuses = createFakePredefinedStatuses(createDateTime()); + + auto fakeUserStatusJob = std::make_shared(); + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentDateTime); + fakeUserStatusJob->setFakeUserStatus(userStatus); + fakeUserStatusJob->setFakePredefinedStatuses(fakePredefinedStatuses); + OCC::UserStatusSelectorModel model(fakeUserStatusJob, std::move(fakeDateTimeProvider)); + + // Was user status set correctly? + QCOMPARE(model.userStatusMessage(), userStatusMessage); + QCOMPARE(model.userStatusEmoji(), userStatusIcon); + QCOMPARE(model.onlineStatus(), userStatusState); + QCOMPARE(model.clearAt(), tr("1 day")); + + // Were predefined statuses fetched correctly? + const auto predefinedStatusesCount = model.predefinedStatusesCount(); + QCOMPARE(predefinedStatusesCount, fakePredefinedStatuses.size()); + for (int i = 0; i < predefinedStatusesCount; ++i) { + const auto predefinedStatus = model.predefinedStatus(i); + QCOMPARE(predefinedStatus.id(), + fakePredefinedStatuses[i].id()); + QCOMPARE(predefinedStatus.message(), + fakePredefinedStatuses[i].message()); + QCOMPARE(predefinedStatus.icon(), + fakePredefinedStatuses[i].icon()); + QCOMPARE(predefinedStatus.messagePredefined(), + fakePredefinedStatuses[i].messagePredefined()); + } + } + + void testCtor_noStatusSet_showSensibleDefaults() + { + OCC::UserStatusSelectorModel model(nullptr, nullptr); + + QCOMPARE(model.userStatusMessage(), ""); + QCOMPARE(model.userStatusEmoji(), "😀"); + QCOMPARE(model.clearAt(), tr("Don't clear")); + } + + void testCtor_fetchStatusButNoStatusSet_showSensibleDefaults() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setFakeUserStatus({ "", "", "", + OCC::UserStatus::OnlineStatus::Offline, false, {} }); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + QCOMPARE(model.onlineStatus(), OCC::UserStatus::OnlineStatus::Online); + QCOMPARE(model.userStatusMessage(), ""); + QCOMPARE(model.userStatusEmoji(), "😀"); + QCOMPARE(model.clearAt(), tr("Don't clear")); + } + + void testSetOnlineStatus_emitOnlineStatusChanged() + { + const OCC::UserStatus::OnlineStatus onlineStatus(OCC::UserStatus::OnlineStatus::Invisible); + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy onlineStatusChangedSpy(&model, + &OCC::UserStatusSelectorModel::onlineStatusChanged); + + model.setOnlineStatus(onlineStatus); + + QCOMPARE(onlineStatusChangedSpy.count(), 1); + } + + void testSetUserStatus_setCustomMessage_userStatusSetCorrect() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy finishedSpy(&model, &OCC::UserStatusSelectorModel::finished); + + const QString userStatusMessage("Some status"); + const QString userStatusIcon("❤"); + const OCC::UserStatus::OnlineStatus userStatusState(OCC::UserStatus::OnlineStatus::Online); + + model.setOnlineStatus(userStatusState); + model.setUserStatusMessage(userStatusMessage); + model.setUserStatusEmoji(userStatusIcon); + model.setClearAt(1); + + model.setUserStatus(); + QCOMPARE(finishedSpy.count(), 1); + + const auto userStatusSet = fakeUserStatusJob->userStatusSetByCallerOfSetUserStatus(); + QCOMPARE(userStatusSet.icon(), userStatusIcon); + QCOMPARE(userStatusSet.message(), userStatusMessage); + QCOMPARE(userStatusSet.state(), userStatusState); + QCOMPARE(userStatusSet.messagePredefined(), false); + const auto clearAt = userStatusSet.clearAt(); + QVERIFY(clearAt.isValid()); + QCOMPARE(clearAt->_type, OCC::ClearAtType::Period); + QCOMPARE(clearAt->_period, 60 * 30); + } + + void testSetUserStatusMessage_predefinedStatusWasSet_userStatusSetCorrect() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setFakePredefinedStatuses(createFakePredefinedStatuses(createDateTime())); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + model.setPredefinedStatus(0); + QSignalSpy finishedSpy(&model, &OCC::UserStatusSelectorModel::finished); + + const QString userStatusMessage("Some status"); + const OCC::UserStatus::OnlineStatus userStatusState(OCC::UserStatus::OnlineStatus::Online); + + model.setOnlineStatus(userStatusState); + model.setUserStatusMessage(userStatusMessage); + model.setClearAt(1); + + model.setUserStatus(); + QCOMPARE(finishedSpy.count(), 1); + + const auto userStatusSet = fakeUserStatusJob->userStatusSetByCallerOfSetUserStatus(); + QCOMPARE(userStatusSet.message(), userStatusMessage); + QCOMPARE(userStatusSet.state(), userStatusState); + QCOMPARE(userStatusSet.messagePredefined(), false); + const auto clearAt = userStatusSet.clearAt(); + QVERIFY(clearAt.isValid()); + QCOMPARE(clearAt->_type, OCC::ClearAtType::Period); + QCOMPARE(clearAt->_period, 60 * 30); + } + + void testSetUserStatusEmoji_predefinedStatusWasSet_userStatusSetCorrect() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setFakePredefinedStatuses(createFakePredefinedStatuses(createDateTime())); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + model.setPredefinedStatus(0); + QSignalSpy finishedSpy(&model, &OCC::UserStatusSelectorModel::finished); + + const QString userStatusIcon("❤"); + const OCC::UserStatus::OnlineStatus userStatusState(OCC::UserStatus::OnlineStatus::Online); + + model.setOnlineStatus(userStatusState); + model.setUserStatusEmoji(userStatusIcon); + model.setClearAt(1); + + model.setUserStatus(); + QCOMPARE(finishedSpy.count(), 1); + + const auto userStatusSet = fakeUserStatusJob->userStatusSetByCallerOfSetUserStatus(); + QCOMPARE(userStatusSet.icon(), userStatusIcon); + QCOMPARE(userStatusSet.state(), userStatusState); + QCOMPARE(userStatusSet.messagePredefined(), false); + const auto clearAt = userStatusSet.clearAt(); + QVERIFY(clearAt.isValid()); + QCOMPARE(clearAt->_type, OCC::ClearAtType::Period); + QCOMPARE(clearAt->_period, 60 * 30); + } + + void testSetPredefinedStatus_emitUserStatusChangedAndSetUserStatus() + { + auto fakeUserStatusJob = std::make_shared(); + auto fakeDateTimeProvider = std::make_unique(); + const auto currentTime = createDateTime(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + const auto fakePredefinedStatuses = createFakePredefinedStatuses(currentTime); + fakeUserStatusJob->setFakePredefinedStatuses(fakePredefinedStatuses); + OCC::UserStatusSelectorModel model(std::move(fakeUserStatusJob), + std::move(fakeDateTimeProvider)); + + QSignalSpy userStatusChangedSpy(&model, + &OCC::UserStatusSelectorModel::userStatusChanged); + QSignalSpy clearAtChangedSpy(&model, + &OCC::UserStatusSelectorModel::clearAtChanged); + + const auto fakePredefinedUserStatusIndex = 0; + model.setPredefinedStatus(fakePredefinedUserStatusIndex); + + QCOMPARE(userStatusChangedSpy.count(), 1); + QCOMPARE(clearAtChangedSpy.count(), 1); + + // Was user status set correctly? + const auto fakePredefinedUserStatus = fakePredefinedStatuses[fakePredefinedUserStatusIndex]; + QCOMPARE(model.userStatusMessage(), fakePredefinedUserStatus.message()); + QCOMPARE(model.userStatusEmoji(), fakePredefinedUserStatus.icon()); + QCOMPARE(model.onlineStatus(), fakePredefinedUserStatus.state()); + QCOMPARE(model.clearAt(), tr("1 hour")); + } + + void testSetClear_setClearAtStage0_emitClearAtChangedAndClearAtSet() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy clearAtChangedSpy(&model, &OCC::UserStatusSelectorModel::clearAtChanged); + + const auto clearAtIndex = 0; + model.setClearAt(clearAtIndex); + + QCOMPARE(clearAtChangedSpy.count(), 1); + QCOMPARE(model.clearAt(), tr("Don't clear")); + } + + void testSetClear_setClearAtStage1_emitClearAtChangedAndClearAtSet() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy clearAtChangedSpy(&model, &OCC::UserStatusSelectorModel::clearAtChanged); + + const auto clearAtIndex = 1; + model.setClearAt(clearAtIndex); + + QCOMPARE(clearAtChangedSpy.count(), 1); + QCOMPARE(model.clearAt(), tr("30 minutes")); + } + + void testSetClear_setClearAtStage2_emitClearAtChangedAndClearAtSet() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy clearAtChangedSpy(&model, &OCC::UserStatusSelectorModel::clearAtChanged); + + const auto clearAtIndex = 2; + model.setClearAt(clearAtIndex); + + QCOMPARE(clearAtChangedSpy.count(), 1); + QCOMPARE(model.clearAt(), tr("1 hour")); + } + + void testSetClear_setClearAtStage3_emitClearAtChangedAndClearAtSet() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy clearAtChangedSpy(&model, &OCC::UserStatusSelectorModel::clearAtChanged); + + const auto clearAtIndex = 3; + model.setClearAt(clearAtIndex); + + QCOMPARE(clearAtChangedSpy.count(), 1); + QCOMPARE(model.clearAt(), tr("4 hours")); + } + + void testSetClear_setClearAtStage4_emitClearAtChangedAndClearAtSet() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy clearAtChangedSpy(&model, &OCC::UserStatusSelectorModel::clearAtChanged); + + const auto clearAtIndex = 4; + model.setClearAt(clearAtIndex); + + QCOMPARE(clearAtChangedSpy.count(), 1); + QCOMPARE(model.clearAt(), tr("Today")); + } + + void testSetClear_setClearAtStage5_emitClearAtChangedAndClearAtSet() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + QSignalSpy clearAtChangedSpy(&model, &OCC::UserStatusSelectorModel::clearAtChanged); + + const auto clearAtIndex = 5; + model.setClearAt(clearAtIndex); + + QCOMPARE(clearAtChangedSpy.count(), 1); + QCOMPARE(model.clearAt(), tr("This week")); + } + + void testClearAtStages() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + QCOMPARE(model.clearAt(), tr("Don't clear")); + const auto clearAtValues = model.clearAtValues(); + QCOMPARE(clearAtValues.count(), 6); + + QCOMPARE(clearAtValues[0], tr("Don't clear")); + QCOMPARE(clearAtValues[1], tr("30 minutes")); + QCOMPARE(clearAtValues[2], tr("1 hour")); + QCOMPARE(clearAtValues[3], tr("4 hours")); + QCOMPARE(clearAtValues[4], tr("Today")); + QCOMPARE(clearAtValues[5], tr("This week")); + } + + void testClearAt_clearAtTimestamp() + { + const auto currentTime = createDateTime(); + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addSecs(30).toTime_t(); + userStatus.setClearAt(clearAt); + + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + + OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider)); + + QCOMPARE(model.clearAt(), tr("Less than a minute")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addSecs(60).toTime_t(); + userStatus.setClearAt(clearAt); + + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + + OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider)); + + QCOMPARE(model.clearAt(), tr("1 minute")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addSecs(60 * 30).toTime_t(); + userStatus.setClearAt(clearAt); + + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + + OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider)); + + QCOMPARE(model.clearAt(), tr("30 minutes")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addSecs(60 * 60).toTime_t(); + userStatus.setClearAt(clearAt); + + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + + OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider)); + + QCOMPARE(model.clearAt(), tr("1 hour")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addSecs(60 * 60 * 4).toTime_t(); + userStatus.setClearAt(clearAt); + + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + + OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider)); + + QCOMPARE(model.clearAt(), tr("4 hours")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addDays(1).toTime_t(); + userStatus.setClearAt(clearAt); + + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + + OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider)); + + QCOMPARE(model.clearAt(), tr("1 day")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Timestamp; + clearAt._timestamp = currentTime.addDays(7).toTime_t(); + userStatus.setClearAt(clearAt); + + auto fakeDateTimeProvider = std::make_unique(); + fakeDateTimeProvider->setCurrentDateTime(currentTime); + + OCC::UserStatusSelectorModel model(userStatus, std::move(fakeDateTimeProvider)); + + QCOMPARE(model.clearAt(), tr("7 days")); + } + } + + void testClearAt_clearAtEndOf() + { + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::EndOf; + clearAt._endof = "day"; + userStatus.setClearAt(clearAt); + + OCC::UserStatusSelectorModel model(userStatus); + + QCOMPARE(model.clearAt(), tr("Today")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::EndOf; + clearAt._endof = "week"; + userStatus.setClearAt(clearAt); + + OCC::UserStatusSelectorModel model(userStatus); + + QCOMPARE(model.clearAt(), tr("This week")); + } + } + + void testClearAt_clearAtAfterPeriod() + { + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Period; + clearAt._period = 60 * 30; + userStatus.setClearAt(clearAt); + + OCC::UserStatusSelectorModel model(userStatus); + + QCOMPARE(model.clearAt(), tr("30 minutes")); + } + + { + OCC::UserStatus userStatus; + OCC::ClearAt clearAt; + clearAt._type = OCC::ClearAtType::Period; + clearAt._period = 60 * 60; + userStatus.setClearAt(clearAt); + + OCC::UserStatusSelectorModel model(userStatus); + + QCOMPARE(model.clearAt(), tr("1 hour")); + } + } + + void testClearUserStatus() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + model.clearUserStatus(); + + QVERIFY(fakeUserStatusJob->messageCleared()); + } + + void testError_couldNotFetchPredefinedStatuses_emitError() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setErrorCouldNotFetchPredefinedUserStatuses(true); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + QCOMPARE(model.errorMessage(), + tr("Could not fetch predefined statuses. Make sure you are connected to the server.")); + } + + void testError_couldNotFetchUserStatus_emitError() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setErrorCouldNotFetchUserStatus(true); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + QCOMPARE(model.errorMessage(), + tr("Could not fetch user status. Make sure you are connected to the server.")); + } + + void testError_userStatusNotSupported_emitError() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setErrorUserStatusNotSupported(true); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + QCOMPARE(model.errorMessage(), + tr("User status feature is not supported. You will not be able to set your user status.")); + } + + void testError_couldSetUserStatus_emitError() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setErrorCouldNotSetUserStatusMessage(true); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + model.setUserStatus(); + + QCOMPARE(model.errorMessage(), + tr("Could not set user status. Make sure you are connected to the server.")); + } + + void testError_emojisNotSupported_emitError() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setErrorEmojisNotSupported(true); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + QCOMPARE(model.errorMessage(), + tr("Emojis feature is not supported. Some user status functionality may not work.")); + } + + void testError_couldNotClearMessage_emitError() + { + auto fakeUserStatusJob = std::make_shared(); + fakeUserStatusJob->setErrorCouldNotClearUserStatusMessage(true); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + model.clearUserStatus(); + + QCOMPARE(model.errorMessage(), + tr("Could not clear user status message. Make sure you are connected to the server.")); + } + + void testError_setUserStatus_clearErrorMessage() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + fakeUserStatusJob->setErrorCouldNotSetUserStatusMessage(true); + model.setUserStatus(); + QVERIFY(!model.errorMessage().isEmpty()); + fakeUserStatusJob->setErrorCouldNotSetUserStatusMessage(false); + model.setUserStatus(); + QVERIFY(model.errorMessage().isEmpty()); + } + + void testError_clearUserStatus_clearErrorMessage() + { + auto fakeUserStatusJob = std::make_shared(); + OCC::UserStatusSelectorModel model(fakeUserStatusJob); + + fakeUserStatusJob->setErrorCouldNotSetUserStatusMessage(true); + model.setUserStatus(); + QVERIFY(!model.errorMessage().isEmpty()); + fakeUserStatusJob->setErrorCouldNotSetUserStatusMessage(false); + model.clearUserStatus(); + QVERIFY(model.errorMessage().isEmpty()); + } +}; + +QTEST_GUILESS_MAIN(TestSetUserStatusDialog) +#include "testsetuserstatusdialog.moc" diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index d241606595ee..7e1fc36c46ea 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -33,6 +33,14 @@ bool itemDidCompleteSuccessfully(const ItemCompletedSpy &spy, const QString &pat return false; } +bool itemDidCompleteSuccessfullyWithExpectedRank(const ItemCompletedSpy &spy, const QString &path, int rank) +{ + if (auto item = spy.findItemWithExpectedRank(path, rank)) { + return item->_status == SyncFileItem::Success; + } + return false; +} + class TestSyncEngine : public QObject { Q_OBJECT @@ -82,6 +90,29 @@ private slots: QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); } + void testDirUploadWithDelayedAlgorithm() { + FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()}; + ItemCompletedSpy completeSpy(fakeFolder); + fakeFolder.localModifier().mkdir("Y"); + fakeFolder.localModifier().insert("Y/d0"); + fakeFolder.localModifier().mkdir("Z"); + fakeFolder.localModifier().insert("Z/d0"); + fakeFolder.localModifier().insert("A/a0"); + fakeFolder.localModifier().insert("B/b0"); + fakeFolder.localModifier().insert("r0"); + fakeFolder.localModifier().insert("r1"); + fakeFolder.syncOnce(); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "Y", 0)); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "Z", 1)); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "Y/d0", 2)); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "Z/d0", 3)); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "A/a0", 4)); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "B/b0", 5)); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "r0", 6)); + QVERIFY(itemDidCompleteSuccessfullyWithExpectedRank(completeSpy, "r1", 7)); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } + void testLocalDelete() { FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()}; ItemCompletedSpy completeSpy(fakeFolder); @@ -336,7 +367,7 @@ private slots: }); // For directly editing the remote checksum - auto &remoteInfo = dynamic_cast(fakeFolder.remoteModifier()); + auto &remoteInfo = fakeFolder.remoteModifier(); // Base mtime with no ms content (filesystem is seconds only) auto mtime = QDateTime::currentDateTimeUtc().addDays(-4); diff --git a/test/testsyncjournaldb.cpp b/test/testsyncjournaldb.cpp index fd404559bced..718920446cc2 100644 --- a/test/testsyncjournaldb.cpp +++ b/test/testsyncjournaldb.cpp @@ -117,7 +117,7 @@ private slots: { SyncJournalFileRecord record; record._path = "foo-nochecksum"; - record._remotePerm = RemotePermissions(); + record._remotePerm = RemotePermissions::fromDbValue("RW"); record._modtime = Utility::qDateTimeToTime_t(QDateTime::currentDateTimeUtc()); QVERIFY(_db.setFileRecord(record)); @@ -214,6 +214,7 @@ private slots: record._path = path; record._type = type; record._etag = initialEtag; + record._remotePerm = RemotePermissions::fromDbValue("RW"); _db.setFileRecord(record); }; auto getEtag = [&](const QByteArray &path) { @@ -275,6 +276,7 @@ private slots: auto makeEntry = [&](const QByteArray &path) { SyncJournalFileRecord record; record._path = path; + record._remotePerm = RemotePermissions::fromDbValue("RW"); _db.setFileRecord(record); }; diff --git a/test/testtheme.cpp b/test/testtheme.cpp index 52bc7b324d49..c50766f925ce 100644 --- a/test/testtheme.cpp +++ b/test/testtheme.cpp @@ -16,6 +16,7 @@ #include "theme.h" #include "themeutils.h" +#include "iconutils.h" class TestTheme : public QObject { diff --git a/test/testunifiedsearchlistmodel.cpp b/test/testunifiedsearchlistmodel.cpp new file mode 100644 index 000000000000..ea7de04badb4 --- /dev/null +++ b/test/testunifiedsearchlistmodel.cpp @@ -0,0 +1,640 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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/unifiedsearchresultslistmodel.h" + +#include "account.h" +#include "accountstate.h" +#include "syncenginetestutils.h" + +#include +#include +#include +#include + +namespace { +/** + * @brief The FakeDesktopServicesUrlHandler + * overrides QDesktopServices::openUrl + **/ +class FakeDesktopServicesUrlHandler : public QObject +{ + Q_OBJECT + +public: + FakeDesktopServicesUrlHandler(QObject *parent = nullptr) + : QObject(parent) + {} + +public: +signals: + void resultClicked(const QUrl &url); +}; + +/** + * @brief The FakeProvider + * is a simple structure that represents initial list of providers and their properties + **/ +class FakeProvider +{ +public: + QString _id; + QString _name; + qint32 _order = std::numeric_limits::max(); + quint32 _numItemsToInsert = 5; // how many fake resuls to insert +}; + +// this will be used when initializing fake search results data for each provider +static const QVector fakeProvidersInitInfo = { + {QStringLiteral("settings_apps"), QStringLiteral("Apps"), -50, 10}, + {QStringLiteral("talk-message"), QStringLiteral("Messages"), -2, 17}, + {QStringLiteral("files"), QStringLiteral("Files"), 5, 3}, + {QStringLiteral("deck"), QStringLiteral("Deck"), 10, 5}, + {QStringLiteral("comments"), QStringLiteral("Comments"), 10, 2}, + {QStringLiteral("mail"), QStringLiteral("Mails"), 10, 15}, + {QStringLiteral("calendar"), QStringLiteral("Events"), 30, 11} +}; + +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":[]}} +)"; + +/** + * @brief The FakeSearchResultsStorage + * emulates the real server storage that contains all the results that UnifiedSearchListmodel will search for + **/ +class FakeSearchResultsStorage +{ + class Provider + { + public: + class SearchResult + { + public: + QString _thumbnailUrl; + QString _title; + QString _subline; + QString _resourceUrl; + QString _icon; + bool _rounded; + }; + + QString _id; + QString _name; + qint32 _order = std::numeric_limits::max(); + qint32 _cursor = 0; + bool _isPaginated = false; + QVector _results; + }; + + FakeSearchResultsStorage() = default; + +public: + static FakeSearchResultsStorage *instance() + { + if (!_instance) { + _instance = new FakeSearchResultsStorage(); + _instance->init(); + } + + return _instance; + }; + + static void destroy() + { + if (_instance) { + delete _instance; + } + + _instance = nullptr; + } + + void init() + { + if (!_searchResultsData.isEmpty()) { + return; + } + + _metaSuccess = {{QStringLiteral("status"), QStringLiteral("ok")}, {QStringLiteral("statuscode"), 200}, + {QStringLiteral("message"), QStringLiteral("OK")}}; + + initProvidersResponse(); + + initSearchResultsData(); + } + + // initialize the JSON response containing the fake list of providers and their properties + void initProvidersResponse() + { + QList providersList; + + for (const auto &fakeProviderInitInfo : fakeProvidersInitInfo) { + providersList.push_back(QVariantMap{ + {QStringLiteral("id"), fakeProviderInitInfo._id}, + {QStringLiteral("name"), fakeProviderInitInfo._name}, + {QStringLiteral("order"), fakeProviderInitInfo._order}, + }); + } + + const QVariantMap ocsMap = { + {QStringLiteral("meta"), _metaSuccess}, + {QStringLiteral("data"), providersList} + }; + + _providersResponse = + QJsonDocument::fromVariant(QVariantMap{{QStringLiteral("ocs"), ocsMap}}).toJson(QJsonDocument::Compact); + } + + // init the map of fake search results for each provider + void initSearchResultsData() + { + for (const auto &fakeProvider : fakeProvidersInitInfo) { + auto &providerData = _searchResultsData[fakeProvider._id]; + providerData._id = fakeProvider._id; + providerData._name = fakeProvider._name; + providerData._order = fakeProvider._order; + if (fakeProvider._numItemsToInsert > pageSize) { + providerData._isPaginated = true; + } + for (quint32 i = 0; i < fakeProvider._numItemsToInsert; ++i) { + providerData._results.push_back( + {"http://example.de/avatar/john/64", QString(QStringLiteral("John Doe in ") + fakeProvider._name), + QString(QStringLiteral("We a discussion about ") + fakeProvider._name + + QStringLiteral(" already. But, let's have a follow up tomorrow afternoon.")), + "http://example.de/call/abcde12345#message_12345", QStringLiteral("icon-talk"), true}); + } + } + } + + const QList resultsForProvider(const QString &providerId, int cursor) + { + QList list; + + const auto results = resultsForProviderAsVector(providerId, cursor); + + if (results.isEmpty()) { + return list; + } + + for (const auto &result : results) { + list.push_back(QVariantMap{ + {"thumbnailUrl", result._thumbnailUrl}, + {"title", result._title}, + {"subline", result._subline}, + {"resourceUrl", result._resourceUrl}, + {"icon", result._icon}, + {"rounded", result._rounded} + }); + } + + return list; + } + + const QVector resultsForProviderAsVector(const QString &providerId, int cursor) + { + QVector results; + + const auto provider = _searchResultsData.value(providerId, Provider()); + + if (provider._id.isEmpty() || cursor > provider._results.size()) { + return results; + } + + const int n = cursor + pageSize > provider._results.size() + ? 0 + : cursor + pageSize; + + for (int i = cursor; i < n; ++i) { + results.push_back(provider._results[i]); + } + + return results; + } + + const QByteArray queryProvider(const QString &providerId, const QString &searchTerm, int cursor) + { + if (!_searchResultsData.contains(providerId)) { + return fake404Response; + } + + if (searchTerm == QStringLiteral("[HTTP500]")) { + return fake500Response; + } + + if (searchTerm == QStringLiteral("[empty]")) { + const QVariantMap dataMap = {{QStringLiteral("name"), _searchResultsData[providerId]._name}, + {QStringLiteral("isPaginated"), false}, {QStringLiteral("cursor"), 0}, + {QStringLiteral("entries"), QVariantList{}}}; + + const QVariantMap ocsMap = {{QStringLiteral("meta"), _metaSuccess}, {QStringLiteral("data"), dataMap}}; + + return QJsonDocument::fromVariant(QVariantMap{{QStringLiteral("ocs"), ocsMap}}) + .toJson(QJsonDocument::Compact); + } + + const auto provider = _searchResultsData.value(providerId, Provider()); + + const auto nextCursor = cursor + pageSize; + + const QVariantMap dataMap = {{QStringLiteral("name"), _searchResultsData[providerId]._name}, + {QStringLiteral("isPaginated"), _searchResultsData[providerId]._isPaginated}, + {QStringLiteral("cursor"), nextCursor}, + {QStringLiteral("entries"), resultsForProvider(providerId, cursor)}}; + + const QVariantMap ocsMap = {{QStringLiteral("meta"), _metaSuccess}, {QStringLiteral("data"), dataMap}}; + + return QJsonDocument::fromVariant(QVariantMap{{QStringLiteral("ocs"), ocsMap}}).toJson(QJsonDocument::Compact); + } + + const QByteArray &fakeProvidersResponseJson() const { return _providersResponse; } + +private: + static FakeSearchResultsStorage *_instance; + + static const int pageSize = 5; + + QMap _searchResultsData; + + QByteArray _providersResponse = fake404Response; + + QVariantMap _metaSuccess; +}; + +FakeSearchResultsStorage *FakeSearchResultsStorage::_instance = nullptr; + +} + +class TestUnifiedSearchListmodel : public QObject +{ + Q_OBJECT + +public: + TestUnifiedSearchListmodel() = default; + + QScopedPointer fakeQnam; + OCC::AccountPtr account; + QScopedPointer accountState; + QScopedPointer model; + QScopedPointer modelTester; + + QScopedPointer fakeDesktopServicesUrlHandler; + + static const 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 cursor = urlQuery.queryItemValue(QStringLiteral("cursor")).toInt(); + const auto searchTerm = urlQuery.queryItemValue(QStringLiteral("term")); + 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); + } + + // handle fetch of providers list + if (path.startsWith(QStringLiteral("/ocs/v2.php/search/providers")) && searchTerm.isEmpty()) { + reply = new FakePayloadReply(op, req, + FakeSearchResultsStorage::instance()->fakeProvidersResponseJson(), fakeQnam.data()); + // handle search for provider + } else if (path.startsWith(QStringLiteral("/ocs/v2.php/search/providers")) && !searchTerm.isEmpty()) { + const auto pathSplit = path.mid(QString(QStringLiteral("/ocs/v2.php/search/providers")).size()) + .split(QLatin1Char('/'), Qt::SkipEmptyParts); + + if (!pathSplit.isEmpty() && path.contains(pathSplit.first())) { + reply = new FakePayloadReply(op, req, + FakeSearchResultsStorage::instance()->queryProvider(pathSplit.first(), searchTerm, cursor), + searchResultsReplyDelay, fakeQnam.data()); + } + } + + if (!reply) { + return qobject_cast(new FakeErrorReply(op, req, this, 404, QByteArrayLiteral("{error: \"Not found!\"}"))); + } + + return reply; + }); + + model.reset(new OCC::UnifiedSearchResultsListModel(accountState.data())); + + modelTester.reset(new QAbstractItemModelTester(model.data())); + + fakeDesktopServicesUrlHandler.reset(new FakeDesktopServicesUrlHandler); + } + void testSetSearchTermStartStopSearch() + { + // make sure the model is empty + model->setSearchTerm(QStringLiteral("")); + QVERIFY(model->rowCount() == 0); + + // #1 test setSearchTerm actually sets the search term and the signal is emitted + QSignalSpy searhTermChanged(model.data(), &OCC::UnifiedSearchResultsListModel::searchTermChanged); + model->setSearchTerm(QStringLiteral("dis")); + QCOMPARE(searhTermChanged.count(), 1); + QCOMPARE(model->searchTerm(), QStringLiteral("dis")); + + // #2 test setSearchTerm actually sets the search term and the signal is emitted + searhTermChanged.clear(); + model->setSearchTerm(model->searchTerm() + QStringLiteral("cuss")); + QCOMPARE(model->searchTerm(), QStringLiteral("discuss")); + QCOMPARE(searhTermChanged.count(), 1); + + // #3 test that model has not started search yet + QVERIFY(!model->isSearchInProgress()); + + + // #4 test that model has started the search after specific delay + QSignalSpy searchInProgressChanged(model.data(), &OCC::UnifiedSearchResultsListModel::isSearchInProgressChanged); + // allow search jobs to get created within the model + QVERIFY(searchInProgressChanged.wait()); + QCOMPARE(searchInProgressChanged.count(), 1); + QVERIFY(model->isSearchInProgress()); + + // #5 test that model has stopped the search after setting empty search term + model->setSearchTerm(QStringLiteral("")); + QVERIFY(!model->isSearchInProgress()); + } + + void testSetSearchTermResultsFound() + { + // make sure the model is empty + model->setSearchTerm(QStringLiteral("")); + QVERIFY(model->rowCount() == 0); + + // test that search term gets set, search gets started and enough results get returned + model->setSearchTerm(model->searchTerm() + QStringLiteral("discuss")); + + QSignalSpy searchInProgressChanged( + model.data(), &OCC::UnifiedSearchResultsListModel::isSearchInProgressChanged); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has started + QCOMPARE(searchInProgressChanged.count(), 1); + QVERIFY(model->isSearchInProgress()); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has finished + QVERIFY(!model->isSearchInProgress()); + + QVERIFY(model->rowCount() > 0); + } + + void testSetSearchTermResultsNotFound() + { + // make sure the model is empty + model->setSearchTerm(QStringLiteral("")); + QVERIFY(model->rowCount() == 0); + + // test that search term gets set, search gets started and enough results get returned + model->setSearchTerm(model->searchTerm() + QStringLiteral("[empty]")); + + QSignalSpy searchInProgressChanged( + model.data(), &OCC::UnifiedSearchResultsListModel::isSearchInProgressChanged); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has started + QCOMPARE(searchInProgressChanged.count(), 1); + QVERIFY(model->isSearchInProgress()); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has finished + QVERIFY(!model->isSearchInProgress()); + + QVERIFY(model->rowCount() == 0); + } + + void testFetchMoreClicked() + { + // make sure the model is empty + model->setSearchTerm(QStringLiteral("")); + QVERIFY(model->rowCount() == 0); + + QSignalSpy searchInProgressChanged( + model.data(), &OCC::UnifiedSearchResultsListModel::isSearchInProgressChanged); + + // test that search term gets set, search gets started and enough results get returned + model->setSearchTerm(model->searchTerm() + QStringLiteral("whatever")); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has started + QVERIFY(model->isSearchInProgress()); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has finished + QVERIFY(!model->isSearchInProgress()); + + const auto numRowsInModelPrev = model->rowCount(); + + // test fetch more results + QSignalSpy currentFetchMoreInProgressProviderIdChanged( + model.data(), &OCC::UnifiedSearchResultsListModel::currentFetchMoreInProgressProviderIdChanged); + QSignalSpy rowsInserted(model.data(), &OCC::UnifiedSearchResultsListModel::rowsInserted); + for (int i = 0; i < model->rowCount(); ++i) { + const auto type = model->data(model->index(i), OCC::UnifiedSearchResultsListModel::DataRole::TypeRole); + + if (type == OCC::UnifiedSearchResult::Type::FetchMoreTrigger) { + const auto providerId = + model->data(model->index(i), OCC::UnifiedSearchResultsListModel::DataRole::ProviderIdRole) + .toString(); + model->fetchMoreTriggerClicked(providerId); + break; + } + } + + // make sure the currentFetchMoreInProgressProviderId was set back and forth and correct number fows has been inserted + QCOMPARE(currentFetchMoreInProgressProviderIdChanged.count(), 1); + + const auto providerIdFetchMoreTriggered = model->currentFetchMoreInProgressProviderId(); + + QVERIFY(!providerIdFetchMoreTriggered.isEmpty()); + + QVERIFY(currentFetchMoreInProgressProviderIdChanged.wait()); + + QVERIFY(model->currentFetchMoreInProgressProviderId().isEmpty()); + + QCOMPARE(rowsInserted.count(), 1); + + const auto arguments = rowsInserted.takeFirst(); + + QVERIFY(arguments.size() > 0); + + const auto first = arguments.at(0).toInt(); + const auto last = arguments.at(1).toInt(); + + const int numInsertedExpected = last - first; + + QCOMPARE(model->rowCount() - numRowsInModelPrev, numInsertedExpected); + + // make sure the FetchMoreTrigger gets removed when no more results available + if (!providerIdFetchMoreTriggered.isEmpty()) { + currentFetchMoreInProgressProviderIdChanged.clear(); + rowsInserted.clear(); + + QSignalSpy rowsRemoved(model.data(), &OCC::UnifiedSearchResultsListModel::rowsRemoved); + + for (int i = 0; i < 10; ++i) { + model->fetchMoreTriggerClicked(providerIdFetchMoreTriggered); + + QVERIFY(currentFetchMoreInProgressProviderIdChanged.wait()); + + if (rowsRemoved.count() > 0) { + break; + } + } + + QCOMPARE(rowsRemoved.count(), 1); + + bool isFetchMoreTriggerFound = false; + + for (int i = 0; i < model->rowCount(); ++i) { + const auto type = model->data(model->index(i), OCC::UnifiedSearchResultsListModel::DataRole::TypeRole); + const auto providerId = model->data(model->index(i), OCC::UnifiedSearchResultsListModel::DataRole::ProviderIdRole) + .toString(); + if (type == OCC::UnifiedSearchResult::Type::FetchMoreTrigger + && providerId == providerIdFetchMoreTriggered) { + isFetchMoreTriggerFound = true; + break; + } + } + + QVERIFY(!isFetchMoreTriggerFound); + } + } + + void testSearchResultlicked() + { + // make sure the model is empty + model->setSearchTerm(QStringLiteral("")); + QVERIFY(model->rowCount() == 0); + + // test that search term gets set, search gets started and enough results get returned + model->setSearchTerm(model->searchTerm() + QStringLiteral("discuss")); + + QSignalSpy searchInProgressChanged( + model.data(), &OCC::UnifiedSearchResultsListModel::isSearchInProgressChanged); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has started + QCOMPARE(searchInProgressChanged.count(), 1); + QVERIFY(model->isSearchInProgress()); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has finished and some results has been received + QVERIFY(!model->isSearchInProgress()); + + QVERIFY(model->rowCount() != 0); + + QDesktopServices::setUrlHandler("http", fakeDesktopServicesUrlHandler.data(), "resultClicked"); + QDesktopServices::setUrlHandler("https", fakeDesktopServicesUrlHandler.data(), "resultClicked"); + + QSignalSpy resultClicked(fakeDesktopServicesUrlHandler.data(), &FakeDesktopServicesUrlHandler::resultClicked); + + // test click on a result item + QString urlForClickedResult; + + for (int i = 0; i < model->rowCount(); ++i) { + const auto type = model->data(model->index(i), OCC::UnifiedSearchResultsListModel::DataRole::TypeRole); + + if (type == OCC::UnifiedSearchResult::Type::Default) { + const auto providerId = + model->data(model->index(i), OCC::UnifiedSearchResultsListModel::DataRole::ProviderIdRole) + .toString(); + urlForClickedResult = model->data(model->index(i), OCC::UnifiedSearchResultsListModel::DataRole::ResourceUrlRole).toString(); + + if (!providerId.isEmpty() && !urlForClickedResult.isEmpty()) { + model->resultClicked(providerId, QUrl(urlForClickedResult)); + break; + } + } + } + + QCOMPARE(resultClicked.count(), 1); + + const auto arguments = resultClicked.takeFirst(); + + const auto urlOpenTriggeredViaDesktopServices = arguments.at(0).toString(); + + QCOMPARE(urlOpenTriggeredViaDesktopServices, urlForClickedResult); + } + + void testSetSearchTermResultsError() + { + // make sure the model is empty + model->setSearchTerm(QStringLiteral("")); + QVERIFY(model->rowCount() == 0); + + QSignalSpy errorStringChanged(model.data(), &OCC::UnifiedSearchResultsListModel::errorStringChanged); + QSignalSpy searchInProgressChanged( + model.data(), &OCC::UnifiedSearchResultsListModel::isSearchInProgressChanged); + + model->setSearchTerm(model->searchTerm() + QStringLiteral("[HTTP500]")); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has started + QVERIFY(model->isSearchInProgress()); + + QVERIFY(searchInProgressChanged.wait()); + + // make sure search has finished + QVERIFY(!model->isSearchInProgress()); + + // make sure the model is empty and an error string has been set + QVERIFY(model->rowCount() == 0); + + QVERIFY(errorStringChanged.count() > 0); + + QVERIFY(!model->errorString().isEmpty()); + } + + void cleanupTestCase() + { + FakeSearchResultsStorage::destroy(); + } +}; + +QTEST_MAIN(TestUnifiedSearchListmodel) +#include "testunifiedsearchlistmodel.moc" diff --git a/test/testutility.cpp b/test/testutility.cpp index cd0d1045c99f..7fa16e57318b 100644 --- a/test/testutility.cpp +++ b/test/testutility.cpp @@ -58,8 +58,7 @@ private slots: void testLaunchOnStartup() { - qsrand(QDateTime::currentDateTime().toTime_t()); - QString postfix = QString::number(qrand()); + QString postfix = QString::number(OCC::Utility::rand()); const QString appName = QString::fromLatin1("testLaunchOnStartup.%1").arg(postfix); const QString guiName = "LaunchOnStartup GUI Name"; @@ -124,8 +123,8 @@ private slots: qDebug() << "Version of installed Nextcloud: " << ver; QVERIFY(!ver.isEmpty()); - QRegExp rx(APPLICATION_SHORTNAME R"( version \d+\.\d+\.\d+.*)"); - QVERIFY(rx.exactMatch(ver)); + const QRegularExpression rx(QRegularExpression::anchoredPattern(APPLICATION_SHORTNAME R"( version \d+\.\d+\.\d+.*)")); + QVERIFY(rx.match(ver).hasMatch()); } else { QVERIFY(versionOfInstalledBinary().isEmpty()); } diff --git a/theme.qrc b/theme.qrc deleted file mode 100644 index 8da6ba56ba45..000000000000 --- a/theme.qrc +++ /dev/null @@ -1,202 +0,0 @@ - - - theme/colored/16-Nextcloud-icon.png - theme/colored/24-Nextcloud-icon.png - theme/colored/32-Nextcloud-icon.png - theme/colored/48-Nextcloud-icon.png - theme/colored/64-Nextcloud-icon.png - theme/colored/128-Nextcloud-icon.png - theme/colored/256-Nextcloud-icon.png - theme/colored/512-Nextcloud-icon.png - theme/colored/1024-Nextcloud-icon.png - theme/colored/state-error-32.png - theme/colored/state-error-64.png - theme/colored/state-error-128.png - theme/colored/state-error-256.png - theme/colored/state-ok-32.png - theme/colored/state-ok-64.png - theme/colored/state-ok-128.png - theme/colored/state-ok-256.png - theme/colored/state-pause-32.png - theme/colored/state-pause-64.png - theme/colored/state-pause-128.png - theme/colored/state-pause-256.png - theme/colored/state-sync-32.png - theme/colored/state-sync-64.png - theme/colored/state-sync-128.png - theme/colored/state-sync-256.png - theme/colored/wizard_logo.png - theme/colored/wizard_logo@2x.png - theme/colored/wizard_logo.svg - theme/white/state-error-32.png - theme/white/state-error-64.png - theme/white/state-error-128.png - theme/white/state-error-256.png - theme/white/state-ok-32.png - theme/white/state-ok-64.png - theme/white/state-ok-128.png - theme/white/state-ok-256.png - theme/white/state-pause-32.png - theme/white/state-pause-64.png - theme/white/state-pause-128.png - theme/white/state-pause-256.png - theme/white/state-sync-32.png - theme/white/state-sync-64.png - theme/white/state-sync-128.png - theme/white/state-sync-256.png - theme/black/state-error-32.png - theme/black/state-error-64.png - theme/black/state-error-128.png - theme/black/state-error-256.png - theme/black/state-ok-32.png - theme/black/state-ok-64.png - theme/black/state-ok-128.png - theme/black/state-ok-256.png - theme/black/state-pause-32.png - theme/black/state-pause-64.png - theme/black/state-pause-128.png - theme/black/state-pause-256.png - theme/black/state-sync-32.png - theme/black/state-sync-64.png - theme/black/state-sync-128.png - theme/black/state-sync-256.png - theme/colored/state-error.svg - theme/colored/state-error-16.png - theme/colored/state-offline.svg - theme/colored/state-offline-16.png - theme/colored/state-offline-32.png - theme/colored/state-offline-64.png - theme/colored/state-offline-128.png - theme/colored/state-offline-256.png - theme/colored/state-ok.svg - theme/colored/state-ok-16.png - theme/colored/state-pause.svg - theme/colored/state-pause-16.png - theme/colored/state-sync.svg - theme/colored/state-sync-16.png - theme/colored/state-warning.svg - theme/colored/state-warning-16.png - theme/colored/state-warning-32.png - theme/colored/state-warning-64.png - theme/colored/state-warning-128.png - theme/colored/state-warning-256.png - theme/black/folder.png - theme/black/folder@2x.png - theme/white/folder.png - theme/white/folder@2x.png - theme/colored/folder.png - theme/colored/folder@2x.png - theme/black/control-next.svg - theme/black/control-prev.svg - theme/black/state-error.svg - theme/black/state-error-16.png - theme/black/state-offline.svg - theme/black/state-offline-16.png - theme/black/state-offline-32.png - theme/black/state-offline-64.png - theme/black/state-offline-128.png - theme/black/state-offline-256.png - theme/black/state-ok.svg - theme/black/state-ok-16.png - theme/black/state-pause.svg - theme/black/state-pause-16.png - theme/black/state-sync.svg - theme/black/state-sync-16.png - theme/black/state-warning.svg - theme/black/state-warning-16.png - theme/black/state-warning-32.png - theme/black/state-warning-64.png - theme/black/state-warning-128.png - theme/black/state-warning-256.png - theme/white/control-next.svg - theme/white/control-prev.svg - theme/white/state-error.svg - theme/white/state-error-16.png - theme/white/state-offline.svg - theme/white/state-offline-16.png - theme/white/state-offline-32.png - theme/white/state-offline-64.png - theme/white/state-offline-128.png - theme/white/state-offline-256.png - theme/white/state-ok.svg - theme/white/state-ok-16.png - theme/white/state-pause.svg - theme/white/state-pause-16.png - theme/white/state-sync.svg - theme/white/state-sync-16.png - theme/white/state-warning.svg - theme/white/state-warning-16.png - theme/white/state-warning-32.png - theme/white/state-warning-64.png - theme/white/state-warning-128.png - theme/white/state-warning-256.png - theme/white/wizard-files.png - theme/white/wizard-files@2x.png - theme/white/wizard-groupware.png - theme/white/wizard-groupware@2x.png - theme/white/wizard-nextcloud.png - theme/white/wizard-nextcloud@2x.png - theme/white/wizard-talk.png - theme/white/wizard-talk@2x.png - theme/black/wizard-files.png - theme/black/wizard-files@2x.png - theme/black/wizard-groupware.png - theme/black/wizard-groupware@2x.png - theme/black/wizard-nextcloud.png - theme/black/wizard-nextcloud@2x.png - theme/black/wizard-talk.png - theme/black/wizard-talk@2x.png - theme/black/wizard-files.png - theme/colored/wizard-files.png - theme/colored/wizard-files@2x.png - theme/colored/wizard-groupware.png - theme/colored/wizard-groupware@2x.png - theme/colored/wizard-nextcloud.png - theme/colored/wizard-nextcloud@2x.png - theme/colored/wizard-talk.png - theme/colored/wizard-talk@2x.png - theme/sync-arrow.svg - theme/white/external.png - theme/white/external@2x.png - theme/black/external.png - theme/black/external@2x.png - theme/colored/external.png - theme/colored/external@2x.png - theme/white/folder.svg - theme/white/more-apps.svg - theme/white/talk-app.svg - theme/white/caret-down.svg - theme/black/caret-down.svg - theme/white/user.svg - theme/black/user.svg - theme/white/add.svg - theme/black/add.svg - theme/black/activity.svg - theme/black/bell.svg - theme/black/state-info.svg - theme/close.svg - theme/files.svg - theme/public.svg - theme/settings.svg - theme/confirm.svg - theme/copy.svg - theme/more.svg - theme/change.svg - theme/lock-http.svg - theme/lock-https.svg - theme/lock-broken.svg - theme/network.svg - theme/account.svg - theme/colored/add.svg - theme/colored/delete.svg - theme/colored/Nextcloud-icon.svg - theme/add.svg - theme/share.svg - theme/reply.svg - theme/magnifying-glass.svg - theme/colored/user-status-online.svg - theme/colored/user-status-invisible.svg - theme/colored/user-status-away.svg - theme/colored/user-status-dnd.svg - - diff --git a/theme.qrc.in b/theme.qrc.in index 63da54883b96..aba4639b4fe6 100644 --- a/theme.qrc.in +++ b/theme.qrc.in @@ -44,6 +44,9 @@ theme/white/state-sync-64.png theme/white/state-sync-128.png theme/white/state-sync-256.png + theme/black/clear.svg + theme/black/comment.svg + theme/black/search.svg theme/black/state-error-32.png theme/black/state-error-64.png theme/black/state-error-128.png @@ -81,6 +84,7 @@ theme/colored/state-warning-128.png theme/colored/state-warning-256.png theme/black/folder.png + theme/black/folder.svg theme/black/folder@2x.png theme/white/folder.png theme/white/folder@2x.png @@ -147,6 +151,7 @@ theme/black/wizard-talk.png theme/black/wizard-talk@2x.png theme/black/wizard-files.png + theme/black/wizard-groupware.svg theme/colored/wizard-files.png theme/colored/wizard-files@2x.png theme/colored/wizard-groupware.png @@ -173,6 +178,9 @@ theme/black/add.svg theme/black/activity.svg theme/black/bell.svg + theme/black/wizard-talk.svg + theme/black/calendar.svg + theme/black/deck.svg theme/black/state-info.svg theme/close.svg theme/files.svg @@ -198,5 +206,8 @@ theme/colored/user-status-invisible.svg theme/colored/user-status-away.svg theme/colored/user-status-dnd.svg + theme/black/email.svg + theme/black/edit.svg + theme/delete.svg diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml index ea5aabde0236..b29db7aafbf7 100644 --- a/theme/Style/Style.qml +++ b/theme/Style/Style.qml @@ -12,6 +12,11 @@ QtObject { property color lightHover: "#f7f7f7" property color menuBorder: "#bdbdbd" + // ErrorBox colors + property color errorBoxTextColor: Theme.errorBoxTextColor + property color errorBoxBackgroundColor: Theme.errorBoxBackgroundColor + property color errorBoxBorderColor: Theme.errorBoxBorderColor + // Fonts // We are using pixel size because this is cross platform comparable, point size isn't property int topLinePixelSize: 12 @@ -56,4 +61,15 @@ QtObject { // Visual behaviour property bool hoverEffectsEnabled: true + + // unified search constants + readonly property int unifiedSearchItemHeight: trayWindowHeaderHeight + readonly property int unifiedSearchResultTextLeftMargin: 18 + readonly property int unifiedSearchResultTextRightMargin: 16 + readonly property int unifiedSearchResulIconWidth: 24 + readonly property int unifiedSearchResulIconLeftMargin: 12 + readonly property int unifiedSearchResulTitleFontSize: topLinePixelSize + readonly property int unifiedSearchResulSublineFontSize: subLinePixelSize + readonly property string unifiedSearchResulTitleColor: "black" + readonly property string unifiedSearchResulSublineColor: "grey" } diff --git a/theme/black/calendar.svg b/theme/black/calendar.svg new file mode 100644 index 000000000000..4ea05fefe9d4 --- /dev/null +++ b/theme/black/calendar.svg @@ -0,0 +1 @@ + diff --git a/theme/black/clear.svg b/theme/black/clear.svg new file mode 100644 index 000000000000..3cf9469e0a93 --- /dev/null +++ b/theme/black/clear.svg @@ -0,0 +1 @@ + diff --git a/theme/black/comment.svg b/theme/black/comment.svg new file mode 100644 index 000000000000..67c3fee585da --- /dev/null +++ b/theme/black/comment.svg @@ -0,0 +1 @@ + diff --git a/theme/black/deck.svg b/theme/black/deck.svg new file mode 100644 index 000000000000..12276249686e --- /dev/null +++ b/theme/black/deck.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/theme/black/edit.svg b/theme/black/edit.svg new file mode 100644 index 000000000000..dda21eb28937 --- /dev/null +++ b/theme/black/edit.svg @@ -0,0 +1,47 @@ + + + + + + + + + + diff --git a/theme/black/email.svg b/theme/black/email.svg new file mode 100644 index 000000000000..56fd74cf823c --- /dev/null +++ b/theme/black/email.svg @@ -0,0 +1 @@ + diff --git a/theme/black/search.svg b/theme/black/search.svg new file mode 100644 index 000000000000..58e7264c601e --- /dev/null +++ b/theme/black/search.svg @@ -0,0 +1 @@ + diff --git a/translations/client_bg.ts b/translations/client_bg.ts index 70b9ef8838dd..6210f0cdf6a3 100644 --- a/translations/client_bg.ts +++ b/translations/client_bg.ts @@ -12,23 +12,36 @@ Open %1 locally - + Отворяне %1 локално + + + + Open share dialog + Отваряне на диалоговия прозорец за споделяне + + + + Share %1 + Споделяне %1 Show more actions - + Показване на повече действия - - Open share dialog - + + View activity + Вижте активността + + + ActivityList - - Share %1 - + + Activity list + Списък на дейностите @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Проверка за промени в '%1' @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + Невъзможно преместването от „%1“ към „%2“ @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Грешка при премахването на „% 1“:% 2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Не можа да бъде премахната папката „% 1“ @@ -185,7 +198,7 @@ Logo - + Лого @@ -195,7 +208,7 @@ Switch to your browser to connect your account - + Превключете към браузъра си, за да свържете вашият профил @@ -331,22 +344,22 @@ End-to-End Encryption with Virtual Files - + Цялостно Криптиране с виртуални файлове You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Изглежда, че функцията за виртуални файлове е активирана в тази папка. В момента не е възможно имплицитно изтегляне на виртуални файлове, които са криптирани цялостно. За да получите най-доброто изживяване с виртуални файлове и цялостно криптиране, уверете се, че криптираната папка е маркирана с „Нека винаги е достъпна локално“. Don't encrypt folder - + Да не се се криптира папка Encrypt folder - + Криптиране на папка @@ -403,7 +416,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Изглежда, че функцията за виртуални файлове е активирана в тази папка. В момента не е възможно имплицитно изтегляне на виртуални файлове, които са криптирани цялостно. За да получите най-доброто изживяване с виртуални файлове и цялостно криптиране, уверете се, че криптираната папка е маркирана с „Нека винаги е достъпна локално“. @@ -415,12 +428,12 @@ Wait for the new sync, then encrypt it. Encryption failed - + Криптирането е неуспешно Could not encrypt folder because the folder does not exist anymore - + Не можа да се криптира папка, защото папката вече не съществува @@ -592,7 +605,7 @@ This action will abort any currently running synchronization. %1 as %2 - + %1 като %2 @@ -756,7 +769,7 @@ This action will abort any currently running synchronization. Certificate & Key (pkcs12): - + Сертификат и ключ (pkcs12): @@ -842,7 +855,7 @@ This action will abort any currently running synchronization. Enter username and password for "%1" at %2. - + Въведете потребителско име и парола за „%1“ на %2. @@ -1018,7 +1031,7 @@ This action will abort any currently running synchronization. Timeout - + Време за изчакване @@ -1098,7 +1111,7 @@ This can be an issue with your OpenSSL libraries. The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + URL адресът за анкета не започва с HTTPS, въпреки че URL адресът за влизане започва с HTTPS. Влизането няма да е възможно, защото това може да е проблем със сигурността. Моля, свържете се с вашия администратор. @@ -1116,7 +1129,7 @@ This can be an issue with your OpenSSL libraries. There was an error accessing the "token" endpoint: <br><em>%1</em> - + Възникна грешка при достъпа на крайната точка „маркер“: <br><em> %1</em> @@ -1133,7 +1146,7 @@ This can be an issue with your OpenSSL libraries. The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + Върнатият URL адрес на сървъра не започва с HTTPS, въпреки че URL адресът за влизане започва с HTTPS. Влизането няма да е възможно, защото това може да е проблем със сигурността. Моля, свържете се с вашия администратор. @@ -1144,34 +1157,34 @@ This can be an issue with your OpenSSL libraries. Невъзможност да се отвори браузъра, моля да копирате връзката в браузъра си. - + Waiting for authorization Изчаква се разрешение - + Polling for authorization Запитване за упълномощаване - + Starting authorization Стартиране на упълномощяване - + Link copied to clipboard. Копирано в клипборда - + Reopen Browser - + Отворете Браузъра отново - + Copy Link - + Копиране на връзката @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Това означава, че клиентът за синхронизация може да не качва локални промени веднага и вместо това само ще сканира за локални промени и ще ги качва през определен интервал от време(на всеки два часа по подразбиране). % 1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Всички файлове във вашата локална папка за синхронизиране '% 1' бяха изтрити. Тези изтривания ще бъдат синхронизирани с вашия сървър, което прави тези файлове недостъпни, освен ако не бъдат възстановени. + Сигурни ли сте, че искате да синхронизирате тези действия със сървъра? +Ако това е инцидент и решите да запазите файловете си, те ще бъдат синхронизирани отново от сървъра. @@ -1399,40 +1421,25 @@ Continuing the sync as normal will cause all your files to be overwritten by an Запазване на Локалните Файлове като Конфликтни - - All files in the sync folder '%1' folder were deleted on the server. + + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Всички файлове в папката за синхронизиране '% 1' бяха изтрити на сървъра. + Всички файлове в папката за синхронизиране „%1“' бяха изтрити на сървъра. Тези изтривания ще бъдат синхронизирани с вашата локална папка за синхронизиране, което прави тези файлове недостъпни, освен ако нямате право да ги възстановите. Ако решите да възстановите файловете, те ще бъдат повторно синхронизирани със сървъра, ако имате права за това. Ако решите да изтриете файловете, те ще бъдат недостъпни за вас, освен ако не сте собственикът. - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. + + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - Всички файлове във вашата локална папка за синхронизиране '% 1' бяха изтрити. Тези изтривания ще бъдат синхронизирани с вашия сървър, което прави тези файлове недостъпни, освен ако не бъдат възстановени. + Всички файлове във вашата локална папка за синхронизиране „%1“ бяха изтрити. Тези изтривания ще бъдат синхронизирани с вашия сървър, което прави тези файлове недостъпни, освен ако не бъдат възстановени. Сигурни ли сте, че искате да синхронизирате тези действия със сървъра? Ако това е инцидент и решите да запазите файловете си, те ще бъдат синхронизирани отново от сървъра. - - - All files in the sync folder "%1" folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - Remove All Files? @@ -1443,6 +1450,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Премахване на всички файлове + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Всички файлове в папката за синхронизиране „%1“ бяха изтрити на сървъра. +Тези изтривания ще бъдат синхронизирани с вашата локална папка за синхронизиране, което прави тези файлове недостъпни, освен ако нямате право да ги възстановите. +Ако решите да възстановите файловете, те ще бъдат повторно синхронизирани със сървъра, ако имате права за това. +Ако решите да изтриете файловете, те ще бъдат недостъпни за вас, освен ако не сте собственикът. + Keep files @@ -1492,7 +1510,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Намерен е стар дневник за синхронизиране „%1“, но не може да бъде премахнат. Моля да се уверите, че в момента не го използва нито едно приложение. @@ -1532,7 +1550,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Sync finished with unresolved conflicts. - + Синхронизирането приключи с неразрешени конфликти. @@ -1680,12 +1698,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Проверка за отдалечени промени „%1“ Checking for changes in local "%1" - + Проверка за локални промени „%1“ @@ -1845,7 +1863,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + Въведете име за новата папка, която ще бъде създадена под „%1“: @@ -1905,7 +1923,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + Виртуалните файлове не се поддържат за основни дялове на Windows като локална папка. Моля, изберете валидна подпапка под буквата на устройството. @@ -2160,7 +2178,7 @@ Note that this selects only what pool upgrades are taken from, and that there ar Reading from keychain failed with error: "%1" - + Четенето от ключодържател беше неуспешно с грешка: „%1“ @@ -2203,7 +2221,7 @@ Note that this selects only what pool upgrades are taken from, and that there ar This entry is provided by the system at "%1" and cannot be modified in this view. - + Този запис е предоставен от системата на „%1“ и не може да бъде модифициран в този изглед. @@ -2255,7 +2273,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Cannot write changes to "%1". - + Невъзможност да се пишат промени в „%1“. @@ -2273,6 +2291,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Добавяне на нов шаблон за игнориране + + OCC::InvalidFilenameDialog + + + Invalid filename + Невалидно име на файл + + + + The file could not be synced because it contains characters which are not allowed on this system. + Файлът не можа да бъде синхронизиран, защото съдържа знаци, които не са разрешени в тази система. + + + + Error + Грешка + + + + Please enter a new name for the file: + Моля, въведете ново име за файла: + + + + New filename + Нново име на файл + + + + Rename file + Преименуване на файл + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Файлът %1, не можа да бъде синхронизиран, защото съдържа знаци, които не са разрешени в тази система. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Следните знаци не са разрешени в системата: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Нямате право да преименувате този файл. Моля, помолете автора на файла да го преименува. + + + + Filename contains illegal characters: %1 + Името на файла съдържа невалидни знаци: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Файлът не можа да се преименува. Моля, уверете се, че сте свързани със сървъра. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Не може да се преименува файл, защото на сървъра, вече съществува файл със същото име. Моля, изберете друго име. + + OCC::LegalNotice @@ -2289,7 +2370,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from <p>Copyright 2017-2021 Nextcloud GmbH<br />Copyright 2012-2021 ownCloud GmbH</p> - + <p>Авторски права 2017-2021 Nextcloud GmbH<br /> Авторски права 2012-2021 ownCloud GmbH</p> @@ -2413,9 +2494,9 @@ Logs will be written to %1 <nobr>Файл „% 1“<br/> не може да бъде отворен за записване.<br/><br/> Изходът на регистрационния файл <b>не</b> може да бъде записан!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> - + <nobr>Файл „% 1“<br/> не може да бъде отворен за записване.<br/><br/> Изходът на регистрационния файл <b>не</b> може да бъде записан!</nobr> @@ -2456,6 +2537,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Налична е нова версия на % 1 Клиент, но процесът на актуализиране е неуспешен.</p><p><b>% 2</b> са изтеглени. Инсталираната версия е% 3</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Налична е нова версия на % 1 Клиент, но процесът на актуализиране е неуспешен.</p><p><b>% 2</b> са изтеглени. Инсталираната версия е% 3. Ако потвърдите рестартиране и актуализиране, компютърът ви може да се рестартира, за да завърши инсталацията.</p> + Ask again later @@ -2590,7 +2676,7 @@ Logs will be written to %1 There was an error accessing the "token" endpoint: <br><em>%1</em> - + Възникна грешка при достъпа на крайната точка „маркер“: <br><em> %1</em> @@ -2625,11 +2711,6 @@ Logs will be written to %1 New %1 Update Ready Готова Нова Актуализация на % 1 - - - New %1 update ready - - A new update for %1 is about to be installed. The updater may ask @@ -2637,6 +2718,16 @@ for additional privileges during the process. Предстои да бъде инсталирана нова актуализация на % 1. Актуализаторът може да поиска допълнителни привилегии по време на процеса. + + + New %1 update ready + Готова е нова актуализация на % 1 + + + + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Предстои да бъде инсталирана нова актуализация за %1. Актуализаторът може да поиска допълнителни привилегии по време на процеса. Вашият компютър може да се рестартира, за да завърши инсталацията. + Downloading version %1. Please wait … @@ -2672,20 +2763,30 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Наличен е нов % 1. Моля, кликнете <a href='%2'>тук</a>, изтегляне на актуализацията. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Актуализацията не можа да се изтегли. Моля, отворете <a href='%1'>тук</a>, за ръчно изтегляне на актуализацията. + Could not download update. Please open %1 to download the update manually. - + Актуализацията не можа да се изтегли. Моля, отворете %1, за ръчно изтегляне на актуализацията. Could not check for new updates. Проверката за актуализации не може да бъде извършена. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Наличен е нов % 1. Моля, отворете <a href='%2'>%2</a>, за изтегляне на актуализацията. + New %1 is available. Please open %2 to download the update. - + Наличен е нов % 1. Моля, отворете %2, за изтегляне на актуализацията. @@ -2723,7 +2824,7 @@ for additional privileges during the process. Connect - + Свързване @@ -2765,28 +2866,28 @@ for additional privileges during the process. Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + Виртуалните файлове не се поддържат за основни дялове на Windows като локална папка. Моля, изберете валидна подпапка под буквата на устройството. %1 folder "%2" is synced to local folder "%3" - + %1 папка „%2“ е синхронизирана с локалната папка „%3“ Sync the folder "%1" - + Синхронизиране на папка „%1“ Warning: The local folder is not empty. Pick a resolution! - + Предупреждение: Локалната папка не е празна. Изберете резолюция! %1 free space %1 gets replaced with the size and a matching unit. Example: 3 MB or 5 GB - + %1 свободно място @@ -2905,7 +3006,7 @@ for additional privileges during the process. The link to your %1 web interface when you open it in the browser. %1 will be replaced with the application name - + Връзката към вашия %1 уеб интерфейс, когато го отворите в браузъра. @@ -2942,7 +3043,7 @@ It is not advisable to use it. Server address does not seem to be valid - + Адресът на сървъра изглежда е невалиден @@ -2978,37 +3079,37 @@ It is not advisable to use it. Време за изчакване при опит за свързване с % 1 при % 2. - + Trying to connect to %1 at %2 … Опит се да се свърже с % 1 при % 2 ... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Заявката за удостоверяване към сървъра беше пренасочена към '% 1'. URL адресът е лош, сървърът е неправилно конфигуриран. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Удостоверената заявка към сървъра беше пренасочена към „%1“. URL адресът е лош, сървърът е неправилно конфигуриран. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Достъпът е забранен от сървъра. За да се провери дали имате правилен достъп<a href="%1"> щракнете тук</a> и ще получите достъп до услугата с вашия браузър. - + There was an invalid response to an authenticated WebDAV request Получен е невалиден отговор на удостоверена заявка за WebDAV - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Местната папка за синхронизиране % 1 вече съществува, настройка за синхронизиране. <br/><br/> - + Creating local sync folder %1 … Създаване на местна папка за синхронизиране % 1 @@ -3018,115 +3119,115 @@ It is not advisable to use it. ок - + OK - + Добре - + failed. неуспешен - + Could not create local folder %1 Локалната папка %1 не може да бъде създадена - + No remote folder specified! Не сте посочили отдалечена папка! - + Error: %1 Грешка: %1 - + creating folder on Nextcloud: %1 Създаване на папка на Nextcloud: %1 - + Remote folder %1 created successfully. Одалечената папка %1 е създадена. - + The remote folder %1 already exists. Connecting it for syncing. Отдалечената папка % 1 вече съществува. Свързване за синхронизиране. - - + + The folder creation resulted in HTTP error code %1 Създаването на папката предизвика HTTP грешка %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Създаването на отдалечена папка беше неуспешно, защото предоставените идентификационни данни са грешни! <br/>Моля, върнете се и проверете вашите идентификационни данни.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Създаването на отдалечена папка беше неуспешно, вероятно защото предоставените идентификационни данни са грешни!</font><br/> Моля, върнете се и проверете вашите идентификационни данни.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Създаването на отдалечената папка %1 се провали: <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Установена е връзка за синхронизиране от % 1 към отдалечена директория % 2. - + Successfully connected to %1! Успешно свързване с %1! - + Connection to %1 could not be established. Please check again. Връзката с % 1 не можа да бъде установена. Моля проверете отново. - + Folder rename failed Преименуването на папка се провали Can't remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - Не може да се премахне и архивира папката, защото папката или файлът в нея е отворен в друга програма. Моля да затворете папката или файла и да натиснете бутон опитайте отново или анулирайте настройката. + Не може да се премахне и архивира папката, защото папката или файлът в нея е отворен в друга програма. Моля да затворете папката или файла и да натиснете бутон опитайте отново или отменете настройката. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + Не може да се премахне и архивира папката, защото папката или файлът в нея е отворен в друга програма. Моля, затворете папката или файла и натиснете бутон повторен опит или отменете настройката. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Локалната папка %1 е създадена успешно!</b></font> OCC::OwncloudWizard + + + Add %1 account + Добавяне на %1 профил + %1 Connection Wizard %1 - Помощник за свързване - - - Add %1 account - - Skip folders configuration @@ -3165,24 +3266,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Следете за безопасността си - - OCC::OwncloudWizardResultPage - - - Everything set up! - Всичко е готово! - - - - Open Local Folder - Отвори локалната папка - - - - Open %1 in Browser - Отвори %1 в браузъра - - OCC::PollJob @@ -3193,6 +3276,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Файлът съдържа крайни интервали и не може да бъде преименуван, тъй като файл със същото име вече съществува на сървъра. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Файлът съдържа крайни интервали и не може да бъде преименуван, тъй като файл със същото име вече съществува локално. + Symbolic links are not supported in syncing. @@ -3208,16 +3301,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. Имена на файлове, завършващи с точка, не се поддържат от тази файлова система. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Имената на файлове, съдържащи символа '% 1', не се поддържат от тази файлова система. + + + File names containing the character "%1" are not supported on this file system. + Имената на файлове, съдържащи символа „%1“, не се поддържат в тази файлова система. + File name contains at least one invalid character @@ -3291,17 +3384,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Conflict when uploading some files to a folder. Those, conflicted, are going to get cleared! - + Конфликт при качване на някои файлове в папка. Тези, които са в конфликт, ще се изчистят! Conflict when uploading a folder. It's going to get cleared! - + Конфликт при качване на папка. Ще бъде изчистен! Conflict when uploading a file. It's going to get removed! - + Конфликт при качване на файл. Ще бъде премахнат! @@ -3344,9 +3437,9 @@ This is a new, experimental mode. If you decide to use it, please report any iss Сървърът отговори с грешка при четене на директория '% 1' : % 2 - + Server replied with an error while reading directory "%1" : %2 - + Сървърът отговори с грешка при четене на директория „%1“: %2 @@ -3359,12 +3452,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Грешка при актуализиране на метаданни: %1 File is currently in use - + Файлът в момента се използва @@ -3377,7 +3470,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss File %1 cannot be downloaded because encryption information is missing. - + Файл %1 не може да бъде изтеглен, защото липсва информация за криптиране. @@ -3389,7 +3482,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss File %1 cannot be downloaded because of a local file name clash! - + Файл % 1 не може да бъде изтеглен поради сблъсък с името на локален файл! @@ -3424,7 +3517,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss The downloaded file is empty, but the server said it should have been %1. - + Изтегленият файл е празен, но сървърът обяви, че е трябвало да бъде % 1. @@ -3439,12 +3532,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Грешка при актуализиране на метаданни: %1 The file %1 is currently in use - + Файлът %1 в момента се използва @@ -3475,7 +3568,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Could not create folder %1 - + Не можа да се създаде папка %1 @@ -3485,12 +3578,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Грешка при актуализиране на метаданни: %1 The file %1 is currently in use - + Файлът %1 в момента се използва @@ -3521,7 +3614,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss File %1 cannot be renamed to %2 because of a local file name clash - + Файл % 1 не може да бъде преименуван на %2 поради сблъсък с името на локален файл! @@ -3531,12 +3624,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Грешка при актуализиране на метаданни: %1 The file %1 is currently in use - + Файлът %1 в момента се използва @@ -3547,7 +3640,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to rename file - + Неуспешно преименуване на файл @@ -3586,12 +3679,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error writing metadata to the database: %1 - + Грешка при актуализиране на метаданните: %1 The file %1 is currently in use - + Файлът %1 в момента се използва @@ -3609,12 +3702,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Грешка при актуализиране на метаданни: %1 The file %1 is currently in use - + Файлът %1 в момента се използва @@ -3673,12 +3766,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Грешка при актуализиране на метаданни: %1 The file %1 is currently in use - + Файлът %1 в момента се използва @@ -3894,7 +3987,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss The file cannot be shared because it does not have sharing permission. - + Файлът не може да бъде споделен, защото е без право за споделяне. @@ -3927,17 +4020,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Note - + Бележка &Share link - &Връзка за споделяне + и Връзка за споделяне Set password - + Задаване на парола @@ -3952,18 +4045,13 @@ This is a new, experimental mode. If you decide to use it, please report any iss Expires - + Изтича Allow Editing Разрешаване на Редактиране - - - Allow editing - Разреши редактиране - Read only @@ -3984,6 +4072,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Защита с Парола + + + Allow editing + Разреши редактиране + + + + View only + Само изглед + Allow upload and editing @@ -3999,16 +4097,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Само за качване - - - Note to recipient - Бележка за получателя - Unshare Прекратяване на споделяне + + + Link name + Име на връзка + + + + Note to recipient + Бележка за получателя + Password protect @@ -4020,15 +4123,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Срок на валидност - - Delete share link - Изтрий споделената връзка + + Delete link + Изтриване на връзка Add another link Добавя още една връзка + + + Delete share link + Изтрий споделената връзка + Confirm Link Share Deletion @@ -4078,19 +4186,19 @@ This is a new, experimental mode. If you decide to use it, please report any iss Няма резултат за '%1' - + No results for "%1" - + Няма резултати за „%1“ Password for share required - + Нужна е парола за споделяне Please enter a password for your email share: - + Моля, въведете парола за споделяне на вашият имейл: @@ -4113,22 +4221,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Can edit - + Може да редактира Note: - + Бележка: Password: - + Парола: Expires: - + Изтича: @@ -4138,12 +4246,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Note to recipient - + Бележка за получателя Set expiration date - + Задаване на дата на изтичане @@ -4168,7 +4276,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password protect - + Защита с парола @@ -4182,12 +4290,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Сподели с %1 - Context menu share @@ -4214,6 +4316,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Сподели чрез %1 + + + + Activity + Активност + Copy private link to clipboard @@ -4285,6 +4393,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Изтриване + + + Share with %1 + parameter is Nextcloud + Сподели с %1 + OCC::SslButton @@ -4430,6 +4544,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Не може да се осъществи сигурна връзка с <i>%1</i>: + + + Additional errors: + Допълнителни грешки: + with Certificate %1 @@ -4604,6 +4723,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Наличен е само % 1, за започване трябват поне % 2 + + + Aborted + Прекратен + @@ -4756,27 +4880,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Невалидни знаци, моля, преименувайте "%1" + + + Synchronization will resume shortly. + Синхронизацията ще се възобнови скоро. + File name contains at least one invalid character Името на файла съдържа поне един невалиден знак - - Aborted - Прекратен - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Дисковото пространство е малко: Пропуснати са изтегляния, които биха намалили свободното място под% 1. - + There is insufficient space available on the server for some uploads. На сървъра няма достатъчно място за някои качвания. + + OCC::SyncStatusSummary + + + + Offline + Офлайн + + + + + + All synced! + Всички са синхронизирани! + + + + Some files couldn't be synced! + Някои файлове не могат да бъдат синхронизирани + + + + See below for errors + Вижте по-долу за грешки + + + + Syncing + Синхронизиране + + + + Sync paused + Синхронизирането е на пауза + + + + Some files could not be synced! + Някои файлове не могат да бъдат синхронизирани + + + + See below for warnings + Вижте по-долу за предупреждения + + + + %1 of %2 · %3 left + %1 от %2 · Остава %3 + + + + %1 of %2 + %1 от %2 + + + + Syncing file %1 of %2 + Синхронизиране на файл %1 от %2 + + OCC::Systray @@ -4844,7 +5029,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p><small>Using virtual files plugin: %1</small></p> - + <p><small>Използване на добавка за виртуални файлове: %1</small></p> @@ -4852,6 +5037,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Това издание е предоставено от % 1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Неуспешно извличане на доставчици + + + + Failed to fetch search providers for '%1'. Error: %2 + Неуспешно извличане на доставчици на търсене на „%1“. Грешка: %2 + + + + Search has failed for '%2'. + Търсенето на „%2“ не бе успешно. + + + + Search has failed for '%1'. Error: %2 + Търсенето на „%1“ не бе успешно. Грешка: %2  + + OCC::User @@ -4909,24 +5117,108 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Функцията за Виртуална файлова система изисква файлова система NTFS, % 1 използва % 2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Не можаха да се извлекът предварително дефинирани състояния. Уверете се, че сте свързани със сървъра. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - + + Could not fetch user status. Make sure you are connected to the server. + Не можа да се извлече потребителски статус. Уверете се, че сте свързани със сървъра. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - + + User status feature is not supported. You will not be able to set your user status. + Функцията за потребителско състояние не се поддържа. Няма да можете да зададете потребителското си състояние. + + + + Emojis feature is not supported. Some user status functionality may not work. + Функцията за емотикони не се поддържа. Някои функции за състоянието на потребителя може да не работят. + + + + Could not set user status. Make sure you are connected to the server. + Не можа да се зададе потребителски статус. Уверете се, че сте свързани със сървъра. + + + + Could not clear user status message. Make sure you are connected to the server. + Съобщението за състоянието на потребителя не можа да бъде изчистено. Уверете се, че сте свързани със сървъра. + + + + + Don't clear + Да не се изчиства + + + + 30 minutes + 30 минути + + + + + 1 hour + 1 час + + + + 4 hours + 4 часа + + + + + Today + Днес + + + + + This week + Тази седмица + + + + Less than a minute + По-малко от минута + + + + 1 minute + 1 минута + + + + %1 minutes + %1 минути + + + + %1 hours + %1 часове + + + + 1 day + 1 ден + + + + %1 days + %1 дни + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Функцията за Виртуална файлова система изисква файлова система NTFS, % 1 използва % 2 @@ -4952,7 +5244,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss You have been logged out of %1 as user %2. Please login again. - + Излязохте от % 1 като потребител % 2. Моля да влезте отново. @@ -4965,43 +5257,43 @@ This is a new, experimental mode. If you decide to use it, please report any iss Form - + Формуляр Log in to your %1 - + Вписване във вашия % 1 Create account with Provider - + Създаване на профил при Доставчик Keep your data secure and under your control - + Поддържайте данните си сигурни и под ваш контрол Secure collaboration & file exchange - + Безопасно сътрудничество и обмен на файлове Easy-to-use web mail, calendaring & contacts - + Лесна за използване уеб поща, календар и контакти Screensharing, online meetings & web conferences - + Споделяне на екрана, онлайн срещи и уеб конференции Host your own server - + Хост на свой собствен сървър @@ -5135,7 +5427,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in remote "%1" - + Проверка за отдалечени промени „%1“ @@ -5145,7 +5437,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in local "%1" - + Проверка за локални промени „%1“ @@ -5264,12 +5556,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss User name - + Потребителско име Server address - + Адрес на сървъра @@ -5284,7 +5576,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Sync Logo - + Лого за синхронизиране @@ -5294,17 +5586,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Local Folder - + Локална папка Synchronize everything from server - + Синхронизиране на всичко от сървъра Ask before syncing folders larger than - + Попитайте, преди да синхронизирате папки, по-големи от @@ -5315,7 +5607,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ask before syncing external storages - + Попитайте, преди да синхронизирате външни хранилища @@ -5340,7 +5632,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Keep local data - + Запазване на локалните данни @@ -5350,7 +5642,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Erase local folder and start a clean sync - + Изтрийте локалната папка и стартирайте на чисто синхронизиране @@ -5395,17 +5687,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss TextLabel - + Текстов етикет Logo - + Лого Server address - + Адрес на сървъра @@ -5420,7 +5712,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss This is the link to your %1 web interface when you open it in the browser. - + Това е връзката към вашия %1 уеб интерфейс, когато го отворите в браузъра. @@ -5443,14 +5735,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Вписване във вашия % 1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Целият профил се синхронизира с локалната папка - - QObject @@ -5517,22 +5801,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Away - + Отсъстващ Do not disturb - + Не безпокой Offline - + Офлайн Online - + На линия @@ -5540,7 +5824,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to connect database. - + Неуспешно свързване на базата данни. + + + + UnifiedSearchInputContainer + + + Search files, messages, events … + Търсене на файлове, съобщения, събития... + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Зареждане на още резултати + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Скелет на резултатите от търсенето. + + + + UnifiedSearchResultListItem + + + Load more results + Зареждане на още резултати @@ -5557,29 +5873,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Профилът е свързан - Current user status is do not disturb - + Account not connected + Профилът не е свързан - Account connected - Профилът е свързан + Current user status is online + Текущият потребителски статус е на линия - Account not connected - Профилът не е свързан + Current user status is do not disturb + Текущият потребителски статус е не безпокойте Account actions Действия на профил + + + Remove Account + Премахване на профил + + + + Set status + Задаване на състояние + @@ -5592,17 +5918,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Вписване - - - Remove Account - Премахване на профил - Remove account Премахване на профил + + UserStatusSelector + + + Online status + Състояние на линия + + + + Online + На линия + + + + Away + Отсъстващ + + + + Do not disturb + Не безпокой + + + + Invisible + Невидим + + + + Status message + Съобщение за състояние + + + + What is your status? + Какъв е вашият статус? + + + + Clear status message after + Изчистване на съобщение за състоянието след това + + + + Clear status message + Изчистване на съобщението за състоянието + + + + Set status message + Задаване на съобщение за състоянието + + Utility @@ -5664,12 +6038,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Заглавката на контролната сума е неправилна. - + The checksum header contained an unknown checksum type '%1' Заглавката на контролната сума съдържаше неизвестен тип контролна сума '%1' @@ -5679,19 +6053,19 @@ This is a new, experimental mode. If you decide to use it, please report any iss Изтегленият файл не съответства на контролната сума, той ще бъде възобновен. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Изтегленият файл не съответства на контролната сума, той ще бъде възобновен. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + Заглавката на контролната сума съдържаше неизвестен тип контролна сума „%1“ - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" - + Изтегленият файл не съответства на контролната сума, той ще бъде възобновен. „%1“ != „%2“ @@ -5718,6 +6092,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Пауза в синхронизирането за всички + + + Set user status + Задаване на потребителско състояние + Add account @@ -5746,18 +6125,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is online - + Текущият потребителски статус е на линия Current user status is do not disturb - - - - - - Show more actions - Показване на повече действия + Текущият потребителски статус е не безпокойте @@ -5819,6 +6192,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Отваряне на диалоговия прозорец за споделяне + + + Unified search results list + Обединен списък с резултати от търсенето + + + + + Show more actions + Показване на повече действия + + + + %1 - File activity + %1 - Файлова активност + main.cpp @@ -5835,7 +6224,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss %1 requires on a working system tray. If you are running XFCE, please follow <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">these instructions</a>. Otherwise, please install a system tray application such as "trayer" and try again. - + % 1 изисква в работеща системна област. Ако използвате XFCE, моля следвайте <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">тези инструкции</a>. В противен случай, моля, инсталирайте приложение в системната област, като например „trayer“ и опитайте отново. @@ -6118,6 +6507,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Влезте в браузъра си (Входен поток v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Всичко е готово! + + + + Open Local Folder + Отвори локалната папка + + + + Open %1 in Browser + Отвори %1 в браузъра + + OCC::ShibbolethCredentials @@ -6170,27 +6577,48 @@ This is a new, experimental mode. If you decide to use it, please report any iss Вписване + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Целият профил се синхронизира с локалната папка + + OCC::UserStatus Away - + Отсъстващ Do not disturb - + Не безпокой Offline - + Офлайн Online - + На линия + + + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Изтеглянето на цялостно шифрован файл беше неуспешно + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Изглежда, че се опитвате да изтеглите виртуален файл, който е цялостно криптиран. Имплицитното изтегляне на такива файлове в момента не се поддържа. За да заобиколите този проблем, отидете на настройките и маркирайте криптираната папка с „Нека винаги е достъпна локално“. \ No newline at end of file diff --git a/translations/client_br.ts b/translations/client_br.ts index 85171af11f14..5c00ddc866ff 100644 --- a/translations/client_br.ts +++ b/translations/client_br.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1137,32 +1150,32 @@ This can be an issue with your OpenSSL libraries. Dibosupl digeriñ ar Furcher, eiliit al liamm d'ho Furcher. - + Waiting for authorization O gortoz an dilesa - + Polling for authorization Votiñ evit an aotre - + Starting authorization Kregia an aotre - + Link copied to clipboard. Liamm eilet er golver. - + Reopen Browser - + Copy Link @@ -1331,6 +1344,13 @@ Talvout a ra ar c'hliant kemprenn a c'hell n'omp pas pellkas ar c %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1392,22 +1412,7 @@ Kendec'hel ar kemprenadenn evel boaz a adskrivao pep restr gant ur stumm ko Gouarn ar Restroù Diabarzh evel Stourm - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1415,7 +1420,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1431,6 +1436,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2259,6 +2272,69 @@ Traoù lec'h m'eo aotreet al lemel a vo lamet ma ampechont lamadur an Ouhzpennañ un tres da dianvezhañ nevez : + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2396,7 +2472,7 @@ Skrivet e vo ar gazetenn e %1 <nobr>Ar restr '%1'<br/> na c'hell ket bezhañ digoret evit skrivañ.<br/> <br/>Ar gazetenn disoc'h ne c'hell ket<b>c'hell</b> ket bezhañ enrollet !</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2439,6 +2515,11 @@ Skrivet e vo ar gazetenn e %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2608,6 +2689,13 @@ Skrivet e vo ar gazetenn e %1 New %1 Update Ready Adnevesadenn nevez prest evit %1 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Un adnevesadenn nevez evit %1 a vo staliet. An adnevesaer a goulenno marteze +evit aotreoù ouzhpenn e pad an oberenn. + New %1 update ready @@ -2615,10 +2703,8 @@ Skrivet e vo ar gazetenn e %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Un adnevesadenn nevez evit %1 a vo staliet. An adnevesaer a goulenno marteze -evit aotreoù ouzhpenn e pad an oberenn. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2655,6 +2741,11 @@ evit aotreoù ouzhpenn e pad an oberenn. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2665,6 +2756,11 @@ evit aotreoù ouzhpenn e pad an oberenn. Could not check for new updates. Dibosupl gwiriañ an adnevesadennoù nevez. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2960,37 +3056,37 @@ It is not advisable to use it. Deuet eo an termenn pa glaskemp genstagaén da %1 da %2. - + Trying to connect to %1 at %2 … Ho klask en em genstagañ da %1 da %2 ... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Goulenn dilesa d'ar servijour a zo bet adhentet da '%1'. An URL a zo fall, mikro'arventennaet eo ar servijour. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. An aksed a zo difennet d'ar servijour. Evit gouzout hag-eñ e c'hallit tizhout ar servijer, <a href="%1">klikit amañ</a> evit tizhout servijoù ho furcher. - + There was an invalid response to an authenticated WebDAV request Ur respont fall d'ar goulenn dilesa WabDAV a zo bet - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Bez ez eus dija eus an teuliad kemprennet diabarzh %1, ho arventennañ anezhañ evit ar gemprenn. <br/><br/> - + Creating local sync folder %1 … O krouiñ an teuliat kemrpennañ diabarzh %1 ... @@ -3000,84 +3096,84 @@ It is not advisable to use it. ok - + OK - + failed. c'hwitet. - + Could not create local folder %1 Dibosupl krouiñ an teuliad diabarzh %1 - + No remote folder specified! Teuliat pell lakaet ebet ! - + Error: %1 Fazi : %1 - + creating folder on Nextcloud: %1 krouiñ teuliadoù war Nextcloud %1 - + Remote folder %1 created successfully. Teuliat pell %1 krouiet mat. - + The remote folder %1 already exists. Connecting it for syncing. Pez ez eus dija eus ar restr pell %1. Ar genstagañ anezhañ evit e kemprenn. - - + + The folder creation resulted in HTTP error code %1 Krouadenn an teuliad en deus roet ar c'hod fazi HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> C'hwitet da grouiñ ar restr pell abalamour an titouroù identitelez roet a zo fall ! <br/>Gwiriit ho titouroù identitelezh.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">C'hwitet da grouiñ an teuliad pell abalamour da titouroù identitelezh fall roet sur walc'h.</font><br/>Gwiriit anezho</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. C'hwitat da grouiñ an teuliad pell %1 gant ar fazi <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Ur genstagadenn kemprenet eus %1 d'an teuliad pell %2 a zo bet staliet. - + Successfully connected to %1! Kenstaget mat da %1 ! - + Connection to %1 could not be established. Please check again. Ar genstagaden da %1 n'eo ket bet graet. Klaskit en dro. - + Folder rename failed C'hwitet da adenvel an teuliad @@ -3087,28 +3183,28 @@ It is not advisable to use it. Dibospul eo lemel hag enrollañ an teuliad peogwir en digor an teuliad pe ar rest en ur program all. Serit an teuliat pe ar restr ha pouerzit war klask en dro pe arestit ar staliadur. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>An teuliad kempren diabarzh %1 a zo bet krouet mat !</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Kemprennadenn Wizard - Add %1 account + + + %1 Connection Wizard + %1 Kemprennadenn Wizard + Skip folders configuration @@ -3141,24 +3237,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Staliet eo pep-tra ! - - - - Open Local Folder - Digeriñ an Teuliad Diabarzh - - - - Open %1 in Browser - Digeriñ %1 er Furcher - - OCC::PollJob @@ -3169,6 +3247,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3186,12 +3274,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3320,7 +3408,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3935,11 +4023,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Aotreañ Embann - - - Allow editing - Cheñchamentoù aotreet - Read only @@ -3960,6 +4043,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Gwarez Ger-tremen + + + Allow editing + Cheñchamentoù aotreet + + + + View only + + Allow upload and editing @@ -3975,16 +4068,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Lakaat ur restr (evit pellkes nemetken) - - - Note to recipient - Kemenañ d'an degemerer - Unshare Nag eskemm ken + + + Link name + + + + + Note to recipient + Kemenañ d'an degemerer + Password protect @@ -3996,15 +4094,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Lakaat un deizat termen - - Delete share link - Lemmet al liamm rannet + + Delete link + Add another link Implij ul liamm all + + + Delete share link + Lemmet al liamm rannet + Confirm Link Share Deletion @@ -4054,7 +4157,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Disoc'h ebet evit '%1' - + No results for "%1" @@ -4158,12 +4261,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Rannañ gant %1 - Context menu share @@ -4190,6 +4287,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Rannañ dre %1 + + + + Activity + + Copy private link to clipboard @@ -4261,6 +4364,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Lemel + + + Share with %1 + parameter is Nextcloud + Rannañ gant %1 + OCC::SslButton @@ -4406,6 +4515,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Na genstag ket e surentez da <i>%1</i> : + + + Additional errors: + + with Certificate %1 @@ -4580,6 +4694,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Nez eus nemet %1 dieub, ret eo kaout %2 d'an neubeutañ evit kregiñ + + + Aborted + + @@ -4732,27 +4851,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Arouez fall, andanvit "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Un arouez fall ez eus d'an neubeutañ en anv restr - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Plas el lenner re vihan : ar bellgargadennoù a lako ar plas dieub da mont dindan %1 a vo ankouaet. - + There is insufficient space available on the server for some uploads. N'ez eus ket trawalc'h a blas war ar servijour evit pelgasadennoù zo. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4828,6 +5008,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>An digoradenn-mañ a zo bet roet gant %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4885,23 +5088,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5419,14 +5706,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Ho c'jont a zo kemprennet d'an teuliad diabarzh - - QObject @@ -5519,6 +5798,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5533,22 +5844,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Kont kenstaged - Current user status is do not disturb + Account not connected - Account connected - Kont kenstaged + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5556,6 +5867,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + Lemel ar c'hont + + + + Set status + + @@ -5568,17 +5889,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Kennaskañ - - - Remove Account - Lemel ar c'hont - Remove account Lemel ar c'hont + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5640,12 +6009,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. N'eo ket mat niverenn kevetalder ar penn. - + The checksum header contained an unknown checksum type '%1' Niverenn kevetalder ar penn en deus ur stumm dianv '%1' @@ -5655,17 +6024,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ar restr pellkarget n'en deus ket an niverenn kevetalder mat, adkroget e vo ar bellgargadenn. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5694,6 +6063,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Ehanañ pep kemprennadenn + + + Set user status + + Add account @@ -5729,12 +6103,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5795,6 +6163,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Digeriñ an diviz rannañ + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6094,6 +6478,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Mont-tre en ho furcher (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Staliet eo pep-tra ! + + + + Open Local Folder + Digeriñ an Teuliad Diabarzh + + + + Open %1 in Browser + Digeriñ %1 er Furcher + + OCC::ShibbolethCredentials @@ -6146,6 +6548,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Kennaskañ + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Ho c'jont a zo kemprennet d'an teuliad diabarzh + + OCC::UserStatus @@ -6169,4 +6579,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_ca.ts b/translations/client_ca.ts index 18972de03ce6..88dc6557b6dc 100644 --- a/translations/client_ca.ts +++ b/translations/client_ca.ts @@ -12,22 +12,35 @@ Open %1 locally - + Obre %1 localment + + + + Open share dialog + Obre el quadre de diàleg de compartició + + + + Share %1 + Comparteix %1 Show more actions - + Mostra més accions - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -41,7 +54,7 @@ Checking for changes in "%1" - + S'està comprovant si hi ha canvis a «%1» @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Error en suprimir «%1»: %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + No s'ha pogut suprimir la carpeta «%1» @@ -1138,32 +1151,32 @@ This can be an issue with your OpenSSL libraries. No es pot obrir el navegador; copieu l'enllaç al navegador. - + Waiting for authorization S'està esperant l'autorització - + Polling for authorization S'està sol·licitant l'autorització - + Starting authorization S'està iniciant l'autorització - + Link copied to clipboard. S'ha copiat l'enllaç al porta-retalls. - + Reopen Browser - + Copy Link Copia l'enllaç @@ -1328,6 +1341,15 @@ This means that the synchronization client might not upload local changes immedi %1 No s'ha pogut fer un seguiment fiable dels canvis en les carpetes sincronitzades. Això significa que és possible que el client de sincronització no pugui carregar els canvis locals immediatament i, en canvi, només cercarà els canvis locals i els pujarà ocasionalment (per defecte, cada dues hores). %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + S'han suprimit tots els fitxers de la carpeta de sincronització local «%1». Aquestes supressions se sincronitzaran amb el servidor, per la qual cosa els fitxers deixaran d'estar disponibles si no els restaureu. +Segur que voleu sincronitzar aquestes accions amb el servidor? +Si es tracta d'un accident i decidiu mantenir els fitxers, es tornaran a sincronitzar des del servidor. + All files in the sync folder '%1' were deleted on the server. @@ -1381,27 +1403,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Mantén els fitxers locals com a conflicte - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - S'han suprimit tots els fitxers de la carpeta de sincronització «%1» del servidor. -Aquestes supressions se sincronitzaran a la vostra carpeta de sincronització local i aquests fitxers deixaran d'estar disponibles si no teniu dret a restaurar-los. -Si decidiu restaurar els fitxers, es tornaran a sincronitzar amb el servidor si teniu drets per a fer-ho. -Si decidiu suprimir els fitxers, deixaran d'estar disponibles, tret que en sigueu el propietari. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - S'han suprimit tots els fitxers de la carpeta de sincronització local «%1». Aquestes supressions se sincronitzaran amb el servidor, per la qual cosa els fitxers deixaran d'estar disponibles si no els restaureu. -Segur que voleu sincronitzar aquestes accions amb el servidor? -Si es tracta d'un accident i decidiu mantenir els fitxers, es tornaran a sincronitzar des del servidor. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1409,7 +1411,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1425,6 +1427,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Suprimeix tots els fitxers + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + S'han suprimit tots els fitxers de la carpeta de sincronització «%1» del servidor. +Aquestes supressions se sincronitzaran a la vostra carpeta de sincronització local i aquests fitxers deixaran d'estar disponibles si no teniu dret a restaurar-los. +Si decidiu restaurar els fitxers, es tornaran a sincronitzar amb el servidor si teniu drets per a fer-ho. +Si decidiu suprimir els fitxers, deixaran d'estar disponibles, tret que en sigueu el propietari. + Keep files @@ -2249,6 +2262,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Afegiu un patró per a ignorar nou: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2386,7 +2462,7 @@ Logs will be written to %1 <nobr>No es pot obrir el fitxer «%1»<br/>en mode d'escriptura.<br/><br/><b>No</b> es pot desar la sortida del registre.</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2429,6 +2505,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Hi ha disponible una nova versió del client del %1 però s'ha produït un error en el procés d'actualització.</p><p>S'ha baixat la versió <b>%2</b>. La versió instal·lada és la %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2598,6 +2679,12 @@ Logs will be written to %1 New %1 Update Ready Actualització nova del %1 a punt + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + S'instal·larà una actualització nova per al %1. És possible que l'actualitzador demani privilegis addicionals durant el procés. + New %1 update ready @@ -2605,9 +2692,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - S'instal·larà una actualització nova per al %1. És possible que l'actualitzador demani privilegis addicionals durant el procés. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2644,6 +2730,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Hi ha disponible la nova versió %1. Feu clic <a href='%2'>aquí</a> per a baixar l'actualització. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2654,6 +2745,11 @@ for additional privileges during the process. Could not check for new updates. No s'ha pogut comprovar si hi ha noves actualitzacions. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2949,37 +3045,37 @@ It is not advisable to use it. S'ha esgotat el temps d'espera en connectar-se a %1 a %2. - + Trying to connect to %1 at %2 … S'està intentant la connexió a %1 a %2... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. S'ha redirigit la sol·licitud autenticada al servidor a «%1». L'URL és incorrecte: el servidor està mal configurat. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. El servidor ha prohibit l'accés. Per a comprovar que hi teniu accés, <a href="%1">feu clic aquí</a> per a accedir al servei amb el vostre navegador. - + There was an invalid response to an authenticated WebDAV request S'ha rebut una resposta no vàlida a una sol·licitud WebDAV autenticada - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronització local %1 ja existeix; s'està configurant per a la sincronització.<br/><br/> - + Creating local sync folder %1 … S'està creant la carpeta de sincronització local %1… @@ -2989,84 +3085,84 @@ It is not advisable to use it. correcte - + OK - + failed. s'ha produït un error. - + Could not create local folder %1 No s'ha pogut crear la carpeta local %1 - + No remote folder specified! No s'ha especificat cap carpeta remota. - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 s'està creant una carpeta al Nextcloud: %1 - + Remote folder %1 created successfully. S'ha creat la carpeta remota %1 correctament. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ja existeix. S'està connectant per a sincronitzar-la. - - + + The folder creation resulted in HTTP error code %1 La creació de la carpeta ha generat el codi d'error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> S'ha produït un error en crear la carpeta perquè les credencials proporcionades són incorrectes.<br/>Comproveu les credencials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">S'ha produït un error en crear la carpeta remota, probablement perquè les credencials proporcionades són incorrectes.</font><br/>Comproveu les credencials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. S'ha produït un error en crear la carpeta remota %1: <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. S'ha configurat una connexió de sincronització de %1 a la carpeta remota %2. - + Successfully connected to %1! S'ha establert la connexió amb %1 correctament. - + Connection to %1 could not be established. Please check again. No s'ha pogut establir la connexió amb %1. Torneu-ho a provar. - + Folder rename failed S'ha produït un error en canviar el nom de la carpeta @@ -3076,28 +3172,28 @@ It is not advisable to use it. No es pot suprimir i fer una còpia de seguretat de la carpeta perquè la carpeta o un fitxer que conté està obert en un altre programa. Tanqueu la carpeta o el fitxer i torneu-ho a provar o cancel·leu la configuració. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>S'ha creat la carpeta de sincronització %1 correctament!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Assistent de connexió del %1 - Add %1 account + + + %1 Connection Wizard + Assistent de connexió del %1 + Skip folders configuration @@ -3130,24 +3226,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Tot està configurat! - - - - Open Local Folder - Obre la carpeta local - - - - Open %1 in Browser - Obre %1 al navegador - - OCC::PollJob @@ -3158,6 +3236,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3173,16 +3261,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. No s'admeten els noms de fitxer que finalitzen amb un punt en aquest sistema de fitxers. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. No s'admeten els noms de fitxers que contenen el caràcter «%1» en aquest sistema de fitxers. + + + File names containing the character "%1" are not supported on this file system. + + File name contains at least one invalid character @@ -3309,7 +3397,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss El servidor ha respost amb un error en llegir la carpeta «%1»: %2 - + Server replied with an error while reading directory "%1" : %2 @@ -3924,11 +4012,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Permet l'edició - - - Allow editing - Permet l'edició - Read only @@ -3949,6 +4032,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Protecció amb contrasenya + + + Allow editing + Permet l'edició + + + + View only + + Allow upload and editing @@ -3964,16 +4057,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Arrossegament de fitxers (només pujada) - - - Note to recipient - Nota per al destinatari - Unshare Deixa de compartir + + + Link name + + + + + Note to recipient + Nota per al destinatari + Password protect @@ -3985,15 +4083,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Definiu una data de venciment - - Delete share link - Suprimeix l'enllaç de compartició + + Delete link + Add another link Afegeix un altre enllaç + + + Delete share link + Suprimeix l'enllaç de compartició + Confirm Link Share Deletion @@ -4043,7 +4146,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No hi ha resultats per a «%1» - + No results for "%1" @@ -4147,12 +4250,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Comparteix amb %1 - Context menu share @@ -4179,6 +4276,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Comparteix mitjançant %1 + + + + Activity + + Copy private link to clipboard @@ -4250,6 +4353,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Suprimeix + + + Share with %1 + parameter is Nextcloud + Comparteix amb %1 + OCC::SslButton @@ -4395,6 +4504,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No es pot establir una connexió segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4569,6 +4683,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Només hi ha %1 disponibles, necessiteu com a mínim %2 per a començar + + + Aborted + S'ha cancel·lat + @@ -4721,44 +4840,105 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caràcters no vàlids; canvieu el nom de «%1». + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nom del fitxer conté com a mínim un caràcter no vàlid - - Aborted - S'ha cancel·lat - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Queda poc espai en el disc: s'han omès les baixades que reduirien l'espai lliure per sota de %1. - + There is insufficient space available on the server for some uploads. No hi ha prou espai en el servidor per a pujar-hi alguns fitxers. - OCC::Systray + OCC::SyncStatusSummary - - Add account - Afegeix un compte + + + Offline + - - Open main dialog - Obre el quadre de diàleg principal + + + + All synced! + - - - Pause sync - Atura la sincronització + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + + + OCC::Systray + + + Add account + Afegeix un compte + + + + Open main dialog + Obre el quadre de diàleg principal + + + + + Pause sync + Atura la sincronització @@ -4817,6 +4997,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Aquesta versió ha estat proporcionada per %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4874,26 +5077,110 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - La característica de sistema de fitxers virtual requereix un sistema de fitxers NTFS; %1 utilitza %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + La característica de sistema de fitxers virtual requereix un sistema de fitxers NTFS; %1 utilitza %2 + + OCC::WebEnginePage @@ -5408,14 +5695,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - El vostre compte està totalment sincronitzat amb la carpeta local - - QObject @@ -5508,6 +5787,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5522,29 +5833,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Compte connectat - Current user status is do not disturb - + Account not connected + Compte no connectat - Account connected - Compte connectat + Current user status is online + - Account not connected - Compte no connectat + Current user status is do not disturb + Account actions Accions del compte + + + Remove Account + Suprimeix el compte + + + + Set status + + @@ -5557,17 +5878,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Inicia la sessió - - - Remove Account - Suprimeix el compte - Remove account Suprimeix el compte + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5629,12 +5998,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. La capçalera de la suma de verificació està mal formada. - + The checksum header contained an unknown checksum type '%1' La capçalera de la suma de verificació contenia un tipus de suma de verificació desconegut «%1» @@ -5644,17 +6013,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss El fitxer baixat no coincideix amb la suma de verificació, es reprendrà. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' El fitxer baixat no coincideix amb la suma de verificació, es reprendrà. «%1» != «%2» - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5683,6 +6052,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Atura la sincronització de tot + + + Set user status + + Add account @@ -5718,12 +6092,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - Mostra més accions - Share %1 @@ -5784,6 +6152,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Obre el quadre de diàleg de compartició + + + Unified search results list + + + + + + Show more actions + Mostra més accions + + + + %1 - File activity + + main.cpp @@ -6083,6 +6467,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Inicieu la sessió al navegador (Flux d'inici de sessió v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Tot està configurat! + + + + Open Local Folder + Obre la carpeta local + + + + Open %1 in Browser + Obre %1 al navegador + + OCC::ShibbolethCredentials @@ -6135,6 +6537,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Inicia la sessió + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + El vostre compte està totalment sincronitzat amb la carpeta local + + OCC::UserStatus @@ -6158,4 +6568,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_cs.ts b/translations/client_cs.ts index ba577d5757b4..f3afa4dd04d3 100644 --- a/translations/client_cs.ts +++ b/translations/client_cs.ts @@ -14,12 +14,6 @@ Open %1 locally Otevřít %1 lokálně - - - - Show more actions - Zobrazit další akce - Open share dialog @@ -30,6 +24,25 @@ Share %1 Sdílet %1 + + + + Show more actions + Zobrazit další akce + + + + View activity + Zobrazit aktivitu + + + + ActivityList + + + Activity list + Seznam aktivit + CloudProviderWrapper @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" „%1“ se nedaří přesunout do „%2“ @@ -1144,32 +1157,32 @@ Toto může být způsobeno problémem s OpenSSL knihovnami. Nepodařilo se otevřít váš prohlížeč – zkopírujte do něho odkaz sami. - + Waiting for authorization Čeká se na pověření - + Polling for authorization Dotazování se na pověření - + Starting authorization Zahajování pověřování - + Link copied to clipboard. Odkaz zkopírován do schránky. - + Reopen Browser Znovu otevřít webový prohlížeč - + Copy Link Zkopírovat odkaz @@ -1336,6 +1349,15 @@ This means that the synchronization client might not upload local changes immedi To znamená, že se může stávat, že synchronizační klient nebude místní změny okamžitě odesílat na server a namísto toho bude pouze skenovat případné lokální změny a odesílat je až příležitostně (výchozí je každé dvě hodiny). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Všechny soubory v místní synchronizované složce „%1“ byly smazány. Tyto soubory budou smazány i v synchronizované složce na serveru a nebudou tedy dostupné, dokud nebudou obnovené. +Opravdu chcete tyto změny provést i na serveru? +Pokud to byla pouze chyba a chcete si tyto soubory ponechat, budou ze serveru znovu synchronizovány. @@ -1397,27 +1419,7 @@ Pokračováním v synchronizaci způsobí přepsání všech vašich souborů st Ponechat místní soubory jako konflikt - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Všechny soubory v synchronizované složce „%1“ byly na serveru smazány. -Tyto soubory budou smazány i ve vaší místní synchronizované složce a nebudou tedy dostupné, pokud nemáte právo obnovovat. -Pokud se rozhodnete soubory ponechat, budou opět synchronizovány se serverem, pokud k tomu máte práva. -Pokud se rozhodnete soubory smazat, budou vám nedostupné, pokud nejste jejich vlastníkem. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Všechny soubory v místní synchronizované složce „%1“ byly smazány. Tyto soubory budou smazány i v synchronizované složce na serveru a nebudou tedy dostupné, dokud nebudou obnovené. -Opravdu chcete tyto změny provést i na serveru? -Pokud to byla pouze chyba a chcete si tyto soubory ponechat, budou ze serveru znovu synchronizovány. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1428,7 +1430,7 @@ Pokud se rozhodnete soubory ponechat, budou opět synchronizovány se serverem, Pokud se rozhodnete soubory smazat, budou vám nedostupné, pokud nejste jejich vlastníkem. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1446,6 +1448,17 @@ Pokud to byla pouze chyba a chcete si tyto soubory ponechat, budou ze serveru zn Remove all files Odebrat veškeré soubory + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Všechny soubory v synchronizované složce „%1“ byly na serveru smazány. +Tyto soubory budou smazány i ve vaší místní synchronizované složce a nebudou tedy dostupné, pokud nemáte právo obnovovat. +Pokud se rozhodnete soubory ponechat, budou opět synchronizovány se serverem, pokud k tomu máte práva. +Pokud se rozhodnete soubory smazat, budou vám nedostupné, pokud nejste jejich vlastníkem. + Keep files @@ -2276,6 +2289,69 @@ Položky u kterých je umožněno mazání budou smazány, pokud brání tomu, a Přidat nový vzor pro ignorované: + + OCC::InvalidFilenameDialog + + + Invalid filename + Neplatný název souboru + + + + The file could not be synced because it contains characters which are not allowed on this system. + Soubor nebyl synchronizován, protože obsahuje znaky, které nejsou na tomto systému povolené. + + + + Error + Chyba + + + + Please enter a new name for the file: + Zadejte nový název pro soubor: + + + + New filename + Nový název souboru + + + + Rename file + Přejmenovat soubor + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Soubor %1 nebyl synchronizován, protože název obsahuje znaky, které nejsou na tomto systému povoleny. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Následující znaky nejsou v systému povoleny: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Nemáte potřebná práva k přejmenování souboru. Požádejte vlastníka souboru, aby ho přejmenoval. + + + + Filename contains illegal characters: %1 + Název souboru obsahuje neplatné znaky: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Přejmenovat soubor se nepodařilo. Ujistěte se, že jste připojení k serveru. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Soubor není možné přejmenovat, protože soubor se stejným názvem na serveru už existuje. Vyberte jiný název. + + OCC::LegalNotice @@ -2416,7 +2492,7 @@ Záznamy událostí budou zapisovány do %1 <nobr>Soubor „%1“<br/>se nedaří otevřít pro zápis.<br/><br/>Výstup záznamu proto <b>nelze</b> uložit!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> Soubor „%1“<br/> se nepodařilo otevřít pro zápis.<br/><br/>Výstup záznamu událostí <b>není</b> možné uložit!<nobr> @@ -2459,6 +2535,11 @@ Záznamy událostí budou zapisovány do %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Je k dispozici nová verze %1 klienta, ale aktualizace se nezdařila.</p><p><b>%2</b> byla stažena. Nyní je nainstalovaná %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Je k dispozici nová verze %1 klienta, ale aktualizace se nezdařila.</p><p><b>%2</b> byla stažena. Nyní je nainstalovaná %3. Pokud potvrdíte restart a aktualizaci, váš počítač se může pro dokončení instalace restartovat.</p> + Ask again later @@ -2628,6 +2709,13 @@ Záznamy událostí budou zapisovány do %1 New %1 Update Ready Je připravena nová aktualizace %1 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Bude instalována nová aktualizace pro %1. V průběhu aktualizace +můžete být požádáni o dodatečná oprávnění. + New %1 update ready @@ -2635,10 +2723,8 @@ Záznamy událostí budou zapisovány do %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Bude instalována nová aktualizace pro %1. V průběhu aktualizace -můžete být požádáni o dodatečná oprávnění. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Bude instalována nová aktualizace pro %1. V průběhu aktualizace můžete být požádáni o dodatečná oprávnění. Váš počítač může být třeba pro dokončení aktualizace restartovat. @@ -2675,6 +2761,11 @@ můžete být požádáni o dodatečná oprávnění. New %1 is available. Please click <a href='%2'>here</a> to download the update. Je k dispozici nové %1. Kliknutím <a href='%2'>sem</a> si stáhnete aktualizaci. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Aktualizaci se nedaří stáhnout. Zkuste to ručně, kliknutím na <a href='%1'>%1</a>. + Could not download update. Please open %1 to download the update manually. @@ -2685,6 +2776,11 @@ můžete být požádáni o dodatečná oprávnění. Could not check for new updates. Nedaří se zjistit dostupnost případných nových aktualizací. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Je k dispozici nové %1. Kliknutím na <a href='%2'>%2</a> si stáhnete aktualizaci. + New %1 is available. Please open %2 to download the update. @@ -2981,37 +3077,37 @@ Nedoporučuje se jí používat. Překročen časový limit při pokusu o připojení k %1 na %2. - + Trying to connect to %1 at %2 … Pokus o připojení k %1 na %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Požadavek na ověření byl přesměrován na „%1“. URL je chybná, server není správně nastaven. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. Požadavek na ověření byl přesměrován na „%1“. URL je chybná, server není správně nastaven. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Přístup zamítnut serverem. Pro ověření správných přístupových práv <a href="%1">klikněte sem</a> a otevřete službu ve svém prohlížeči. - + There was an invalid response to an authenticated WebDAV request Přišla neplatná odpověď na WebDAV požadavek s ověřením se - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Místní synchronizovaná složka %1 už existuje, nastavuje se pro synchronizaci.<br/><br/> - + Creating local sync folder %1 … Vytváření místní složky pro synchronizaci %1… @@ -3021,84 +3117,84 @@ Nedoporučuje se jí používat. OK - + OK OK - + failed. nezdařilo se. - + Could not create local folder %1 Nedaří se vytvořit místní složku %1 - + No remote folder specified! Není nastavena žádná federovaná složka! - + Error: %1 Chyba: %1 - + creating folder on Nextcloud: %1 vytváří se složka na Nextcloud: %1 - + Remote folder %1 created successfully. Složka %1 byla na federované straně úspěšně vytvořena. - + The remote folder %1 already exists. Connecting it for syncing. Složka %1 už na federované straně existuje. Probíhá propojení synchronizace. - - + + The folder creation resulted in HTTP error code %1 Vytvoření složky se nezdařilo s HTTP chybou %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Vytvoření federované složky se nezdařilo, pravděpodobně z důvodu neplatných přihlašovacích údajů.<br/>Vraťte se zpět a zkontrolujte je.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Vytvoření federované složky se nezdařilo, pravděpodobně z důvodu neplatných přihlašovacích údajů.</font><br/>Vraťte se zpět a zkontrolujte je.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Vytváření federované složky %1 se nezdařilo s chybou <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Bylo nastaveno synchronizované spojení z %1 do federovaného adresáře %2. - + Successfully connected to %1! Úspěšně spojeno s %1. - + Connection to %1 could not be established. Please check again. Spojení s %1 se nedaří navázat. Znovu to zkontrolujte. - + Folder rename failed Přejmenování složky se nezdařilo @@ -3108,28 +3204,28 @@ Nedoporučuje se jí používat. Složku není možné odstranit ani zazálohovat, protože podložka nebo soubor v něm je otevřen v jiném programu. Zavřete podsložku nebo soubor v dané aplikaci a zkuste znovu nebo celou tuto akci zrušte. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Složku není možné odstranit ani zazálohovat, protože podložka nebo soubor v něm je otevřen v jiném programu. Zavřete podsložku nebo soubor v dané aplikaci a zkuste znovu nebo celou tuto akci zrušte. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Místní synchronizovaná složka %1 byla úspěšně vytvořena!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Průvodce spojením - Add %1 account Přidat %1 účet + + + %1 Connection Wizard + %1 Průvodce spojením + Skip folders configuration @@ -3168,24 +3264,6 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Zůstaňte v bezpečí - - OCC::OwncloudWizardResultPage - - - Everything set up! - Všechno je nastaveno - - - - Open Local Folder - Otevřít místní složku - - - - Open %1 in Browser - Otevřít %1 v prohlížeči - - OCC::PollJob @@ -3196,6 +3274,16 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Název souboru začíná mezerami a nebylo ho možné přejmenovat, protože na serveru už existuje soubor se stejným názvem. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Název souboru začíná mezerami a nebylo ho možné přejmenovat, protože lokálně už existuje soubor se stejným názvem. + Symbolic links are not supported in syncing. @@ -3213,12 +3301,12 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. Názvy souborů obsahující znak „%1“ nejsou na tomto souborovém systému podporovány. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. Názvy souborů obsahující znak „%1“ nejsou na tomto souborovém systému podporovány. @@ -3347,7 +3435,7 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Server vrátil chybu při čtení adresáře „%1“: %2 - + Server replied with an error while reading directory "%1" : %2 Server vrátil chybu při čtení adresáře „%1“: %2 @@ -3962,11 +4050,6 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Allow Editing Povolit upravování - - - Allow editing - Povolit úpravy - Read only @@ -3987,6 +4070,16 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Password Protect Chránit heslem + + + Allow editing + Povolit úpravy + + + + View only + Pouze prohlížet + Allow upload and editing @@ -4002,16 +4095,21 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros File drop (upload only) Přetažení souboru (pouze nahrání) - - - Note to recipient - Poznámka pro příjemce - Unshare Přestat sdílet + + + Link name + Název odkazu + + + + Note to recipient + Poznámka pro příjemce + Password protect @@ -4023,15 +4121,20 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Nastavit datum skončení platnosti - - Delete share link - Smazat odkaz pro sdílení + + Delete link + Smazat odkaz Add another link Přidat další odkaz + + + Delete share link + Smazat odkaz pro sdílení + Confirm Link Share Deletion @@ -4081,7 +4184,7 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Žádné výsledky pro „%1“ - + No results for "%1" Žádné výsledky pro „%1“ @@ -4185,12 +4288,6 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Sdílet s %1 - Context menu share @@ -4217,6 +4314,12 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Share via %1 Sdílet prostřednictvím %1 + + + + Activity + Aktivita + Copy private link to clipboard @@ -4288,6 +4391,12 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Delete Smazat + + + Share with %1 + parameter is Nextcloud + Sdílet s %1 + OCC::SslButton @@ -4433,6 +4542,11 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Cannot connect securely to <i>%1</i>: Nelze se bezpečně připojit k <i>%1</i>: + + + Additional errors: + Další chyby: + with Certificate %1 @@ -4607,6 +4721,11 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Placeholders are postfixed with file sizes using Utility::octetsToString() Je dostupných pouze %1, pro spuštění je potřeba alespoň %2 + + + Aborted + Přerušeno + @@ -4759,27 +4878,88 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Invalid characters, please rename "%1" Neplatné znaky, přejmenujte „%1“ + + + Synchronization will resume shortly. + V synchronizaci bude zakrátko navázáno. + File name contains at least one invalid character Název souboru obsahuje přinejmenším jeden neplatný znak - - Aborted - Přerušeno - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Na disku dochází místo: Stahování které by zmenšilo volné místo pod %1 bude přeskočeno. - + There is insufficient space available on the server for some uploads. Na serveru není pro některé z nahrávaných souborů dostatek místa. + + OCC::SyncStatusSummary + + + + Offline + Offline + + + + + + All synced! + Vše synchronizováno! + + + + Some files couldn't be synced! + Některé soubory nebylo možné synchronizovat! + + + + See below for errors + Chyby viz níže + + + + Syncing + Synchronizuje se + + + + Sync paused + Synchronizace pozastavena + + + + Some files could not be synced! + Některé soubory nebylo možné synchronizovat! + + + + See below for warnings + Varování viz níže + + + + %1 of %2 · %3 left + %1 z %2 · %3 zbývá + + + + %1 of %2 + %1 z %2 + + + + Syncing file %1 of %2 + Synchronizuje se soubor %1 z %2 + + OCC::Systray @@ -4847,7 +5027,7 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros <p><small>Using virtual files plugin: %1</small></p> - <p><small>pomocí zásuvného modulu pro virtuální soubory: %1</small></p> + <p><small>Používá zásuvný modul pro virtuální soubory: %1</small></p> @@ -4855,6 +5035,29 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros <p>Toto vydání bylo poskytnuto %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Nepodařilo se získat seznam poskytovatelů. + + + + Failed to fetch search providers for '%1'. Error: %2 + Nepodařilo se získat z poskytovatelů vyhledávání pro „%1“: Chyba: %2 + + + + Search has failed for '%2'. + Hledání „%2“ se nezdařilo. + + + + Search has failed for '%1'. Error: %2 + Hledání „%1“ se nezdařilo: chyba: %2 + + OCC::User @@ -4912,24 +5115,108 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Funkce virtuální souborový systém vyžaduje souborový systém NTFS, %1 používá %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Nepodařilo se získat předdefinované stavy. Ověřte, že jste připojení k serveru. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Stažení souboru, šifrovaného mezi koncovými body, se nezdařilo + + Could not fetch user status. Make sure you are connected to the server. + Nepodařilo se zjistit stav uživatele. Ověřte, že jste připojení k serveru. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Zdá se, že se pokoušíte stáhnout si virtuální soubor, který je šifrován mezi koncovými body. V tuto chvíli není výslovné stahování si takových souborů podporováno. Pokud potřebujete tento problém obejít, jděte do nastavení a označte šifrované složky jako „Vždy zpřístupnit lokálně“. + + User status feature is not supported. You will not be able to set your user status. + Funkce stavu uživatele není podporována. Nebudete moci nastavit svůj stav uživatele. + + + + Emojis feature is not supported. Some user status functionality may not work. + Funkce emotikonů není podporovaná. Některé funkce stavu uživatele nemusí fungovat. + + + + Could not set user status. Make sure you are connected to the server. + Nepodařilo se nastavit stav uživatele. Ověřte, že jste připojení k serveru. + + + + Could not clear user status message. Make sure you are connected to the server. + Nepodařilo se vyčistit zprávu stavu uživatele. Ověřte, že jste připojení k serveru. + + + + + Don't clear + Nečistit + + + + 30 minutes + 30 minut + + + + + 1 hour + 1 hodina + + + + 4 hours + 4 hodiny + + + + + Today + Dnes + + + + + This week + Tento týden + + + + Less than a minute + Méně než minuty + + + + 1 minute + 1 minuta + + + + %1 minutes + %1 minut + + + + %1 hours + %1 hodin + + + + 1 day + 1 den + + + + %1 days + %1 dny + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Funkce virtuální souborový systém vyžaduje souborový systém NTFS, %1 používá %2 @@ -5446,14 +5733,6 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Přihlaste se do svého %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Celý váš účet je synchronizován do místní složky - - QObject @@ -5546,6 +5825,38 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Nepodařilo se připojit k databázi. + + UnifiedSearchInputContainer + + + Search files, messages, events … + Hledat soubory, zprávy, události + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Načíst další výsledky + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Kostra výsledku vyhledávání. + + + + UnifiedSearchResultListItem + + + Load more results + Načíst další výsledky + + UserLine @@ -5560,29 +5871,39 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros - Current user status is online - Stávající stav uživatele je online + Account connected + Účet připojen - Current user status is do not disturb - Stávající stav uživatele je nerušit + Account not connected + Účet nepřipojen - Account connected - Účet připojen + Current user status is online + Stávající stav uživatele je online - Account not connected - Účet nepřipojen + Current user status is do not disturb + Stávající stav uživatele je nerušit Account actions Akce účtu + + + Remove Account + Odebrat účet + + + + Set status + Nastavit stav + @@ -5595,17 +5916,65 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Log in Přihlásit - - - Remove Account - Odebrat účet - Remove account Odebrat účet + + UserStatusSelector + + + Online status + Stav online + + + + Online + Online + + + + Away + Pryč + + + + Do not disturb + Nerušit + + + + Invisible + Neviditelný + + + + Status message + Stavová zpráva + + + + What is your status? + Jaký je váš stav? + + + + Clear status message after + Vyčistit stavovou zprávu po uplynutí + + + + Clear status message + Vyčistit stavovou zprávu + + + + Set status message + Nastavit stavovou zprávu + + Utility @@ -5667,12 +6036,12 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros ValidateChecksumHeader - + The checksum header is malformed. Hlavička kontrolního součtu nemá správnou podobu. - + The checksum header contained an unknown checksum type '%1' Hlavička kontrolního součtu obsahovala neznámý typ součtu „%1“ @@ -5682,17 +6051,17 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Stažený soubor neodpovídá kontrolnímu součtu, bude stažen znovu. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Stažený soubor neodpovídá kontrolnímu součtu, bude stažen znovu. „%1“ != „%2“ - + The checksum header contained an unknown checksum type "%1" Hlavička kontrolního součtu obsahovala neznámý typ součtu „%1“ - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" Stažený soubor neodpovídá kontrolnímu součtu, bude stažen znovu. „%1“ != „%2“ @@ -5721,6 +6090,11 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Pause sync for all Pozastavit synchronizaci u všeho + + + Set user status + Nastavit stav uživatele + Add account @@ -5756,12 +6130,6 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Current user status is do not disturb Stávající stav uživatele je nerušit - - - - Show more actions - Zobrazit další akce - Share %1 @@ -5822,6 +6190,22 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Open share dialog Otevřít dialog sdílení + + + Unified search results list + Seznam výsledků sjednoceného vyhledávání + + + + + Show more actions + Zobrazit další akce + + + + %1 - File activity + %1 – aktivita ohledně souboru + main.cpp @@ -6121,6 +6505,24 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Přihlášení v prohlížeči (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Všechno je nastaveno + + + + Open Local Folder + Otevřít místní složku + + + + Open %1 in Browser + Otevřít %1 v prohlížeči + + OCC::ShibbolethCredentials @@ -6173,6 +6575,14 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Přihlásit se + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Celý váš účet je synchronizován do místní složky + + OCC::UserStatus @@ -6196,4 +6606,17 @@ Toto je nový, experimentální režim. Pokud se jej rozhodnete používat, pros Online + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Stažení souboru, šifrovaného mezi koncovými body, se nezdařilo + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Zdá se, že se pokoušíte stáhnout si virtuální soubor, který je šifrován mezi koncovými body. V tuto chvíli není výslovné stahování si takových souborů podporováno. Pokud potřebujete tento problém obejít, jděte do nastavení a označte šifrované složky jako „Vždy zpřístupnit lokálně“. + + \ No newline at end of file diff --git a/translations/client_da.ts b/translations/client_da.ts index 9237a745b11a..b1f43857a35f 100644 --- a/translations/client_da.ts +++ b/translations/client_da.ts @@ -4,7 +4,7 @@ Activity action button - + Aktivitetshandlingsknap @@ -12,23 +12,36 @@ Open %1 locally - + Åbn %1 lokalt + + + + Open share dialog + Åbn deledialogen + + + + Share %1 + Del %1 Show more actions - + Vis flere handlinger - - Open share dialog - + + View activity + Se aktivitet + + + ActivityList - - Share %1 - + + Activity list + Aktivitetsliste @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Søger efter ændringer i "%1" @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + Kunne ikke flytte "%1" til "%2" @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Fejl ved fjernelse af "%1": %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Kunne ikke fjerne mappen "%1" @@ -185,7 +198,7 @@ Logo - + Logo @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Du ser ud til at have funktionen Virtual Files aktiveret i denne mappe. I øjeblikket er det ikke muligt implicit at downloade virtuelle filer, der er End-to-End-krypteret. For at få den bedste oplevelse med virtuelle filer og ende-til-ende-kryptering skal du sørge for, at den krypterede mappe er markeret med "Gør altid tilgængelig lokalt". @@ -756,7 +769,7 @@ Denne handling vil annullere alle i øjeblikket kørende synkroniseringer. Certificate & Key (pkcs12): - + Certifikat og nøgle (pkcs12): @@ -842,7 +855,7 @@ Denne handling vil annullere alle i øjeblikket kørende synkroniseringer. Enter username and password for "%1" at %2. - + Indtast brugernavn og adgangskode til "%1" ved %2. @@ -974,12 +987,12 @@ Denne handling vil annullere alle i øjeblikket kørende synkroniseringer. Do you want to delete the directory <i>%1</i> and all its contents permanently? - + Vil du slette mappen <i>%1</i> og alt dens indhold permanent? Do you want to delete the file <i>%1</i> permanently? - + Vil du slette filen <i>%1</i> permanent? @@ -1142,32 +1155,32 @@ Dette kan være et problem med dine OpenSSL biblioteker. Kunne ikke åbne browseren, venligst kopier linket og åben i en browser. - + Waiting for authorization Venter på godkendelse - + Polling for authorization Forespørger godkendelse - + Starting authorization Påbegynder godkendelse - + Link copied to clipboard. Link kopieret til udklipsholder - + Reopen Browser - + Copy Link @@ -1336,6 +1349,13 @@ Dette betyder at synkroniseringsklienten muligvis ikke sender lokale ændringer %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1396,22 +1416,7 @@ Fortsætter sync som normalt, vil alle dine filer blive overskrevne med en ældr Behold Lokale Filer der Konflikter - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1419,7 +1424,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1435,6 +1440,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2263,6 +2276,69 @@ Elementer hvor sletning er tilladt vil blive slettet hvis de hindre en folder fr Tilføj nyt ignorermønster: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2400,7 +2476,7 @@ Loggen bliver skrevet til %1 <nobr>Fil '%1'<br/>kan ikke åbnes for skrivning.<br/><br/>Log resultatet kan <b>ikke</b> gemmes!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2443,6 +2519,11 @@ Loggen bliver skrevet til %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2612,6 +2693,12 @@ Loggen bliver skrevet til %1 New %1 Update Ready Ny %1 opdatering klar + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + En ny opdatering til %1 er klar til at blive installeret. Opdateringen kan bede om privilegier under processen. + New %1 update ready @@ -2619,9 +2706,8 @@ Loggen bliver skrevet til %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - En ny opdatering til %1 er klar til at blive installeret. Opdateringen kan bede om privilegier under processen. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2658,6 +2744,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2668,6 +2759,11 @@ for additional privileges during the process. Could not check for new updates. Kunne ikke søge efter nye opdateringer. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2964,37 +3060,37 @@ Det frarådes at benytte den. Timeout ved forsøg på forbindelse til %1 hos %2. - + Trying to connect to %1 at %2 … Prøver at forbinde til %1 hos %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Den godkendte forespørgsel til serveren blev omdirigeret til '%1'. URL'n er ugyldig, serveren er forkert konfigureret. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Adgang forbudt fra serveren. For at kontrollere din adgang, <a href="%1">Klik her</a> for tilgang til servicen fra din browser. - + There was an invalid response to an authenticated WebDAV request Modtog ugyldigt svar på autentificeret WebDAV forespørgsel - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Lokal sync mappe %1 findes allerede. Forbinder til synkronisering.<br/><br/> - + Creating local sync folder %1 … Opretter lokal sync mappe %1 … @@ -3004,84 +3100,84 @@ Det frarådes at benytte den. ok - + OK - + failed. mislykkedes. - + Could not create local folder %1 Kunne ikke oprette lokal mappe %1 - + No remote folder specified! Ingen afsides mappe angivet! - + Error: %1 Fejl: %1 - + creating folder on Nextcloud: %1 opretter mappe hos Nextcloud: %1 - + Remote folder %1 created successfully. Afsides mappe %1 oprettet med succes. - + The remote folder %1 already exists. Connecting it for syncing. Den afsides mappe %1 findes allerede. Forbinder til den for synkronisering. - - + + The folder creation resulted in HTTP error code %1 Mappeoprettelsen resulterede i HTTP fejlkode %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Oprettelse af den afsides mappe fejlede da brugeroplysningerne er forkerte!<br/>Gå venligst tilbage og kontroller dine brugeroplysninger.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Afsides mappe oprettelse fejlede sansynligvis på grund af forkert angivne brugeroplysninger.</font><br/>Gå venligst tilbage og kontroller dine brugeroplysninger.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Oprettelse af afsides mappe %1 fejlet med fejl <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. En sync forbindelse fra %1 til afsides mappe %2 blev oprettet. - + Successfully connected to %1! Forbundet til %1 med succes! - + Connection to %1 could not be established. Please check again. Forbindelse til %1 kunne ikke etableres. Kontroller venligst igen. - + Folder rename failed Fejl ved omdøbning af mappe @@ -3091,28 +3187,28 @@ Det frarådes at benytte den. Kan ikke fjerne eller kopiere mappen fordi mappen eller en fil i den er åben i et andet program. Luke venligst mappen eller filen og tryk Prøv igen eller afbryd installeringen. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Lokal sync mappe %1 oprette med succes!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Forbindelses guide - Add %1 account + + + %1 Connection Wizard + %1 Forbindelses guide + Skip folders configuration @@ -3145,24 +3241,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Alt er sat op! - - - - Open Local Folder - Åbn lokal mappe - - - - Open %1 in Browser - Åbn %1 i browser - - OCC::PollJob @@ -3173,6 +3251,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3190,12 +3278,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3324,7 +3412,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3939,11 +4027,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Tillad Redigering - - - Allow editing - Tillad redigering - Read only @@ -3964,6 +4047,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Beskyt med Adgangskode + + + Allow editing + Tillad redigering + + + + View only + + Allow upload and editing @@ -3979,16 +4072,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Fil drop (kun upload) - - - Note to recipient - Note til modtager - Unshare Ophæv deling + + + Link name + + + + + Note to recipient + Note til modtager + Password protect @@ -4000,15 +4098,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Angiv udløbsdato - - Delete share link - Slet delingslink + + Delete link + Add another link Tilføj et link mere + + + Delete share link + Slet delingslink + Confirm Link Share Deletion @@ -4058,7 +4161,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ingen resultater for '%1' - + No results for "%1" @@ -4162,12 +4265,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Del med %1 - Context menu share @@ -4194,6 +4291,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Del via %1 + + + + Activity + + Copy private link to clipboard @@ -4265,6 +4368,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Slet + + + Share with %1 + parameter is Nextcloud + Del med %1 + OCC::SslButton @@ -4410,6 +4519,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Kan ikke sikret forbinde til <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4584,6 +4698,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Kun %1 til rådighed, behøver mindst %2 for at starte + + + Aborted + + @@ -4736,27 +4855,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Ugyldige karakterer, omdøb venligst "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Filnavnet indeholder mindst ét ugyldigt tegn - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Diskplads begrænset: Downloads der bringer ledig plads under %1 ignoreres. - + There is insufficient space available on the server for some uploads. Der er utilstrækkelig plads på serveren til visse uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4832,6 +5012,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Denne udgivelse blev leveret af %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4889,23 +5092,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5423,14 +5710,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log ind på din %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Hele din konto er synkroniseret til den lokale mappe - - QObject @@ -5523,6 +5802,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5537,29 +5848,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - Nuværende brugerstatus er online + Account connected + Kontoen er tilknyttet - Current user status is do not disturb - Nuværende brugerstatus er forstyr ikke + Account not connected + Kontoen er ikke tilknyttet - Account connected - Kontoen er tilknyttet + Current user status is online + Nuværende brugerstatus er online - Account not connected - Kontoen er ikke tilknyttet + Current user status is do not disturb + Nuværende brugerstatus er forstyr ikke Account actions Kontohandlinger + + + Remove Account + Fjern konto + + + + Set status + + @@ -5572,17 +5893,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Log ind - - - Remove Account - Fjern konto - Remove account Fjern konto + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5644,12 +6013,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Kontrolsum-hovedet er misdannet. - + The checksum header contained an unknown checksum type '%1' Hovedet af kontrolsummen indeholder en ukendt kontrolsums-type '%1' @@ -5659,17 +6028,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Den hentede fil svarer ikke til kontrolsummen, den bliver genoptaget. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Den hentede fil matcher ikke kontrolsummen, den vil blive genoptaget. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5698,6 +6067,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Sæt alle synk. på pause + + + Set user status + + Add account @@ -5733,12 +6107,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb Nuværende brugerstatus er forstyr ikke - - - - Show more actions - Vis flere handlinger - Share %1 @@ -5799,6 +6167,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Åbn delingsdialog + + + Unified search results list + + + + + + Show more actions + Vis flere handlinger + + + + %1 - File activity + + main.cpp @@ -6098,6 +6482,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Login fra din browser (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Alt er sat op! + + + + Open Local Folder + Åbn lokal mappe + + + + Open %1 in Browser + Åbn %1 i browser + + OCC::ShibbolethCredentials @@ -6150,6 +6552,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log ind + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Hele din konto er synkroniseret til den lokale mappe + + OCC::UserStatus @@ -6173,4 +6583,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_de.ts b/translations/client_de.ts index 51401d2d5a69..9b19dc71405d 100644 --- a/translations/client_de.ts +++ b/translations/client_de.ts @@ -14,12 +14,6 @@ Open %1 locally %1 lokal öffnen - - - - Show more actions - Weitere Aktionen anzeigen - Open share dialog @@ -30,6 +24,25 @@ Share %1 %1 teilen + + + + Show more actions + Weitere Aktionen anzeigen + + + + View activity + Aktivitäten anzeigen + + + + ActivityList + + + Activity list + Aktivitätenliste + CloudProviderWrapper @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" Konnte "%1" nicht nach "%2" verschieben @@ -886,7 +899,7 @@ Diese Aktion bricht jede derzeit laufende Synchronisierung ab. Sync Conflict - Syncronisations-Konflikt + Synchronisations-Konflikt @@ -1144,32 +1157,32 @@ Dies kann ein Problem mit Ihren OpenSSL-Bibliotheken sein. Der Browser kann nicht geöffnet werden. Bitte kopieren Sie den Link in Ihren Browser. - + Waiting for authorization Warte auf Autorisierung - + Polling for authorization Abruf der Autorisierung - + Starting authorization Starte Autorisierung - + Link copied to clipboard. Link in die Zwischenablage kopiert. - + Reopen Browser Browser erneut öffnen - + Copy Link Link kopieren @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Dies bedeutet, dass der Synchronisierungs-Client lokale Änderungen möglicherweise nicht sofort hochlädt, sondern nur nach lokalen Änderungen sucht und diese gelegentlich hochlädt (standardmäßig alle zwei Stunden). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Alle Dateien im lokalen Synchronisierungs-Ordner '%1' wurden gelöscht. Diese Löschung wird mit Ihrem Server synchronisiert, wodurch die Dateien nicht mehr verfügbar sind, es sei denn, diese werden wiederhergestellt. +Sind Sie sich sicher, dass Sie diese Aktion mit Ihrem Server synchronisieren möchten? +Falls dies ein Missgeschick war und Sie sich zum Behalten der Dateien entscheiden, werden diese wieder vom Server synchronisiert. @@ -1398,27 +1420,7 @@ Wenn diese Synchronisierung fortgesetzt wird, werden Dateien eventuell von älte Lokale Dateien als Konflikt behalten - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Alle Dateien im Sync-Ordner '%1' wurden auf dem Server gelöscht. -Diese Löschungen werden mit Ihrem lokalen Sync-Ordner synchronisiert, wodurch diese Dateien nicht verfügbar sind, es sei denn, Sie haben das Recht, sie wiederherzustellen. -Wenn Sie sich entscheiden, die Dateien wiederherzustellen, werden sie erneut mit dem Server synchronisiert, wenn Sie das Recht dazu haben. -Wenn Sie sich entscheiden, die Dateien zu löschen, sind sie für Sie nicht mehr verfügbar, es sei denn, Sie sind der Eigentümer. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Alle Dateien im lokalen Synchronisierungs-Ordner '%1' wurden gelöscht. Diese Löschung wird mit Ihrem Server synchronisiert, wodurch die Dateien nicht mehr verfügbar sind, es sei denn, diese werden wiederhergestellt. -Sind Sie sich sicher, dass Sie diese Aktion mit Ihrem Server synchronisieren möchten? -Falls dies ein Missgeschick war und Sie sich zum Behalten der Dateien entscheiden, werden diese wieder vom Server synchronisiert. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1429,7 +1431,7 @@ Wenn Sie sich entscheiden, die Dateien wiederherzustellen, werden sie erneut mit Wenn Sie sich entscheiden, die Dateien zu löschen, sind sie für Sie nicht mehr verfügbar, es sei denn, Sie sind der Eigentümer. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1447,6 +1449,17 @@ Falls dies ein Missgeschick war und Sie sich zum Behalten der Dateien entscheide Remove all files Alle Dateien entfernen + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Alle Dateien im Sync-Ordner '%1' wurden auf dem Server gelöscht. +Diese Löschungen werden mit Ihrem lokalen Sync-Ordner synchronisiert, wodurch diese Dateien nicht verfügbar sind, es sei denn, Sie haben das Recht, sie wiederherzustellen. +Wenn Sie sich entscheiden, die Dateien wiederherzustellen, werden sie erneut mit dem Server synchronisiert, wenn Sie das Recht dazu haben. +Wenn Sie sich entscheiden, die Dateien zu löschen, sind sie für Sie nicht mehr verfügbar, es sei denn, Sie sind der Eigentümer. + Keep files @@ -2277,6 +2290,69 @@ Objekte, bei denen Löschen erlaubt ist, werden gelöscht, wenn diese das Lösch Neues Ignoriermuster hinzufügen + + OCC::InvalidFilenameDialog + + + Invalid filename + Ungültiger Dateiname + + + + The file could not be synced because it contains characters which are not allowed on this system. + Die Datei konnte nicht synchronisiert werden, da der Name Zeichen enthält, die auf diesem System nicht zulässig sind. + + + + Error + Fehler + + + + Please enter a new name for the file: + Bitte geben Sie einen neuen Namen für die Datei ein: + + + + New filename + Neuer Dateiname + + + + Rename file + Datei umbenennen + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Die Datei %1 konnte nicht synchronisiert werden, da der Name Zeichen enthält, die auf diesem System nicht zulässig sind. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Die folgenden Zeichen sind auf dem System nicht erlaubt: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Sie haben nicht die Berechtigung, diese Datei umzubenennen. Bitte wenden Sie sich an den Autor der Datei, um sie umzubenennen. + + + + Filename contains illegal characters: %1 + Dateiname enthält unzulässige Zeichen: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Datei konnte nicht umbenannt werden. Bitte stellen Sie sicher, dass Sie mit dem Server verbunden sind. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Die Datei kann nicht umbenannt werden, da eine Datei mit demselben Namen bereits auf dem Server existiert. Bitte wählen Sie einen anderen Namen. + + OCC::LegalNotice @@ -2417,7 +2493,7 @@ Protokolle werden in % 1 geschrieben <nobr>Datei '%1'<br/>kann nicht zum Schreiben geöffnet werden.<br/><br/>Die Protokolldatei kann <b>nicht</b> gespeichert werden!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>Datei "%1"<br/>kann nicht zum Schreiben geöffnet werden.<br/><br/>Die Protokolldatei kann <b>nicht</b> gespeichert werden!</nobr> @@ -2460,6 +2536,11 @@ Protokolle werden in % 1 geschrieben <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Eine neue Version des %1 - Clients ist verfügbar, aber die Aktualisierung ist fehlgeschlagen.</p><p><b>%2</b> wurde heruntergeladen. Die installierte Version ist %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Eine neue Version des %1 - Clients ist verfügbar, aber die Aktualisierung ist fehlgeschlagen.</p><p><b>%2</b> wurde heruntergeladen. Die installierte Version ist %3. Wenn Sie Neustart und Aktualisieren bestätigen, wird Ihr Computer möglicherweise neu gestartet, um die Installation abzuschließen.</p> + Ask again later @@ -2629,6 +2710,12 @@ Protokolle werden in % 1 geschrieben New %1 Update Ready Neue %1 Aktualisierung verfügbar + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Eine neue Aktualisierung für %1 wird installiert. Während des Aktualisierungsvorgangs werden Sie eventuell gefragt, zusätzliche Berechtigungen zu gewähren. + New %1 update ready @@ -2636,9 +2723,8 @@ Protokolle werden in % 1 geschrieben - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Eine neue Aktualisierung für %1 wird installiert. Während des Aktualisierungsvorgangs werden Sie eventuell gefragt, zusätzliche Berechtigungen zu gewähren. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Eine neue Aktualisierung für %1 wird installiert. Während des Aktualisierungsvorgangs werden Sie eventuell aufgefordert, zusätzliche Berechtigungen zu gewähren. Ihr Computer wird möglicherweise neu gestartet, um die Installation abzuschließen. @@ -2675,6 +2761,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Neue Version von %1 vorhanden. Bitte klicken Sie <a href='%2'>hier</a> um die Aktualisierung herunterzuladen. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Aktualisierung kann nicht herunter geladen werden. Bitte öffnen Sie <a href='%1'>%1</a>, um die Aktualisierung manuell herunterzuladen. + Could not download update. Please open %1 to download the update manually. @@ -2685,6 +2776,11 @@ for additional privileges during the process. Could not check for new updates. Auf neue Aktualisierungen kann nicht geprüft werden. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Neue Version von %1 vorhanden. Bitte öffnen Sie <a href='%2'>%2</a> um die Aktualisierung herunterzuladen. + New %1 is available. Please open %2 to download the update. @@ -2981,37 +3077,37 @@ Es wird davon abgeraten sie zu verwenden. Zeitüberschreitung beim Verbindungsversuch mit %1 unter %2. - + Trying to connect to %1 at %2 … Verbindungsversuch mit %1 unter %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Die Authentifizierungs-Anfrage an den Server wurde weitergeleitet an '%1'. Diese Adresse ist ungültig, der Server ist falsch konfiguriert. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. Die Authentifizierungs-Anfrage an den Server wurde weitergeleitet an "%1". Diese Adresse ist ungültig, der Server ist falsch konfiguriert. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Zugang vom Server nicht erlaubt. <a href="%1">Klicken Sie hier</a> zum Zugriff auf den Dienst mithilfe Ihres Browsers, so dass Sie sicherstellen können, dass Ihr Zugang ordnungsgemäß funktioniert. - + There was an invalid response to an authenticated WebDAV request Ungültige Antwort auf eine WebDAV-Authentifizeriungs-Anfrage - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Lokaler Sync-Ordner %1 existiert bereits, aktiviere Synchronistation.<br/><br/> - + Creating local sync folder %1 … Lokaler Ordner %1 für die Synchronisierung wird erstellt … @@ -3021,84 +3117,84 @@ Es wird davon abgeraten sie zu verwenden. OK - + OK OK - + failed. fehlgeschlagen. - + Could not create local folder %1 Der lokale Ordner %1 konnte nicht erstellt werden - + No remote folder specified! Kein entfernter Ordner angegeben! - + Error: %1 Fehler: %1 - + creating folder on Nextcloud: %1 Erstelle Ordner auf Nextcloud: %1 - + Remote folder %1 created successfully. Entfernter Ordner %1 erfolgreich erstellt. - + The remote folder %1 already exists. Connecting it for syncing. Der Ordner %1 ist auf dem Server bereits vorhanden. Verbinde zur Synchronisierung. - - + + The folder creation resulted in HTTP error code %1 Das Erstellen des Ordners erzeugte den HTTP-Fehler-Code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Die Erstellung des entfernten Ordners ist fehlgeschlagen, weil die angegebenen Zugangsdaten falsch sind. <br/>Bitte gehen Sie zurück und überprüfen Sie die Zugangsdaten.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Die Erstellung des entfernten Ordners ist fehlgeschlagen, vermutlich sind die angegebenen Zugangsdaten falsch.</font><br/>Bitte gehen Sie zurück und überprüfen Sie Ihre Zugangsdaten.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Entfernter Ordner %1 konnte mit folgendem Fehler nicht erstellt werden: <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Eine Synchronisierungsverbindung für Ordner %1 zum entfernten Ordner %2 wurde eingerichtet. - + Successfully connected to %1! Erfolgreich verbunden mit %1! - + Connection to %1 could not be established. Please check again. Die Verbindung zu %1 konnte nicht hergestellt werden. Bitte prüfen Sie die Einstellungen erneut. - + Folder rename failed Ordner umbenennen fehlgeschlagen. @@ -3108,28 +3204,28 @@ Es wird davon abgeraten sie zu verwenden. Der Ordner kann nicht entfernt und gesichert werden, da der Ordner oder einer seiner Dateien in einem anderen Programm geöffnet ist. Bitte schließen Sie den Ordner oder die Datei oder beenden Sie die Installation. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Der Ordner kann nicht entfernt und gesichert werden, da der Ordner oder einer seiner Dateien in einem anderen Programm geöffnet ist. Bitte schließen Sie den Ordner oder die Datei und versuchen Sie es erneut oder beenden Sie die Installation. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Lokaler Sync-Ordner %1 erfolgreich erstellt!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1-Verbindungsassistent - Add %1 account %1 Konto hinzufügen + + + %1 Connection Wizard + %1-Verbindungsassistent + Skip folders configuration @@ -3168,24 +3264,6 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Bleiben Sie sicher - - OCC::OwncloudWizardResultPage - - - Everything set up! - Alles ist eingerichtet! - - - - Open Local Folder - Öffne lokalen Ordner - - - - Open %1 in Browser - %1 im Browser öffnen - - OCC::PollJob @@ -3196,6 +3274,16 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Datei enthält Leerzeichen am Ende und konnte nicht umbenannt werden, da eine Datei mit demselben Namen bereits auf dem Server existiert. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Datei enthält Leerzeichen am Ende und konnte nicht umbenannt werden, da eine Datei mit demselben Namen bereits lokal existiert. + Symbolic links are not supported in syncing. @@ -3211,16 +3299,16 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver File names ending with a period are not supported on this file system. Dateinamen, die mit einem Punkt enden, werden von diesem Dateisystem nicht unterstützt. - - - File names containing the character "%1" are not supported on this file system. - Dateinamen, welche das Zeichen "%1" enthalten, werden von diesem Dateisystem nicht unterstützt. - File names containing the character '%1' are not supported on this file system. Dateinamen, welche das Zeichen '%1' enthalten, werden von diesem Dateisystem nicht unterstützt. + + + File names containing the character "%1" are not supported on this file system. + Dateinamen, welche das Zeichen "%1" enthalten, werden von diesem Dateisystem nicht unterstützt. + File name contains at least one invalid character @@ -3347,7 +3435,7 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Der Server hat während des Lesens des Verzeichnisses '%1' mit einem Fehler geantwortet: %2 - + Server replied with an error while reading directory "%1" : %2 Der Server hat während des Lesens des Verzeichnisses "%1" mit einem Fehler geantwortet: %2 @@ -3962,11 +4050,6 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Allow Editing Bearbeitung erlauben - - - Allow editing - Bearbeitung erlauben - Read only @@ -3987,6 +4070,16 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Password Protect Passwortschutz + + + Allow editing + Bearbeitung erlauben + + + + View only + Nur anzeigen + Allow upload and editing @@ -4002,16 +4095,21 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver File drop (upload only) Dateien ablegen (nur Hochladen) - - - Note to recipient - Notiz an Empfänger - Unshare Freigabe aufheben + + + Link name + Link-Name + + + + Note to recipient + Notiz an Empfänger + Password protect @@ -4023,15 +4121,20 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Ablaufdatum setzen - - Delete share link - Freigabe-Link löschen + + Delete link + Link löschen Add another link Weiteren Link hinzufügen + + + Delete share link + Freigabe-Link löschen + Confirm Link Share Deletion @@ -4081,7 +4184,7 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Keine Ergebnisse für '%1' - + No results for "%1" Keine Ergebnisse für "%1" @@ -4185,12 +4288,6 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Teile mit %1 - Context menu share @@ -4217,6 +4314,12 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Share via %1 Teilen mittels %1 + + + + Activity + Aktivität + Copy private link to clipboard @@ -4288,6 +4391,12 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Delete Löschen + + + Share with %1 + parameter is Nextcloud + Teile mit %1 + OCC::SslButton @@ -4433,6 +4542,11 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Cannot connect securely to <i>%1</i>: Kann keine sichere Verbindung zu <i>%1</i> herstellen: + + + Additional errors: + Zusätzliche Fehler: + with Certificate %1 @@ -4607,6 +4721,11 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Placeholders are postfixed with file sizes using Utility::octetsToString() Nur %1 sind verfügbar. Zum Beginnen werden mindestens %2 benötigt. + + + Aborted + Abgebrochen + @@ -4759,27 +4878,88 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Invalid characters, please rename "%1" Ungültige Zeichen, bitte benennen Sie "%1" um + + + Synchronization will resume shortly. + Die Synchronisierung wird in Kürze fortgesetzt. + File name contains at least one invalid character Der Dateiname enthält mindestens ein ungültiges Zeichen - - Aborted - Abgebrochen - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Der freie Speicherplatz wird knapp: Downloads, die den freien Speicher unter %1 reduzieren, wurden ausgelassen. - + There is insufficient space available on the server for some uploads. Auf dem Server ist für einige Dateien zum Hochladen nicht genug Platz. + + OCC::SyncStatusSummary + + + + Offline + Offline + + + + + + All synced! + Alles synchronisiert! + + + + Some files couldn't be synced! + Einige Dateien konnten nicht synchronisiert werden! + + + + See below for errors + Warnungen siehe unten + + + + Syncing + Synchronisiere + + + + Sync paused + Synchronisierung pausiert + + + + Some files could not be synced! + Einige Dateien konnten nicht synchronisiert werden! + + + + See below for warnings + Warnungen siehe unten + + + + %1 of %2 · %3 left + %1 von %2 · %3 verbleiben + + + + %1 of %2 + %1 von %2 + + + + Syncing file %1 of %2 + Synchronisiere Datei %1 von %2 + + OCC::Systray @@ -4855,6 +5035,29 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver <p>Diese Version wird von %1 bereitgestellt</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Anbieter konnten nicht abgerufen werden. + + + + Failed to fetch search providers for '%1'. Error: %2 + Konnte Suchanbieter für '%1' nicht abrufen. Fehler: %2 + + + + Search has failed for '%2'. + Suche nach '%2' fehlgeschlagen. + + + + Search has failed for '%1'. Error: %2 + Suche nach '%1' fehlgeschlagen. Fehler: %2 + + OCC::User @@ -4912,24 +5115,108 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Die Funktion "Virtuelles Dateisystem" erfordert ein NTFS-Dateisystem, %1 verwendet %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Vordefinierte Status konnten nicht abgerufen werden. Stellen Sie bitte sicher, dass Sie mit dem Server verbunden sind. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Herunterladen einer Ende-zu-Ende-verschlüsselten Datei fehlgeschlagen + + Could not fetch user status. Make sure you are connected to the server. + Benutzerstatus konnte nicht abgerufen werden. Stellen Sie bitte sicher, dass Sie mit dem Server verbunden sind. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Es scheint, dass Sie versuchen, eine virtuelle Datei herunterzuladen, die Ende-zu-Ende-verschlüsselt ist. Das implizite Herunterladen solcher Dateien wird derzeit nicht unterstützt. Um dieses Problem zu umgehen, gehen Sie in die Einstellungen und markieren Sie den verschlüsselten Ordner mit "Immer lokal verfügbar machen". + + User status feature is not supported. You will not be able to set your user status. + Benutzerstatus-Funktion wird nicht unterstützt. Sie können Ihren Benutzerstatus nicht setzen, + + + + Emojis feature is not supported. Some user status functionality may not work. + Emoji-Funktion wird nicht unterstützt. Einige Benutzerstatus-Funktionen funktionieren unter Umständen nicht. + + + + Could not set user status. Make sure you are connected to the server. + Benutzerstatus konnte nicht gesetzt werden. Stellen Sie bitte sicher, dass Sie mit dem Server verbunden sind. + + + + Could not clear user status message. Make sure you are connected to the server. + Statusnachricht des Benutzers konnte nicht gelöscht werden. Stellen Sie bitte sicher, dass Sie mit dem Server verbunden sind. + + + + + Don't clear + Nicht löschen + + + + 30 minutes + 30 Minuten + + + + + 1 hour + 1 Stunde + + + + 4 hours + 4 Stunden + + + + + Today + Heute + + + + + This week + Diese Woche + + + + Less than a minute + Weniger als eine Minute + + + + 1 minute + 1 Minute + + + + %1 minutes + %1 Minuten + + + + %1 hours + %1 Stunden + + + + 1 day + 1 Tag + + + + %1 days + %1 Tage + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Die Funktion "Virtuelles Dateisystem" erfordert ein NTFS-Dateisystem, %1 verwendet %2 @@ -5446,14 +5733,6 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Bei %1 anmelden - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Ihr gesamtes Konto wird mit dem lokalen Ordner synchronisiert. - - QObject @@ -5546,6 +5825,38 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Fehler beim Verbinden mit der Datenbank. + + UnifiedSearchInputContainer + + + Search files, messages, events … + Suche Dateien, Nachrichten und Termine … + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Weitere Ergebnisse laden + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Suchergebnis-Skelett. + + + + UnifiedSearchResultListItem + + + Load more results + Weitere Ergebnisse laden + + UserLine @@ -5560,29 +5871,39 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver - Current user status is online - Aktueller Benutzerstatus ist Online + Account connected + Konto verbunden - Current user status is do not disturb - Aktueller Benutzerstatus ist Nicht stören + Account not connected + Konto nicht verbunden - Account connected - Konto verbunden + Current user status is online + Aktueller Benutzerstatus ist Online - Account not connected - Konto nicht verbunden + Current user status is do not disturb + Aktueller Benutzerstatus ist Nicht stören Account actions Konto-Aktionen + + + Remove Account + Konto entfernen + + + + Set status + Status setzen + @@ -5595,17 +5916,65 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Log in Anmelden - - - Remove Account - Konto entfernen - Remove account Konto löschen + + UserStatusSelector + + + Online status + Online-Status + + + + Online + Online + + + + Away + Abwesend + + + + Do not disturb + Nicht stören + + + + Invisible + Unsichtbar + + + + Status message + Statusnachricht + + + + What is your status? + Wie ist Ihr Status? + + + + Clear status message after + Statusnachricht löschen nach + + + + Clear status message + Statusnachricht löschen + + + + Set status message + Statusnachricht setzen + + Utility @@ -5667,12 +6036,12 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver ValidateChecksumHeader - + The checksum header is malformed. Der Prüfsummen-Header hat ein fehlerhaftes Format. - + The checksum header contained an unknown checksum type '%1' Der Prüfsummen-Header enthielt einen unbekannten Prüfsummentyp '%1' @@ -5682,17 +6051,17 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Die heruntergeladene Datei entspricht nicht der Prüfsumme, das Herunterladen wird wiederaufgenommen. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Die heruntergeladene Datei stimmt nicht mit der Prüfsumme überein, sie wird fortgesetzt. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" Der Prüfsummen-Header enthielt einen unbekannten Prüfsummentyp "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" Die heruntergeladene Datei stimmt nicht mit der Prüfsumme überein, sie wird fortgesetzt. "%1" != "%2" @@ -5721,6 +6090,11 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Pause sync for all Synchronisierung für alle pausieren + + + Set user status + Benutzerstatus setzen + Add account @@ -5756,12 +6130,6 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Current user status is do not disturb Aktueller Benutzerstatus ist Nicht stören - - - - Show more actions - Weitere Aktionen anzeigen - Share %1 @@ -5822,6 +6190,22 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Open share dialog Teilen-Dialog öffnen + + + Unified search results list + Einheitliche Suchergebnisliste + + + + + Show more actions + Weitere Aktionen anzeigen + + + + %1 - File activity + %1 - Dateiaktivitäten + main.cpp @@ -6121,6 +6505,24 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Melden Sie sich in Ihren Browser an (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Alles ist eingerichtet! + + + + Open Local Folder + Öffne lokalen Ordner + + + + Open %1 in Browser + %1 im Browser öffnen + + OCC::ShibbolethCredentials @@ -6173,6 +6575,14 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Anmelden + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Ihr gesamtes Konto wird mit dem lokalen Ordner synchronisiert. + + OCC::UserStatus @@ -6196,4 +6606,17 @@ Dies ist ein neuer, experimenteller Modus. Wenn Sie sich entscheiden, ihn zu ver Online + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Herunterladen einer Ende-zu-Ende-verschlüsselten Datei fehlgeschlagen + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Es scheint, dass Sie versuchen, eine virtuelle Datei herunterzuladen, die Ende-zu-Ende-verschlüsselt ist. Das implizite Herunterladen solcher Dateien wird derzeit nicht unterstützt. Um dieses Problem zu umgehen, gehen Sie in die Einstellungen und markieren Sie den verschlüsselten Ordner mit "Immer lokal verfügbar machen". + + \ No newline at end of file diff --git a/translations/client_el.ts b/translations/client_el.ts index 18e3e2358c25..ca007aa8c0cb 100644 --- a/translations/client_el.ts +++ b/translations/client_el.ts @@ -12,22 +12,35 @@ Open %1 locally - + Ανοίξτε το %1 τοπικά + + + + Open share dialog + Άνοιγμα του διαλόγου διαμοιρασμού + + + + Share %1 + Κοινή χρήση %1 Show more actions - + Εμφάνιση περισσότερων ενεργειών. - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Γίνεται έλεγχος για αλλαγές στο «%1» @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Σφάλμα αφαίρεσης «%1»: %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Αδυναμία αφαίρεσης φακέλου «%1» @@ -185,7 +198,7 @@ Logo - + Λογότυπο @@ -195,7 +208,7 @@ Switch to your browser to connect your account - + Μεταβείτε στο πρόγραμμα περιήγησής σας για να συνδέσετε τον λογαριασμό σας @@ -331,7 +344,7 @@ End-to-End Encryption with Virtual Files - + Κρυπτογράφηση από άκρο σε άκρο με εικονικά αρχεία @@ -341,12 +354,12 @@ Don't encrypt folder - + Να μην κρυπτογραφηθεί ο φάκελος Encrypt folder - + Κρυπτογράφηση φακέλου @@ -415,7 +428,7 @@ Wait for the new sync, then encrypt it. Encryption failed - + Αποτυχία κρυπτογράφησης @@ -1140,34 +1153,34 @@ This can be an issue with your OpenSSL libraries. Δεν μπορεί να ανοίξει ο Περιηγητής, παρακαλώ αντιγράψτε τον σύνδεσμο στον Περιηγητή σας. - + Waiting for authorization Αναμονή εξουσιοδότησης - + Polling for authorization Αίτημα για εξουσιοδότηση - + Starting authorization Έναρξη εξουσιοδότησης - + Link copied to clipboard. Ο σύνδεσμος αντιγράφηκε στο πρόχειρο. - + Reopen Browser - + Copy Link - + Αντιγραφή συνδέσμου @@ -1332,6 +1345,13 @@ This means that the synchronization client might not upload local changes immedi Αυτό σημαίνει ότι η εφαρμογή δεν θα ανεβάσει τις τοπικές αλλαγές άμεσα, θα ελέγξει μόνο τις τοπικές αλλαγές και θα τις ανεβάσει περιοδικά (κάθε δύο ώρες από προεπιλογή). + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Όλα τα αρχεία στον τοπικό σας φάκελο συγχρονισμού '% 1' διαγράφησαν. Αυτές οι διαγραφές θα συγχρονιστούν με τον διακομιστή σας, καθιστώντας τα αρχεία αυτά μη διαθέσιμα εκτός αν γίνει επαναφορά. Είστε βέβαιοι ότι θέλετε να συγχρονίσετε αυτές τις ενέργειες με τον διακομιστή; Εάν αυτό ήταν ατύχημα και αποφασίσετε να διατηρήσετε τα αρχεία σας, θα συγχρονιστούν ξανά από το διακομιστή. + All files in the sync folder '%1' were deleted on the server. @@ -1392,22 +1412,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Διατήρηση τοπικών αρχείων ως Διένεξη - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Όλα τα αρχεία στο φάκελο συγχρονισμού '% 1' διαγράφηκαν στο διακομιστή. Αυτές οι διαγραφές θα συγχρονιστούν με τον τοπικό φάκελο συγχρονισμού, καθιστώντας αυτά τα αρχεία μη διαθέσιμα εκτός εάν έχετε δικαίωμα επαναφοράς. Εάν αποφασίσετε να επαναφέρετε τα αρχεία, θα συγχρονιστούν ξανά με τον διακομιστή, εφόσον έχετε τα δικαιώματα. Εάν αποφασίσετε να διαγράψετε τα αρχεία, θα είναι μη διαθέσιμα σε εσάς, εκτός εάν είστε ο κάτοχος. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Όλα τα αρχεία στον τοπικό σας φάκελο συγχρονισμού '% 1' διαγράφησαν. Αυτές οι διαγραφές θα συγχρονιστούν με τον διακομιστή σας, καθιστώντας τα αρχεία αυτά μη διαθέσιμα εκτός αν γίνει επαναφορά. Είστε βέβαιοι ότι θέλετε να συγχρονίσετε αυτές τις ενέργειες με τον διακομιστή; Εάν αυτό ήταν ατύχημα και αποφασίσετε να διατηρήσετε τα αρχεία σας, θα συγχρονιστούν ξανά από το διακομιστή. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1415,7 +1420,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1431,6 +1436,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Κατάργηση όλων των αρχείων. + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Όλα τα αρχεία στο φάκελο συγχρονισμού '% 1' διαγράφηκαν στο διακομιστή. Αυτές οι διαγραφές θα συγχρονιστούν με τον τοπικό φάκελο συγχρονισμού, καθιστώντας αυτά τα αρχεία μη διαθέσιμα εκτός εάν έχετε δικαίωμα επαναφοράς. Εάν αποφασίσετε να επαναφέρετε τα αρχεία, θα συγχρονιστούν ξανά με τον διακομιστή, εφόσον έχετε τα δικαιώματα. Εάν αποφασίσετε να διαγράψετε τα αρχεία, θα είναι μη διαθέσιμα σε εσάς, εκτός εάν είστε ο κάτοχος. + Keep files @@ -2242,7 +2255,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Cannot write changes to "%1". - + Αδυναμία εγγραφής αλλαγών στο «%1» @@ -2260,6 +2273,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Προσθήκη νέας συνθήκης αγνόησης: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2276,7 +2352,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from <p>Copyright 2017-2021 Nextcloud GmbH<br />Copyright 2012-2021 ownCloud GmbH</p> - + <p>Πνευματικά δικαιώματα 2017-2021 Nextcloud GmbH<br />Πνευματικά δικαιώματα 2012-2021 ownCloud GmbH</p> @@ -2398,7 +2474,7 @@ Logs will be written to %1 <nobr>Το αρχείο '%1'<br/>δεν μπορεί να ανοιχθεί για εγγραφή.<br/><br/>Το αρχείο καταγραφής <b>δεν</b> μπορεί να αποθηκευτεί!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2441,6 +2517,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Διατίθεται μια νέα έκδοση του % 1 Client, αλλά η διαδικασία ενημέρωσης απέτυχε. Έγινε λήψη του </p><p><b>2% </b>. Η εγκατεστημένη έκδοση είναι % 3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2610,6 +2691,13 @@ Logs will be written to %1 New %1 Update Ready Νέα %1 Ενημέρωση Έτοιμη + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Μια νέα ενημέρωση για %1 πρόκειται να εγκατασταθεί. Ο βοηθός ενημέρωσης μπορεί να ζητήσει +επιπλέον παραχωρήσεις δικαιωμάτων κατά τη διαδικασία. + New %1 update ready @@ -2617,10 +2705,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Μια νέα ενημέρωση για %1 πρόκειται να εγκατασταθεί. Ο βοηθός ενημέρωσης μπορεί να ζητήσει -επιπλέον παραχωρήσεις δικαιωμάτων κατά τη διαδικασία. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2657,6 +2743,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Το νέο % 1 είναι διαθέσιμο. Κάντε κλικ <a href='%2'>εδώ</a>για λήψη της ενημέρωσης. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2667,6 +2758,11 @@ for additional privileges during the process. Could not check for new updates. Αδυναμία ελέγχου για νέες ενημερώσεις. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2708,7 +2804,7 @@ for additional privileges during the process. Connect - + Σύνδεση @@ -2760,7 +2856,7 @@ for additional privileges during the process. Sync the folder "%1" - + Συγχρονισμός του φακέλου «%1» @@ -2771,7 +2867,7 @@ for additional privileges during the process. %1 free space %1 gets replaced with the size and a matching unit. Example: 3 MB or 5 GB - + %1 ελεύθερος χώρος @@ -2963,37 +3059,37 @@ It is not advisable to use it. Λήξη χρονικού ορίου κατά τη σύνδεση σε %1 σε %2. - + Trying to connect to %1 at %2 … Προσπάθεια σύνδεσης στο %1 για %2 '...' - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Η πιστοποιημένη αίτηση στον διακομιστή ανακατευθύνθηκε σε '%1'. Το URL είναι εσφαλμένο, ο διακομιστής δεν έχει διαμορφωθεί σωστά. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Απαγόρευση πρόσβασης από τον διακομιστή. Για να επιβεβαιώσετε ότι έχετε δικαιώματα πρόσβασης, <a href="%1">πατήστε εδώ</a> για να προσπελάσετε την υπηρεσία με το πρόγραμμα πλοήγησής σας. - + There was an invalid response to an authenticated WebDAV request Υπήρξε μη έγκυρη απάντηση σε πιστοποιημένη αίτηση WebDAV - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Ο τοπικός φάκελος συγχρονισμού %1 υπάρχει ήδη, ρύθμιση για συγχρονισμό.<br/><br/> - + Creating local sync folder %1 … Δημιουργία τοπικού φακέλου συγχρονισμού %1 '...' @@ -3003,84 +3099,84 @@ It is not advisable to use it. οκ - + OK - + Εντάξει - + failed. απέτυχε. - + Could not create local folder %1 Αδυναμία δημιουργίας τοπικού φακέλου %1 - + No remote folder specified! Δεν προσδιορίστηκε κανένας απομακρυσμένος φάκελος! - + Error: %1 Σφάλμα: %1 - + creating folder on Nextcloud: %1 δημιουργία φακέλου στο Nextcloud: %1 - + Remote folder %1 created successfully. Ο απομακρυσμένος φάκελος %1 δημιουργήθηκε με επιτυχία. - + The remote folder %1 already exists. Connecting it for syncing. Ο απομακρυσμένος φάκελος %1 υπάρχει ήδη. Θα συνδεθεί για συγχρονισμό. - - + + The folder creation resulted in HTTP error code %1 Η δημιουργία φακέλου είχε ως αποτέλεσμα τον κωδικό σφάλματος HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Η δημιουργία απομακρυσμένου φακέλλου απέτυχε επειδή τα διαπιστευτήρια είναι λάθος!<br/>Παρακαλώ επιστρέψετε και ελέγξετε τα διαπιστευτήριά σας.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Η δημιουργία απομακρυσμένου φακέλου απέτυχε, πιθανώς επειδή τα διαπιστευτήρια που δόθηκαν είναι λάθος.</font><br/>Παρακαλώ επιστρέψτε πίσω και ελέγξτε τα διαπιστευτήρια σας.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Η δημιουργία απομακρυσμένου φακέλου %1 απέτυχε με σφάλμα <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Μια σύνδεση συγχρονισμού από τον απομακρυσμένο κατάλογο %1 σε %2 έχει ρυθμιστεί. - + Successfully connected to %1! Επιτυχής σύνδεση με %1! - + Connection to %1 could not be established. Please check again. Αδυναμία σύνδεσης στον %1. Παρακαλώ ελέξτε ξανά. - + Folder rename failed Αποτυχία μετονομασίας φακέλου @@ -3090,28 +3186,28 @@ It is not advisable to use it. Αδυναμία αφαίρεσης και δημιουργίας αντιγράφου ασφαλείας του φακέλου διότι ο φάκελος ή ένα αρχείο του είναι ανοικτό από άλλο πρόγραμμα. Παρακαλώ κλείστε τον φάκελο ή το αρχείο και πατήστε επανάληψη ή ακυρώστε την ρύθμιση. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Επιτυχής δημιουργία τοπικού φακέλου %1 για συγχρονισμό!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Οδηγός Σύνδεσης - Add %1 account + + + %1 Connection Wizard + %1 Οδηγός Σύνδεσης + Skip folders configuration @@ -3144,24 +3240,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Μείνετε ασφαλής. - - OCC::OwncloudWizardResultPage - - - Everything set up! - Όλα είναι ρυθμισμένα! - - - - Open Local Folder - Άνοιγμα τοπικού φακέλου - - - - Open %1 in Browser - Άνοιγμα %1 στο Πρόγραμμα Περιήγησης - - OCC::PollJob @@ -3172,6 +3250,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3187,16 +3275,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. Τα ονόματα αρχείων που τελειώνουν με τελεία δεν υποστηρίζονται σε αυτό το σύστημα αρχείων. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Τα ονόματα αρχείων που περιέχουν τον χαρακτήρα '% 1' δεν υποστηρίζονται σε αυτό το σύστημα αρχείων. + + + File names containing the character "%1" are not supported on this file system. + + File name contains at least one invalid character @@ -3323,7 +3411,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ο διακομιστής απάντησε με σφάλμα κατά την ανάγνωση της διεύθυνσης ΄%1' : %2 - + Server replied with an error while reading directory "%1" : %2 @@ -3343,7 +3431,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss File is currently in use - + Το αρχείο χρησιμοποιείται αυτήν τη στιγμή @@ -3423,7 +3511,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss The file %1 is currently in use - + Το αρχείο %1 χρησιμοποιείται αυτήν τη στιγμή @@ -3454,7 +3542,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Could not create folder %1 - + Αδυναμία δημιουργίας φακέλου: %1 @@ -3464,12 +3552,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Σφάλμα ενημέρωσης μεταδεδομένων: %1 The file %1 is currently in use - + Το αρχείο %1 χρησιμοποιείται αυτήν τη στιγμή @@ -3510,12 +3598,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Σφάλμα ενημέρωσης μεταδεδομένων: %1 The file %1 is currently in use - + Το αρχείο %1 χρησιμοποιείται αυτήν τη στιγμή @@ -3526,7 +3614,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to rename file - + Αποτυχία μετονομασίας αρχείου @@ -3565,12 +3653,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error writing metadata to the database: %1 - + Σφάλμα εγγραφής μεταδεδομένων στη βάση δεδομένων: %1 The file %1 is currently in use - + Το αρχείο %1 χρησιμοποιείται αυτήν τη στιγμή @@ -3588,12 +3676,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Σφάλμα ενημέρωσης μεταδεδομένων: %1 The file %1 is currently in use - + Το αρχείο %1 χρησιμοποιείται αυτήν τη στιγμή @@ -3652,12 +3740,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Σφάλμα ενημέρωσης μεταδεδομένων: %1 The file %1 is currently in use - + Το αρχείο %1 χρησιμοποιείται αυτήν τη στιγμή @@ -3906,7 +3994,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Note - + Σημείωση @@ -3916,7 +4004,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Set password - + Ορισμός συνθηματικού @@ -3931,18 +4019,13 @@ This is a new, experimental mode. If you decide to use it, please report any iss Expires - + Λήγει Allow Editing Να επιτρέπεται η επεξεργασία - - - Allow editing - Επιτρέπεται η επεξεργασία - Read only @@ -3963,6 +4046,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Προστασία με συνθηματικό + + + Allow editing + Επιτρέπεται η επεξεργασία + + + + View only + + Allow upload and editing @@ -3978,16 +4071,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Απόθεση αρχείου (μόνο μεταφόρτωση) - - - Note to recipient - Σημείωση προς τον παραλήπτη - Unshare Αναίρεση διαμοιρασμού + + + Link name + + + + + Note to recipient + Σημείωση προς τον παραλήπτη + Password protect @@ -3999,15 +4097,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ορισμός ημερομηνίας λήξης - - Delete share link - Διαγραφή κοινόχρηστου συνδέσμου + + Delete link + Add another link Προσθήκη άλλου συνδέσμου + + + Delete share link + Διαγραφή κοινόχρηστου συνδέσμου + Confirm Link Share Deletion @@ -4057,7 +4160,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Κανένα αποτέλεσμα για '%1' - + No results for "%1" @@ -4097,17 +4200,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Note: - + Σημείωση: Password: - + Συνθηματικό: Expires: - + Λήγει: @@ -4122,7 +4225,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Set expiration date - + Ορισμός ημερομηνίας λήξης @@ -4147,7 +4250,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password protect - + Προστασία με συνθηματικό @@ -4161,12 +4264,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Διαμοιρασμός με %1 - Context menu share @@ -4193,6 +4290,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Διαμοιρασμός μέσω %1 + + + + Activity + + Copy private link to clipboard @@ -4264,11 +4367,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Διαγραφή - - - OCC::SslButton - + + Share with %1 + parameter is Nextcloud + Διαμοιρασμός με %1 + + + + OCC::SslButton + + <h3>Certificate Details</h3> <h3>Λεπτομέρειες Πιστοποιητικού</h3> @@ -4409,6 +4518,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Αδυναμία ασφαλούς σύνδεσης σε <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4565,7 +4679,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Could not update file: %1 - + Αδυναμία ενημέρωσης αρχείου: %1. @@ -4583,6 +4697,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Μόνο %1 είναι διαθέσιμα, απαιτούνται τουλάχιστον %2 για την εκκίνηση + + + Aborted + Ματαιώθηκε + @@ -4735,27 +4854,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Μη έγκυροι χαρακτήρες, παρακαλώ μετονομάστε το "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Το όνομα αρχείου περιέχει έναν τουλάχιστον μη έγκυρο χαρακτήρα - - Aborted - Ματαιώθηκε - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Ο χώρος δίσκου είναι χαμηλός: Οι λήψεις που θα μειώσουν τον ελέυθερο χώρο κάτω από %1 θα αγνοηθούν. - + There is insufficient space available on the server for some uploads. Μη αρκετός διαθέσιμος χώρος στον διακομιστή για μερικές μεταφορτώσεις. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4831,6 +5011,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Η έκδοση παρέχεται από %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4888,25 +5091,109 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Η δυνατότητα εικονικού συστήματος αρχείων απαιτεί σύστημα αρχείων NTFS, το %1 χρησιμοποιεί %2. + + Could not fetch predefined statuses. Make sure you are connected to the server. + - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + Να μη γίνεται εκκαθάριση + + + + 30 minutes + 30 λεπτά + + + + + 1 hour + 1 ώρα + + + + 4 hours + 4 ώρες + + + + + Today + Σήμερα + + + + + This week + Αυτή την εβδομάδα + + + + Less than a minute + Λιγότερο από ένα λεπτό + + + + 1 minute + 1 λεπτό + + + + %1 minutes + %1 λεπτά + + + + %1 hours + %1 ώρες + + + + 1 day + 1 ημέρα + + + + %1 days + %1 ημέρες + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Η δυνατότητα εικονικού συστήματος αρχείων απαιτεί σύστημα αρχείων NTFS, το %1 χρησιμοποιεί %2. + OCC::WebEnginePage @@ -4944,23 +5231,23 @@ This is a new, experimental mode. If you decide to use it, please report any iss Form - + Φόρμα Log in to your %1 - + Συνδεθείτε στο δικό σας %1 Create account with Provider - + Δημιουργία λογαριασμού με τον πάροχο Keep your data secure and under your control - + Διατηρήστε τα δεδομένα σας ασφαλή και υπό τον έλεγχό σας @@ -5243,12 +5530,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss User name - + Όνομα χρήστη Server address - + Διεύθυνση διακομιστή @@ -5263,7 +5550,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Sync Logo - + Λογότυπο συγχρονισμού @@ -5273,17 +5560,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Local Folder - + Τοπικός φάκελος Synchronize everything from server - + Συγχρονισμός όλων από τον διακομιστή Ask before syncing folders larger than - + Να ζητείται επιβεβαίωση πριν τον συγχρονισμό φακέλων μεγαλύτερων από @@ -5294,7 +5581,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ask before syncing external storages - + Να ζητείται επιβεβαίωση επιβεβαίωση πριν τον συγχρονισμό εξωτερικών αποθηκευτικών χώρων @@ -5319,7 +5606,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Keep local data - + Διατήρηση τοπικών δεδομένων @@ -5329,7 +5616,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Erase local folder and start a clean sync - + Διαγραφή τοπικού φακέλου και εκκίνηση καθαρού συγχρονισμού @@ -5379,12 +5666,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Logo - + Λογότυπο Server address - + Διεύθυνση διακομιστή @@ -5422,14 +5709,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Συνδεθείτε στο δικό σας %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Ολόκληρος ο λογαριασμός σας έχει συγχρονιστεί με τον τοπικό φάκελο - - QObject @@ -5501,17 +5780,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Do not disturb - + Μην ενοχλείτε Offline - + Εκτός σύνδεσης Online - + Σε σύνδεση @@ -5519,6 +5798,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to connect database. + Αποτυχία σύνδεσης με βάση δεδομένων. + + + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results @@ -5536,29 +5847,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Συνδεδεμένος λογαριασμός - Current user status is do not disturb - + Account not connected + Ο λογαριασμός δεν συνδέθηκε - Account connected - Συνδεδεμένος λογαριασμός + Current user status is online + - Account not connected - Ο λογαριασμός δεν συνδέθηκε + Current user status is do not disturb + Account actions Δραστηριότητα λογαριασμού + + + Remove Account + Αφαίρεση λογαριασμού + + + + Set status + Ορισμός κατάστασης + @@ -5571,17 +5892,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Είσοδος - - - Remove Account - Αφαίρεση λογαριασμού - Remove account Αφαίρεση λογαριασμού + + UserStatusSelector + + + Online status + Κατάσταση σε σύνδεση + + + + Online + Σε σύνδεση + + + + Away + + + + + Do not disturb + Μην ενοχλείτε + + + + Invisible + Αόρατος + + + + Status message + Μήνυμα κατάστασης + + + + What is your status? + Ποια είναι η κατάστασή σας; + + + + Clear status message after + Εκκαθάριση μηνύματος κατάστασης μετά από + + + + Clear status message + Εκκαθάριση μηνύματος κατάστασης + + + + Set status message + Ορισμός μηνύματος κατάστασης + + Utility @@ -5643,12 +6012,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Η κεφαλίδα του αθροίσματος ελέγχου δεν είναι σωστά διαμορφωμένη. - + The checksum header contained an unknown checksum type '%1' Το checksum header περιέχει άγνωστο τύπο checksum '%1' @@ -5658,17 +6027,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Το αρχείο που λήφθηκε δεν επαληθεύεται από τον έλεγχο, θα συγχρονιστεί ξανά. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Το ληφθέν αρχείο δεν ταιριάζει με το άθροισμα ελέγχου, θα επαναληφθεί. '% 1'! = '% 2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5697,6 +6066,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Παύση όλων των συγχρονισμών + + + Set user status + Ορισμός κατάστασης χρήστη + Add account @@ -5732,12 +6106,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - Εμφάνιση περισσότερων ενεργειών. - Share %1 @@ -5798,6 +6166,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Άνοιγμα του διαλόγου διαμοιρασμού + + + Unified search results list + + + + + + Show more actions + Εμφάνιση περισσότερων ενεργειών. + + + + %1 - File activity + + main.cpp @@ -6097,6 +6481,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Σύνδεση στον περιηγητή σας (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Όλα είναι ρυθμισμένα! + + + + Open Local Folder + Άνοιγμα τοπικού φακέλου + + + + Open %1 in Browser + Άνοιγμα %1 στο Πρόγραμμα Περιήγησης + + OCC::ShibbolethCredentials @@ -6149,6 +6551,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Είσοδος + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Ολόκληρος ο λογαριασμός σας έχει συγχρονιστεί με τον τοπικό φάκελο + + OCC::UserStatus @@ -6159,16 +6569,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss Do not disturb - + Μην ενοχλείτε Offline - + Εκτός σύνδεσης Online + Σε σύνδεση + + + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". diff --git a/translations/client_en_GB.ts b/translations/client_en_GB.ts index ffa05c39e56e..647f59d52e22 100644 --- a/translations/client_en_GB.ts +++ b/translations/client_en_GB.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1330,6 +1343,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1385,22 +1405,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Keep Local Files as Conflict - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1408,7 +1413,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1424,6 +1429,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2250,6 +2263,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + The file could not be synced because its name contains characters which are not allowed on this system. + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2387,7 +2463,7 @@ Logs will be written to %1 <nobr>File '%1'<br/>cannot be opened for writing.<br/><br/>The log output can <b>not</b> be saved!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2430,6 +2506,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2599,6 +2680,13 @@ Logs will be written to %1 New %1 Update Ready New %1 Update Ready + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + New %1 update ready @@ -2606,10 +2694,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2646,6 +2732,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2656,6 +2747,11 @@ for additional privileges during the process. Could not check for new updates. Could not check for new updates. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2951,37 +3047,37 @@ It is not advisable to use it. Timeout while trying to connect to %1 at %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Local sync folder %1 already exists, setting it up for sync.<br/><br/> - + Creating local sync folder %1 … @@ -2991,84 +3087,84 @@ It is not advisable to use it. ok - + OK - + failed. failed. - + Could not create local folder %1 Could not create local folder %1 - + No remote folder specified! No remote folder specified! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. Remote folder %1 created successfully. - + The remote folder %1 already exists. Connecting it for syncing. The remote folder %1 already exists. Connecting it for syncing. - - + + The folder creation resulted in HTTP error code %1 The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Remote folder %1 creation failed with error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! Successfully connected to %1! - + Connection to %1 could not be established. Please check again. Connection to %1 could not be established. Please check again. - + Folder rename failed Folder rename failed @@ -3078,28 +3174,28 @@ It is not advisable to use it. Can't remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Local sync folder %1 successfully created!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Connection Wizard - Add %1 account + + + %1 Connection Wizard + %1 Connection Wizard + Skip folders configuration @@ -3132,24 +3228,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Everything set up! - - - - Open Local Folder - Open Local Folder - - - - Open %1 in Browser - Open %1 in Browser - - OCC::PollJob @@ -3160,6 +3238,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3177,12 +3265,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3311,7 +3399,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3926,11 +4014,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Allow Editing - - - Allow editing - Allow editing - Read only @@ -3951,6 +4034,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Password Protect + + + Allow editing + Allow editing + + + + View only + + Allow upload and editing @@ -3966,16 +4059,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) File drop (upload only) - - - Note to recipient - Note to recipient - Unshare Unshare + + + Link name + + + + + Note to recipient + Note to recipient + Password protect @@ -3987,8 +4085,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Set expiration date - - Delete share link + + Delete link @@ -3996,6 +4094,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4045,7 +4148,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No results for '%1' - + No results for "%1" @@ -4149,12 +4252,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Share with %1 - Context menu share @@ -4181,6 +4278,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4252,6 +4355,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Delete + + + Share with %1 + parameter is Nextcloud + Share with %1 + OCC::SslButton @@ -4397,6 +4506,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Cannot connect securely to <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4571,6 +4685,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Only %1 are available, need at least %2 to start + + + Aborted + + @@ -4723,27 +4842,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Invalid characters, please rename "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character File name contains at least one invalid character - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Disk space is low: Downloads that would reduce free space below %1 were skipped. - + There is insufficient space available on the server for some uploads. There is insufficient space available on the server for some uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4819,6 +4999,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>This release was supplied by %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4876,23 +5079,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5410,14 +5697,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Your entire account is synced to the local folder - - QObject @@ -5510,6 +5789,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5524,22 +5835,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5547,6 +5858,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Account actions + + + Remove Account + + + + + Set status + + @@ -5559,17 +5880,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Log in - - - Remove Account - - Remove account Remove account + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5631,12 +6000,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' The checksum header contained an unknown checksum type '%1' @@ -5646,17 +6015,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss The downloaded file does not match the checksum, it will be resumed. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5685,6 +6054,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5720,12 +6094,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5786,6 +6154,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6085,6 +6469,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + Everything set up! + + + + Open Local Folder + Open Local Folder + + + + Open %1 in Browser + Open %1 in Browser + + OCC::ShibbolethCredentials @@ -6137,6 +6539,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Your entire account is synced to the local folder + + OCC::UserStatus @@ -6160,4 +6570,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_eo.ts b/translations/client_eo.ts index ab3fd42c5357..baa62252308e 100644 --- a/translations/client_eo.ts +++ b/translations/client_eo.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. La retumilo ne malfermeblis; kopiu la ligilon mane en vian retumilon. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1330,6 +1343,13 @@ Tio signifas, ke la sinkroniga kliento eble ne alŝutas tuj lokajn ŝanĝojn kaj %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1390,22 +1410,7 @@ Se vi plu sinkronigas, la sinkronigo anstataŭigos ĉiujn viajn dosierojn per an Konservi la lokajn dosierojn kiel konfliktojn - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1413,7 +1418,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1429,6 +1434,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2257,6 +2270,69 @@ Elementoj, kies forigo estas permesita, estos forigitaj, se ili malhelpas forigo Aldoni novan ignoran modelon: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2394,7 +2470,7 @@ Protokoloj estos skribataj al %1. <nobr>Dosiero „%1“<br/>ne eblis malfermiĝi.<br/><br/>La eligo de la protokolo <b>ne</b> povas esti konservita!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2437,6 +2513,11 @@ Protokoloj estos skribataj al %1. <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2606,6 +2687,12 @@ Protokoloj estos skribataj al %1. New %1 Update Ready Nova ĝisdatigo por %1 pretas + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Nova ĝisdatigo por %1 ekinstaliĝos. La ĝisdatigilo eble petos pliajn permesojn dum la instalado. + New %1 update ready @@ -2613,9 +2700,8 @@ Protokoloj estos skribataj al %1. - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Nova ĝisdatigo por %1 ekinstaliĝos. La ĝisdatigilo eble petos pliajn permesojn dum la instalado. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2652,6 +2738,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2662,6 +2753,11 @@ for additional privileges during the process. Could not check for new updates. Ne eblis kontroli, ĉu estas novaj ĝisdatigoj. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2957,37 +3053,37 @@ It is not advisable to use it. Eltempiĝo dum konekto al %1 ĉe %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La aŭtentiga peto al la servilo alidirektis al „%1“. La retadreso eraras; la servilo estas misagordita. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Aliro nepermesata de la servilo. Por kontroli, ĉu vi rajtas pri aliro, <a href="%1">alklaku ĉi tie</a> por iri al la servo pere de via retumilo. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Sinkroniga dosierujo loka %1 jam ekzistas, agordante ĝin por la sinkronigo.<br/><br/> - + Creating local sync folder %1 … @@ -2997,84 +3093,84 @@ It is not advisable to use it. bone - + OK - + failed. malsukcesis. - + Could not create local folder %1 Ne eblis krei lokan dosierujon %1 - + No remote folder specified! Neniu fora dosierujo specifita! - + Error: %1 Eraro: %1 - + creating folder on Nextcloud: %1 kreado de dosierujo ĉe Nextcloud: %1 - + Remote folder %1 created successfully. Fora dosierujo %1 sukcese kreita - + The remote folder %1 already exists. Connecting it for syncing. La fora dosierujo %1 jam ekzistas. Konektado. - - + + The folder creation resulted in HTTP error code %1 Dosieruja kreado ricevis HTTP-eraran kodon %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Kreo de fora dosierujo malsukcesis, ĉar la akreditiloj ne ĝustas!<br/>Bv. antaŭeniri kaj kontroli viajn akreditilojn.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Kreado de fora dosierujo malsukcesis, eble ĉar la akreditiloj ne ĝustas.</font><br/>Bv. antaŭeniri kaj kontroli viajn akreditilojn.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Kreado de fora dosierujo %1 malsukcesis kun eraro <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Sinkroniga konekto el %1 al fora dosierujo %2 agordiĝis. - + Successfully connected to %1! Sukcese konektita al %1! - + Connection to %1 could not be established. Please check again. Konekto al %1 ne eblis. Bv. rekontroli. - + Folder rename failed Dosieruja alinomado malsukcesis. @@ -3084,28 +3180,28 @@ It is not advisable to use it. Ne eblas forigi kaj savkopii la dosierujon, ĉar tiu dosierujo aŭ iu dosiero ene de ĝi estas malfermita en alia programo. Bv. malfermi la dosierujon aŭ dosieron kaj reprovi, aŭ nuligu la agordojn. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Loka sinkroniga dosierujo %1 sukcese kreita!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Asistilo pri konekto %1 - Add %1 account + + + %1 Connection Wizard + Asistilo pri konekto %1 + Skip folders configuration @@ -3138,24 +3234,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Ĉio estas agordita! - - - - Open Local Folder - Malfermi lokan dosierujon - - - - Open %1 in Browser - Malfermi %1 per la retumilo - - OCC::PollJob @@ -3166,6 +3244,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3183,12 +3271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3317,7 +3405,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3932,11 +4020,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Permesi redakton - - - Allow editing - Permesi modifon - Read only @@ -3957,6 +4040,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Protekti per pasvorto + + + Allow editing + Permesi modifon + + + + View only + + Allow upload and editing @@ -3972,16 +4065,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Demeti dosieron (nur alŝuto) - - - Note to recipient - Noto por la ricevonto - Unshare Malkunhavigi + + + Link name + + + + + Note to recipient + Noto por la ricevonto + Password protect @@ -3993,15 +4091,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Uzi limdaton - - Delete share link - Forigi kunhavo-ligilon + + Delete link + Add another link Aldoni plian ligilon + + + Delete share link + Forigi kunhavo-ligilon + Confirm Link Share Deletion @@ -4051,7 +4154,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Neniu rezulto por „%1“ - + No results for "%1" @@ -4155,12 +4258,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Kunhavigi kun %1 - Context menu share @@ -4187,6 +4284,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4258,6 +4361,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Forigi + + + Share with %1 + parameter is Nextcloud + Kunhavigi kun %1 + OCC::SslButton @@ -4402,6 +4511,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Ne eblas konekte sekura al <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4576,6 +4690,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Nur disponeblas %1, bezono de almenaŭ %2 por eki + + + Aborted + + @@ -4728,27 +4847,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Nevalidaj signoj, bv. alinomi „%1“ + + + Synchronization will resume shortly. + + File name contains at least one invalid character La dosiernomo enhavas almenaŭ unu nevalidan signon. - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Diskospaco ne sufiĉas: elŝutoj, kiuj reduktos liberan spacon sub %1, ne okazis. - + There is insufficient space available on the server for some uploads. La servilo ne plu havas sufiĉan spacon por iuj alŝutoj. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4824,6 +5004,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Tiu eldono estis liverita de %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4881,23 +5084,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5415,14 +5702,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Via tuta konta sinkroniĝas kun la loka dosierujo. - - QObject @@ -5515,6 +5794,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5529,22 +5840,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Konto konektita - Current user status is do not disturb + Account not connected - Account connected - Konto konektita + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5552,6 +5863,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + + + + + Set status + + @@ -5564,17 +5885,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Ensaluti - - - Remove Account - - Remove account Forigi konton + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5636,12 +6005,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. La kontrosumo-kapo estas misformita. - + The checksum header contained an unknown checksum type '%1' La kontrosumo-kapo enhavas nekonatan kontrolsumo-tipon „%1“ @@ -5651,17 +6020,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss La elŝutita dosiero ne kongruas kun la kontrolsumo, ĝi estos re-elŝutita. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5690,6 +6059,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5725,12 +6099,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5791,6 +6159,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6090,6 +6474,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ensaluti pere de via retumilo (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Ĉio estas agordita! + + + + Open Local Folder + Malfermi lokan dosierujon + + + + Open %1 in Browser + Malfermi %1 per la retumilo + + OCC::ShibbolethCredentials @@ -6142,6 +6544,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Via tuta konta sinkroniĝas kun la loka dosierujo. + + OCC::UserStatus @@ -6165,4 +6575,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es.ts b/translations/client_es.ts index fb803ca6026b..677f1df13ecc 100644 --- a/translations/client_es.ts +++ b/translations/client_es.ts @@ -14,12 +14,6 @@ Open %1 locally Abrir %1 localmente - - - - Show more actions - Mostrar más acciones - Open share dialog @@ -30,6 +24,25 @@ Share %1 Compartir %1 + + + + Show more actions + Mostrar más acciones + + + + View activity + Ver actividad + + + + ActivityList + + + Activity list + Lista de actividad + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - No se ha podido mover "%1" a "%1" + Could not move "%1" to "%2" + No se ha podido mover "%1" a "%2" @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Parece que tienes la función de Archivos Virtuales activada en esta carpeta. Por el momento, no es posible descargar automáticamente los archivos virtuales que están cifrados de extremo a extremo. Para obtener la mejor experiencia con los archivos virtuales y el cifrado de extremo a extremo, asegúrate de que la carpeta cifrada está marcada con "Hacer que esté siempre disponible localmente". @@ -842,7 +855,7 @@ Además, esta acción interrumpirá cualquier sincronización en curso. Enter username and password for "%1" at %2. - + Introduce usuario y contraseña para "%1" en %2. @@ -1098,7 +1111,7 @@ Esto podría ser un problema con tu librería OpenSSL The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + La URL de la consulta no comienza con HTTPS a pesar de que la URL de inicio de sesión comenzó con HTTPS. El inicio de sesión no será posible porque esto podría ser un problema de seguridad. Por favor, póngase en contacto con su administrador. @@ -1116,7 +1129,7 @@ Esto podría ser un problema con tu librería OpenSSL There was an error accessing the "token" endpoint: <br><em>%1</em> - + Hubo un error accediendo al "token" endpoint: <br><em>%1</em> @@ -1133,7 +1146,7 @@ Esto podría ser un problema con tu librería OpenSSL The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + La URL de consulta no comienza con HTTPS a pesar de que la URL de inicio de sesión comenzó con HTTPS. El inicio de sesión no será posible porque esto podría ser un problema de seguridad. Por favor, póngase en contacto con su administrador. @@ -1144,32 +1157,32 @@ Esto podría ser un problema con tu librería OpenSSL No se ha podido abrir el navegador, por favor copie el enlace en su navegador. - + Waiting for authorization Esperando autorización - + Polling for authorization Pidiendo autorización - + Starting authorization Iniciando autorización - + Link copied to clipboard. Enlace copiado al portapapeles. - + Reopen Browser Reabrir el navegador - + Copy Link Copiar Link @@ -1337,6 +1350,16 @@ This means that the synchronization client might not upload local changes immedi Esto significa que el cliente de sincronización podría no subir inmediatamente los cambios de las carpetas locales, y en lugar de eso solo escaneará buscando cambios locales y los subirá ocasionalmente (cada dos horas por defecto). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Todos los archivos en tu carpeta local de sincronización «%1» serán borrados. +Esta eliminación será sincronizada con tu servidor, haciendo que esos archivos no estén disponibles a no ser que sean restaurados. +¿Estás seguro de que deseas sincronizarte con el servidor? +Si esto ha sido un accidente, y decides mantener tus archivos, serán re-sincronizados con el servidor. @@ -1398,40 +1421,25 @@ Si continua con la sincronización todos los archivos serán remplazados por su Mantener los archivos locales en caso de conflicto - - All files in the sync folder '%1' folder were deleted on the server. + + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Todos los archivos en la carpeta de sincronización «%1» han sido eliminados en el servidor. -Esta eliminación se sincronizará con tu carpeta local sincronizada, haciendo que esos archivos ya no estén disponibles a no ser que tengas derecho a restaurarlos. + Todos los archivos en la carpeta de sincronización "%1" han sido eliminados del servidor. +Esta eliminación se sincronizará con tu carpeta local, haciendo que esos archivos ya no estén disponibles a no ser que tengas derecho a restaurarlos. Si decides restaurar los archivos, volverán a sincronizarse con el servidor si tienes derecho a hacer esto. Si decides eliminar los archivos, ya no los tendrás disponibles, a no ser que seas el propietario. - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Todos los archivos en tu carpeta local de sincronización «%1» serán borrados. -Esta eliminación será sincronizada con tu servidor, haciendo que esos archivos no estén disponibles a no ser que sean restaurados. -¿Estás seguro de que deseas sincronizarte con el servidor? -Si esto ha sido un accidente, y decides mantener tus archivos, serán re-sincronizados con el servidor. - - - - All files in the sync folder "%1" folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - + Todos los archivos en la carpeta de sincronización "%1" serán eliminados. +Esta eliminación será sincronizada con tu servidor, haciendo que esos archivos no estén disponibles a no ser que sean restaurados. +¿Estás seguro de que deseas sincronizar esta acción con el servidor? +Si esto ha sido un accidente, y decides mantener tus archivos, serán re-sincronizados desde el servidor. @@ -1443,6 +1451,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Eliminar todos los archivos + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Todos los archivos en la carpeta de sincronización «%1» han sido eliminados en el servidor. +Esta eliminación se sincronizará con tu carpeta local sincronizada, haciendo que esos archivos ya no estén disponibles a no ser que tengas derecho a restaurarlos. +Si decides restaurar los archivos, volverán a sincronizarse con el servidor si tienes derecho a hacer esto. +Si decides eliminar los archivos, ya no los tendrás disponibles, a no ser que seas el propietario. + Keep files @@ -1492,7 +1511,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Se ha encontrado un registro de sincronización antiguo "%1", que no se ha podido eliminar. Por favor, asegúrese de que ninguna aplicación lo está utilizando en este momento. @@ -1680,12 +1699,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Buscando cambios en carpeta remota "%1" Checking for changes in local "%1" - + Buscando cambios en carpeta local "%1" @@ -1845,7 +1864,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + Introduce el nombre de la nueva carpeta que se creará debajo de "%1": @@ -2160,7 +2179,7 @@ Tenga en cuenta que esto sólo selecciona de qué grupo se tomarán las actualiz Reading from keychain failed with error: "%1" - + La lectura del keychain falló con el error "%1" @@ -2203,7 +2222,7 @@ Tenga en cuenta que esto sólo selecciona de qué grupo se tomarán las actualiz This entry is provided by the system at "%1" and cannot be modified in this view. - + Esta entrada la proporciona el sistema en "%1" y no se puede modificar en esta vista. @@ -2255,7 +2274,7 @@ Los elementos que se permite su borrado se eliminarán si impiden que un directo Cannot write changes to "%1". - + No se pudo escribir los cambios a "%1". @@ -2273,6 +2292,69 @@ Los elementos que se permite su borrado se eliminarán si impiden que un directo Añadir un nuevo patrón de archivos ignorados: + + OCC::InvalidFilenameDialog + + + Invalid filename + Nombre de archivo no válido + + + + The file could not be synced because it contains characters which are not allowed on this system. + El archivo no puede ser sincronizado porque contiene caracteres que no se permiten en el sistema. + + + + Error + Error + + + + Please enter a new name for the file: + Por favor, escribe un nuevo nombre para el archivo: + + + + New filename + Nuevo nombre de archivo + + + + Rename file + Renombrar archivo + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + El archivo %1 no puede ser sincronizado porque el nombre contiene caracteres que no se permiten en el sistema. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Los siguientes caracteres no se permiten en el sistema: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + No tienes permisos para renombrar este archivo. Por favor, dile al autor del archivo que lo renombre. + + + + Filename contains illegal characters: %1 + El nombre del archivo contiene caracteres ilegales: %1 + + + + Could not rename file. Please make sure you are connected to the server. + No se ha podido renombrar el archivo. Por favor, asegúrese de que está conectado al servidor. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + No se puede renombrar el archivo porque hay un archivo con el mismo nombre en el servidor. Por favor, elije otro nombre. + + OCC::LegalNotice @@ -2413,9 +2495,9 @@ Los registros se guardarán en: %1 <nobr>El archivo '%1'<br/>no se puede abrir para escritura.<br/><br/>¡El archivo de registro <b>no</b> se puede guardar!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> - + <nobr>El archivo "%1"<br/>no se puede abrir para escritura.<br/><br/>¡El archivo de registro <b>no se puede</b> guardar!</nobr> @@ -2456,6 +2538,11 @@ Los registros se guardarán en: %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Está disponible una nueva versión de %1 Client, pero el proceso de actualización falló.</p><p><b>%2</b> fue descargado. La versión instalada es %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Una nueva versión del Cliente %1 está disponible pero el proceso de actualización ha fallado.</p><p><b>%2</b> se ha descargado. La versión instalada es %3. Si confirmas el reinicio y la actualización, es posible que su ordenador se reinicie para completar la instalación. + Ask again later @@ -2625,16 +2712,21 @@ Los registros se guardarán en: %1 New %1 Update Ready La nueva %1 actualización está lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Se instalará una nueva actualización de %1. Durante esta actualización puede que se soliciten privilegios adicionales. + New %1 update ready - + La nueva %1 actualización está lista - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Se instalará una nueva actualización de %1. Durante esta actualización puede que se soliciten privilegios adicionales. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Está a punto de ser instalada una nueva actualización para %1 . Es posible que el actualizador solicite privilegios adicionales durante el proceso. Es posible que su ordenador se deba reiniciar para completar la instalación. @@ -2671,6 +2763,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. La nueva %1 está disponible. Por favor, haz clic <a href='%2'>aquí</a> para descargar la actualización. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + No se puede descargar la actualización. Por favor, abra <a href='%1'>%1</a> para descargar la actualización manualmente. + Could not download update. Please open %1 to download the update manually. @@ -2681,6 +2778,11 @@ for additional privileges during the process. Could not check for new updates. No se puede comprobar si hay actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + La nueva %1 está disponible. Por favor, abra<a href='%2'>%2</a> para descargar la actualización. + New %1 is available. Please open %2 to download the update. @@ -2769,12 +2871,12 @@ for additional privileges during the process. %1 folder "%2" is synced to local folder "%3" - + %1 carpeta "%2" está sincronizada con la carpeta local "%3" Sync the folder "%1" - + Sincronizar la carpeta "%1" @@ -2977,37 +3079,37 @@ No se recomienda usarla. Tiempo de espera agotado mientras se intentaba conectar a %1 en %2 - + Trying to connect to %1 at %2 … Intentando conectar a %1 desde %2 ... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La petición autenticada al servidor ha sido redirigida a '%1'. La dirección URL es errónea, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + La petición autenticada al servidor ha sido redirigida a "%1". La URL es errónea, el servidor está mal configurado. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso denegado por el servidor. Para verificar que tiene acceso, <a href="%1">haga clic aquí</a> para acceder al servicio desde el navegador. - + There was an invalid response to an authenticated WebDAV request Ha habido una respuesta no válida a una solicitud autenticada de WebDAV - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, configurándola para la sincronización.<br/><br/> - + Creating local sync folder %1 … Creando carpeta de sincronización local %1 ... @@ -3017,84 +3119,84 @@ No se recomienda usarla. bien - + OK OK - + failed. ha fallado. - + Could not create local folder %1 No se ha podido crear la carpeta local %1 - + No remote folder specified! ¡No se ha especificado ninguna carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 Creando carpeta en Nextcloud: %1 - + Remote folder %1 created successfully. Carpeta remota %1 creado correctamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectándola para sincronizacion. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta ha producido el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota ha fallado debido a que las credenciales proporcionadas son incorrectas!<br/>Por favor, vuelva atrás y compruebe sus credenciales</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota ha fallado, probablemente porque las credenciales proporcionadas son incorrectas.</font><br/>Por favor, vuelva atrás y compruebe sus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Creación %1 de carpeta remota ha fallado con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Se ha configarado una conexión de sincronización desde %1 al directorio remoto %2 - + Successfully connected to %1! ¡Conectado con éxito a %1! - + Connection to %1 could not be established. Please check again. No se ha podido establecer la conexión con %1. Por favor, compruébelo de nuevo. - + Folder rename failed Error al renombrar la carpeta @@ -3104,28 +3206,28 @@ No se recomienda usarla. No se puede eliminar y respaldar la carpeta porque la misma o un fichero en ella está abierto por otro programa. Por favor, cierre la carpeta o el fichero y reintente, o cancele la instalación. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. No se pudo eliminar y restaurar la carpeta porque ella o un archivo dentro de ella está abierto por otro programa. Por favor, cierre la carpeta o el archivo y pulsa en reintentar o cancelar la instalación. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Carpeta de sincronización local %1 creada con éxito</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Asistente de conexión %1 - Add %1 account Añadir %1 cuenta + + + %1 Connection Wizard + Asistente de conexión %1 + Skip folders configuration @@ -3164,24 +3266,6 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Mantente a salvo - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo listo! - - - - Open Local Folder - Abrir carpeta local - - - - Open %1 in Browser - Abrir %1 en el navegador - - OCC::PollJob @@ -3192,6 +3276,16 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + El archivo contiene espacios al final y no puede ser renombrado porque ya existe un archivo con el mismo nombre en el servidor. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + El archivo contiene espacios al final y no puede ser renombrado porque ya existe localmente un archivo con el mismo nombre. + Symbolic links are not supported in syncing. @@ -3207,16 +3301,16 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c File names ending with a period are not supported on this file system. Los nombres de archivo que terminan con un punto no son compatibles con este sistema de archivos. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Los nombres de archivo que contienen el carácter «%1» no son compatibles con este sistema de archivos. + + + File names containing the character "%1" are not supported on this file system. + Los nombres de archivo que contienen el carácter "%1" no son compatibles con este sistema de archivos. + File name contains at least one invalid character @@ -3343,9 +3437,9 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c El servidor contestó con un error al leer el directorio «%1» : %2 - + Server replied with an error while reading directory "%1" : %2 - + El servidor contestó con un error al leer el directorio "%1" : %2 @@ -3958,11 +4052,6 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Allow Editing Permitir edición - - - Allow editing - Permitir edición - Read only @@ -3983,6 +4072,16 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Password Protect Protección con contraseña + + + Allow editing + Permitir edición + + + + View only + Solo lectura + Allow upload and editing @@ -3998,16 +4097,21 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c File drop (upload only) Entrega de archivos (solo subida) - - - Note to recipient - Nota para el destinatario - Unshare Dejar de compartir + + + Link name + Nombre del enlace + + + + Note to recipient + Nota para el destinatario + Password protect @@ -4019,15 +4123,20 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Fijar fecha de caducidad - - Delete share link - Eliminar enlace compartido + + Delete link + Borrar enlace Add another link Añadir otro enlace + + + Delete share link + Eliminar enlace compartido + Confirm Link Share Deletion @@ -4077,9 +4186,9 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c No hay resultados para '%1' - + No results for "%1" - + Sin resultados para "%1" @@ -4181,12 +4290,6 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Compartir con %1 - Context menu share @@ -4213,6 +4316,12 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Share via %1 Compartir vía %1 + + + + Activity + Actividad + Copy private link to clipboard @@ -4284,6 +4393,12 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Delete Eliminar + + + Share with %1 + parameter is Nextcloud + Compartir con %1 + OCC::SslButton @@ -4429,6 +4544,11 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Cannot connect securely to <i>%1</i>: No puedo conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4603,6 +4723,11 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Placeholders are postfixed with file sizes using Utility::octetsToString() Solo %1 disponible, se necesita por lo menos %2 para comenzar + + + Aborted + Cancelado + @@ -4755,27 +4880,88 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Invalid characters, please rename "%1" Caracteres inválidos, por favor renombre "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Nombre de archivo contiene al menos un caracter no válido - - Aborted - Cancelado - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Poco espacio libre en disco: La descarga lo reducirá por debajo del %1, deberia abortar. - + There is insufficient space available on the server for some uploads. No hay suficiente espacio libre en el servidor para algunas subidas. + + OCC::SyncStatusSummary + + + + Offline + No conectado + + + + + + All synced! + ¡Todo sincronizado! + + + + Some files couldn't be synced! + ¡Algunos archivos no han podido ser sincronizados! + + + + See below for errors + Comprueba abajo los errores + + + + Syncing + Sincronizando + + + + Sync paused + Sincronización pausada + + + + Some files could not be synced! + + + + + See below for warnings + Comprueba abajo los avisos + + + + %1 of %2 · %3 left + %1 de %2 · quedan %3 + + + + %1 of %2 + %1 de %2 + + + + Syncing file %1 of %2 + Sincronizando archivo %1 de %2 + + OCC::Systray @@ -4851,6 +5037,29 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c <p>Esta versión ha sido suministrada por %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4908,24 +5117,108 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - La característica de archivos virtuales necesita un sistema de archivos NTFS, %1 está usando %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + No se han podido recuperar los estados predefinidos. Asegúrese de que está conectado al servidor. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - La descarga del archivo cifrado extremo a extremo falló + + Could not fetch user status. Make sure you are connected to the server. + No se ha podido obtener el estado del usuario. Asegúrese de que está conectado al servidor. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Parece que está intentando descargar un archivo virtual que está cifrado de extremo a extremo. Por el momento, no está soportada la descarga implícita de estos archivos. Para solucionar este problema, vaya a ajustes y marque la carpeta cifrada con "Hacer que esté siempre localmente disponible". + + User status feature is not supported. You will not be able to set your user status. + La función de estado de usuario no es compatible. No podrás establecer tu estado de usuario. + + + + Emojis feature is not supported. Some user status functionality may not work. + La función de emojis no es compatible. Es posible que algunas funciones de estado del usuario no funcionen. + + + + Could not set user status. Make sure you are connected to the server. + No se ha podido establecer el estado del usuario. Asegúrese de que está conectado al servidor. + + + + Could not clear user status message. Make sure you are connected to the server. + No se ha podido borrar el mensaje de estado del usuario. Asegúrese de que está conectado al servidor. + + + + + Don't clear + No borrar + + + + 30 minutes + 30 minutos + + + + + 1 hour + 1 hora + + + + 4 hours + 4 horas + + + + + Today + Hoy + + + + + This week + Esta semana + + + + Less than a minute + Hace menos de un minuto + + + + 1 minute + 1 minuto + + + + %1 minutes + %1 minutos + + + + %1 hours + %1 horas + + + + 1 day + 1 día + + + + %1 days + %1 días + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + La característica de archivos virtuales necesita un sistema de archivos NTFS, %1 está usando %2 @@ -5134,7 +5427,7 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Checking for changes in remote "%1" - + Buscando cambios en carpeta remota "%1" @@ -5144,7 +5437,7 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Checking for changes in local "%1" - + Buscando cambios en carpeta local "%1" @@ -5442,14 +5735,6 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Entra en tu %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Tu cuenta entera está sincronizada con la carpeta local - - QObject @@ -5542,6 +5827,38 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Fallo en la conexión a la base de datos. + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5556,29 +5873,39 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c - Current user status is online - El estado actual del usuario es en línea + Account connected + Cuenta conectada - Current user status is do not disturb - El estado actual del usuario es no molestar + Account not connected + Cuenta no conectada - Account connected - Cuenta conectada + Current user status is online + El estado actual del usuario es en línea - Account not connected - Cuenta no conectada + Current user status is do not disturb + El estado actual del usuario es no molestar Account actions Acciones de la cuenta + + + Remove Account + Eliminar Cuenta + + + + Set status + Establecer estado + @@ -5591,17 +5918,65 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Log in Iniciar sesión - - - Remove Account - Eliminar Cuenta - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + Estado en línea + + + + Online + En línea + + + + Away + Ausente + + + + Do not disturb + No molestar + + + + Invisible + Invisible + + + + Status message + Mensaje de estado + + + + What is your status? + ¿Cuál es su estado? + + + + Clear status message after + Borrar el mensaje de estado después de + + + + Clear status message + Borrar el mensaje de estado + + + + Set status message + Establecer un mensaje de estado + + Utility @@ -5663,12 +6038,12 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c ValidateChecksumHeader - + The checksum header is malformed. El encabezado del checksum tiene un formato incorrecto. - + The checksum header contained an unknown checksum type '%1' El encabezado del checksum contenía un tipo de comprobación desconocido: '%1' @@ -5678,19 +6053,19 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Al archivo descargado no le coincide el checksum, se volverá a bajar. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' El archivo descargado no coincide con la suma de comprobación (checksum), será reanudado. «%1» != «%2» - + The checksum header contained an unknown checksum type "%1" - + El encabezado del checksum contenía un tipo de comprobación desconocido: "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" - + El archivo descargado no coincide con la suma de comprobación (checksum), se reanudará. "%1" != "%2" @@ -5717,6 +6092,11 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Pause sync for all Pausar sincronización para todos + + + Set user status + Cambiar el estado del usuario + Add account @@ -5752,12 +6132,6 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Current user status is do not disturb El estado actual del usuario es no molestar - - - - Show more actions - Mostrar más acciones - Share %1 @@ -5818,6 +6192,22 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Open share dialog Abrir diálogo de compartir + + + Unified search results list + + + + + + Show more actions + Mostrar más acciones + + + + %1 - File activity + %1 - Actividad del archivo + main.cpp @@ -6117,6 +6507,24 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Inicia sesión en tu navegador Web (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo listo! + + + + Open Local Folder + Abrir carpeta local + + + + Open %1 in Browser + Abrir %1 en el navegador + + OCC::ShibbolethCredentials @@ -6169,6 +6577,14 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Inicio de sesión + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Tu cuenta entera está sincronizada con la carpeta local + + OCC::UserStatus @@ -6192,4 +6608,17 @@ Esta es un modo nuevo y experimental. Si decides usarlo, por favor, informa de c Conectado + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + La descarga del archivo cifrado extremo a extremo falló + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Parece que está intentando descargar un archivo virtual que está cifrado de extremo a extremo. Por el momento, no está soportada la descarga implícita de estos archivos. Para solucionar este problema, vaya a ajustes y marque la carpeta cifrada con "Hacer que esté siempre localmente disponible". + + \ No newline at end of file diff --git a/translations/client_es_AR.ts b/translations/client_es_AR.ts index 6efb17bd0798..4e4c44d3485a 100644 --- a/translations/client_es_AR.ts +++ b/translations/client_es_AR.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1324,6 +1337,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1377,22 +1397,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Mantener Archivos Locales como Conflicto - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1400,7 +1405,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1416,6 +1421,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2240,6 +2253,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2375,7 +2451,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/>no puede ser abierto para escritura.<br/><br/>¡El archivo de log <b>no</b> puede ser guardado!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2418,6 +2494,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2587,6 +2668,12 @@ Logs will be written to %1 New %1 Update Ready + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + + New %1 update ready @@ -2594,8 +2681,7 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. @@ -2633,6 +2719,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2643,6 +2734,11 @@ for additional privileges during the process. Could not check for new updates. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2938,37 +3034,37 @@ It is not advisable to use it. Tiempo excedido mientras se intentaba conectar a %1 desde %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> El directorio de sincronización local %1 ya existe, configurándolo para la sincronización.<br/><br/> - + Creating local sync folder %1 … @@ -2978,84 +3074,84 @@ It is not advisable to use it. aceptar - + OK - + failed. Error. - + Could not create local folder %1 No fue posible crear el directorio local %1 - + No remote folder specified! ¡No se ha especificado un directorio remoto! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. El directorio remoto %1 fue creado con éxito. - + The remote folder %1 already exists. Connecting it for syncing. El directorio remoto %1 ya existe. Estableciendo conexión para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación del directorio resultó en un error HTTP con código de error %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> <p><font color="red">Error al crear el directorio remoto porque las credenciales provistas son incorrectas.</font><br/>Por favor, volvé atrás y verificá tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Error al crear el directorio remoto, probablemente porque las credenciales provistas son incorrectas.</font><br/>Por favor, volvé atrás y verificá tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Se prtodujo un error <tt>%2</tt> al crear el directorio remoto %1. - + A sync connection from %1 to remote directory %2 was set up. Fue creada una conexión de sincronización desde %1 al directorio remoto %2. - + Successfully connected to %1! Conectado con éxito a %1! - + Connection to %1 could not be established. Please check again. No fue posible establecer la conexión a %1. Por favor, intentalo nuevamente. - + Folder rename failed Error Al Renombrar Directorio @@ -3065,28 +3161,28 @@ It is not advisable to use it. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Directorio local %1 creado</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3119,24 +3215,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo configurado! - - - - Open Local Folder - Abrir directorio local - - - - Open %1 in Browser - - - OCC::PollJob @@ -3147,6 +3225,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3164,12 +3252,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3298,7 +3386,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3913,11 +4001,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3938,6 +4021,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3953,16 +4046,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Soltar archivo (solo para carga) - - - Note to recipient - Nota al destinatario - Unshare + + + Link name + + + + + Note to recipient + Nota al destinatario + Password protect @@ -3974,8 +4072,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de caducidad - - Delete share link + + Delete link @@ -3983,6 +4081,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link Agregar otro enlace + + + Delete share link + + Confirm Link Share Deletion @@ -4032,7 +4135,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + No results for "%1" @@ -4136,12 +4239,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4168,6 +4265,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4239,6 +4342,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Eliminar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4382,6 +4491,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4556,6 +4670,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() + + + Aborted + + @@ -4709,26 +4828,87 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - File name contains at least one invalid character + + Synchronization will resume shortly. - - Aborted + + File name contains at least one invalid character - + Disk space is low: Downloads that would reduce free space below %1 were skipped. - + There is insufficient space available on the server for some uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4804,6 +4984,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4861,23 +5064,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5395,14 +5682,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Tu cuenta completa está sincronizada al directorio local - - QObject @@ -5495,6 +5774,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5509,22 +5820,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Cuenta conectada - Current user status is do not disturb + Account not connected - Account connected - Cuenta conectada + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5532,6 +5843,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5544,17 +5865,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5616,12 +5985,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5631,17 +6000,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5670,6 +6039,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5705,12 +6079,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5771,6 +6139,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6070,6 +6454,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo configurado! + + + + Open Local Folder + Abrir directorio local + + + + Open %1 in Browser + + + OCC::ShibbolethCredentials @@ -6122,6 +6524,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Tu cuenta completa está sincronizada al directorio local + + OCC::UserStatus @@ -6145,4 +6555,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_CL.ts b/translations/client_es_CL.ts index acdff425a7bf..40cb692728ee 100644 --- a/translations/client_es_CL.ts +++ b/translations/client_es_CL.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_CO.ts b/translations/client_es_CO.ts index f52e62dffeba..188a2260632e 100644 --- a/translations/client_es_CO.ts +++ b/translations/client_es_CO.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_CR.ts b/translations/client_es_CR.ts index 00f0718ece09..0f8f1fc0d1e2 100644 --- a/translations/client_es_CR.ts +++ b/translations/client_es_CR.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_DO.ts b/translations/client_es_DO.ts index ac89b0e07dbf..220d2cd5637b 100644 --- a/translations/client_es_DO.ts +++ b/translations/client_es_DO.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_EC.ts b/translations/client_es_EC.ts index 574e0829dc93..0db0f0049509 100644 --- a/translations/client_es_EC.ts +++ b/translations/client_es_EC.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link Agregar otro enlace + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_GT.ts b/translations/client_es_GT.ts index eaed8c23b245..099fe9dbd9c6 100644 --- a/translations/client_es_GT.ts +++ b/translations/client_es_GT.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_HN.ts b/translations/client_es_HN.ts index 2e388d1346e4..20073cf6a61f 100644 --- a/translations/client_es_HN.ts +++ b/translations/client_es_HN.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_MX.ts b/translations/client_es_MX.ts index 3e752b1f6213..99a8f43ac54f 100644 --- a/translations/client_es_MX.ts +++ b/translations/client_es_MX.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Soltar archivo (solo carga) - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establece la fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_es_SV.ts b/translations/client_es_SV.ts index f5f6b0827a15..56b6f4e198c1 100644 --- a/translations/client_es_SV.ts +++ b/translations/client_es_SV.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuar con la sincronización como normal causará que todos tus archivos sea Mantener los Archivos Locales como Conflictos - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>El archivo '%1'<br/> no se puede abrir para escritura. <br/><br/> ¡La salida de la bitácora <b>no</b>puede ser guardada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,13 @@ Logs will be written to %1 New %1 Update Ready Actualización %1 Nueva Lista + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar +mas privilegios durante el proceso. + New %1 update ready @@ -2599,10 +2687,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Una nueva actualización para %1 está a punto de ser instalada. El programa de actualización puede solicitar -mas privilegios durante el proceso. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2639,6 +2725,11 @@ mas privilegios durante el proceso. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2649,6 +2740,11 @@ mas privilegios durante el proceso. Could not check for new updates. No fue posible verificar nuevas actualizaciones. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Expiró el tiempo al tratar de conectarse a %1 en %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La solicitud autenticada al servidor fue redireccionada a '%1'. La liga está mal, el servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido por el servidor. Para verificar que tengas el acceso correcto, <a href="%1">haz click aquí</a> para acceder al servicio con tu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La carpeta de sincronización local %1 ya existe, preparandola para la sincronización. <br/><br/> - + Creating local sync folder %1 … @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. falló. - + Could not create local folder %1 No fue posible crear la carpeta local %1 - + No remote folder specified! ¡No se especificó la carpeta remota! - + Error: %1 Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. La carpeta remota %1 fue creada exitosamente. - + The remote folder %1 already exists. Connecting it for syncing. La carpeta remota %1 ya existe. Conectandola para sincronizar. - - + + The folder creation resulted in HTTP error code %1 La creación de la carpeta dio como resultado el código de error HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ¡La creación de la carpeta remota falló porque las credenciales proporcionadas están mal!<br/> Por favor regresa y verifica tus credenciales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creación de la carpeta remota falló probablemente porque las credenciales proporcionadas son incorrectas. </font><br/> Por favor regresa y verifica tus credenciales.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La creación de la carpeta remota %1 falló con el error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una conexión de sincronización de %1 al directorio remoto %2 fue establecida. - + Successfully connected to %1! ¡Conectado exitosamente a %1! - + Connection to %1 could not be established. Please check again. No se pudo establecer la conexión a %1. Por favor verifica de nuevo. - + Folder rename failed Falla al renombrar la carpeta @@ -3071,28 +3167,28 @@ It is not advisable to use it. No se puede eliminar la carpeta de respaldos porque la carpeta o un archivo en ella está en uso por otro programa. Por favor cierra la carpeta o archivo y haz click en reintentar o cancela la configuración. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>¡La carpeta de sincronización local %1 fue creada exitosamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistente de Conexión - Add %1 account + + + %1 Connection Wizard + %1 Asistente de Conexión + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ¡Todo está configurado! - - - - Open Local Folder - Abrir Carpeta Local - - - - Open %1 in Browser - Abrir %1 en el Navegador - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permitir edición - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Permitir edición + + + + View only + + Allow upload and editing @@ -3960,13 +4053,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Permitir carga - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3980,8 +4078,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss Establecer fecha de expiración - - Delete share link + + Delete link @@ -3989,6 +4087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss No se encontraron resultados para '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Borrar + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: No se puede conectar de forma segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Solo tiene %1 disponible, se necesita de al menos %2 para iniciar + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caracteres inválidos, por favor renombra "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character El nombre del archivo contiene al menos un caracter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Espacio en disco bajo: Las descargas que podrían reducir el espacio por debajo de %1 se omitieron. - + There is insufficient space available on the server for some uploads. No hay espacio disponible en el servidor para algunas cargas. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - La totalidad de tu cuenta está sincronizada a la carpeta local - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Acciones de la cuenta + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sesión - - - Remove Account - - Remove account Eliminar cuenta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ¡Todo está configurado! + + + + Open Local Folder + Abrir Carpeta Local + + + + Open %1 in Browser + Abrir %1 en el Navegador + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + La totalidad de tu cuenta está sincronizada a la carpeta local + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_et.ts b/translations/client_et.ts index a11288bdf805..a6633b2e9433 100644 --- a/translations/client_et.ts +++ b/translations/client_et.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1324,6 +1337,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1377,22 +1397,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1400,7 +1405,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1416,6 +1421,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2240,6 +2253,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2375,7 +2451,7 @@ Logs will be written to %1 <nobr>Faili '%1'<br/>ei saa kirjutamiseks avada.<br/><br/>Logi väljundit <b>ei saa</b> salvestada!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2418,6 +2494,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2587,6 +2668,12 @@ Logs will be written to %1 New %1 Update Ready Uus %1 uuendus on valmis + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + + New %1 update ready @@ -2594,8 +2681,7 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. @@ -2633,6 +2719,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2643,6 +2734,11 @@ for additional privileges during the process. Could not check for new updates. Uuenduste kontrollimine ebaõnnestus. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2938,37 +3034,37 @@ It is not advisable to use it. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Kohalik kataloog %1 on juba olemas. Valmistan selle ette sünkroniseerimiseks. - + Creating local sync folder %1 … @@ -2978,84 +3074,84 @@ It is not advisable to use it. ok - + OK - + failed. ebaõnnestus. - + Could not create local folder %1 Ei suuda tekitada kohalikku kataloogi %1 - + No remote folder specified! Ühtegi võrgukataloogi pole määratletud! - + Error: %1 Viga: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. Eemalolev kaust %1 on loodud. - + The remote folder %1 already exists. Connecting it for syncing. Serveris on kataloog %1 juba olemas. Ühendan selle sünkroniseerimiseks. - - + + The folder creation resulted in HTTP error code %1 Kausta tekitamine lõppes HTTP veakoodiga %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Kataloogi loomine serverisse ebaõnnestus, kuna kasutajatõendid on valed!<br/>Palun kontrolli oma kasutajatunnust ja parooli.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Serveris oleva kataloogi tekitamine ebaõnnestus tõenäoliselt valede kasutajatunnuste tõttu.</font><br/>Palun mine tagasi ning kontrolli kasutajatunnust ning parooli.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Kataloogi %1 tekitamine serverisse ebaõnnestus veaga <tt>%2</tt> - + A sync connection from %1 to remote directory %2 was set up. Loodi sünkroniseerimisühendus kataloogist %1 serveri kataloogi %2 - + Successfully connected to %1! Edukalt ühendatud %1! - + Connection to %1 could not be established. Please check again. Ühenduse loomine %1 ebaõnnestus. Palun kontrolli uuesti. - + Folder rename failed Kataloogi ümbernimetamine ebaõnnestus @@ -3065,28 +3161,28 @@ It is not advisable to use it. Ei suuda eemaldada ning varundada kataloogi kuna kataloog või selles asuv fail on avatud mõne teise programmi poolt. Palun sulge kataloog või fail ning proovi uuesti või katkesta paigaldus. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Kohalik kataloog %1 edukalt loodud!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 seadistamise juhendaja - Add %1 account + + + %1 Connection Wizard + %1 seadistamise juhendaja + Skip folders configuration @@ -3119,24 +3215,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Kõik on seadistatud! - - - - Open Local Folder - Ava Kohalik Kataloog - - - - Open %1 in Browser - Ava %1 veebilehitsejas - - OCC::PollJob @@ -3147,6 +3225,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3164,12 +3252,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3298,7 +3386,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3913,11 +4001,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Luba muutmine - Read only @@ -3938,6 +4021,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Luba muutmine + + + + View only + + Allow upload and editing @@ -3953,16 +4046,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Faili lohistamine (ainult üleslaadimine) - - - Note to recipient - Märge saajale - Unshare + + + Link name + + + + + Note to recipient + Märge saajale + Password protect @@ -3974,15 +4072,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Määra aegumise kuupäev - - Delete share link - Kustuta jagamise link + + Delete link + Add another link + + + Delete share link + Kustuta jagamise link + Confirm Link Share Deletion @@ -4032,7 +4135,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + No results for "%1" @@ -4136,12 +4239,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4168,6 +4265,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4239,6 +4342,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Kustuta + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4384,6 +4493,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4558,6 +4672,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() + + + Aborted + + @@ -4710,24 +4829,85 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Faili nimesonvähemalt üks keelatud märk - - Aborted + + Disk space is low: Downloads that would reduce free space below %1 were skipped. - - Disk space is low: Downloads that would reduce free space below %1 were skipped. + + There is insufficient space available on the server for some uploads. + + + OCC::SyncStatusSummary - - There is insufficient space available on the server for some uploads. + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 @@ -4806,6 +4986,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4863,23 +5066,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5397,14 +5684,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Kogu Su konto sünkroniseeriti kohalikku kataloogi - - QObject @@ -5497,6 +5776,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5511,22 +5822,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5534,6 +5845,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + + + + + Set status + + @@ -5546,17 +5867,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Logi sisse - - - Remove Account - - Remove account Eemalda konto + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5618,12 +5987,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5633,17 +6002,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5672,6 +6041,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5707,12 +6081,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5773,6 +6141,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6072,6 +6456,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + Kõik on seadistatud! + + + + Open Local Folder + Ava Kohalik Kataloog + + + + Open %1 in Browser + Ava %1 veebilehitsejas + + OCC::ShibbolethCredentials @@ -6124,6 +6526,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Kogu Su konto sünkroniseeriti kohalikku kataloogi + + OCC::UserStatus @@ -6147,4 +6557,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_eu.ts b/translations/client_eu.ts index ceb7217472a1..c24b19cd19fd 100644 --- a/translations/client_eu.ts +++ b/translations/client_eu.ts @@ -14,12 +14,6 @@ Open %1 locally Ireki %1 lokalean - - - - Show more actions - Erakutsi ekintza gehiago - Open share dialog @@ -30,6 +24,25 @@ Share %1 Partekatu %1 + + + + Show more actions + Erakutsi ekintza gehiago + + + + View activity + Ikusi jarduera + + + + ActivityList + + + Activity list + Jarduera zerrenda + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - Ezin izan da "%1" "%1"-ra mugitu + Could not move "%1" to "%2" + Ezin izan da "%1" "%2"-(e)ra mugitu @@ -1144,32 +1157,32 @@ Baliteke OpenSSL liburutegiekin arazoa egotea. Ezin izan da nabigatzailea ireki, kopiatu eta itsatsi esteka hau zure nabigatzailean. - + Waiting for authorization Baimenaren zain. - + Polling for authorization Baimena eskatzen - + Starting authorization Baimena lortzen - + Link copied to clipboard. Lotura arbelera kopiatua da - + Reopen Browser Berrireki nabigatzailea - + Copy Link Kopiatu esteka @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Honek esan nahi du sinkronizazio bezeroak agian ez duela berehalakoan kargatuko tokiko aldaketak eta haren ordez tokiko aldaketak bilatu eta tarteka kargatuko ditu (berez, bi orduero). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Zure tokiko '%1' sinkronizazio karpetako fitxategi guztiak ezabatu dira. Ezabaketa hauek zerbitzarian sinkronizatuko dira, beraz ezingo dituzu fitxategiok erabili leheneratu ezean. +Ziur zaude ekintza hauek zerbitzarian sinkronizatu nahi dituzula? +Ezabaketa nahigabea izan bada eta erabakitzen baduzu fitxategiok mantentzea, hauek zerbitzarian ber-sinkronizatuko dira. @@ -1399,27 +1421,7 @@ Nahi al duzu zure tokiko fitxategi berrienak gatazkako fitxategi gisa mantentzea Mantendu fitxategi lokalak gatazka gisa - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - '% 1' sinkronizazio-karpetaren fitxategi guztiak ezabatuko dira zerbitzaritik. -Ezabaketa horiek zure sinkronizazio-karpetan sinkronizatuko dira, eta horren ondorioz fitxategiak ezingo dituzu berriro erabili leheneratzeko eskubiderik ez baduzu. -Fitxategiak leheneratzea erabakitzen baduzu, zerbitzariarekin berriro sinkronizatuko dira horretarako eskubiderik baduzu. -Fitxategiak ezabatzea erabakitzen baduzu, ez dira erabilgarri egongo, jabea izan ezean. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Zure tokiko '%1' sinkronizazio karpetako fitxategi guztiak ezabatu dira. Ezabaketa hauek zerbitzarian sinkronizatuko dira, beraz ezingo dituzu fitxategiok erabili leheneratu ezean. -Ziur zaude ekintza hauek zerbitzarian sinkronizatu nahi dituzula? -Ezabaketa nahigabea izan bada eta erabakitzen baduzu fitxategiok mantentzea, hauek zerbitzarian ber-sinkronizatuko dira. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1430,7 +1432,7 @@ Fitxategiak leheneratzea erabakitzen baduzu, berriro sinkronizatuko dira zerbitz Fitxategiak ezabatzea erabakitzen baduzu, ezingo dituzu erabilgarri izan, jabea ez bazara behintzat. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1448,6 +1450,17 @@ Istripua izan bada eta zure fitxategiak mantentzea erabakitzen baduzu, zerbitzar Remove all files Ezabatu fitxategi guztiak + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + '% 1' sinkronizazio-karpetaren fitxategi guztiak ezabatuko dira zerbitzaritik. +Ezabaketa horiek zure sinkronizazio-karpetan sinkronizatuko dira, eta horren ondorioz fitxategiak ezingo dituzu berriro erabili leheneratzeko eskubiderik ez baduzu. +Fitxategiak leheneratzea erabakitzen baduzu, zerbitzariarekin berriro sinkronizatuko dira horretarako eskubiderik baduzu. +Fitxategiak ezabatzea erabakitzen baduzu, ez dira erabilgarri egongo, jabea izan ezean. + Keep files @@ -2278,6 +2291,69 @@ Ezabatu daitezkeen elementuak ezabatu egingo dira karpeta bat ezabatzea ekiditen Gehitu ez-ikusteko patroi berria: + + OCC::InvalidFilenameDialog + + + Invalid filename + Fitxategi-izen baliogabea + + + + The file could not be synced because it contains characters which are not allowed on this system. + Fitxategia ezin da sinkronizatu sisteman onartuta ez dauden karaktereak dituelako. + + + + Error + Errorea + + + + Please enter a new name for the file: + Mesedez, sartu izen berri bat fitxategiarentzat: + + + + New filename + Fitxategi-izen berria + + + + Rename file + Berrizendatu fitxategia + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + %1 fitxategia ezin izan da sinkronizatu izenak sisteman onartuta ez dauden karaktereak dituelako. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Hurrengo karaktereak ez daude sisteman onartuta: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Ez duzu baimenik fitxategi hau berrizendatzeko. Mesedez, eskatu fitxategiaren jabeari berrizendatzeko. + + + + Filename contains illegal characters: %1 + Fitxategiak karaktere ilegalak dauzka: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Ezin izan da fitxategia berrizendatu. Mesedez egiaztatu zerbitzarira konektatuta zaudela. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Ezin da fitxategia berrizendatu izen berdina duen fitxategi bat existitzen delako zerbitzarian dagoeneko. Mesedez, aukeratu beste izen bat. + + OCC::LegalNotice @@ -2417,7 +2493,7 @@ Erregistroak %1(e)an idatziko dira. <nobr>'%1' Fitxategia<br/> ezin da idazteko ireki.<br/><br/>Egunkariaren irteera <b>ezin</b> da gorde!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>"%1" fitxategia<br/> ezin da ireki idazteko.<br/><br/> Erregistroaren irteera <b>ezin da </b> gorde!</nobr> @@ -2460,6 +2536,11 @@ Erregistroak %1(e)an idatziko dira. <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p> %1 bezeroaren bertsio berri bat eskuragarri dago.</p><p><b>%2</b>deskargatu da. Instalatuta dagoen bertsioa %3 da.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>% 1 bezeroaren bertsio berria eskuragarri dago baina eguneratze prozesuak huts egin du.</p><p><b>%2</b> deskargatu da. Instalatutako bertsioa %3 da. Berrabiaraztea eta eguneratzea baieztatzen baduzu, baliteke ordenagailua berrabiaraztea instalazioa amaitzeko.</p> + Ask again later @@ -2629,6 +2710,13 @@ Erregistroak %1(e)an idatziko dira. New %1 Update Ready %1 eguneraketa berria prest dago + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + %1-etarako eguneraketa bat instalatzeko prest dago. Instalatzaileak +pribilegio gehigarriak eskatzen ahal dizu prozesuan. + New %1 update ready @@ -2636,10 +2724,8 @@ Erregistroak %1(e)an idatziko dira. - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - %1-etarako eguneraketa bat instalatzeko prest dago. Instalatzaileak -pribilegio gehigarriak eskatzen ahal dizu prozesuan. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + % 1-erako eguneraketa berri bat instalatzeko prest dago. Eguneratzaileak pribilegio gehigarriak eska ditzake prozesuan zehar. Baliteke ordenagailua berrabiaraztea instalazioa osatzeko. @@ -2676,6 +2762,11 @@ pribilegio gehigarriak eskatzen ahal dizu prozesuan. New %1 is available. Please click <a href='%2'>here</a> to download the update. %1 berria dago eskuragarri. Egin klik <a href='%2'>hemen</a> eguneraketa deskargatzeko. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Ezin da eguneraketa deskargatu. Mesedez, ireki <a href='%1'>%1</a> eguneraketa eskuz deskargatzeko. + Could not download update. Please open %1 to download the update manually. @@ -2686,6 +2777,11 @@ pribilegio gehigarriak eskatzen ahal dizu prozesuan. Could not check for new updates. Ezin da eguneraketarik bilatu. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + %1 berria dago eskuragarri. Mesedez, ireki<a href='%2'>%2</a> eguneraketa deskargatzeko. + New %1 is available. Please open %2 to download the update. @@ -2982,37 +3078,37 @@ Ez da gomendagarria erabiltzea. Denbora iraungi da %1era %2n konektatzen saiatzean. - + Trying to connect to %1 at %2 … %2 zerbitzarian dagoen %1 konektatzen... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Zerbitzariari egindako eskaera autentifikatua '%1'ra birbideratu da. URLa okerra da, zerbitzaria gaizki konfiguratuta dago. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. Zerbitzarira autentifikatutako eskaera "% 1" ra birbideratu da. URLa okerra da, zerbitzaria gaizki konfiguratuta dago. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Sarrera zerbitzariarengatik ukatuta. Sarerra egokia duzula egiaztatzeko, egin <a href="%1">klik hemen</a> zerbitzura zure arakatzailearekin sartzeko. - + There was an invalid response to an authenticated WebDAV request Baliogabeko erantzuna jaso du autentifikaturiko WebDAV eskaera batek - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Bertako %1 karpeta dagoeneko existitzen da, sinkronizaziorako prestatzen.<br/><br/> - + Creating local sync folder %1 … %1 sinkronizazio karpeta lokala sortzen... @@ -3022,84 +3118,84 @@ Ez da gomendagarria erabiltzea. ados - + OK OK - + failed. huts egin du. - + Could not create local folder %1 Ezin da %1 karpeta lokala sortu - + No remote folder specified! Ez da urruneko karpeta zehaztu! - + Error: %1 Errorea: %1 - + creating folder on Nextcloud: %1 Nextcloud-en karpeta sortzen: %1 - + Remote folder %1 created successfully. Urruneko %1 karpeta ongi sortu da. - + The remote folder %1 already exists. Connecting it for syncing. Urruneko %1 karpeta dagoeneko existintzen da. Bertara konetatuko da sinkronizatzeko. - - + + The folder creation resulted in HTTP error code %1 Karpeta sortzeak HTTP %1 errore kodea igorri du - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Huts egin du urrutiko karpeta sortzen emandako kredintzialak ez direlako zuzenak!<br/> Egin atzera eta egiaztatu zure kredentzialak.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Urruneko karpeten sortzeak huts egin du ziuraski emandako kredentzialak gaizki daudelako.</font><br/>Mesedez atzera joan eta egiaztatu zure kredentzialak.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Urruneko %1 karpetaren sortzeak huts egin du <tt>%2</tt> errorearekin. - + A sync connection from %1 to remote directory %2 was set up. Sinkronizazio konexio bat konfiguratu da %1 karpetatik urruneko %2 karpetara. - + Successfully connected to %1! %1-era ongi konektatu da! - + Connection to %1 could not be established. Please check again. %1 konexioa ezin da ezarri. Mesedez egiaztatu berriz. - + Folder rename failed Karpetaren berrizendatzeak huts egin du @@ -3109,28 +3205,28 @@ Ez da gomendagarria erabiltzea. Ezin da karpeta ezabatu eta kopia egin, karpeta edo barruko fitxategiren bat beste programa batean irekita dagoelako. Mesedez itxi karpeta edo fitxategia eta sakatu berrekin edo ezeztatu konfigurazioa. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Ezin da karpeta kendu eta babeskopiarik egin, karpeta edo barruko fitxategiren bat beste programa batean irekita dagoelako. Itxi karpeta edo fitxategia eta sakatu berriro saiatu edo bertan behera utzi konfigurazioa. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Bertako sinkronizazio %1 karpeta ongi sortu da!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Konexio Morroia - Add %1 account Gehitu %1 kontua + + + %1 Connection Wizard + %1 Konexio Morroia + Skip folders configuration @@ -3169,24 +3265,6 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Jarraitu era seguruan - - OCC::OwncloudWizardResultPage - - - Everything set up! - Dena konfiguratu da! - - - - Open Local Folder - Ireki karpeta lokala - - - - Open %1 in Browser - Ireki %1 Arakatzailean - - OCC::PollJob @@ -3197,6 +3275,16 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3212,16 +3300,16 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di File names ending with a period are not supported on this file system. Puntu batekin amaitzen diren fitxategi-izenak ez dira onartzen fitxategi-sistema honetan. - - - File names containing the character "%1" are not supported on this file system. - "%1" karakterea daukaten fitxategi-izenak ez dira onartzen fitxategi-sistema honetan. - File names containing the character '%1' are not supported on this file system. '%1' karakterea daukaten fitxategi-izenak ez dira onartzen fitxategi-sistema honetan. + + + File names containing the character "%1" are not supported on this file system. + "%1" karakterea daukaten fitxategi-izenak ez dira onartzen fitxategi-sistema honetan. + File name contains at least one invalid character @@ -3348,7 +3436,7 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Zerbitzariak errore batekin erantzun du irakurtzean '%1' : %2 direktorioa - + Server replied with an error while reading directory "%1" : %2 Zerbitzariak errore batekin erantzun du "% 1" direktorioa irakurtzean:% 2 @@ -3963,11 +4051,6 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Allow Editing Editatzea baimendu - - - Allow editing - Baimendu editatzea - Read only @@ -3988,6 +4071,16 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Password Protect Pasahitzarekin babestu + + + Allow editing + Baimendu editatzea + + + + View only + Ikusi soilik + Allow upload and editing @@ -4003,16 +4096,21 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di File drop (upload only) Fitxategia jaregin (kargatzeko soilik) - - - Note to recipient - Oharra hartzailearentzat - Unshare Ez partekatu + + + Link name + Estekaren izena + + + + Note to recipient + Oharra hartzailearentzat + Password protect @@ -4024,15 +4122,20 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Ezarri iraungitze-data - - Delete share link - Ezabatu partekatze esteka + + Delete link + Ezabatu esteka Add another link Gehitu beste esteka bat + + + Delete share link + Ezabatu partekatze esteka + Confirm Link Share Deletion @@ -4082,7 +4185,7 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Ez dago emaitzarik '%1'(r)entzako - + No results for "%1" Ez dago "% 1" (r)entzako emaitzarik @@ -4186,12 +4289,6 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - %1(r)ekin partekatu - Context menu share @@ -4218,6 +4315,12 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Share via %1 Partekatu %1 bidez + + + + Activity + Jarduera + Copy private link to clipboard @@ -4289,6 +4392,12 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Delete Ezabatu + + + Share with %1 + parameter is Nextcloud + %1(r)ekin partekatu + OCC::SslButton @@ -4434,6 +4543,11 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Cannot connect securely to <i>%1</i>: Ezin da segurtasunarekin <i>%1</i>(e)ra konektatu: + + + Additional errors: + + with Certificate %1 @@ -4608,6 +4722,11 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Placeholders are postfixed with file sizes using Utility::octetsToString() %1 bakarrik dago eskuragarri, gutxienez %2 behar da hasteko. + + + Aborted + Bertan behera utzia + @@ -4760,27 +4879,88 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Invalid characters, please rename "%1" Baliogabeko karaktereak, aldatu "%1" izena + + + Synchronization will resume shortly. + Sinkronizazioak laster jarraituko du. + File name contains at least one invalid character Fitxategi izenak behintzat baliogabeko karaktere bat du - - Aborted - Bertan behera utzia - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Toki gutxi dago diskoan: toki librea %1 azpitik gutxituko zuten deskargak saltatu egin dira. - + There is insufficient space available on the server for some uploads. Ez dago nahiko toki erabilgarririk zerbitzarian hainbat kargatarako. + + OCC::SyncStatusSummary + + + + Offline + Lineaz kanpo + + + + + + All synced! + Dena sinkronizatuta! + + + + Some files couldn't be synced! + Fitxategi batzuk ezin izan dira sinkronizatu! + + + + See below for errors + Ikusi azpian erroreentzako + + + + Syncing + Sinkronizatzen + + + + Sync paused + Sinkronizazioa pausatua + + + + Some files could not be synced! + Fitxategi batzuk ezin izan dira sinkronizatu! + + + + See below for warnings + Ikusi azpian oharrentzako + + + + %1 of %2 · %3 left + %2tik %1 · %3 falta dira + + + + %1 of %2 + %2tik %1 + + + + Syncing file %1 of %2 + %2tik %1 fitxategia sinkronizatzen + + OCC::Systray @@ -4856,6 +5036,29 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di <p>Argitalpen hau %1(e)k eman du</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4913,24 +5116,108 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Fitxategi birtualen sistemak NTFS fitxategi sistema bat behar du, %1-ek darabilena %2 da. + + Could not fetch predefined statuses. Make sure you are connected to the server. + Ezin izan dira aurrez definitutako egoerak eskuratu. Ziurtatu zerbitzarira konektatuta zaudela. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Deskarga edo muturretik muturrerako zifratzeak huts egin du. + + Could not fetch user status. Make sure you are connected to the server. + Ezin izan da erabiltzaile egoera eskuratu. Ziurtatu zerbitzarira konektatuta zaudela. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Badirudi muturretik muturrera zifratuta dagoen fitxategi birtuala deskargatzen saiatzen ari zarela. Une honetan ez da fitxategi horiek deskargatzea inplizituki onartzen. Arazo hau konpontzeko, joan ezarpenetara eta markatu enkriptatutako karpeta "Jarri beti erabilgarri lokalean". + + User status feature is not supported. You will not be able to set your user status. + Erabiltzailearen egoera ezaugarria ez da onartzen. Ezin izango duzu zure erabiltzaile egoera ezarri. + + + + Emojis feature is not supported. Some user status functionality may not work. + Emotikonoak ezaugarria ez da onartzen. Baliteke zenbait erabiltzaileren egoera funtzionalitateak ez funtzionatzea. + + + + Could not set user status. Make sure you are connected to the server. + Ezin izan da erabiltzaile egoera ezarri. Ziurtatu zerbitzarira konektatuta zaudela. + + + + Could not clear user status message. Make sure you are connected to the server. + Ezin izan da garbitu erabiltzailearen egoera mezua. Ziurtatu zerbitzarira konektatuta zaudela. + + + + + Don't clear + Ez garbitu + + + + 30 minutes + 30 minutu + + + + + 1 hour + Ordu 1 + + + + 4 hours + 4 ordu + + + + + Today + Gaur + + + + + This week + Aste honetan + + + + Less than a minute + Minutu bat baino gutxiago + + + + 1 minute + Minutu 1 + + + + %1 minutes + %1 minutu + + + + %1 hours + %1 ordu + + + + 1 day + Egun 1 + + + + %1 days + %1 egun + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Fitxategi birtualen sistemak NTFS fitxategi sistema bat behar du, %1-ek darabilena %2 da. @@ -5447,14 +5734,6 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Hasi saioa %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Zure kontu osoa karpeta lokalera sinkronizaturik dago - - QObject @@ -5547,6 +5826,38 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Datu-basera konektatzeak huts egin du + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5561,29 +5872,39 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di - Current user status is online - Erabiltzailea linean dago + Account connected + Kontua konektatuta - Current user status is do not disturb - Erabiltzailea 'ez molestatu' egoeran dago + Account not connected + Kontua ez dago konektatuta - Account connected - Kontua konektatuta + Current user status is online + Erabiltzailea linean dago - Account not connected - Kontua ez dago konektatuta + Current user status is do not disturb + Erabiltzailea 'ez molestatu' egoeran dago Account actions Kontuaren ekintzak + + + Remove Account + Kendu kontua + + + + Set status + Ezarri egoera + @@ -5596,17 +5917,65 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Log in Hasi saioa - - - Remove Account - Kendu kontua - Remove account Kendu kontua + + UserStatusSelector + + + Online status + Lineako egoera + + + + Online + Linean + + + + Away + Kanpoan + + + + Do not disturb + Ez molestatu + + + + Invisible + Ikusezina + + + + Status message + Egoera mezua + + + + What is your status? + Zein da zure egoera? + + + + Clear status message after + Garbitu egoera mezua ondoren + + + + Clear status message + Garbitu egoera mezua ondoren + + + + Set status message + Ezarri egoera-mezua + + Utility @@ -5668,12 +6037,12 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di ValidateChecksumHeader - + The checksum header is malformed. Kontroleko baturaren goiburua gaizki osatu da. - + The checksum header contained an unknown checksum type '%1' Kontroleko baturaren goiburuak '%1' motako kontroleko batura ezezagun bat dauka @@ -5683,17 +6052,17 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Deskargatu den fitxategia ez dator bat kontroleko baturarekin, berrekin egingo da. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Deskargatu den fitxategia ez dator bat kontroleko baturarekin, berrekin egingo da. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" Kontroleko baturaren goiburuak "%1" motako kontroleko batura ezezagun bat dauka - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" Deskargatu den fitxategia ez dator bat kontroleko baturarekin, berrekin egingo da. "%1" != "%2" @@ -5722,6 +6091,11 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Pause sync for all Pausatu sinkronizazioa guztientzat + + + Set user status + Ezarri erabiltzaile-egoera + Add account @@ -5757,12 +6131,6 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Current user status is do not disturb Erabiltzailea 'ez molestatu' egoeran dago - - - - Show more actions - Erakutsi ekintza gehiago - Share %1 @@ -5823,6 +6191,22 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Open share dialog Ireki partekatzeko elkarrizketa-koadroa + + + Unified search results list + + + + + + Show more actions + Erakutsi ekintza gehiago + + + + %1 - File activity + %1 - Fitxategiaren jarduera + main.cpp @@ -6122,6 +6506,24 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Sartu zure nabigatzailean (2. bertsioko Login Bidea) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Dena konfiguratu da! + + + + Open Local Folder + Ireki karpeta lokala + + + + Open %1 in Browser + Ireki %1 Arakatzailean + + OCC::ShibbolethCredentials @@ -6174,6 +6576,14 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Hasi saioa + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Zure kontu osoa karpeta lokalera sinkronizaturik dago + + OCC::UserStatus @@ -6197,4 +6607,17 @@ Modu hau berria eta experimentala da. Erabiltzea erabakitzen baduzu, agertzen di Linean + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Deskarga edo muturretik muturrerako zifratzeak huts egin du. + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Badirudi muturretik muturrera zifratuta dagoen fitxategi birtuala deskargatzen saiatzen ari zarela. Une honetan ez da fitxategi horiek deskargatzea inplizituki onartzen. Arazo hau konpontzeko, joan ezarpenetara eta markatu enkriptatutako karpeta "Jarri beti erabilgarri lokalean". + + \ No newline at end of file diff --git a/translations/client_fa.ts b/translations/client_fa.ts index 77265e7be035..c07c89e8cb6e 100644 --- a/translations/client_fa.ts +++ b/translations/client_fa.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1381,22 +1401,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an پرونده های محلی را به عنوان ناسازگار نگه دارید - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1404,7 +1409,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1420,6 +1425,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2244,6 +2257,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2379,7 +2455,7 @@ Logs will be written to %1 <nobr>پرونده '1%' <br/> را نمی توان برای نوشتن باز کرد. <br/><br/>خروجی log <b>نمی تواند</b> ذخیره شود!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2422,6 +2498,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2591,6 +2672,12 @@ Logs will be written to %1 New %1 Update Ready به روز رسانی جدید 1% آماده است + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + یک به روز رسانی جدید برای 1% در حال نصب است. به روز رسان ممکن است امتیازات اضافی در طول پردازش درخواست کند. + New %1 update ready @@ -2598,9 +2685,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - یک به روز رسانی جدید برای 1% در حال نصب است. به روز رسان ممکن است امتیازات اضافی در طول پردازش درخواست کند. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2637,6 +2723,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2647,6 +2738,11 @@ for additional privileges during the process. Could not check for new updates. نمی توان به روز رسانی های جدید را بررسی کرد. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2942,37 +3038,37 @@ It is not advisable to use it. هنگام تلاش برای اتصال به 1% در 2% زمان به پایان رسید. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. درخواست تایید شده به سرور '1%' هدایت شد. آدرس بد است، سرور اشتباه پیکربندی شده است. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. دسترسی توسط سرور ممنوع شد. برای تأیید اینکه شما دسترسی مناسب دارید، <a href="%1">اینجا را کلیک کنید </a> تا با مرورگر خود به سرویس دسترسی پیدا کنید. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> پوشه همگام سازی محلی %1 در حال حاضر موجود است، تنظیم آن برای همگام سازی. <br/><br/> - + Creating local sync folder %1 … @@ -2982,84 +3078,84 @@ It is not advisable to use it. خوب - + OK - + failed. ناموفق. - + Could not create local folder %1 نمی تواند پوشه محلی ایجاد کند %1 - + No remote folder specified! هیچ پوشه از راه دوری مشخص نشده است! - + Error: %1 خطا: %1 - + creating folder on Nextcloud: %1 ایجاد پوشه در نکس کلود: %1 - + Remote folder %1 created successfully. پوشه از راه دور %1 با موفقیت ایجاد شده است. - + The remote folder %1 already exists. Connecting it for syncing. در حال حاضر پوشه از راه دور %1 موجود است. برای همگام سازی به آن متصل شوید. - - + + The folder creation resulted in HTTP error code %1 ایجاد پوشه به خطای HTTP کد 1% منجر شد - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> ایجاد پوشه از راه دور ناموفق بود به علت اینکه اعتبارهای ارائه شده اشتباه هستند!<br/>لطفا اعتبارهای خودتان را بررسی کنید.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red"> ایجاد پوشه از راه دور ناموفق بود، شاید به علت اعتبارهایی که ارئه شده اند، اشتباه هستند.</font><br/> لطفا باز گردید و اعتبار خود را بررسی کنید.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. ایجاد پوشه از راه دور %1 ناموفق بود با خطا <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. یک اتصال همگام سازی از %1 تا %2 پوشه از راه دور راه اندازی شد. - + Successfully connected to %1! با موفقیت به %1 اتصال یافت! - + Connection to %1 could not be established. Please check again. اتصال به %1 نمی تواند مقرر باشد. لطفا دوباره بررسی کنید. - + Folder rename failed تغییر نام پوشه ناموفق بود @@ -3069,12 +3165,12 @@ It is not advisable to use it. نمی توانید پوشه را حذف کنید یا پشتیبان بگیرید زیرا پوشه یا یک پرونده در آن در برنامه دیگری باز است. لطفا پوشه یا پرونده را ببندید و مجددا تلاش کنید یا تنظیم را لغو کنید. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b> پوشه همگام سازی محلی %1 با موفقیت ساخته شده است!</b></font> @@ -3082,13 +3178,13 @@ It is not advisable to use it. OCC::OwncloudWizard - - %1 Connection Wizard + + Add %1 account - - Add %1 account + + %1 Connection Wizard @@ -3123,24 +3219,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - همه چیز تنظیم شده است! - - - - Open Local Folder - باز کردن پوشه محلی - - - - Open %1 in Browser - بازکردن %1 در مرورگر - - OCC::PollJob @@ -3151,6 +3229,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3168,12 +3256,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3302,7 +3390,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3917,11 +4005,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing اجازه ویرایش - - - Allow editing - اجازه‌ی ویرایش - Read only @@ -3942,6 +4025,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect محافظت کلمه عبور + + + Allow editing + اجازه‌ی ویرایش + + + + View only + + Allow upload and editing @@ -3957,16 +4050,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) انداختن فایل (فقط آپلود) - - - Note to recipient - توجه داشته باشید به گیرنده - Unshare لغو اشتراک + + + Link name + + + + + Note to recipient + توجه داشته باشید به گیرنده + Password protect @@ -3978,15 +4076,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss تنظیم تاریخ انقضا - - Delete share link - پیوند اشتراک را حذف کنید + + Delete link + Add another link افزودن آدرس دیگر + + + Delete share link + پیوند اشتراک را حذف کنید + Confirm Link Share Deletion @@ -4036,7 +4139,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss هیچ نتیجه ای برای '1%' وجود ندارد - + No results for "%1" @@ -4140,12 +4243,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4172,6 +4269,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4243,6 +4346,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete حذف + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4387,6 +4496,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: عدم امکان اتصال امن به <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4561,6 +4675,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() تنها 1% موجود است، حداقل 2% برای شروع مورد نیاز است + + + Aborted + + @@ -4713,27 +4832,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" کاراکتر نامعتبر، لطفا "%1" را تغییر نام دهید + + + Synchronization will resume shortly. + + File name contains at least one invalid character نام فایل دارای حداقل یک کاراکتر نامعتبر است - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. فضای دیسک کم است: دانلودهایی که فضای آزاد را به کمتر از 1% کاهش می دهند رد می شوند. - + There is insufficient space available on the server for some uploads. برای بعضی از بارگذاری ها در سرور فضای کافی موجود نیست. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4809,6 +4989,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4866,23 +5069,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5400,14 +5687,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - کل حساب شما با پوشه محلی همگام سازی شده است - - QObject @@ -5500,6 +5779,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5514,22 +5825,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5537,6 +5848,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions اقدامات حساب + + + Remove Account + + + + + Set status + + @@ -5549,17 +5870,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in ورود - - - Remove Account - - Remove account حذف حساب کاربری + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5621,12 +5990,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5636,17 +6005,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5675,6 +6044,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5710,12 +6084,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5776,6 +6144,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6075,6 +6459,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + همه چیز تنظیم شده است! + + + + Open Local Folder + باز کردن پوشه محلی + + + + Open %1 in Browser + بازکردن %1 در مرورگر + + OCC::ShibbolethCredentials @@ -6127,6 +6529,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + کل حساب شما با پوشه محلی همگام سازی شده است + + OCC::UserStatus @@ -6150,4 +6560,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_fi.ts b/translations/client_fi.ts index 78a39c542d97..8ccbe0f02923 100644 --- a/translations/client_fi.ts +++ b/translations/client_fi.ts @@ -12,22 +12,35 @@ Open %1 locally - + Avaa %1 paikallisesti + + + + Open share dialog + Avaa jakoikkuna + + + + Share %1 + Jaa %1 Show more actions - + Näytä enemmän toimintoja - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -755,7 +768,7 @@ Tämä toiminto peruu kaikki tämänhetkiset synkronoinnit. Certificate & Key (pkcs12): - + Varmenne & avain (pkcs12): @@ -1143,32 +1156,32 @@ OpenSSL-kirjastosi kanssa saattaa olla ongelma. Selainta ei voitu avata. Kopioi linkki selaimeesi. - + Waiting for authorization Odotetaan valtuutusta - + Polling for authorization Kysellään valtuutusta - + Starting authorization Aloitetaan valtuutus - + Link copied to clipboard. Linkki kopioitu leikepöydälle. - + Reopen Browser Avaa selain uudelleen - + Copy Link Kopioi linkki @@ -1333,6 +1346,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1386,22 +1406,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Pidä paikalliset tiedostot konfliktina - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1409,7 +1414,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1425,6 +1430,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Poista kaikki tiedostot + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -1647,7 +1660,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Synchronizing with local folder - + Synkronoidaan paikallisen kansion kanssa @@ -1987,7 +2000,7 @@ If this was an accident and you decide to keep your files, they will be re-synce &Channel - + &Kanava @@ -2063,7 +2076,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Change update channel? - + Vaihdetaanko päivityskanavaa? @@ -2075,7 +2088,7 @@ Note that this selects only what pool upgrades are taken from, and that there ar Change update channel - + Vaihda päivityskanava @@ -2253,6 +2266,69 @@ Kohteet, joissa poisto on sallittu, poistetaan, jos ne estävät kansion poistam Lisää uusi ohituskaava: + + OCC::InvalidFilenameDialog + + + Invalid filename + Virheellinen tiedostonimi + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + Virhe + + + + Please enter a new name for the file: + Anna uusi nimi tiedostolle: + + + + New filename + Uusi tiedostonimi + + + + Rename file + Nimeä tiedosto uudelleen + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + Tiedostoa ei voitu nimetä uudelleen. Varmista, että olet yhteydessä palvelimeen. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2388,7 +2464,7 @@ Logs will be written to %1 <nobr>Tiedostoa '%1'<br/>ei voida avata kirjoittamista varten.<br/><br/>Lokitulostusta<b>ei</b>pystytä tallentamaan!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2431,6 +2507,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2600,16 +2681,21 @@ Logs will be written to %1 New %1 Update Ready Uusi %1-päivitys valmiina + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Uusi %1-päivitys on valmiina asennettavaksi. Päivitysohjelma saattaa pyytää lisäoikeuksia päivityksen aikana. + New %1 update ready - + Uusi %1-päivitys valmiina - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Uusi %1-päivitys on valmiina asennettavaksi. Päivitysohjelma saattaa pyytää lisäoikeuksia päivityksen aikana. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2646,6 +2732,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Uusi %1 on saatavilla. Klikkaa <a href='%2'>tästä</a> ladataksesi päivityksen. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2656,6 +2747,11 @@ for additional privileges during the process. Could not check for new updates. Päivitysten tarkistus epäonnistui. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2749,7 +2845,7 @@ for additional privileges during the process. Sync the folder "%1" - + Synkronoi kansio "%1" @@ -2952,37 +3048,37 @@ Sen käyttäminen ei ole suositeltavaa. Aikakatkaisu yrittäessä yhteyttä kohteeseen %1 osoitteessa %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Palvelin esti käyttämisen. Vahvista käyttöoikeutesi palvelimeen <a href="%1">napsauttamalla tästä</a> ja kirjaudu palveluun selaimella. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Paikallinen kansio %1 on jo olemassa, asetetaan se synkronoitavaksi.<br/><br/> - + Creating local sync folder %1 … Luodaan paikallinen synkronointikansio %1 … @@ -2992,84 +3088,84 @@ Sen käyttäminen ei ole suositeltavaa. ok - + OK OK - + failed. epäonnistui. - + Could not create local folder %1 Paikalliskansion %1 luonti epäonnistui - + No remote folder specified! Etäkansiota ei määritelty! - + Error: %1 Virhe: %1 - + creating folder on Nextcloud: %1 luodaan kansio Nextcloudiin: %1 - + Remote folder %1 created successfully. Etäkansio %1 luotiin onnistuneesti. - + The remote folder %1 already exists. Connecting it for syncing. Etäkansio %1 on jo olemassa. Otetaan siihen yhteyttä tiedostojen täsmäystä varten. - - + + The folder creation resulted in HTTP error code %1 Kansion luonti aiheutti HTTP-virhekoodin %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Etäkansion luominen epäonnistui koska antamasi tunnus/salasana ei täsmää!<br/>Ole hyvä ja palaa tarkistamaan tunnus/salasana</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Pilvipalvelun etäkansion luominen ei onnistunut , koska tunnistautumistietosi ovat todennäköisesti väärin.</font><br/>Palaa takaisin ja tarkista käyttäjätunnus ja salasana.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Etäkansion %1 luonti epäonnistui, virhe <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Täsmäysyhteys kansiosta %1 etäkansioon %2 on asetettu. - + Successfully connected to %1! Yhteys kohteeseen %1 muodostettiin onnistuneesti! - + Connection to %1 could not be established. Please check again. Yhteyttä osoitteeseen %1 ei voitu muodostaa. Ole hyvä ja tarkista uudelleen. - + Folder rename failed Kansion nimen muuttaminen epäonnistui @@ -3079,28 +3175,28 @@ Sen käyttäminen ei ole suositeltavaa. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Paikallinen synkronointikansio %1 luotu onnistuneesti!</b></font> OCC::OwncloudWizard + + + Add %1 account + Lisää %1-tili + %1 Connection Wizard %1-yhteysavustaja - - - Add %1 account - - Skip folders configuration @@ -3133,24 +3229,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pysy turvassa - - OCC::OwncloudWizardResultPage - - - Everything set up! - Kaikki valmiina! - - - - Open Local Folder - Avaa paikallinen kansio - - - - Open %1 in Browser - Avaa %1 selaimessa - - OCC::PollJob @@ -3161,6 +3239,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3178,18 +3266,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. File name contains at least one invalid character - + Tiedoston nimi sisältää ainakin yhden virheellisen merkin @@ -3209,7 +3297,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss File/Folder is ignored because it's hidden. - + Tiedosto/kansio ohitetaan, koska se on piilotettu. @@ -3279,12 +3367,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Not allowed because you don't have permission to add subfolders to that folder - + Ei sallittu, koska oikeutesi eivät riitä alikansioiden lisäämiseen kyseiseen kansioon Not allowed because you don't have permission to add files in that folder - + Ei sallittu, koska käyttöoikeutesi eivät riitä tiedostojen lisäämiseen kyseiseen kansioon @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error while reading the database - + Virhe tietokantaa luettaessa @@ -3312,7 +3400,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3327,12 +3415,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Virhe metatietoja päivittäessä: %1 File is currently in use - + Tiedosto on tällä hetkellä käytössä @@ -3407,12 +3495,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Virhe päivittäessä metatietoja: %1 The file %1 is currently in use - + Tiedosto %1 on tällä hetkellä käytössä @@ -3443,7 +3531,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Could not create folder %1 - + Ei voitu luoda kansiota %1 @@ -3453,12 +3541,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Virhe metatietoja päivittäessä: %1 The file %1 is currently in use - + Tiedosto %1 on tällä hetkellä käytössä @@ -3499,12 +3587,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Virhe metatietoja päivittäessä: %1 The file %1 is currently in use - + Tiedosto %1 on tällä hetkellä käytössä @@ -3515,7 +3603,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to rename file - + Tiedoston uudelleennimeäminen epäonnistui @@ -3536,7 +3624,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Wrong HTTP code returned by server. Expected 204, but received "%1 %2". - + Palvelin palautti väärän HTTP-koodin. Odotettiin 204, vastaanotettiin "%1 %2". @@ -3554,12 +3642,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error writing metadata to the database: %1 - + Virhe kirjoittaessa metatietoja tietokantaan: %1 The file %1 is currently in use - + Tiedosto %1 on tällä hetkellä käytössä @@ -3577,12 +3665,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Virhe metatietoja päivittäessä: %1 The file %1 is currently in use - + Tiedosto %1 on tällä hetkellä käytössä @@ -3641,12 +3729,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Virhe metatietoja päivittäessä: %1 The file %1 is currently in use - + Tiedosto %1 on tällä hetkellä käytössä @@ -3905,7 +3993,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Set password - + Aseta salasana @@ -3920,18 +4008,13 @@ This is a new, experimental mode. If you decide to use it, please report any iss Expires - + Vanhenee Allow Editing Salli muokkaus - - - Allow editing - Salli muokkaus - Read only @@ -3952,6 +4035,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Salasanasuojaus + + + Allow editing + Salli muokkaus + + + + View only + + Allow upload and editing @@ -3967,16 +4060,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Tiedostojen pudotus (vain lähetys) - - - Note to recipient - Huomio vastaanottajalle - Unshare Poista jako + + + Link name + Linkin nimi + + + + Note to recipient + Huomio vastaanottajalle + Password protect @@ -3988,15 +4086,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Aseta vanhenemispäivä - - Delete share link - Poista jakolinkki + + Delete link + Poista linkki Add another link Lisää toinen linkki + + + Delete share link + Poista jakolinkki + Confirm Link Share Deletion @@ -4046,14 +4149,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ei tuloksia haulla '%1' - + No results for "%1" - + Ei tuloksia haulla "%1" Password for share required - + Salasana vaaditaan jakoon @@ -4081,7 +4184,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Can edit - + Voi muokata @@ -4091,12 +4194,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password: - + Salasana: Expires: - + Vanhenee: @@ -4111,7 +4214,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Set expiration date - + Aseta vanhenemispäivä @@ -4136,7 +4239,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password protect - + Suojaa salasanalla @@ -4150,12 +4253,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4164,7 +4261,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Select new location … - + Valitse uusi sijainti… @@ -4182,6 +4279,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Jaa käyttäen %1 + + + + Activity + + Copy private link to clipboard @@ -4200,7 +4303,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Resharing this folder is not allowed - + Tämän kansion uudelleenjakaminen ei ole sallittu @@ -4253,6 +4356,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Poista + + + Share with %1 + parameter is Nextcloud + Jaa %1 kanssa + OCC::SslButton @@ -4398,6 +4507,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Yhteyttä kohteeseen <i>%1</i> ei voi muodostaa turvallisesti: + + + Additional errors: + + with Certificate %1 @@ -4554,7 +4668,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Could not update file: %1 - + Tiedostoa ei voitu päivittää: %1 @@ -4572,6 +4686,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Vain %1 on käytettävissä, käynnistymiseen tarvitaan %2 + + + Aborted + Peruutettu + @@ -4725,26 +4844,87 @@ This is a new, experimental mode. If you decide to use it, please report any iss Virheellisiä merkkejä, anna uusi nimi kohteelle "%1" - - File name contains at least one invalid character - Tiedoston nimi sisältää ainakin yhden virheellisen merkin + + Synchronization will resume shortly. + - - Aborted - Peruutettu + + File name contains at least one invalid character + Tiedoston nimi sisältää ainakin yhden virheellisen merkin - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Levytila on vähissä. Lataukset, jotka pienentäisivät tilaa alle %1 ohitettiin. - + There is insufficient space available on the server for some uploads. Palvelimella on liian vähän tilaa joillekin latauksille. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4820,6 +5000,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4877,23 +5080,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + 30 minuuttia + + + + + 1 hour + 1 tunti + + + + 4 hours + 4 tuntia + + + + + Today + Tänään + + + + + This week + Tämä viikko + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5411,14 +5698,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Koko tilisi on synkronoitu paikalliseen kansioon - - QObject @@ -5508,6 +5787,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to connect database. + Tietokantaan yhdistäminen epäonnistui. + + + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results @@ -5525,29 +5836,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - Nykyinen käyttäjän tila on Online + Account connected + Tili yhdistetty - Current user status is do not disturb - Nykyinen käyttäjän tila on 'Älä häiritse' + Account not connected + Tiliä ei yhdistetty - Account connected - Tili yhdistetty + Current user status is online + Nykyinen käyttäjän tila on Online - Account not connected - Tiliä ei yhdistetty + Current user status is do not disturb + Nykyinen käyttäjän tila on 'Älä häiritse' Account actions Tilin toiminnot + + + Remove Account + Poista tili + + + + Set status + Aseta tilatieto + @@ -5560,17 +5881,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Kirjaudu sisään - - - Remove Account - Poista tili - Remove account Poista tili + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + Poissa + + + + Do not disturb + Älä häiritse + + + + Invisible + Näkymätön + + + + Status message + Tilaviesti + + + + What is your status? + Mikä on tilatietosi? + + + + Clear status message after + + + + + Clear status message + Tyhjennä tilaviesti + + + + Set status message + Aseta tilaviesti + + Utility @@ -5632,12 +6001,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Tarkistussumman otsake on muodostettu väärin. - + The checksum header contained an unknown checksum type '%1' Tarkistussumman otsake sisälsi tuntemattoman tarkistussummatyypin '%1' @@ -5647,17 +6016,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ladattu tiedosto ei vastaa tarkistussummaa, jatketaan. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Ladattu tiedosto ei vastaa tarkistussummaa, jatketaan. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5686,6 +6055,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Tauota synkronointi + + + Set user status + Aseta käyttäjän tila + Add account @@ -5721,12 +6095,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb Nykyinen käyttäjän tila on 'Älä häiritse' - - - - Show more actions - Näytä lisää toimintoja - Share %1 @@ -5787,6 +6155,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Avaa jakoikkuna + + + Unified search results list + + + + + + Show more actions + Näytä lisää toimintoja + + + + %1 - File activity + + main.cpp @@ -6086,6 +6470,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Kirjaudu selaimessa (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Kaikki valmiina! + + + + Open Local Folder + Avaa paikallinen kansio + + + + Open %1 in Browser + Avaa %1 selaimessa + + OCC::ShibbolethCredentials @@ -6138,6 +6540,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Kirjaudu sisään + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Koko tilisi on synkronoitu paikalliseen kansioon + + OCC::UserStatus @@ -6161,4 +6571,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Online + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_fr.ts b/translations/client_fr.ts index 0ab74e45b39e..0d2b7536e0b7 100644 --- a/translations/client_fr.ts +++ b/translations/client_fr.ts @@ -12,22 +12,35 @@ Open %1 locally - + Ouvrir %1 localement + + + + Open share dialog + Ouvrir la fenêtre de partage + + + + Share %1 + Partager %1 Show more actions - + Afficher les autres actions - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Vérification des modifications dans "%1" @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + Impossible de déplacer "%1" vers "%2" @@ -147,17 +160,17 @@ Error removing "%1": %2 - + Erreur lors de la suppression de "%1" : %2 Error removing '%1': %2 - Erreur lors de la suppression de '%1': %2 + Erreur lors de la suppression de '%1' : %2 Could not remove folder "%1" - + Impossible de supprimer le dossier "%1" @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Il semble que la fonctionnalité de fichiers virtuels soit activée sur ce dossier. Pour le moment, il n'est pas possible de télécharger implicitement des fichiers virtuels qui sont chiffrés de bout en bout. Pour bénéficier d'une expérience optimale avec les fichiers virtuels et le chiffrement de bout en bout, assurez-vous que le dossier chiffré soit paramétré avec l'option "Rendre toujours disponible localement". @@ -403,7 +416,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Il semble que la fonctionnalité de fichiers virtuels soit activée sur ce dossier. Pour le moment, il n'est pas possible de télécharger implicitement des fichiers virtuels qui sont chiffrés de bout en bout. Pour bénéficier d'une expérience optimale avec les fichiers virtuels et le chiffrement de bout en bout, assurez-vous que le dossier chiffré soit paramétré avec l'option "Rendre toujours disponible localement". @@ -840,7 +853,7 @@ Vous prenez vos propres risques. Enter username and password for "%1" at %2. - + Saisir le nom d'utilisateur et le mot de passe pour "%1" sur %2. @@ -1096,7 +1109,7 @@ Cela peut être un problème avec vos bibliothèques OpenSSL. The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + L'URL du sondage ne commence pas par HTTPS alors que l'URL de connexion commence par HTTPS. La connexion ne sera pas possible car cela pourrait être un problème de sécurité. Veuillez contacter votre administrateur. @@ -1131,7 +1144,7 @@ Cela peut être un problème avec vos bibliothèques OpenSSL. The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + L'URL renvoyée par le serveur ne commence pas par HTTPS alors que l'URL de connexion commence par HTTPS. La connexion ne sera pas possible car cela pourrait être un problème de sécurité. Veuillez contacter votre administrateur. @@ -1142,32 +1155,32 @@ Cela peut être un problème avec vos bibliothèques OpenSSL. Impossible d'ouvrir le navigateur, veuillez copier le lien dans votre navigateur Web. - + Waiting for authorization En attente de l'autorisation - + Polling for authorization En attente de l'autorisation - + Starting authorization Démarrage de l'autorisation - + Link copied to clipboard. Lien copié dans le presse-papier - + Reopen Browser Rouvrir le navigateur - + Copy Link Copier le lien @@ -1337,6 +1350,15 @@ Cela signifie que le client de synchronisation peut ne pas télécharger immédi %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Tous les fichiers contenus dans le dossier synchronisé '%1' ont été supprimés. Ces suppressions seront synchronisées avec votre serveur, rendant ces fichiers inaccessibles sauf s'ils sont restaurés. +Êtes-vous sûr de vouloir synchroniser ces actions avec le serveur ? +S'il s'agissait d'un accident et que vous choisissiez de conserver vos fichiers, ils seront synchronisés à nouveau depuis le serveur. @@ -1398,40 +1420,25 @@ Continuer la synchronisation comme d'habitude fera en sorte que tous les fi Conserver les fichiers locaux comme Conflits - - All files in the sync folder '%1' folder were deleted on the server. + + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Tous les fichiers du dossier de synchronisation '%1' ont été supprimés sur le serveur. + Tous les fichiers du dossier de synchronisation "%1" ont été supprimés sur le serveur. Ces suppressions seront synchronisées avec votre dossier local, ce qui rendra les fichiers non disponibles à moins que vous ayez les droits de les restaurer. Si vous décidez de garder ces fichiers, ils seront resynchronisés avec le serveur si vous avez les droits pour le faire. Si vous décidez de supprimer ces fichiers, ils ne vous seront plus accessibles à moins que vous en soyez le propriétaire. - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. + + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - Tous les fichiers contenus dans le dossier synchronisé '%1' ont été supprimés. Ces suppressions seront synchronisées avec votre serveur, rendant ces fichiers inaccessibles sauf s'ils sont restaurés. + Tous les fichiers contenus dans le dossier synchronisé "%1" ont été supprimés. Ces suppressions seront synchronisées avec votre serveur, rendant ces fichiers inaccessibles sauf s'ils sont restaurés ultérieurement. Êtes-vous sûr de vouloir synchroniser ces actions avec le serveur ? S'il s'agissait d'un accident et que vous choisissiez de conserver vos fichiers, ils seront synchronisés à nouveau depuis le serveur. - - - All files in the sync folder "%1" folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - Remove All Files? @@ -1442,6 +1449,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Supprimer tous les fichiers + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Tous les fichiers du dossier de synchronisation '%1' ont été supprimés sur le serveur. +Ces suppressions seront synchronisées avec votre dossier local, ce qui rendra les fichiers non disponibles à moins que vous ayez les droits de les restaurer. +Si vous décidez de garder ces fichiers, ils seront resynchronisés avec le serveur si vous avez les droits pour le faire. +Si vous décidez de supprimer ces fichiers, ils ne vous seront plus accessibles à moins que vous en soyez le propriétaire. + Keep files @@ -1491,7 +1509,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Un ancien fichier journal "%1" a été trouvé, mais ne peut être supprimé. Veuillez vous assurer qu’aucune application ne l'utilise en ce moment. @@ -1679,12 +1697,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Vérification des modifications dans "%1" distant Checking for changes in local "%1" - + Vérification des modifications dans "%1" local @@ -1844,7 +1862,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + Entrez le nom du nouveau dossier à créer dans "%1" : @@ -1904,7 +1922,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + Vous ne pouvez pas définir la racine d'une partition Windows pour votre dossier local. Veuillez choisir un (sous)dossier de la partition. @@ -2202,7 +2220,7 @@ Notez que cela ne permet seulement de sélectionner où sont récupérées les m This entry is provided by the system at "%1" and cannot be modified in this view. - + Cette entrée est fournie par le système dans "%1" et ne peut être modifiée dans cette vue. @@ -2254,7 +2272,7 @@ Les éléments ayant l'option "Autoriser la suppression" pourront Cannot write changes to "%1". - + Impossible d'écrire les modifications sur "%1". @@ -2272,6 +2290,69 @@ Les éléments ayant l'option "Autoriser la suppression" pourront Ajouter un nouveau motif d'exclusion : + + OCC::InvalidFilenameDialog + + + Invalid filename + Nom de fichier invalide + + + + The file could not be synced because it contains characters which are not allowed on this system. + Le fichier n'a pas pu être synchronisé parce qu'il contiens des caractères invalides ou non-supportés par votre système. + + + + Error + Erreur + + + + Please enter a new name for the file: + Veuillez saisir le nouveau nom du fichier : + + + + New filename + Nouveau nom de fichier + + + + Rename file + Renommer le fichier + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Les caractères suivants ne sont pas supportés par votre système : * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Vous n'avez pas la permission de renommer ce fichier. Veuillez demander à son auteur de le renommer. + + + + Filename contains illegal characters: %1 + Le nom du fichier contiens des caractères illégaux: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Impossible de renommer le fichier. Veuillez vous certifier que vous êtes bien connecté au serveur. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2326,7 +2407,8 @@ Si activés, les logs seront écrits dans %1 This setting persists across client restarts. Note that using any logging command line options will override this setting. - + Ce paramètre persiste lors des redémarrages du client. +Notez que l'utilisation de toute option de ligne de commande de journalisation remplacera ce paramètre. @@ -2411,7 +2493,7 @@ Les journaux seront écrits dans %1. <nobr>Le fichier '%1'<br/>ne peut être ouvert en écriture.<br/><br/>Le fichier de journalisation <b>ne peut pas</b> être enregistré !</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2454,6 +2536,11 @@ Les journaux seront écrits dans %1. <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Une nouvelle version %1 est disponible pour le client mais la mise à jour a échoué.</p><p><b>%2</b> a été téléchargée. La version installée est %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2593,7 +2680,7 @@ Les journaux seront écrits dans %1. Empty JSON from OAuth2 redirect - + Vider le JSON de la redirection OAuth2 @@ -2623,11 +2710,6 @@ Les journaux seront écrits dans %1. New %1 Update Ready Une nouvelle mise à jour de %1 est disponible - - - New %1 update ready - - A new update for %1 is about to be installed. The updater may ask @@ -2635,6 +2717,16 @@ for additional privileges during the process. Une mise à jour de %1 est sur le point d'être installée. L'assistant de mise à jour peut vous demandez des autorisations supplémentaires afin de procéder à l'installation. + + + New %1 update ready + Une nouvelle mise à jour de %1 est disponible + + + + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Une nouvelle mise à jour pour %1 est sur le point d'être installée. Le dispositif de mise à jour peut demander des autorisations supplémentaires au cours du processus. Votre ordinateur peut redémarrer pour terminer l'installation. + Downloading version %1. Please wait … @@ -2670,6 +2762,11 @@ L'assistant de mise à jour peut vous demandez des autorisations supplémen New %1 is available. Please click <a href='%2'>here</a> to download the update. Le nouveau %1 est disponible. Veuillez cliquer <a href='%2'> ici </a> pour télécharger la mise à jour. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2680,6 +2777,11 @@ L'assistant de mise à jour peut vous demandez des autorisations supplémen Could not check for new updates. Impossible de vérifier la présence de nouvelles mises à jour. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2768,12 +2870,12 @@ L'assistant de mise à jour peut vous demandez des autorisations supplémen %1 folder "%2" is synced to local folder "%3" - + Le dossier %1 "%2" est synchronisé avec le dossier local "%3". Sync the folder "%1" - + Synchroniser le dossier "%1" @@ -2976,37 +3078,37 @@ Il est déconseillé de l'utiliser. Délai d'attente dépassé lors de la connexion à %1 sur %2. - + Trying to connect to %1 at %2 … Tentative de connexion à %1 sur %2 ... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La requête d'authentification vers le serveur a été redirigée vers '%1'. L'URL est erronée, le serveur est mal configuré. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Accès impossibe. Afin de vérifier l'accès au serveur, <a href="%1">cliquez ici</a> et connectez-vous au service avec votre navigateur web. - + There was an invalid response to an authenticated WebDAV request Il y a eu une réponse invalide à une demande WebDAV authentifiée - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Le dossier de synchronisation local %1 existe déjà, configuration de la synchronisation.<br/><br/> - + Creating local sync folder %1 … Création du dossier local de synchronisation %1 ... @@ -3016,84 +3118,84 @@ Il est déconseillé de l'utiliser. ok - + OK OK - + failed. échoué. - + Could not create local folder %1 Impossible de créer le dossier local %1 - + No remote folder specified! Aucun dossier distant spécifié ! - + Error: %1 Erreur : %1 - + creating folder on Nextcloud: %1 Création du dossier sur Nextcloud : %1 - + Remote folder %1 created successfully. Le dossier distant %1 a été créé avec succès. - + The remote folder %1 already exists. Connecting it for syncing. Le dossier distant %1 existe déjà. Connexion. - - + + The folder creation resulted in HTTP error code %1 La création du dossier a généré le code d'erreur HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> La création du dossier distant a échoué car les identifiants de connexion sont erronés !<br/>Veuillez revenir en arrière et vérifier ces derniers.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La création du dossier distant a échoué, probablement parce que les informations d'identification fournies sont fausses.</font><br/>Veuillez revenir en arrière et les vérifier.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. La création du dossier distant "%1" a échouée avec l'erreur <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Une synchronisation entre le dossier local %1 et le dossier distant %2 a été configurée. - + Successfully connected to %1! Connecté avec succès à %1 ! - + Connection to %1 could not be established. Please check again. La connexion à %1 n'a pu être établie. Veuillez réessayer. - + Folder rename failed Echec du renommage du dossier @@ -3103,28 +3205,28 @@ Il est déconseillé de l'utiliser. Impossible de supprimer et de sauvegarder le dossier parce que ce dossier ou un de ses fichiers est ouvert dans un autre programme. Veuillez fermer le dossier ou le fichier et ré-essayer, ou annuler l'installation. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Dossier de synchronisation local %1 créé avec succès !</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Assistant de Connexion %1 - Add %1 account Ajout du compte %1 + + + %1 Connection Wizard + Assistant de Connexion %1 + Skip folders configuration @@ -3157,24 +3259,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Restez en sécurité - - OCC::OwncloudWizardResultPage - - - Everything set up! - Tout est configuré ! - - - - Open Local Folder - Ouvrir le dossier local - - - - Open %1 in Browser - Ouvrir %1 dans le navigateur web - - OCC::PollJob @@ -3185,6 +3269,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3200,16 +3294,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. Les noms de fichier se terminant par un point ne sont pas pris en charge sur votre système. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Les noms de fichier contenant le caractère '%1' ne sont pas pris en charge sur votre système. + + + File names containing the character "%1" are not supported on this file system. + Les noms de fichiers contenant le caractère "%1" ne sont pas pris en charge par ce système de fichiers. + File name contains at least one invalid character @@ -3238,7 +3332,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Stat failed. - + Stat échoué. @@ -3288,37 +3382,37 @@ This is a new, experimental mode. If you decide to use it, please report any iss Conflict when uploading a folder. It's going to get cleared! - + Conflit lors de l'envoi d'un dossier. Il va être supprimé ! Conflict when uploading a file. It's going to get removed! - + Conflit lors de l'envoi d'un fichier. Il va être supprimé ! Ignored because of the "choose what to sync" blacklist - + Ignoré en raison de la liste noire "Sélectionner le contenu à synchroniser". Not allowed because you don't have permission to add subfolders to that folder - + Non autorisé car vous n'avez pas la permission d'ajouter des sous-dossiers dans ce dossier Not allowed because you don't have permission to add files in that folder - + Non autorisé car vous n'avez pas la permission d'ajouter des fichiers dans ce dossier Not allowed to upload this file because it is read-only on the server, restoring - + Non autorisé à envoyer ce fichier car il est en lecture seule sur le serveur. Restauration Moved to invalid target, restoring - + Déplacé vers une cible invalide, restauration @@ -3336,7 +3430,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3351,12 +3445,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Erreur lors de la mise à jour des métadonnées : %1 File is currently in use - + Le fichier est actuellement en cours d'utilisation @@ -3369,7 +3463,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss File %1 cannot be downloaded because encryption information is missing. - + Le fichier %1 ne peut pas être téléchargé car les informations de chiffrement sont manquantes. @@ -3381,7 +3475,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss File %1 cannot be downloaded because of a local file name clash! - + Le fichier %1 ne peut pas être téléchargé en raison d'un conflit sur le nom de fichier local ! @@ -3416,7 +3510,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss The downloaded file is empty, but the server said it should have been %1. - + Le fichier téléchargé est vide bien que le serveur indique que sa taille devrait être de %1. @@ -3431,12 +3525,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Erreur lors de la mise à jour des métadonnées : %1 The file %1 is currently in use - + Le fichier %1 est en cours d'utilisation @@ -3477,12 +3571,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Erreur lors de la mise à jour des métadonnées : %1 The file %1 is currently in use - + Le fichier %1 est en cours d'utilisation @@ -3523,12 +3617,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Erreur lors de la mise à jour des métadonnées : %1 The file %1 is currently in use - + Le fichier %1 est en cours d'utilisation @@ -3539,7 +3633,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to rename file - + Échec lors du changement de nom du fichier @@ -3583,7 +3677,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss The file %1 is currently in use - + Le fichier %1 est en cours d'utilisation @@ -3601,12 +3695,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Erreur lors de la mise à jour des métadonnées : %1 The file %1 is currently in use - + Le fichier %1 est en cours d'utilisation @@ -3665,12 +3759,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Erreur lors de la mise à jour des métadonnées : %1 The file %1 is currently in use - + Le fichier %1 est en cours d'utilisation @@ -3886,7 +3980,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss The file cannot be shared because it does not have sharing permission. - + Le fichier ne peut pas être partagé car il ne dispose pas des permissions de partage. @@ -3929,7 +4023,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Set password - + Définir le mot de passe @@ -3951,11 +4045,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Autoriser les modifications - - - Allow editing - Autoriser la modification - Read only @@ -3976,6 +4065,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Protéger par mot de passe + + + Allow editing + Autoriser la modification + + + + View only + Voir uniquement + Allow upload and editing @@ -3991,16 +4090,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Dépôt de fichier (envoi uniquement) - - - Note to recipient - Note au destinataire - Unshare Ne plus partager + + + Link name + Nom du lien + + + + Note to recipient + Note au destinataire + Password protect @@ -4012,15 +4116,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Définir une date d'expiration - - Delete share link - Supprimer le lien de partage + + Delete link + Supprimer le lien Add another link Ajouter un autre lien + + + Delete share link + Supprimer le lien de partage + Confirm Link Share Deletion @@ -4071,9 +4180,9 @@ This is a new, experimental mode. If you decide to use it, please report any iss Aucun résultat pour '%1' - + No results for "%1" - + Aucun résultat pour "%1" @@ -4175,12 +4284,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Partager avec %1 - Context menu share @@ -4207,6 +4310,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Partager via %1 + + + + Activity + + Copy private link to clipboard @@ -4278,6 +4387,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Supprimer + + + Share with %1 + parameter is Nextcloud + Partager avec %1 + OCC::SslButton @@ -4423,6 +4538,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Impossible de se connecter de manière sécurisée à <i>%1</i> : + + + Additional errors: + + with Certificate %1 @@ -4597,6 +4717,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Seulement %1 disponibles, il faut au moins %2 pour démarrer + + + Aborted + Annulé + @@ -4749,27 +4874,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caractères non valides. Veuillez renommer "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Le nom de fichier contient au moins un caractère non valable - - Aborted - Annulé - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. L'espace disque est faible : les téléchargements qui amèneraient à réduire l'espace libre en dessous de %1 ont été ignorés. - + There is insufficient space available on the server for some uploads. Il n'y a pas suffisamment d’espace disponible sur le serveur pour certains téléversements. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4845,6 +5031,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cette version est fournie par %1. + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4902,25 +5111,109 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - La fonctionnalité système de fichiers virtuels requiert un système de fichiers de type NTFS alors que %1 utilise %2. + + Could not fetch predefined statuses. Make sure you are connected to the server. + - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + Emojis feature is not supported. Some user status functionality may not work. + La fonction Emojis n'est pas prise en charge. Certaines fonctionnalités du statut de l'utilisateur peuvent ne pas fonctionner. + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + Impossible d'effacer le message de statut de l'utilisateur. Assurez-vous que vous êtes connecté au serveur. + + + + + Don't clear + Ne pas effacer + + + + 30 minutes + 30 minutes + + + + + 1 hour + 1 heure + + + + 4 hours + 4 heures + + + + + Today + Aujourd'hui + + + + + This week + Cette semaine + + + + Less than a minute + Il y a moins d'une minute + + + + 1 minute + 1 minute + + + + %1 minutes + %1 minutes + + + + %1 hours + %1 heures + + + + 1 day + 1 jour + + + + %1 days + %1 jours + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + La fonctionnalité système de fichiers virtuels requiert un système de fichiers de type NTFS alors que %1 utilise %2. + OCC::WebEnginePage @@ -5128,7 +5421,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in remote "%1" - + Vérification des modifications dans "%1" distant @@ -5138,7 +5431,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in local "%1" - + Vérification des modifications dans "%1" local @@ -5436,14 +5729,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Se connecter sur votre %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Votre compte est intégralement synchronisé avec le dossier local - - QObject @@ -5533,6 +5818,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to connect database. + Impossible de connecter la base de données. + + + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results @@ -5550,29 +5867,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - Le statut actuel de l'utilisateur est en ligne + Account connected + Compte connecté - Current user status is do not disturb - Le statut actuel de l'utilisateur est ne pas déranger + Account not connected + Compte non connecté - Account connected - Compte connecté + Current user status is online + Le statut actuel de l'utilisateur est en ligne - Account not connected - Compte non connecté + Current user status is do not disturb + Le statut actuel de l'utilisateur est ne pas déranger Account actions Actions du compte + + + Remove Account + Supprimer le compte + + + + Set status + Définir le statut + @@ -5585,17 +5912,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Se connecter - - - Remove Account - Supprimer le compte - Remove account Supprimer le compte + + UserStatusSelector + + + Online status + Statut en ligne + + + + Online + En ligne + + + + Away + Absent(e) + + + + Do not disturb + Ne pas déranger + + + + Invisible + Invisible + + + + Status message + Message de statut + + + + What is your status? + Quel est votre statut ? + + + + Clear status message after + Effacer le message de statut après + + + + Clear status message + Effacer le message de statut + + + + Set status message + Définir le message de statut + + Utility @@ -5657,12 +6032,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. L'en-tête de la somme de contrôle est mal formé. - + The checksum header contained an unknown checksum type '%1' L'en-tête de la somme de contrôle contenait un type de somme de contrôle inconnu '% 1' @@ -5672,17 +6047,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Le fichier téléchargé ne correspond pas à la somme de contrôle, il va être téléchargé à nouveau. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Le fichier téléchargé ne correspond pas à la somme de contrôle, il va être téléchargé à nouveau. '%1' <> '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5711,6 +6086,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Suspendre toutes les synchronisations + + + Set user status + Définir le statut de l'utilisateur + Add account @@ -5746,12 +6126,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb Le statut actuel de l'utilisateur est ne pas déranger - - - - Show more actions - Afficher plus d'actions - Share %1 @@ -5812,6 +6186,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Ouvrir la fenêtre de partage + + + Unified search results list + + + + + + Show more actions + Afficher plus d'actions + + + + %1 - File activity + + main.cpp @@ -6111,6 +6501,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Connectez-vous avec votre navigateur web (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Tout est configuré ! + + + + Open Local Folder + Ouvrir le dossier local + + + + Open %1 in Browser + Ouvrir %1 dans le navigateur web + + OCC::ShibbolethCredentials @@ -6163,6 +6571,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Se connecter + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Votre compte est intégralement synchronisé avec le dossier local + + OCC::UserStatus @@ -6186,4 +6602,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss En ligne + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Le téléchargement d'un fichier chiffré de bout en bout a échoué + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_gl.ts b/translations/client_gl.ts index cadb004fecf1..8c0b59bcd783 100644 --- a/translations/client_gl.ts +++ b/translations/client_gl.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1144,32 +1157,32 @@ Isto pode ser un problema coas súas bibliotecas OpenSSL. Non foi posíbel abrir o navegador, copie a ligazón ao seu navegador. - + Waiting for authorization Agardando autorización - + Polling for authorization Solicitando autorización - + Starting authorization Iniciando autorización - + Link copied to clipboard. A ligazón foi copiada no portapapeis. - + Reopen Browser Volver abrir o navegador - + Copy Link Copiar a ligazón @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Isto significa que o cliente de sincronización podería non enviar os cambios inmediatamente, e no canto diso, só examinará buscando cambios locais e enviaraos ocasionalmente (por omisión cada dúas horas) %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Todos os ficheiros do cartafol de sincronización local «%1» foron eliminados. Estas eliminacións sincronizaranse co servidor, facendo que estes ficheiros non estean dispoñíbeis a non ser que se restauren. +Confirma que quere sincronizar estas accións co servidor? +Se fose un accidente e decide manter os seus ficheiros, volverán ser sincronizados dende o servidor. @@ -1398,27 +1420,7 @@ Continuando a sincronización como normal fará que todos os seus ficheiros sexa Mantener os ficheiros locais en caso de conflito - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Todos os ficheiros no cartafol de sincronización «%1» foron eliminados no servidor. -Estas eliminacións sincronizarse co seu cartafol de sincronización local, facendo que estes ficheiros non estean dispoñíbeis a menos que teña dereitos para restauralos. -Se decide restaurar os ficheiros, resincronizaranse co servidor se ten dereitos para facelo. -Se decide eliminar os ficheiros, non poderá dispor deles a non ser que sexa o propietario. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Todos os ficheiros do cartafol de sincronización local «%1» foron eliminados. Estas eliminacións sincronizaranse co servidor, facendo que estes ficheiros non estean dispoñíbeis a non ser que se restauren. -Confirma que quere sincronizar estas accións co servidor? -Se fose un accidente e decide manter os seus ficheiros, volverán ser sincronizados dende o servidor. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1426,7 +1428,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1442,6 +1444,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Retirar todos os ficheiros + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Todos os ficheiros no cartafol de sincronización «%1» foron eliminados no servidor. +Estas eliminacións sincronizarse co seu cartafol de sincronización local, facendo que estes ficheiros non estean dispoñíbeis a menos que teña dereitos para restauralos. +Se decide restaurar os ficheiros, resincronizaranse co servidor se ten dereitos para facelo. +Se decide eliminar os ficheiros, non poderá dispor deles a non ser que sexa o propietario. + Keep files @@ -2272,6 +2285,69 @@ Os elementos onde se permite a eliminación eliminaranse se impiden que se elimi Engadir un novo patrón a ignorar: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2412,7 +2488,7 @@ Os rexistros escribiranse en %1 <nobr>O ficheiro «%1»<br/> non se pode abrir para escritura.<br/><br/>A saída do rexistro <b>non</n> se pode gardar!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2455,6 +2531,11 @@ Os rexistros escribiranse en %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Hai dispoñíbel unha nova versión do cliente %1 , pero o proceso de actualización fallou.</p><p> Descargouse a <b>%2</b>. A versión instalada é a %3</p>. + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2624,6 +2705,13 @@ Os rexistros escribiranse en %1 New %1 Update Ready Preparada a nova actualización %1 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Está a piques de instalarse unha nova actualización para %1. O proceso de +actualización pode pedir privilexios adicionais durante o procedemento. + New %1 update ready @@ -2631,10 +2719,8 @@ Os rexistros escribiranse en %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Está a piques de instalarse unha nova actualización para %1. O proceso de -actualización pode pedir privilexios adicionais durante o procedemento. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2671,6 +2757,11 @@ actualización pode pedir privilexios adicionais durante o procedemento.New %1 is available. Please click <a href='%2'>here</a> to download the update. Está dispoñíbel a nova versión de %1. Prema <a href='%2'>aquí</a> para descargar a actualización. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2681,6 +2772,11 @@ actualización pode pedir privilexios adicionais durante o procedemento.Could not check for new updates. Non foi posíbel comprobar se hai novas actualizacións. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2977,37 +3073,37 @@ Recomendámoslle que non o use. Esgotouse o tempo tentando conectar con %1 en %2. - + Trying to connect to %1 at %2 … Tentando conectar con %1 en %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. A solicitude autenticada no servidor foi redirixida a «%1», O URL é incorrecto, o servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acceso prohibido polo servidor. Para comprobar que dispón do acceso axeitado, <a href="%1">prema aquí</a> para acceder ao servizo co seu navegador. - + There was an invalid response to an authenticated WebDAV request Deuse unha resposta incorrecta a unha solicitude de WebDAV autenticada - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> O cartafol de sincronización local %1 xa existe. Configurándoo para a sincronización.<br/><br/> - + Creating local sync folder %1 … Creando o cartafol local de sincronización %1… @@ -3017,84 +3113,84 @@ Recomendámoslle que non o use. aceptar - + OK - + failed. fallou. - + Could not create local folder %1 Non foi posíbel crear o cartafol local %1 - + No remote folder specified! Non se especificou o cartafol remoto! - + Error: %1 Erro: %1 - + creating folder on Nextcloud: %1 creando un cartafol no Nextcloud: %1 - + Remote folder %1 created successfully. O cartafol remoto %1 creouse correctamente. - + The remote folder %1 already exists. Connecting it for syncing. O cartafol remoto %1 xa existe. Conectándoo para a sincronización. - - + + The folder creation resulted in HTTP error code %1 A creación do cartafol resultou nun código de erro HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> A creación do cartafol remoto fracasou por mor de seren incorrectas as credenciais!<br/>Volva atrás e comprobe as súas credenciais.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">A creación do cartafol remoto fallou probabelmente debido a que as credenciais que se deron non foran as correctas.</font><br/>Volva atrás e comprobe as súas credenciais.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Produciuse un fallo ao crear o cartafol remoto %1 e dou o erro <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Estabeleceuse a conexión de sincronización de %1 ao directorio remoto %2. - + Successfully connected to %1! Conectou satisfactoriamente con %1! - + Connection to %1 could not be established. Please check again. Non foi posíbel estabelecer a conexión con %1. Compróbeo de novo. - + Folder rename failed Non foi posíbel renomear o cartafol @@ -3104,28 +3200,28 @@ Recomendámoslle que non o use. Non é posíbel retirar e facer unha copia de seguridade do cartafol, xa que o cartafol ou un ficheiro está aberto noutro programa Peche o cartafol ou o ficheiro e ténteo de novo, ou cancele a acción. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>O cartafol local de sincronización %1 creouse correctamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Asistente de conexión %1 - Add %1 account Engadir %1 conta + + + %1 Connection Wizard + Asistente de conexión %1 + Skip folders configuration @@ -3164,24 +3260,6 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Permanecer seguro - - OCC::OwncloudWizardResultPage - - - Everything set up! - Todo axustado! - - - - Open Local Folder - Abrir o cartafol local - - - - Open %1 in Browser - Abrir %1 no navegador - - OCC::PollJob @@ -3192,6 +3270,16 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3207,16 +3295,16 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe File names ending with a period are not supported on this file system. Os nomes de ficheiros que rematan cun punto non son compatíbeis con este sistema de ficheiros. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Os nomes de ficheiros que conteñen o carácter «%1» non son compatíbeis con este sistema de ficheiros. + + + File names containing the character "%1" are not supported on this file system. + + File name contains at least one invalid character @@ -3343,7 +3431,7 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe O servidor respondeu cun erro ao ler o directorio «%1» : %2 - + Server replied with an error while reading directory "%1" : %2 @@ -3958,11 +4046,6 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Allow Editing Permitir a edición - - - Allow editing - Permitir a edición - Read only @@ -3983,6 +4066,16 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Password Protect Protexido con contrasinal + + + Allow editing + Permitir a edición + + + + View only + + Allow upload and editing @@ -3998,16 +4091,21 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe File drop (upload only) Soltar ficheiro (só envíos) - - - Note to recipient - Nota para o destinatario - Unshare Deixar de compartir + + + Link name + + + + + Note to recipient + Nota para o destinatario + Password protect @@ -4019,15 +4117,20 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Definir a data de caducidade - - Delete share link - Eliminar a ligazón compartida + + Delete link + Add another link Engadir outra ligazón + + + Delete share link + Eliminar a ligazón compartida + Confirm Link Share Deletion @@ -4077,7 +4180,7 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Non hai resultados para «%1» - + No results for "%1" @@ -4181,12 +4284,6 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Compartir con %1 - Context menu share @@ -4213,6 +4310,12 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Share via %1 Compartido mediante %1 + + + + Activity + + Copy private link to clipboard @@ -4284,6 +4387,12 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Delete Eliminar + + + Share with %1 + parameter is Nextcloud + Compartir con %1 + OCC::SslButton @@ -4429,6 +4538,11 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Cannot connect securely to <i>%1</i>: Non se pode conectar de xeito seguro con <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4603,6 +4717,11 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Placeholders are postfixed with file sizes using Utility::octetsToString() Só %1 está dispoñíbel, necesita polo menos %2 para comezar + + + Aborted + Interrompido + @@ -4755,27 +4874,88 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Invalid characters, please rename "%1" Caracteres incorrectos, déalle outro nome a «%1» + + + Synchronization will resume shortly. + + File name contains at least one invalid character O nome de ficheiro contén algún carácter incorrecto - - Aborted - Interrompido - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Pouco espazo dispoñíbel no disco: As descargas que reduzan o tamaño por baixo de %1 van ser omitidas. - + There is insufficient space available on the server for some uploads. Non hai espazo libre abondo no servisor para algúns envíos. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4851,6 +5031,29 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe <p>Esta versión foi fornecida por %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4908,26 +5111,110 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - A funcionalidade do sistema de ficheiros virtual require un sistema de ficheiros NTFS, %1 está a usar %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + A funcionalidade do sistema de ficheiros virtual require un sistema de ficheiros NTFS, %1 está a usar %2 + + OCC::WebEnginePage @@ -5442,14 +5729,6 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Acceda ao seu %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Toda a súa conta está sincronizada co cartafol local - - QObject @@ -5542,6 +5821,38 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5556,29 +5867,39 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe - Current user status is online - + Account connected + Conta conectada - Current user status is do not disturb - + Account not connected + Conta sen conectar - Account connected - Conta conectada + Current user status is online + - Account not connected - Conta sen conectar + Current user status is do not disturb + Account actions Accións da conta + + + Remove Account + Retirar a conta + + + + Set status + + @@ -5591,17 +5912,65 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Log in Acceder - - - Remove Account - Retirar a conta - Remove account Retirar a conta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5663,12 +6032,12 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe ValidateChecksumHeader - + The checksum header is malformed. A cabeceira da suma de comprobación é incorrecta. - + The checksum header contained an unknown checksum type '%1' A cabeceira da suma de comprobación contén un tipo de suma de comprobación descoñecido «%1» @@ -5678,17 +6047,17 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe O ficheiro descargado non coincide coa suma de comprobación. Retomase. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' O ficheiro descargado non coincide coa suma de comprobación. Retomase. «%1' != '%2» - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5717,6 +6086,11 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Pause sync for all Por en pausa a sincronización para todos + + + Set user status + + Add account @@ -5752,12 +6126,6 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Current user status is do not disturb - - - - Show more actions - Amosar máis accións - Share %1 @@ -5818,6 +6186,22 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Open share dialog Abrir o diálogo de compartición + + + Unified search results list + + + + + + Show more actions + Amosar máis accións + + + + %1 - File activity + + main.cpp @@ -6117,6 +6501,24 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Acceda no seu navegador (Fluxo de acceso v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Todo axustado! + + + + Open Local Folder + Abrir o cartafol local + + + + Open %1 in Browser + Abrir %1 no navegador + + OCC::ShibbolethCredentials @@ -6169,6 +6571,14 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe Acceder + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Toda a súa conta está sincronizada co cartafol local + + OCC::UserStatus @@ -6192,4 +6602,17 @@ Este é un novo modo experimental. Se decide usalo, agradecémoslle que informe + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_he.ts b/translations/client_he.ts index 65098e7ce47b..aa53cef84e1f 100644 --- a/translations/client_he.ts +++ b/translations/client_he.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1139,32 +1152,32 @@ This can be an issue with your OpenSSL libraries. לא ניתן לפתוח את הדפדפן, נא להעתיק את הקישור לדפדפן שלך. - + Waiting for authorization בהמתנה לאימות - + Polling for authorization מתבצע תשאול לאימות - + Starting authorization האימות מתחיל - + Link copied to clipboard. קישור הועתק ללוח הגזירים. - + Reopen Browser פתיחת דפדפן מחדש - + Copy Link העתקת קישור @@ -1329,6 +1342,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an להשאיר את הקבצים המקומיים כסותרים - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files להסיר את כל הקבצים + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2247,6 +2260,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from הוספת תבנית התעלמות חדשה: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2382,7 +2458,7 @@ Logs will be written to %1 - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2425,6 +2501,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2594,6 +2675,13 @@ Logs will be written to %1 New %1 Update Ready עדכון חדש של %1 מוכן + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + עדכון חדש של %1 מועמד להתקנה. תכנית ההתקנה עשויה +לבקש ממך הרשאות נוספות במהלך הדרך. + New %1 update ready @@ -2601,10 +2689,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - עדכון חדש של %1 מועמד להתקנה. תכנית ההתקנה עשויה -לבקש ממך הרשאות נוספות במהלך הדרך. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2641,6 +2727,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2651,6 +2742,11 @@ for additional privileges during the process. Could not check for new updates. נא ניתן לבדוק אם יש עדכונים חדשים. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2947,37 +3043,37 @@ It is not advisable to use it. הזמן שהוקצב להתחברות אל %1 ב־%2 פג. - + Trying to connect to %1 at %2 … מתבצע ניסיון להתחבר אל %1 ב־%2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. הבקשה המאומתת לשרת הופנתה אל ‚%1’. הכתובת שגויה, השרת לא מוגדר נכון. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. הגישה נאסרה על ידי השרת. כדי לוודא שיש לך גישה כנדרש, עליך <a href="%1">ללחוץ כאן</a> כדי לגשת לשירות עם הדפדפן שלך. - + There was an invalid response to an authenticated WebDAV request התגובה לבקשת ה־WebDAV המאומתת שגויה - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> תיקיית הסנכרון המקומית %1 כבר קיימת, מוגדרת לסנכרון. <br/><br/> - + Creating local sync folder %1 … תיקיית הסנכרון המקומית %1 נוצרת… @@ -2987,84 +3083,84 @@ It is not advisable to use it. בסדר - + OK אישור - + failed. כשלון. - + Could not create local folder %1 לא ניתן ליצור את התיקייה המקומית %1 - + No remote folder specified! לא צוינה תיקייה מרוחקת! - + Error: %1 שגיאה: %1 - + creating folder on Nextcloud: %1 נוצרת תיקייה ב־Nextcloud:‏ %1 - + Remote folder %1 created successfully. התיקייה המרוחקת %1 נוצרה בהצלחה. - + The remote folder %1 already exists. Connecting it for syncing. התיקייה המרוחקת %1 כבר קיימת. היא מחוברת לטובת סנכרון. - - + + The folder creation resulted in HTTP error code %1 יצירת התיקייה הובילה לקוד שגיאה %1 ב־HTTP - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> יצירת התיקייה המרוחקת נכשלה כיוון שפרטי הגישה שסופקו שגויים!<br/>נא לחזור ולאמת את פרטי הגישה שלך.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. יצירת התיקייה המרוחקת %1 נכשלה עם השגיאה <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. הוקם חיבור סנכרון מצד %1 אל התיקייה המרוחקת %2. - + Successfully connected to %1! ההתחברות אל %1 הצליחה! - + Connection to %1 could not be established. Please check again. לא ניתן להקים את ההתחברות אל %1. נא לבדוק שוב. - + Folder rename failed שינוי שם התיקייה נכשל @@ -3074,28 +3170,28 @@ It is not advisable to use it. לא ניתן להסיר ולגבות את התיקייה או שקובץ בה כבר פתוח בתכנית אחרת. נא לסגור את התיקייה או את הקובץ וללחוץ על ניסיון חוזר או לבטל את ההקמה. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>תיקיית הסנכורן המקומי %1 נוצרה בהצלחה!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - אשף החיבור אל %1 - Add %1 account הוספת חשבון %1 + + + %1 Connection Wizard + אשף החיבור אל %1 + Skip folders configuration @@ -3128,24 +3224,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - הכול הוגדר! - - - - Open Local Folder - פתיחת תיקייה מקומית - - - - Open %1 in Browser - לפתוח את %1 בדפדפן - - OCC::PollJob @@ -3156,6 +3234,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3173,12 +3261,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3307,7 +3395,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3922,11 +4010,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing לאפשר עריכה - - - Allow editing - לאפשר עריכה - Read only @@ -3947,6 +4030,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect הגנה בססמה + + + Allow editing + לאפשר עריכה + + + + View only + + Allow upload and editing @@ -3962,16 +4055,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) השלכת קבצים (העלאה בלבד) - - - Note to recipient - מסר לנמען - Unshare ביטול שיתוף + + + Link name + + + + + Note to recipient + מסר לנמען + Password protect @@ -3983,15 +4081,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss הגדרת תאריך תפוגה - - Delete share link - מחיקת קישור שיתוף + + Delete link + Add another link הוספת קישור נוסף + + + Delete share link + מחיקת קישור שיתוף + Confirm Link Share Deletion @@ -4041,7 +4144,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss אין תוצאות לחיפוש אחר ‚%1’ - + No results for "%1" @@ -4145,12 +4248,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - שיתוף עם %1 - Context menu share @@ -4177,6 +4274,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 שיתוף דרך %1 + + + + Activity + + Copy private link to clipboard @@ -4248,6 +4351,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete מחיקה + + + Share with %1 + parameter is Nextcloud + שיתוף עם %1 + OCC::SslButton @@ -4393,6 +4502,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: לא ניתן להתחבר באופן מאובטח אל <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4567,6 +4681,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() + + + Aborted + + @@ -4719,27 +4838,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" תווים שגויים, נא לשנות את השם של „%1” + + + Synchronization will resume shortly. + + File name contains at least one invalid character שם הקובץ מכיל אות שגויה אחת לפחות - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. אין די מקום פנוי בכונן: הורדות שעלולות להוריד את הנפח הפנוי מתחת לסף של %1 ידולגו. - + There is insufficient space available on the server for some uploads. אין מספיק מקום זה בשרת לחלק מההורדות. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4815,6 +4995,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>גרסה זו סופקה על ידי %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4872,23 +5075,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5406,14 +5693,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - כל החשבון שלך מסונכרן לתיקייה הנוכחית - - QObject @@ -5506,6 +5785,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5520,22 +5831,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + חשבון מחובר - Current user status is do not disturb + Account not connected - Account connected - חשבון מחובר + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5543,6 +5854,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions פעולות חשבון + + + Remove Account + + + + + Set status + + @@ -5555,17 +5876,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in כניסה - - - Remove Account - - Remove account הסרת חשבון + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5627,12 +5996,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. כותרת הבדיקה פגומה. - + The checksum header contained an unknown checksum type '%1' @@ -5642,17 +6011,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5681,6 +6050,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5716,12 +6090,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5782,6 +6150,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6081,6 +6465,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss כניסה בדפדפן שלך (תזרים כניסה גרסה 2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + הכול הוגדר! + + + + Open Local Folder + פתיחת תיקייה מקומית + + + + Open %1 in Browser + לפתוח את %1 בדפדפן + + OCC::ShibbolethCredentials @@ -6133,6 +6535,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss כניסה + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + כל החשבון שלך מסונכרן לתיקייה הנוכחית + + OCC::UserStatus @@ -6156,4 +6566,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_hr.ts b/translations/client_hr.ts index e5f2526def1f..bbf58df35072 100644 --- a/translations/client_hr.ts +++ b/translations/client_hr.ts @@ -14,12 +14,6 @@ Open %1 locally Otvori %1 lokalno - - - - Show more actions - Prikaži dodatne radnje - Open share dialog @@ -30,6 +24,25 @@ Share %1 Dijeli %1 + + + + Show more actions + Prikaži dodatne radnje + + + + View activity + + + + + ActivityList + + + Activity list + + CloudProviderWrapper @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1144,32 +1157,32 @@ Možda se radi o pogrešci u radu OpenSSL biblioteka. Otvaranje preglednika nije uspjelo, kopirajte poveznicu u preglednik. - + Waiting for authorization Čekanje autorizacije - + Polling for authorization Dohvaćanje podataka za autorizaciju - + Starting authorization Pokretanje autorizacije - + Link copied to clipboard. Poveznica je kopirana u međuspremnik. - + Reopen Browser Ponovno otvori preglednik - + Copy Link Kopiraj poveznicu @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi To znači da klijent za sinkronizaciju možda neće odmah otpremiti lokalne promjene i umjesto toga će skenirati u potrazi za lokalnim promjenama i povremeno ih otpremati (svaka dva sata prema zadanim postavkama). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Sve datoteke u vašoj lokalnoj mapi za sinkronizaciju „%1” su izbrisane. Ova će se brisanja sinkronizirati s vašim poslužiteljem, što znači da će te datoteke biti nedostupne ako ih ne vratite. +Jeste li sigurni da želite sinkronizirati te radnje s poslužiteljem? +Ako ste slučajno odabrali ovu radnju i želite zadržati svoje datoteke, ponovno će se sinkronizirati s poslužitelja. @@ -1398,27 +1420,7 @@ Nastavljanje sinkronizacije uzrokovat će zamjenu svih vaših datoteka starijim Zadrži lokalne datoteke kao datoteke nepodudaranja - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Sve datoteke u mapi za sinkronizaciju „%1” izbrisane su s poslužitelja. -Ta će se brisanja sinkronizirati s lokalnom mapom za sinkronizaciju, što znači da će takve datoteke biti nedostupne ako nemate ovlasti za vraćanje. -Ako odlučite vratiti datoteke, ponovno će se sinkronizirati s poslužiteljem ako imate potrebne ovlasti. -Ako odlučite izbrisati datoteke, one će vam biti nedostupne ako niste njihov vlasnik. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Sve datoteke u vašoj lokalnoj mapi za sinkronizaciju „%1” su izbrisane. Ova će se brisanja sinkronizirati s vašim poslužiteljem, što znači da će te datoteke biti nedostupne ako ih ne vratite. -Jeste li sigurni da želite sinkronizirati te radnje s poslužiteljem? -Ako ste slučajno odabrali ovu radnju i želite zadržati svoje datoteke, ponovno će se sinkronizirati s poslužitelja. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1426,7 +1428,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1442,6 +1444,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Ukloni sve datoteke + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Sve datoteke u mapi za sinkronizaciju „%1” izbrisane su s poslužitelja. +Ta će se brisanja sinkronizirati s lokalnom mapom za sinkronizaciju, što znači da će takve datoteke biti nedostupne ako nemate ovlasti za vraćanje. +Ako odlučite vratiti datoteke, ponovno će se sinkronizirati s poslužiteljem ako imate potrebne ovlasti. +Ako odlučite izbrisati datoteke, one će vam biti nedostupne ako niste njihov vlasnik. + Keep files @@ -2272,6 +2285,69 @@ Stavke za koje je dopušteno brisanje bit će izbrisane ako sprječavaju uklanja Dodaj novi obrazac za zanemarivanje: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2412,7 +2488,7 @@ Zapisi se zapisuju u %1 <nobr>Datoteka ‘%1’<br/>se ne može otvoriti radi zapisivanja.<br/><br/>Izlaz zapisa <b>ne može</b> se spremiti!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2455,6 +2531,11 @@ Zapisi se zapisuju u %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Raspoloživa je nova inačica klijenta %1 ali nije uspjelo ažuriranje na novu inačicu.</p><p><b>%2</b> je preuzet. Instalirana je inačica %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2624,6 +2705,13 @@ Zapisi se zapisuju u %1 New %1 Update Ready Novo %1 ažuriranje je spremno + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Sada će se instalirati novo ažuriranje za %1. Alat za ažuriranje može tražiti +dodatne ovlasti tijekom postupka. + New %1 update ready @@ -2631,10 +2719,8 @@ Zapisi se zapisuju u %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Sada će se instalirati novo ažuriranje za %1. Alat za ažuriranje može tražiti -dodatne ovlasti tijekom postupka. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2671,6 +2757,11 @@ dodatne ovlasti tijekom postupka. New %1 is available. Please click <a href='%2'>here</a> to download the update. Dostupan je %1. Kliknite <a href=’%2’>ovdje</a> za preuzimanje ažuriranja. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2681,6 +2772,11 @@ dodatne ovlasti tijekom postupka. Could not check for new updates. Nije moguće provjeriti ima li novih ažuriranja. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2977,37 +3073,37 @@ Nije preporučljivo koristiti ga. Istek vremena tijekom povezivanja s %1 na %2. - + Trying to connect to %1 at %2 … Pokušaj povezivanja s %1 na %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Autorizirani zahtjev poslužitelju preusmjeren je na '%1'. URL je neispravan, poslužitelj je pogrešno konfiguriran. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Poslužitelj je zabranio pristup. Kako biste provjerili imate li ispravan pristup, <a href="%1">kliknite ovdje</a> kako biste pristupili servisu putem preglednika. - + There was an invalid response to an authenticated WebDAV request Došlo je do nevažećeg odgovora na autorizirani zahtjev protokola WebDAV - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Mapa za lokalnu sinkronizaciju %1 već postoji, postavljanje za sinkronizaciju.<br/><br/> - + Creating local sync folder %1 … Stvaranje mape za lokalnu sinkronizaciju %1… @@ -3017,84 +3113,84 @@ Nije preporučljivo koristiti ga. uspješno - + OK U redu - + failed. neuspješno. - + Could not create local folder %1 Nije moguće stvoriti lokalnu mapu %1 - + No remote folder specified! Nije navedena nijedna udaljena mapa! - + Error: %1 Pogreška: %1 - + creating folder on Nextcloud: %1 stvaranje mape na Nextcloudu: %1 - + Remote folder %1 created successfully. Uspješno je stvorena udaljena mapa %1. - + The remote folder %1 already exists. Connecting it for syncing. Udaljena mapa %1 već postoji. Povezivanje radi sinkronizacije. - - + + The folder creation resulted in HTTP error code %1 Stvaranje mape rezultiralo je HTTP šifrom pogreške %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Stvaranje udaljene mape nije uspjelo jer su navedene vjerodajnice pogrešne!<br/>Vratite se i provjerite svoje vjerodajnice.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color=“red“>Stvaranje udaljene mape nije uspjelo vjerojatno zbog pogrešnih unesenih vjerodajnica.</font><br/>Vratite se i provjerite vjerodajnice.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Stvaranje udaljene mape %1 nije uspjelo, pogreška: <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Postavljena je sinkronizacijska veza od %1 do udaljenog direktorija %2. - + Successfully connected to %1! Uspješno povezivanje s %1! - + Connection to %1 could not be established. Please check again. Veza s %1 nije uspostavljena. Provjerite opet. - + Folder rename failed Preimenovanje mape nije uspjelo @@ -3104,28 +3200,28 @@ Nije preporučljivo koristiti ga. Nije moguće ukloniti i izraditi sigurnosnu kopiju mape jer je mapa ili datoteka u njoj otvorena u drugom programu. Zatvorite mapu ili datoteku i pritisnite Pokušaj ponovo ili otkažite postavljanje. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Nije moguće ukloniti i izraditi sigurnosnu kopiju mape jer je mapa ili datoteka u njoj otvorena u drugom programu. Zatvorite mapu ili datoteku i pritisnite Pokušaj ponovo ili otkažite postavljanje. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color=“green“><b>Mapa za lokalnu sinkronizaciju %1 uspješno je stvorena!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Čarobnjak za povezivanje - Add %1 account Dodaj %1 račun + + + %1 Connection Wizard + %1 Čarobnjak za povezivanje + Skip folders configuration @@ -3164,24 +3260,6 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Zadrži stari - - OCC::OwncloudWizardResultPage - - - Everything set up! - Sve je postavljeno! - - - - Open Local Folder - Otvori lokalnu mapu - - - - Open %1 in Browser - Otvori %1 u pregledniku - - OCC::PollJob @@ -3192,6 +3270,16 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3207,16 +3295,16 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav File names ending with a period are not supported on this file system. Nazivi datoteka koji završavaju točkom nisu podržani u ovom datotečnom sustavu. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Nazivi datoteka koji sadrže znak „%1”nisu podržani u ovom datotečnom sustavu. + + + File names containing the character "%1" are not supported on this file system. + + File name contains at least one invalid character @@ -3343,7 +3431,7 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Poslužitelj je javio pogrešku pri čitanju direktorija '%1' : %2 - + Server replied with an error while reading directory "%1" : %2 @@ -3958,11 +4046,6 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Allow Editing Dopusti uređivanje - - - Allow editing - Dopusti uređivanje - Read only @@ -3983,6 +4066,16 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Password Protect Zaštita zaporkom + + + Allow editing + Dopusti uređivanje + + + + View only + + Allow upload and editing @@ -3998,16 +4091,21 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav File drop (upload only) Povlačenje datoteke (samo za otpremanje) - - - Note to recipient - Obavijest primatelju - Unshare Prestani dijeliti + + + Link name + + + + + Note to recipient + Obavijest primatelju + Password protect @@ -4019,15 +4117,20 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Postavi datum isteka - - Delete share link - Izbriši poveznicu dijeljenja + + Delete link + Add another link Dodaj drugu poveznicu + + + Delete share link + Izbriši poveznicu dijeljenja + Confirm Link Share Deletion @@ -4077,7 +4180,7 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Nema rezultata za ‘%1’ - + No results for "%1" @@ -4181,12 +4284,6 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Dijeli s %1 - Context menu share @@ -4213,6 +4310,12 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Share via %1 Dijeli putem %1 + + + + Activity + + Copy private link to clipboard @@ -4284,6 +4387,12 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Delete Izbriši + + + Share with %1 + parameter is Nextcloud + Dijeli s %1 + OCC::SslButton @@ -4429,6 +4538,11 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Cannot connect securely to <i>%1</i>: Nije moguće sigurno se povezati s <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4603,6 +4717,11 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Placeholders are postfixed with file sizes using Utility::octetsToString() Dostupno je samo %1, za pokretanje je potrebno najmanje %2 + + + Aborted + Prekinuto + @@ -4755,49 +4874,110 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Invalid characters, please rename "%1" Nevažeći znakovi, preimenujte „%1” + + + Synchronization will resume shortly. + + File name contains at least one invalid character Naziv datoteke sadrži barem jedan nevažeći znak - - Aborted - Prekinuto - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Premalo prostora na disku: preskočena su preuzimanja koja bi smanjila slobodni prostor ispod %1. - + There is insufficient space available on the server for some uploads. Na nekim poslužiteljima nema dovoljno slobodnog prostora za određene otpreme. - OCC::Systray + OCC::SyncStatusSummary - - Add account - Dodaj račun + + + Offline + - - Open main dialog - Otvori glavni dijaloški okvir + + + + All synced! + - - - Pause sync - Pauziraj sinkronizaciju + + Some files couldn't be synced! + - - - Resume sync + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + + + OCC::Systray + + + Add account + Dodaj račun + + + + Open main dialog + Otvori glavni dijaloški okvir + + + + + Pause sync + Pauziraj sinkronizaciju + + + + + Resume sync Nastavi sinkronizaciju @@ -4851,6 +5031,29 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav <p>Ovo izdanje isporučuje %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4908,24 +5111,108 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Značajka virtualnog datotečnog sustava zahtijeva datotečni sustav NTFS, %1 upotrebljava %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Preuzimanje cjelovito šifrirane datoteke nije uspjelo + + Could not fetch user status. Make sure you are connected to the server. + - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Čini se da pokušavate preuzeti virtualnu datoteku koja je cjelovito šifrirana. Implicitno preuzimanje takvih datoteka trenutno nije podržano. Kako biste zaobišli ovaj problem, otvorite postavke i za šifriranu mapu označite „Učini uvijek dostupnim lokalno“. + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Značajka virtualnog datotečnog sustava zahtijeva datotečni sustav NTFS, %1 upotrebljava %2 @@ -5442,14 +5729,6 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Prijavite se u svoj %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Cijeli se račun sinkronizira s lokalnom mapom - - QObject @@ -5542,6 +5821,38 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Povezivanje baze podataka nije uspjelo. + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5556,29 +5867,39 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav - Current user status is online - Trenutni status korisnika je „na mreži“ + Account connected + Račun povezan - Current user status is do not disturb - Trenutni status korisnika je „ne ometaj“ + Account not connected + Račun nije povezan - Account connected - Račun povezan + Current user status is online + Trenutni status korisnika je „na mreži“ - Account not connected - Račun nije povezan + Current user status is do not disturb + Trenutni status korisnika je „ne ometaj“ Account actions Radnje računa + + + Remove Account + Izbriši račun + + + + Set status + + @@ -5591,17 +5912,65 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Log in Prijava - - - Remove Account - Izbriši račun - Remove account Izbriši račun + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5663,12 +6032,12 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav ValidateChecksumHeader - + The checksum header is malformed. Zaglavlje kontrolnog zbroja pogrešno je oblikovano. - + The checksum header contained an unknown checksum type '%1' Zaglavlje kontrolnog zbroja sadrži nepoznatu vrstu kontrolnog zbroja ‘%1’ @@ -5678,17 +6047,17 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Preuzeta se datoteka ne podudara s kontrolnim zbrojem, nastavit će se. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Preuzeta se datoteka ne podudara s kontrolnim zbrojem, nastavit će se. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5717,6 +6086,11 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Pause sync for all Pauziraj sinkronizaciju za sve + + + Set user status + + Add account @@ -5752,12 +6126,6 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Current user status is do not disturb Trenutni status korisnika je „ne ometaj“ - - - - Show more actions - Prikaži dodatne radnje - Share %1 @@ -5818,6 +6186,22 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Open share dialog Otvori dijaloški okvir za dijeljenje + + + Unified search results list + + + + + + Show more actions + Prikaži dodatne radnje + + + + %1 - File activity + + main.cpp @@ -6117,6 +6501,24 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Prijavite se u svoj preglednik (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Sve je postavljeno! + + + + Open Local Folder + Otvori lokalnu mapu + + + + Open %1 in Browser + Otvori %1 u pregledniku + + OCC::ShibbolethCredentials @@ -6169,6 +6571,14 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Prijava + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Cijeli se račun sinkronizira s lokalnom mapom + + OCC::UserStatus @@ -6192,4 +6602,17 @@ Ovo je novi, eksperimentalni način rada. Ako se odlučite aktivirati ga, prijav Na mreži + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Preuzimanje cjelovito šifrirane datoteke nije uspjelo + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Čini se da pokušavate preuzeti virtualnu datoteku koja je cjelovito šifrirana. Implicitno preuzimanje takvih datoteka trenutno nije podržano. Kako biste zaobišli ovaj problem, otvorite postavke i za šifriranu mapu označite „Učini uvijek dostupnim lokalno“. + + \ No newline at end of file diff --git a/translations/client_hu.ts b/translations/client_hu.ts index 33b3b6befea2..89f4463567a0 100644 --- a/translations/client_hu.ts +++ b/translations/client_hu.ts @@ -14,12 +14,6 @@ Open %1 locally %1 megnyitása helyben - - - - Show more actions - További műveletek megjelenítése - Open share dialog @@ -30,6 +24,25 @@ Share %1 %1 megosztása + + + + Show more actions + További műveletek megjelenítése + + + + View activity + Tevékenység megtekintése + + + + ActivityList + + + Activity list + Tevékenységlista + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + A(z) „%1” nem helyezhető át ide: „%2” @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Úgy néz ki, hogy engedélyezte a Virtuális fájlok funkciót ezen a mappán. Pillanatnyilag nem lehet implicit módon olyan virtuális fájlokat letölteni, melyek végpontok közti titkosítással vannak ellátva. A legjobb élmény érdekében győződjön meg róla, hogy a titkosított mappa meg legyen jelölve, hogy mindig elérhető legyen helyben is. @@ -592,7 +605,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. %1 as %2 - + %1 mint %2 @@ -756,7 +769,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Certificate & Key (pkcs12): - + Tanúsítvány és kulcs (pkcs12): @@ -804,7 +817,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Some settings were configured in newer versions of this client and use features that are not available in this version.<br><br>%1<br><br>The current configuration file was already backed up to <i>%2</i>. - Néhány beállítást a kliens újabb verzióiban konfiguráltak, és olyan funkciókat használnak, amelyek ebben a verzióban nem érhetők el. <br> <br>%1<br><br>Az aktuális konfigurációs fájlról már készült biztonsági másolat: <i>%2< / i>. + Néhány beállítást a kliens újabb verzióiban konfiguráltak, és olyan funkciókat használnak, amelyek ebben a verzióban nem érhetők el. <br> <br>%1<br><br>Az aktuális konfigurációs fájlról már készült biztonsági másolat: <i>%2</i>. @@ -842,7 +855,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Enter username and password for "%1" at %2. - + Felhasználónév és jelszó beírása ehhez: „%1”, itt: %2. @@ -897,7 +910,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Which version of the file do you want to keep?<br/>If you select both versions, the local file will have a number added to its name. - A fájl melyik verzióját kívánja megtartani?<br/>Ha mindkét verziót kiválasztja, a helyi fájl számmal nevét számmal egészítjük ki. + A fájl melyik verzióját tartja meg?<br/>Ha mindkét verziót kiválasztja, akkor a helyi fájl neve egy számmal lesz kiegészítve. @@ -925,23 +938,23 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. <a href="%1">Open local version</a> - <a href="%1"> Helyi verzió megnyitása</a> + <a href="%1">Helyi verzió megnyitása</a> Server version - Szerver verzió + Kiszolgáló verziója <a href="%1">Open server version</a> - <a href="%1"> A szerveren tárolt verzió megnyitása </a> + <a href="%1">A kiszolgálón tárolt verzió megnyitása</a> Keep selected version - A kiválasztott verzió megtartása + Kiválasztott verzió megtartása @@ -951,8 +964,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Open server version - A szerveren tárolt verzió megnyitása - + A kiszolgálón tárolt verzió megnyitása @@ -962,12 +974,12 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Keep local version - A helyi verzió megtartása + Helyi verzió megtartása Keep server version - A szerveren tárolt verzió megtartása + Kiszolgálón tárolt verzió megtartása @@ -985,7 +997,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Confirm deletion - A törlés megerősítésére + Törlés megerősítése @@ -1053,7 +1065,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Server error: PROPFIND reply is not XML formatted! - Szerverhiba: A PROPFIND válasz nem XML formátumú! + Kiszolgálóhiba: A PROPFIND válasz nem XML formátumú! @@ -1066,7 +1078,7 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Directory not accessible on client, permission denied - A mappa nem érhető el a kliensen, az engedély megtagadva + A könyvtár nem érhető el a kliensen, az engedély megtagadva @@ -1076,12 +1088,12 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Filename encoding is not valid - A fájlnév kódolása nem érvényes + A fájlnév kódolása érvénytelen Error while reading directory %1 - Hiba történt a(z) %1 könyvtár olvasása közben + Hiba történt a(z) %1 könyvtár olvasása során @@ -1090,7 +1102,8 @@ Ez a művelet megszakítja a jelenleg futó szinkronizálást. Could not generate the metadata for encryption, Unlocking the folder. This can be an issue with your OpenSSL libraries. - Nem sikerült létrehozni a metaadatokat a titkosításhoz. a mappa feloldásakor. Ezt a problémát valószínűleg az OpenSSL könyvtárakban kell keresni. + Nem sikerült előállítani a metaadatokat a titkosításhoz. A mappa feloldásra kerül. +Ezt a problémát valószínűleg az OpenSSL programkönyvtárakban kell keresni. @@ -1098,7 +1111,7 @@ This can be an issue with your OpenSSL libraries. The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + A lekérdezési URL nem HTTPS-sel kezdődik, pedig a bejelentkezési URL HTTPS-sel kezdődött. A bejelentkezés nem lesz lehetséges, mert biztonsági problémát jelenthet. Lépjen kapcsolatba a rendszergazdával. @@ -1116,7 +1129,7 @@ This can be an issue with your OpenSSL libraries. There was an error accessing the "token" endpoint: <br><em>%1</em> - + Hiba történt a „token” végpont elérésekor: <br><em>%1</em> @@ -1133,7 +1146,7 @@ This can be an issue with your OpenSSL libraries. The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + A visszaadott kiszolgáló URL nem HTTPS-sel kezdődik, pedig a bejelentkezési URL HTTPS-sel kezdődött. A bejelentkezés nem lesz lehetséges, mert biztonsági problémát jelenthet. Lépjen kapcsolatba a rendszergazdával. @@ -1144,34 +1157,34 @@ This can be an issue with your OpenSSL libraries. A böngésző nem nyitható meg, másolja a hivatkozást a böngészőjébe. - + Waiting for authorization Várakozás a hitelesítésre - + Polling for authorization Hitelesítés lekérése - + Starting authorization Hitelesítés indítása - + Link copied to clipboard. Hivatkozás a vágólapra másolva. - + Reopen Browser - Böngésző újra nyitása + Böngésző újranyitása - + Copy Link - Link másolása + Hivatkozás másolása @@ -1222,7 +1235,7 @@ This can be an issue with your OpenSSL libraries. %1 has been added. %1 names a file. - % 1 hozzáadva. + %1 hozzáadva. @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Ez azt jelenti, hogy a szinkronizációs kliens lehet, hogy nem fogja azonnal feltölteni a helyi módosításokat, ehelyett idöközönként változásokat keres, és alkalmanként feltölti azokat (alapértelmezés szerint két óránként). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + A(z) „%1” helyi szinkronizálási mappában található összes fájl törölve lett. Ezek a törlések szinkronizálva lesznek a kiszolgálóval, így ezek nem lesznek elérhetők, amíg vissza nem állítják őket. +Biztos, hogy szinkronizálni akarja ezeket a változásokat a kiszolgálóval? +Ha ez véletlen volt, és úgy dönt, hogy megtartja ezeket a fájlokat, akkor újra szinkronizálva lesznek a kiszolgálóról. @@ -1398,38 +1420,24 @@ A szinkronizálás folytatásával az összes fájlja felül lesz írva egy rég Helyi fájlok megtartása ütközésként - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - A(z) '%1' mappában lévő összes fájl törlésre került a szerverről. Ezeket a törléseket szinkronizáljuk a helyi szinkronizálási mappával, így, hacsak nincs joga a visszaállításra, ezek a fájlok nem lesznek elérhetők. -Ha úgy dönt, hogy visszaállítja a fájlokat, akkor azokat újra szinkronizálja a szerverrel, ha erre jogosult. -Ha úgy dönt, hogy törli a fájlokat, akkor azok nem lesznek elérhetők Önnek, hacsak nem Ön a tulajdonos. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - A(z) '%1' helyi szinkronizáló mappában lévő összes fájlt törölték. Ezeket a törléseket szinkronizáljuk a szerverrel, így ezek a fájlok nem lesznek elérhetők, amíg vissza nem állítják őket. -Biztosan szinkronizálni szeretné ezeket a műveleteket a szerverrel? -Ha ez véletlen volt, és úgy dönt, hogy megtartja a fájljait, azokat újra szinkronizálja a szerver. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - + A(z) „%1” szinkronizálási mappa összes fájlja törlésre került a kiszolgálón. +Ez töröl mindent a helyi szinkronizálási mappában, így nem lesznek elérhetőek ezek a fájlok, hacsak nincs helyreállítási joga. +Ha úgy dönt, hogy visszaállítja a fájlokat, akkor újra fel lesznek töltve a kiszolgálóra, ha van ehhez joga. +Ha úgy dönt, hogy törli ezeket a fájlokat, akkor többé nem fogja azokat elérni, hacsak nem Ön a tulajdonos. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - + A(z) „%1” helyi szinkronizálási mappában található összes fájl törölve lett. Ezek a törlések szinkronizálva lesznek a kiszolgálóval, így ezek nem lesznek elérhetőek, hacsak helyre nem állítja őket. +Biztos, hogy szinkronizálni akarja ezeket a változásokat a kiszolgálóval? +Ha ez véletlen volt, és úgy dönt, hogy megtartja ezeket a fájlokat, akkor újra letöltésre kerülnek a kiszolgálóról. @@ -1439,7 +1447,18 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files - Az összes fájl eltávolítása + Összes fájl eltávolítása + + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + A(z) „%1” szinkronizálási mappában lévő összes fájl törlésre került a kiszolgálóról. +Ezek a törlések szinkronizálva lesznek a helyi szinkronizálási mappával, így, hacsak nincs joga a helyreállításhoz, akkor ezek a fájlok nem lesznek elérhetők. +Ha úgy dönt, hogy helyreállítja a fájlokat, akkor azokat újra lesznek szinkronizálva a kiszolgálóval, ha erre jogosult. +Ha úgy dönt, hogy törli a fájlokat, akkor azok nem lesznek elérhetők Önnek, hacsak nem Ön a tulajdonos. @@ -1452,12 +1471,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Create new folder - Új mappát létrehozása + Új mappa létrehozása Enter folder name - Írja be a mappa nevét + Adja meg a mappa nevét @@ -1490,7 +1509,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Egy régi szinkronizálási naplófájl található: „%1”, de az nem törölhető. Győződjön meg róla, hogy jelenleg egy alkalmazás sem használja. @@ -1678,12 +1697,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Változások keresése a(z) „%1” távoli mappában Checking for changes in local "%1" - + Változások keresése a(z) „%1” helyi mappában @@ -1843,7 +1862,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + Adja meg a(z) „%1” alatt létrehozandó új mappa nevét: @@ -1892,7 +1911,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Use virtual files instead of downloading content immediately %1 - Használjon virtuális fájlokat a tartalom azonnali letöltése helyett %1 + Virtuális fájlok használata a tartalom azonnali letöltése helyett %1 @@ -1903,12 +1922,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + A virtuális fájlok nem támogatottak a windowsos partíciók gyökerében helyi mappaként. Válasszon érvényes almappát a meghajtó betűjele alatt. Virtual files are not available for the selected folder - Virtuális fájlok nem érhetők el a kiválasztott mappához + A virtuális fájlok nem érhetők el a kiválasztott mappához @@ -1939,7 +1958,7 @@ If this was an accident and you decide to keep your files, they will be re-synce We received an unexpected download Content-Length. - Helytelen letöltött tartalomhosszúságot kaptunk. + Váratlan letöltési „Content-Length” fejléc fogadva. @@ -2064,7 +2083,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Create Debug Archive … - Hibakeresési archívum létrehozása ... + Hibakeresési archívum létrehozása… @@ -2074,7 +2093,7 @@ If this was an accident and you decide to keep your files, they will be re-synce You cannot disable autostart because system-wide autostart is enabled. - Az automatikus indítást nem tilthatja le, mert az egész rendszerre kiterjedő automatikus indítás engedélyezve van. + Az automatikus indítást nem tilthatja le, mert az egész rendszerre kiterjedő automatikus indítás engedélyezett. @@ -2098,7 +2117,7 @@ Ne feledje, hogy ez csak azt választja ki, hogy a frissítések milyen készlet Cancel - Mégsem + Mégse @@ -2118,7 +2137,7 @@ Ne feledje, hogy ez csak azt választja ki, hogy a frissítések milyen készlet Debug archive is created at %1 - A hibakeresési archívum a(z) %1 címen jön létre + A hibakeresési archívum itt lett létrehozva: %1 @@ -2158,7 +2177,7 @@ Ne feledje, hogy ez csak azt választja ki, hogy a frissítések milyen készlet Reading from keychain failed with error: "%1" - + A kulcstartóról olvasás sikertelen, a hiba a következő: „%1” @@ -2201,7 +2220,7 @@ Ne feledje, hogy ez csak azt választja ki, hogy a frissítések milyen készlet This entry is provided by the system at "%1" and cannot be modified in this view. - + A bejegyzést az itt lévő rendszer biztosítja: „%1”, és nem lehet módosítani ebben a nézetben. @@ -2253,7 +2272,7 @@ Ahol a törlés engedélyezett, ott az elemek törölve lesznek, ha megakadályo Cannot write changes to "%1". - + A változások nem írhatóak ide: „%1”. @@ -2271,6 +2290,69 @@ Ahol a törlés engedélyezett, ott az elemek törölve lesznek, ha megakadályo Új kihagyási minta hozzáadása: + + OCC::InvalidFilenameDialog + + + Invalid filename + Érvénytelen fájlnév + + + + The file could not be synced because it contains characters which are not allowed on this system. + A fájlt nem sikerült szinkronizálni, mert a rendszeren nem megengedett karaktereket tartalmaz. + + + + Error + Hiba + + + + Please enter a new name for the file: + Adjon meg egy új nevet a fájlnak: + + + + New filename + Új fájlnév + + + + Rename file + Fájl átnevezése + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + A(z) %1 fájlt nem sikerült szinkronizálni, mert a neve a rendszeren nem megengedett karaktereket tartalmaz. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + A következő karakterek nem engedélyezettek a rendszeren: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Nincs engedélye átnevezni ezt a fájlt. Kérje meg a fájl szerzőjét, hogy nevezze át. + + + + Filename contains illegal characters: %1 + A fájlnév érvénytelen karaktereket tartalmaz: %1 + + + + Could not rename file. Please make sure you are connected to the server. + A fájl nem nevezhető át. Győződjön meg róla, hogy kapcsolódik-e a kiszolgálóhoz + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + A fájl nem nevezhető át, mert létezik egy ugyanilyen nevű fájl a kiszolgálón. Válasszon másik nevet. + + OCC::LegalNotice @@ -2287,7 +2369,7 @@ Ahol a törlés engedélyezett, ott az elemek törölve lesznek, ha megakadályo <p>Copyright 2017-2021 Nextcloud GmbH<br />Copyright 2012-2021 ownCloud GmbH</p> - + <p>Copyright 2017-2021 Nextcloud GmbH<br />Copyright 2012-2021 ownCloud GmbH</p> @@ -2412,9 +2494,9 @@ A naplók ide lesznek írva: %1 <nobr>A(z) „%1” fájlt<br/>nem lehet írásra megnyitni.<br/><br/>A naplózás kimenete <b>nem</b> menthető!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> - + <nobr>A(z) „%1” fájlt<br/>nem lehet írásra megnyitni.<br/><br/>A naplózás kimenete <b>nem</b> menthető!</nobr> @@ -2455,10 +2537,15 @@ A naplók ide lesznek írva: %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p> A(z) %1 ügyfél új verziója elérhető, de a frissítési folyamat sikertelen volt.</p><p><b>%2</b> letöltve. A telepített verzió: %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p> A(z) %1 ügyfél új verziója elérhető, de a frissítési folyamat sikertelen volt.</p><b>%2</b> letöltve. A telepített verzió: %3. Ha megerősíti az újraindítást és a frissítést, akkor a számítógép újraindul a telepítés befejezéséhez.<p> + Ask again later - Kérdezzen rá később + Rákérdezés később @@ -2589,7 +2676,7 @@ A naplók ide lesznek írva: %1 There was an error accessing the "token" endpoint: <br><em>%1</em> - + Hiba történt a „token” végpont elérésekor: <br><em>%1</em> @@ -2624,16 +2711,21 @@ A naplók ide lesznek írva: %1 New %1 Update Ready Új %1 frissítés érhető el + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Egy új %1 frissítés fog települni. A frissítő további jogosultságokat kérhet a folyamat során. + New %1 update ready - + Új %1 frissítés érhető el - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Egy új %1 frissítés fog települni. A frissítő további jogosultságokat kérhet a folyamat során. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Egy új %1 frissítés fog települni. A frissítő további jogosultságokat kérhet a folyamat során. A számítógép újraindulhat a telepítés befejezéséhez. @@ -2670,6 +2762,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Új %1 elérhető. A frissítés letöltéséhez kattintson <a href='%2'> ide </a>. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Nem lehetett letölteni a frissítést. Nyissa meg a <a href='%1'>%1ot</a> frissítés kézi letöltéséhez. + Could not download update. Please open %1 to download the update manually. @@ -2680,6 +2777,11 @@ for additional privileges during the process. Could not check for new updates. A frissítések nem ellenőrizhatőek. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Új %1 érhető el. A frissítés letöltéséhez nyissa meg a <a href='%2'>%2ot</a>. + New %1 is available. Please open %2 to download the update. @@ -2763,17 +2865,17 @@ for additional privileges during the process. Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + A virtuális fájlok nem támogatottak a windowsos partíciók gyökerében helyi mappaként. Válasszon érvényes almappát a meghajtó betűjele alatt. %1 folder "%2" is synced to local folder "%3" - + A(z) „%2” %1 mappa szinkronizálva van a(z) „%3” helyi mappába Sync the folder "%1" - + A(z) „%1” mappa szinkronizálása @@ -2976,37 +3078,37 @@ Használata nem ajánlott. Időtúllépés az ehhez kapcsolódás közben: %1, itt: %2. - + Trying to connect to %1 at %2 … Kapcsolódási kísérlet ehhez: %1, itt: %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. A hitelesített kiszolgálókérés át lett irányítva ide: „%1”. Az URL hibás, a kiszolgáló rosszul van beállítva. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + A hitelesített kiszolgálókérés át lett irányítva ide: „%1”. Az URL hibás, a kiszolgáló rosszul van beállítva. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. A hozzáférést megtagadta a kiszolgáló. Annak ellenőrzéséhez, hogy a megfelelő hozzáféréssel rendelkezik, <a href="%1">kattintson ide</a> a szolgáltatás böngészőből történő eléréséhez. - + There was an invalid response to an authenticated WebDAV request Érvénytelen válasz érkezett a hitelesített WebDAV kérésre - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> A helyi %1 mappa már létezik, állítsa be a szinkronizálását.<br/><br/> - + Creating local sync folder %1 … A(z) %1 helyi szinkronizálási mappa létrehozása… @@ -3016,84 +3118,84 @@ Használata nem ajánlott. ok - + OK OK - + failed. sikertelen. - + Could not create local folder %1 A(z) %1 helyi mappa nem hozható létre - + No remote folder specified! Nincs távoli mappa megadva! - + Error: %1 Hiba: %1 - + creating folder on Nextcloud: %1 mappa létrehozása a Nextcloudon: %1 - + Remote folder %1 created successfully. A(z) %1 távoli mappa sikeresen létrehozva. - + The remote folder %1 already exists. Connecting it for syncing. A(z) %1 távoli mappa már létezik. Kapcsolódás a szinkronizáláshoz. - - + + The folder creation resulted in HTTP error code %1 A könyvtár létrehozása HTTP %1 hibakódot eredményezett - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> A távoli mappa létrehozása meghiúsult, mert a megadott hitelesítő adatok hibásak.<br/>Lépjen vissza, és ellenőrizze az adatait.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">A távoli mappa létrehozása sikertelen, valószínűleg azért, mert hibás hitelesítési adatokat adott meg.</font><br/>Lépjen vissza, és ellenőrizze az adatait.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. A távoli %1 mappa létrehozása meghiúsult, hibaüzenet: <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. A szinkronizálási kapcsolat a(z) %1 és a(z) %2 távoli mappa között létrejött. - + Successfully connected to %1! Sikeresen kapcsolódva ehhez: %1! - + Connection to %1 could not be established. Please check again. A kapcsolat a(z) %1 kiszolgálóval nem hozható létre. Ellenőrizze újra. - + Folder rename failed A mappa átnevezése nem sikerült @@ -3103,28 +3205,28 @@ Használata nem ajánlott. Nem távolíthatja el és készíthet biztonsági másolatot egy mappáról, mert a mappa, vagy egy benne lévő fájl meg van nyitva egy másik programban. Zárja be a mappát vagy fájlt, és nyomja meg az újrapróbálkozást, vagy szakítsa meg a beállítást. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Nem távolíthatja el és készíthet biztonsági másolatot egy mappáról, mert a mappa, vagy egy benne lévő fájl meg van nyitva egy másik programban. Zárja be a mappát vagy fájlt, és nyomja meg az újrapróbálkozást, vagy szakítsa meg a beállítást. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>A(z) %1 helyi szinkronizációs mappa sikeresen létrehozva.</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 kapcsolódási varázsló - Add %1 account %1 fiók hozzáadása + + + %1 Connection Wizard + %1 kapcsolódási varázsló + Skip folders configuration @@ -3163,24 +3265,6 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Maradjon biztonságban - - OCC::OwncloudWizardResultPage - - - Everything set up! - Minden beállítva! - - - - Open Local Folder - Helyi mappa megnyitása - - - - Open %1 in Browser - %1 megnyitása böngészőben - - OCC::PollJob @@ -3191,6 +3275,16 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + A fájl záró szóközöket tartalmaz, és nem lehetett átnevezni, mert egy azonos nevű fájl már létezik a szerveren. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + A fájl záró szóközöket tartalmaz, és nem lehetett átnevezni, mert egy azonos nevű fájl már létezik a helyi számítógépen. + Symbolic links are not supported in syncing. @@ -3208,13 +3302,13 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze - File names containing the character "%1" are not supported on this file system. - + File names containing the character '%1' are not supported on this file system. + A(z) „%1” karaktert tartalmazó fájlnevek nem támogatottak ezen a fájlrendszeren. - - File names containing the character '%1' are not supported on this file system. - A(z) '%1' karaktert tartalmazó fájlnevek nem támogatottak ebben a fájlrendszerben. + + File names containing the character "%1" are not supported on this file system. + A(z) „%1” karaktert tartalmazó fájlnevek nem támogatottak ezen a fájlrendszeren. @@ -3239,32 +3333,32 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze File/Folder is ignored because it's hidden. - A fájlt / mappát figyelmen kívül hagyva, mivel rejtett. + A fájl/mappa figyelmen kívül hagyva, mert rejtett. Stat failed. - Stat nem sikerült. + Az elem kizárás vagy hiba miatt kihagyva. Conflict: Server version downloaded, local copy renamed and not uploaded. - Konfliktus: A kiszolgáló verziója letöltve, a helyi példány átnevezve és nincs feltöltve. + Ütközés: A kiszolgáló verziója letöltve, a helyi példány átnevezve és nem lett feltöltve. The filename cannot be encoded on your file system. - A fájlnév nem kódolható a fájlrendszerben. + A fájlnév nem kódolható a fájlrendszeren. The filename is blacklisted on the server. - A fájlnév feketelistára került a szerveren. + A fájlnév feketelistára került a kiszolgálón. File has extension reserved for virtual files. - A fájl kiterjesztése virtuális fájlokra van fenntartva. + A fájlnak virtuális fájlok számára fenntartott kiterjesztése van. @@ -3274,37 +3368,37 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze permissions - engedélyek + jogosultságok file id - fájl azonosítója + fájlazonosító server reported no %1 - szerver nem jelentett %1 + kiszolgáló jelentése: hiányzó %1 Conflict when uploading some files to a folder. Those, conflicted, are going to get cleared! - + Ütközés a fájlok mappába feltöltésekor. Az ütköző fájlok törölve lesznek! Conflict when uploading a folder. It's going to get cleared! - + Ütközés a mappa feltöltésekor. Törölve lesz! Conflict when uploading a file. It's going to get removed! - + Ütközés a fájl feltöltésekor. Törölve lesz! Ignored because of the "choose what to sync" blacklist - A "válassza ki a szinkronizálni kívánt elemeket" feketelista miatt figyelmen kívül hagyva + A „válassza ki a szinkronizálni kívánt elemeket” feketelista miatt figyelmen kívül hagyva @@ -3319,12 +3413,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Not allowed to upload this file because it is read-only on the server, restoring - Nem lehet ezt a fájlt feltölteni, mert csak olvasható a szerveren, visszaállítva + Ezt a fájlt nem lehet feltölteni, mert csak olvasható a kiszolgálón, helyreállítás Moved to invalid target, restoring - Érvénytelen célba mozgatás, visszaállítás + Érvénytelen célba mozgatás, helyreállítás @@ -3334,17 +3428,17 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error while reading the database - Hiba történt az adatbázis olvasása közben + Hiba történt az adatbázis olvasása során Server replied with an error while reading directory '%1' : %2 - A kiszolgáló a következő hibával válaszolt a(z) '%1' könyvtár olvasása közben: % 2 + A kiszolgáló a következő hibával válaszolt a(z) „%1” könyvtár olvasása során: %2 - + Server replied with an error while reading directory "%1" : %2 - + A kiszolgáló a következő hibával válaszolt a(z) „%1” könyvtár olvasása során: %2 @@ -3357,12 +3451,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error updating metadata: %1 - + Hiba a metaadatok frissítésekor: %1 File is currently in use - + A fájl jelenleg használatban van @@ -3422,7 +3516,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze The downloaded file is empty, but the server said it should have been %1. - + A letöltött fájl üres, de a kiszolgáló szerint %1 méretűnek kellene lennie. @@ -3437,12 +3531,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error updating metadata: %1 - + Hiba a metaadatok frissítésekor: %1 The file %1 is currently in use - A %1 fájl épp használatban van + A(z) %1 fájl épp használatban van @@ -3473,7 +3567,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Could not create folder %1 - + A(z) %1 mappa nem hozható létre @@ -3483,12 +3577,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error updating metadata: %1 - + Hiba a metaadatok frissítésekor: %1 The file %1 is currently in use - + A(z) %1 fájl jelenleg használatban van @@ -3529,12 +3623,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error updating metadata: %1 - + Hiba a metaadatok frissítésekor: %1 The file %1 is currently in use - A %1 fájl épp használatban van + A(z) %1 fájl épp használatban van @@ -3566,7 +3660,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Wrong HTTP code returned by server. Expected 204, but received "%1 %2". - A kiszolgáló helytelen HTTP-kódot adott vissza. 204-re várt, de az érték "%1 %2" volt. + A kiszolgáló helytelen HTTP-kódot adott vissza. 204-et várt, de az érték "%1 %2" volt. @@ -3584,12 +3678,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error writing metadata to the database: %1 - + Hiba a metaadatok adatbázisba írásakor: %1 The file %1 is currently in use - A %1 fájl épp használatban van + A(z) %1 fájl épp használatban van @@ -3597,7 +3691,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Could not rename %1 to %2, error: %3 - A(z) %1, nem nevezhető át erre: %2, hiba: %3 + A(z) %1 nem nevezhető át erre: %2, hiba: %3 @@ -3607,12 +3701,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error updating metadata: %1 - + Hiba a metaadatok frissítésekor: %1 The file %1 is currently in use - + A(z) %1 fájl jelenleg használatban van @@ -3661,7 +3755,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Failed to unlock encrypted folder. - Nem sikerült a titkosított mappa feloldása. + Nem sikerült feloldani a titkosított mappát. @@ -3671,12 +3765,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Error updating metadata: %1 - + Hiba a metaadatok frissítésekor: %1 The file %1 is currently in use - A %1 fájl épp használatban van + A(z) %1 fájl épp használatban van @@ -3935,7 +4029,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Set password - + Jelszó beállítása @@ -3957,11 +4051,6 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Allow Editing Szerkesztés engedélyezése - - - Allow editing - Szerkesztés engedélyezése - Read only @@ -3982,6 +4071,16 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Password Protect Jelszavas védelem + + + Allow editing + Szerkesztés engedélyezése + + + + View only + Csak megtekintés + Allow upload and editing @@ -3997,20 +4096,25 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze File drop (upload only) Fájl ejtés (csak feltöltés) - - - Note to recipient - Jegyzet a címzettnek - Unshare Megosztás visszavonása + + + Link name + Hivatkozás neve + + + + Note to recipient + Jegyzet a címzettnek + Password protect - Jelszóvédelem + Jelszavas védelem @@ -4018,15 +4122,20 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Lejárati idő beállítása - - Delete share link - Megosztási hivatkozás törlése + + Delete link + Hivatkozás törlése Add another link Egyéb hivatkozás hozzáadása + + + Delete share link + Megosztási hivatkozás törlése + Confirm Link Share Deletion @@ -4063,7 +4172,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Search globally - Keresés mindenben + Keresés globálisan @@ -4076,19 +4185,19 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Nincs találat erre: „%1” - + No results for "%1" - + Nincs találat erre: „%1” Password for share required - + A megosztáshoz jelszó szükséges Please enter a password for your email share: - + Adjon meg egy jelszót a levélmegosztáshoz: @@ -4111,22 +4220,22 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Can edit - + Szerkesztheti Note: - + Megjegyzés: Password: - + Jelszó: Expires: - + Lejárat: @@ -4136,12 +4245,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Note to recipient - + Jegyzet a címzettnek Set expiration date - + Lejárati idő beállítása @@ -4166,7 +4275,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Password protect - + Jelszavas védelem @@ -4180,12 +4289,6 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Megosztás vele: %1 - Context menu share @@ -4194,7 +4297,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Select new location … - Új hely kiválasztása … + Új hely kiválasztása… @@ -4212,6 +4315,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Share via %1 Megosztás ezzel: %1 + + + + Activity + Tevékenység + Copy private link to clipboard @@ -4230,7 +4339,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Resharing this folder is not allowed - A mappa újramegosztása nem megengedett + A mappa továbbosztása nem megengedett @@ -4256,17 +4365,17 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Resolve conflict … - Konfliktus feloldása … + Konfliktus feloldása… Move and rename … - Áthelyezés és átnevezés … + Áthelyezés és átnevezés… Move, rename and upload … - Áthelyezés, átnevezés és feltöltés … + Áthelyezés, átnevezés és feltöltés… @@ -4276,13 +4385,19 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Move and upload … - Áthelyezés és feltöltés … + Áthelyezés és feltöltés… Delete Törlés + + + Share with %1 + parameter is Nextcloud + Megosztás vele: %1 + OCC::SslButton @@ -4428,6 +4543,11 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Cannot connect securely to <i>%1</i>: Nem sikerült biztonságosan kapcsolódni ide: <i>%1</i>: + + + Additional errors: + További hibák: + with Certificate %1 @@ -4602,6 +4722,11 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Placeholders are postfixed with file sizes using Utility::octetsToString() Csak %1 érhető el, de legalább %2 kell az indításhoz + + + Aborted + Megszakítva + @@ -4754,27 +4879,88 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Invalid characters, please rename "%1" Érvénytelen karakterek, nevezze át: „%1” + + + Synchronization will resume shortly. + A szinkronizálás rövidesen folytatódik. + File name contains at least one invalid character A fájlnév legalább egy érvénytelen karaktert tartalmaz - - Aborted - Megszakítva - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Túl kevés a tárterület: A letöltések, melyek %1 alá csökkentették volna a szabad tárhelyet, kihagyásra kerültek. - + There is insufficient space available on the server for some uploads. Egyes feltöltésekhez nincs elég hely a kiszolgálón. + + OCC::SyncStatusSummary + + + + Offline + Offline + + + + + + All synced! + Minden szinkronizálva! + + + + Some files couldn't be synced! + Néhány fájlt nem lehet szinkronizálni! + + + + See below for errors + A hibákat lásd lent + + + + Syncing + Szinkronizálás + + + + Sync paused + Szinkronizálás szüneteltetve + + + + Some files could not be synced! + Néhány fájlt nem lehet szinkronizálni. + + + + See below for warnings + A figyelmeztetéseket lásd lent + + + + %1 of %2 · %3 left + %1 / %2 · %3 van hátra + + + + %1 of %2 + %1 / %2 + + + + Syncing file %1 of %2 + %1 / %2 fájl szinkronizálása + + OCC::Systray @@ -4785,7 +4971,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Open main dialog - Fő ablak megnyitása + Főablak megnyitása @@ -4807,7 +4993,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Exit %1 - Kilépés %1 + Kilépés a %1ból @@ -4837,12 +5023,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze <p>Version %1. For more information please click <a href='%2'>here</a>.</p> - <p>%1 verzió. További információkért kattintson <a href='%2'>ide</a>.</p> + <p>Verzió: %1. További információkért kattintson <a href='%2'>ide</a>.</p> <p><small>Using virtual files plugin: %1</small></p> - + <p><small>Virtuális fájlok bővítmény használata: %1</small></p> @@ -4850,6 +5036,29 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze <p>Ezt a kiadást a %1 biztosította</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + A szolgáltatók lekérése sikertelen + + + + Failed to fetch search providers for '%1'. Error: %2 + A(z) „%1” keresésszolgáltatóinak lekérése sikertelen. Hiba: %2 + + + + Search has failed for '%2'. + A keresés a következőre sikertelen: „%2”. + + + + Search has failed for '%1'. Error: %2 + A keresés a következőre sikertelen: „%1”. Hiba: %2 + + OCC::User @@ -4860,7 +5069,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Synced %1 - Szinkronizálva %1 + %1 szinkronizálva @@ -4903,28 +5112,112 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Cancel - Mégsem + Mégse - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - A virtuális fájlrendszer szolgáltatáshoz NTFS fájlrendszerre van szükség,%1 a következőt használja: %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Az előre meghatározott állapotok nem kérhetők le. Győződjön meg róla, hogy kapcsolódik a kiszolgálóhoz. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - + + Could not fetch user status. Make sure you are connected to the server. + A felhasználói állapot nem kérhető le. Győződjön meg róla, hogy kapcsolódik a kiszolgálóhoz. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Úgy néz ki, hogy egy végpontok közti titkosítással ellátott virtuális fájlt akar letölteni. Az ilyen fájlok implicit letöltése jelenleg nem támogatott. Kerülőmegoldásként menjen a beállításokba, és kapcsolja be hogy mindig elérhető legyen helyben is. + + User status feature is not supported. You will not be able to set your user status. + A felhasználói állapot funkció nem támogatott. Nem fog tudni egyéni állapotot beállítani. + + + + Emojis feature is not supported. Some user status functionality may not work. + Az emodzsi funkció nem támogatott. Egyes állapotfunkciók lehet, hogy nem fognak működni. + + + + Could not set user status. Make sure you are connected to the server. + A felhasználói állapot nem állítható be. Győződjön meg róla, hogy kapcsolódik a kiszolgálóhoz. + + + + Could not clear user status message. Make sure you are connected to the server. + A felhasználói állapot nem törölhető. Győződjön meg róla, hogy kapcsolódik a kiszolgálóhoz. + + + + + Don't clear + Ne törölje + + + + 30 minutes + 30 perc + + + + + 1 hour + 1 óra + + + + 4 hours + 4 óra + + + + + Today + Ma + + + + + This week + Ezen a héten + + + + Less than a minute + Kevesebb mint egy perc + + + + 1 minute + 1 perc + + + + %1 minutes + %1 perc + + + + %1 hours + %1 óra + + + + 1 day + 1 nap + + + + %1 days + %1 nap + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + A virtuális fájlrendszer szolgáltatáshoz NTFS fájlrendszerre van szükség, a(z) %1 a következőt használja: %2 @@ -4950,7 +5243,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze You have been logged out of %1 as user %2. Please login again. - %2 felhasználóként kijelentkezett innen: %1. Kérjük, jelentkezzen be újra. + %2 felhasználóként kijelentkezett innen: %1. Jelentkezzen be újra. @@ -4999,7 +5292,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Host your own server - Működtesse saját szerverét + Saját kiszolgáló üzemeltetése @@ -5017,7 +5310,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze The server on account %1 runs an unsupported version %2. Using this client with unsupported server versions is untested and potentially dangerous. Proceed at your own risk. - A(z) %1 fiók kiszolgálója nem támogatott verziót (%2) futtat. Ennek a kliensnek a nem támogatott szerver verziókkal történő használata nem tesztelt és potenciálisan veszélyes. Folytatás kizárólag saját felelősségére. + A(z) %1 fiók kiszolgálója nem támogatott verziót (%2) futtat. Ennek a kliensnek a nem támogatott kiszolgálóverziókkal történő használata nem tesztelt és potenciálisan veszélyes. Folytatás kizárólag saját felelősségére. @@ -5133,7 +5426,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Checking for changes in remote "%1" - + Változások keresése a(z) „%1” távoli mappában @@ -5143,7 +5436,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Checking for changes in local "%1" - + Változások keresése a(z) „%1” helyi mappában @@ -5267,7 +5560,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Server address - Szerver címe + Kiszolgálócím @@ -5282,7 +5575,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Sync Logo - Szinkronizálása logó + Szinkronizálás logó @@ -5297,7 +5590,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Synchronize everything from server - Szinkronizáljon a szerverről mindent + Minden szinkronizálása a kiszolgálóról @@ -5398,12 +5691,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Logo - Logo + Logó Server address - Szerver címe + Kiszolgálócím @@ -5413,12 +5706,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze This is the link to your %1 web interface when you open it in the browser.<br/>It looks like https://cloud.example.com or https://example.com/cloud - Ez a link a(z) %1 webes felületére, amikor a böngészőben megnyitja. <br/> Úgy néz ki, mint https://cloud.example.com vagy https://example.com/cloud + Ez egy hivatkozás a(z) %1 webes felületére, ha böngészőben nyitja meg. <br/>Ezekhez hasonló: https://cloud.example.com vagy https://example.com/cloud This is the link to your %1 web interface when you open it in the browser. - Ez a(z) %1 webes felületre mutató link, amikor megnyitja a böngészőben. + Ez a(z) %1 webes felületre mutató hivatkozás, ha a böngészőben nyitja meg. @@ -5428,7 +5721,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Sign up with a provider - Iratkozzon fel egy szolgáltatóhoz + Regisztráció egy szolgáltatóval @@ -5441,14 +5734,6 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Jelentkezzen be: %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - A teljes fiókja szinkronizálásra került a helyi mappába. - - QObject @@ -5541,6 +5826,38 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Az adatbázishoz való kapcsolódás sikertelen. + + UnifiedSearchInputContainer + + + Search files, messages, events … + Fájlok, üzenetek, események keresése… + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + További találatok betöltése + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Keresési találatok vázlata. + + + + UnifiedSearchResultListItem + + + Load more results + További találatok betöltése + + UserLine @@ -5555,29 +5872,39 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze - Current user status is online - A jelenlegi felhasználói állapot online + Account connected + Fiók csatlakoztatva - Current user status is do not disturb - A jelenlegi felhasználói állapot ne zavarjanak + Account not connected + A fiók nincs összekapcsolva - Account connected - Fiók csatlakoztatva + Current user status is online + Jelenlegi felhasználói állapot: online - Account not connected - A fiók nincs összekapcsolva + Current user status is do not disturb + Jelenlegi felhasználói állapot: ne zavarjanak Account actions Fiókműveletek + + + Remove Account + Fiók törlése + + + + Set status + Állapot beállítása + @@ -5590,17 +5917,65 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Log in Bejelentkezés - - - Remove Account - Fiók törlése - Remove account Fiók eltávolítása + + UserStatusSelector + + + Online status + Online állapot + + + + Online + Online + + + + Away + Távol + + + + Do not disturb + Ne zavarjanak + + + + Invisible + Láthatatlan + + + + Status message + Állapotüzenet + + + + What is your status? + Mi az állapota? + + + + Clear status message after + Állapotüzenet törlése ennyi idő után: + + + + Clear status message + Állapotüzenet törlése + + + + Set status message + Állapotüzenet beállítása + + Utility @@ -5662,34 +6037,34 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze ValidateChecksumHeader - + The checksum header is malformed. Az ellenőrzőösszeg fejléc rosszul formázott. - + The checksum header contained an unknown checksum type '%1' Az ellenőrzőösszeg fejléc ismeretlen típusú értéket tartalmazott: „%1” The downloaded file does not match the checksum, it will be resumed. - A letöltött fájl nem felel meg az ellenőrzőösszegénet, újra le lesz töltve. + A letöltött fájl ellenőrzőösszege nem egyezik, újra le lesz töltve. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - A letöltött fájl ellenőrző összege nem helyes, folytatni fogjuk. '%1'!='% 2' + A letöltött fájl ellenőrzőösszege nem egyezik, újra le lesz töltve. „%1” != „%2” - + The checksum header contained an unknown checksum type "%1" - + Az ellenőrzőösszeg fejléc ismeretlen típusú értéket tartalmazott: „%1” - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" - + A letöltött fájl ellenőrzőösszege nem egyezik, újra le lesz töltve. „%1” != „%2” @@ -5697,7 +6072,7 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Nextcloud desktop main dialog - A Nextcloud asztali alkalmazás főablak + A Nextcloud asztali alkalmazás főablaka @@ -5716,6 +6091,11 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Pause sync for all Szinkronizálás szüneteltetése mindenkinek + + + Set user status + Felhasználó állapotának beállítása + Add account @@ -5739,23 +6119,17 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Current user avatar - Jelenlegi felhasználói avatár + Jelenlegi felhasználói profilkép Current user status is online - A jelenlegi felhasználói állapot online + Jelenlegi felhasználói állapot: online Current user status is do not disturb - A jelenlegi felhasználói állapot ne zavarjanak - - - - - Show more actions - További műveletek megjelenítése + Jelenlegi felhasználói állapot: ne zavarjanak @@ -5780,12 +6154,12 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Open local folder of current account - Az aktuális fiók helyi mappájának megnyitása + A jelenlegi fiók helyi mappájának megnyitása Open Nextcloud Talk in browser - A Nextcloud Talk alkalmazás megnyitása böngészőben + A Nextcloud Beszélgetés alkalmazás megnyitása böngészőben @@ -5810,30 +6184,46 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Open %1 locally - Nyissa meg helyben ezt: %1 + A(z) %1 megnyitása helyben Open share dialog Megosztási párbeszédpanel megnyitása + + + Unified search results list + Egyesített keresési találatlista + + + + + Show more actions + További műveletek megjelenítése + + + + %1 - File activity + %1 – Fájl tevékenység + main.cpp System Tray not available - Rendszertálca nem érhető el + Nem érhető el értesítési terület %1 requires on a working system tray. If you are running XFCE, please follow <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">these instructions</a>. Otherwise, please install a system tray application such as 'trayer' and try again. - A(z) %1 használatához szükséges egy működő rendszertálcára. Ha XFCE-t használ, akkor kövesse <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">ezt az útmutatót</a>. Egyébként, telepítsen egy rendszertálca alkalmazást – mint például a „trayer” – és próbálja újra. + A(z) %1 használatához szükséges egy értesíési terület. Ha XFCE-t használ, akkor kövesse <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">ezt az útmutatót</a>. Egyébként, telepítsen egy értesítési terület alkalmazást – mint például a „trayer” – és próbálja újra. %1 requires on a working system tray. If you are running XFCE, please follow <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">these instructions</a>. Otherwise, please install a system tray application such as "trayer" and try again. - A(z) %1 használatához működő rendszertálcára van szükség. Ha XFCE-t használ, akkor kövesse <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">ezt az útmutatót</a>. Egyébként, telepítsen egy rendszertálca alkalmazást – mint például a „trayer” – és próbálja újra. + A(z) %1 használatához működő értesítési területre van szükség. Ha XFCE-t használ, akkor kövesse <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">ezt az útmutatót</a>. Egyébként, telepítsen egy értesítési terület alkalmazást – mint például a „trayer” – és próbálja újra. @@ -6116,6 +6506,24 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Bejelentkezés böngészőben (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Minden beállítva! + + + + Open Local Folder + Helyi mappa megnyitása + + + + Open %1 in Browser + %1 megnyitása böngészőben + + OCC::ShibbolethCredentials @@ -6168,6 +6576,14 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Bejelentkezés + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + A teljes fiókja szinkronizálásra került a helyi mappába. + + OCC::UserStatus @@ -6191,4 +6607,17 @@ Ez egy új, kísérleti mód. Ha úgy dönt, hogy használja, kérjük, jelezze Online + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + A végpontok közötti titkosítással rendelkező fájl letöltése sikertelen + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Úgy néz ki, hogy egy végpontok közti titkosítással ellátott virtuális fájlt akar letölteni. Az ilyen fájlok implicit letöltése jelenleg nem támogatott. Kerülőmegoldásként menjen a beállításokba, és kapcsolja be, hogy mindig elérhető legyen helyben is. + + \ No newline at end of file diff --git a/translations/client_id.ts b/translations/client_id.ts index a1f6e77eea2d..42493c11b82f 100644 --- a/translations/client_id.ts +++ b/translations/client_id.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1330,6 +1343,13 @@ Ini artinya sinkronisasi klien mungkin tidak menggunggah perubahan lokal seseger %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1385,22 +1405,7 @@ Melanjutkan sinkronisasi seperti biasanya akan menyebabkan semua berkas Anda dit Buat Berkas Lokal sebagai Konflik - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1408,7 +1413,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1424,6 +1429,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2250,6 +2263,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2386,7 +2462,7 @@ Logs will be written to %1 <nobr>Berkas '%1'<br/>tidak dapat dibuka untuk ditulis.<br/><br/>Keluaran log <b>tidak</b>dapat disimpan!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2429,6 +2505,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2598,6 +2679,13 @@ Logs will be written to %1 New %1 Update Ready %1 Pembaruan Baru Siap + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Sebuah pembaruan baru untuk %1 akan dipasang. Pemasang pembaruan mungkin akan meminta +beberapa ijin pada saat proses berjalan. + New %1 update ready @@ -2605,10 +2693,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Sebuah pembaruan baru untuk %1 akan dipasang. Pemasang pembaruan mungkin akan meminta -beberapa ijin pada saat proses berjalan. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2645,6 +2731,11 @@ beberapa ijin pada saat proses berjalan. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2655,6 +2746,11 @@ beberapa ijin pada saat proses berjalan. Could not check for new updates. Tidak dapat mengecek pembaruan baru. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2950,37 +3046,37 @@ It is not advisable to use it. Waktu habis saat mencoba untuk menghubungkan ke %1 di %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Permintaan autentikasi ke server telah dialihkan ke '%1'. URL sangat buruk, server salah konfigurasi. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Akses ditolak dari server. Untuk memverifikasi bahwa Anda memiliki akses yang benar, <a href="%1">klik disini</a> untuk akses ke layanan dengan peramban Anda. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Folder sinkronisasi lokal %1 sudah ada, mengatur untuk disinkronisasi.<br/><br/> - + Creating local sync folder %1 … @@ -2990,84 +3086,84 @@ It is not advisable to use it. ok - + OK - + failed. gagal. - + Could not create local folder %1 Tidak dapat membuat folder lokal %1 - + No remote folder specified! Tidak ada folder remote yang ditentukan! - + Error: %1 Galat: %1 - + creating folder on Nextcloud: %1 Membuat folder di Nextcloud: %1 - + Remote folder %1 created successfully. Folder remote %1 sukses dibuat. - + The remote folder %1 already exists. Connecting it for syncing. Folder remote %1 sudah ada. Menghubungkan untuk sinkronisasi. - - + + The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! - + Connection to %1 could not be established. Please check again. - + Folder rename failed @@ -3077,12 +3173,12 @@ It is not advisable to use it. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> @@ -3090,13 +3186,13 @@ It is not advisable to use it. OCC::OwncloudWizard - - %1 Connection Wizard + + Add %1 account - - Add %1 account + + %1 Connection Wizard @@ -3131,24 +3227,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - - - - - Open Local Folder - - - - - Open %1 in Browser - - - OCC::PollJob @@ -3159,6 +3237,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3176,12 +3264,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3310,7 +3398,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3925,11 +4013,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Izinkan penyuntingan - Read only @@ -3950,6 +4033,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + Izinkan penyuntingan + + + + View only + + Allow upload and editing @@ -3965,16 +4058,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Berkas jatuh (hanya unggah) - - - Note to recipient - Catatan untuk penerima - Unshare + + + Link name + + + + + Note to recipient + Catatan untuk penerima + Password protect @@ -3986,15 +4084,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Atur tanggal kedaluwarsa - - Delete share link - Hapus tautan berbagi + + Delete link + Add another link Tambah tautan lain + + + Delete share link + Hapus tautan berbagi + Confirm Link Share Deletion @@ -4044,7 +4147,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + No results for "%1" @@ -4148,12 +4251,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4180,6 +4277,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4251,6 +4354,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Hapus + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4394,6 +4503,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4568,6 +4682,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() + + + Aborted + + @@ -4721,26 +4840,87 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - File name contains at least one invalid character + + Synchronization will resume shortly. - - Aborted + + File name contains at least one invalid character - + Disk space is low: Downloads that would reduce free space below %1 were skipped. - + There is insufficient space available on the server for some uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4816,6 +4996,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4873,23 +5076,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5407,14 +5694,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - - - QObject @@ -5507,6 +5786,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5521,22 +5832,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Akun terhubung - Current user status is do not disturb + Account not connected - Account connected - Akun terhubung + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5544,6 +5855,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + + + + + Set status + + @@ -5556,17 +5877,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Log masuk - - - Remove Account - - Remove account Hapus akun + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5628,12 +5997,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5643,17 +6012,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5682,6 +6051,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5717,12 +6091,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5783,6 +6151,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6082,6 +6466,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + + + + + Open Local Folder + + + + + Open %1 in Browser + + + OCC::ShibbolethCredentials @@ -6134,6 +6536,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + + + OCC::UserStatus @@ -6157,4 +6567,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_is.ts b/translations/client_is.ts index 7a0a887583e9..7b7f58f6258a 100644 --- a/translations/client_is.ts +++ b/translations/client_is.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1142,32 +1155,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization Bíð eftir auðkenningu - + Polling for authorization Er á vakt eftir auðkenningu - + Starting authorization Ræsi auðkenningu - + Link copied to clipboard. Tengill afritaður á klippispjald. - + Reopen Browser - + Copy Link @@ -1334,6 +1347,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1387,22 +1407,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Halda skrám á tölvunni við árekstra - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1410,7 +1415,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1426,6 +1431,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2251,6 +2264,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Bæta við nýju hunsunarmynstri: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2386,7 +2462,7 @@ Logs will be written to %1 - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2430,6 +2506,11 @@ niðurhals. Uppsetta útgáfan er %3.</p> <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2599,6 +2680,12 @@ niðurhals. Uppsetta útgáfan er %3.</p> New %1 Update Ready Ný %1 uppfærsla tiltæk + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + + New %1 update ready @@ -2606,8 +2693,7 @@ niðurhals. Uppsetta útgáfan er %3.</p> - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. @@ -2645,6 +2731,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2655,6 +2746,11 @@ for additional privileges during the process. Could not check for new updates. Gat ekki athugað með nýjar uppfærslur. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2954,37 +3050,37 @@ Ekki er mælt með því að hún sé notuð. Féll á tíma þegar reynt var að tengjast við %1 á %2. - + Trying to connect to %1 at %2 … Reyni að tengjast við %1 á %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> - + Creating local sync folder %1 … Bý til staðværu samstillingarmöppuna %1 … @@ -2994,84 +3090,84 @@ Ekki er mælt með því að hún sé notuð. Í lagi - + OK - + failed. mistókst. - + Could not create local folder %1 Gat ekki búið til staðværu möppuna %1 - + No remote folder specified! Engin fjartengd mappa tilgreind! - + Error: %1 Villa: %1 - + creating folder on Nextcloud: %1 bý til möppu á Nextcloud: %1 - + Remote folder %1 created successfully. Það tókst að búa til fjartengdu möppuna %1. - + The remote folder %1 already exists. Connecting it for syncing. - - + + The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! Tenging við %1 tókst! - + Connection to %1 could not be established. Please check again. Ekki tókst að koma á tengingu við %1. Prófaðu aftur. - + Folder rename failed Endurnefning möppu mistókst @@ -3081,28 +3177,28 @@ Ekki er mælt með því að hún sé notuð. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Það tókst að búa til staðværu möppuna %1!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 tengingaleiðarvísir - Add %1 account + + + %1 Connection Wizard + %1 tengingaleiðarvísir + Skip folders configuration @@ -3135,24 +3231,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Allt er uppsett! - - - - Open Local Folder - Opna staðværa möppu - - - - Open %1 in Browser - Opna %1 í vafra - - OCC::PollJob @@ -3163,6 +3241,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3180,12 +3268,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3314,7 +3402,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3929,11 +4017,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Leyfa breytingar - - - Allow editing - Leyfa breytingar - Read only @@ -3954,6 +4037,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Verja með lykilorði + + + Allow editing + Leyfa breytingar + + + + View only + + Allow upload and editing @@ -3969,16 +4062,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Slepping skráa (einungis innsending) - - - Note to recipient - Minnispunktur til viðtakanda - Unshare Hætta deilingu + + + Link name + + + + + Note to recipient + Minnispunktur til viðtakanda + Password protect @@ -3990,15 +4088,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Setja gildistíma - - Delete share link - Eyða tengli á sameign + + Delete link + Add another link Bæta við öðrum tengli + + + Delete share link + Eyða tengli á sameign + Confirm Link Share Deletion @@ -4049,7 +4152,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Engar niðurstöður fyrir '%1' - + No results for "%1" @@ -4153,12 +4256,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Deila með %1 - Context menu share @@ -4185,6 +4282,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Deila með %1 + + + + Activity + + Copy private link to clipboard @@ -4256,6 +4359,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Eyða + + + Share with %1 + parameter is Nextcloud + Deila með %1 + OCC::SslButton @@ -4401,6 +4510,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Get ekki tengst á öruggan hátt við <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4575,6 +4689,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Einungis %1 eru tiltæk, þarf a.m.k. %2 til að ræsa + + + Aborted + + @@ -4727,24 +4846,85 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Ógildir stafir, endurnefndu "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Skráarheitið inniheldur að minnsta kosti einn ógildan staf - - Aborted + + Disk space is low: Downloads that would reduce free space below %1 were skipped. - - Disk space is low: Downloads that would reduce free space below %1 were skipped. + + There is insufficient space available on the server for some uploads. + + + OCC::SyncStatusSummary - - There is insufficient space available on the server for some uploads. + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 @@ -4823,6 +5003,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Þessi útgáfa var gefin út af %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4881,23 +5084,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5415,14 +5702,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Allt á notandaaðgangnum þínum er samstillt við staðværu möppuna - - QObject @@ -5515,6 +5794,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5529,22 +5840,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Aðgangur er tengdur - Current user status is do not disturb + Account not connected - Account connected - Aðgangur er tengdur + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5552,6 +5863,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Aðgerðir fyrir aðgang + + + Remove Account + Fjarlægja aðgang + + + + Set status + + @@ -5564,17 +5885,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Skrá inn - - - Remove Account - Fjarlægja aðgang - Remove account Fjarlægja reikning + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5636,12 +6005,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5651,17 +6020,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5690,6 +6059,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Gera hlé á samstillingu fyrir allt + + + Set user status + + Add account @@ -5725,12 +6099,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5791,6 +6159,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Opna deilingarglugga + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6097,6 +6481,24 @@ sjálfgefið? Skráðu þig inn í vafranum þínum (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Allt er uppsett! + + + + Open Local Folder + Opna staðværa möppu + + + + Open %1 in Browser + Opna %1 í vafra + + OCC::ShibbolethCredentials @@ -6150,6 +6552,14 @@ sjálfgefið? Skrá inn + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Allt á notandaaðgangnum þínum er samstillt við staðværu möppuna + + OCC::UserStatus @@ -6173,4 +6583,17 @@ sjálfgefið? + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_it.ts b/translations/client_it.ts index bdb3a85af848..cc94d2103743 100644 --- a/translations/client_it.ts +++ b/translations/client_it.ts @@ -14,12 +14,6 @@ Open %1 locally Apri %1 localmente - - - - Show more actions - Mostra altre azioni - Open share dialog @@ -30,6 +24,25 @@ Share %1 Condividi %1 + + + + Show more actions + Mostra altre azioni + + + + View activity + Vedi attività + + + + ActivityList + + + Activity list + Lista attività + CloudProviderWrapper @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" Impossibile spostare "%1" in "%2" @@ -1144,32 +1157,32 @@ Questo può essere un problema delle le tue librerie OpenSSL. Impossibile aprire il browser, copia il collegamento nel tuo browser. - + Waiting for authorization In attesa di autorizzazione - + Polling for authorization Richiesta di autorizzazione - + Starting authorization Avvio autorizzazione - + Link copied to clipboard. Collegamento copiato negli appunti. - + Reopen Browser Riapri browser - + Copy Link Copia collegamento @@ -1338,6 +1351,15 @@ This means that the synchronization client might not upload local changes immedi Questo significa che il client di sincronizzazione potrebbe non caricare le modifiche locali immediatamente e, invece, eseguirà solo la scansione delle modifiche locali e le caricherà occasionalmente (ogni due ore, in modo predefinito). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Tutti i file nella cartella locale di sincronizzazione '%1' sono stati eliminati. Queste eliminazioni saranno sincronizzate con il tuo server, rendendo tali file indisponibili, a meno di un ripristino. +Sei sicuro di voler sincronizzare queste azioni con il server? +Se è stato un errore e decidi di tenere i file, saranno sincronizzati nuovamente dal server. @@ -1399,27 +1421,7 @@ Se continui normalmente la sincronizzazione provocherai la sovrascrittura di tut Mantieni i file locali come conflitto - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Tutti i file nella cartella di sincronizzazione '%1' sono stati eliminati sul server. -Queste eliminazioni saranno sincronizzate con la tua cartella locale, rendendo tali file indisponibili, a meno che tu abbia il permesso per ripristinarli. -Se decidi di ripristinare i file, essi saranno sincronizzati nuovamente con il server, se hai i diritti per farlo. -Se decidi di eliminare i file, non saranno più disponibili, a meno che tu sia il proprietario. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Tutti i file nella cartella locale di sincronizzazione '%1' sono stati eliminati. Queste eliminazioni saranno sincronizzate con il tuo server, rendendo tali file indisponibili, a meno di un ripristino. -Sei sicuro di voler sincronizzare queste azioni con il server? -Se è stato un errore e decidi di tenere i file, saranno sincronizzati nuovamente dal server. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1430,7 +1432,7 @@ Se decidi di ripristinare i file, essi saranno sincronizzati nuovamente con il s Se decidi di eliminare i file, non saranno più disponibili, a meno che tu sia il proprietario. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1448,6 +1450,17 @@ Se è stato un errore e decidi di tenere i file, saranno sincronizzati nuovament Remove all files Rimuovi tutti i file + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Tutti i file nella cartella di sincronizzazione '%1' sono stati eliminati sul server. +Queste eliminazioni saranno sincronizzate con la tua cartella locale, rendendo tali file indisponibili, a meno che tu abbia il permesso per ripristinarli. +Se decidi di ripristinare i file, essi saranno sincronizzati nuovamente con il server, se hai i diritti per farlo. +Se decidi di eliminare i file, non saranno più disponibili, a meno che tu sia il proprietario. + Keep files @@ -2276,6 +2289,69 @@ Gli elementi per i quali è consentita l'eliminazione saranno eliminati se Aggiungi un nuovo modello di esclusione: + + OCC::InvalidFilenameDialog + + + Invalid filename + Nome del file non valido + + + + The file could not be synced because it contains characters which are not allowed on this system. + Il file non è stato sincronizzato perché contiene caratteri non consentiti in questo sistema. + + + + Error + Errore + + + + Please enter a new name for the file: + Inserisci un nome nuovo per il file: + + + + New filename + Nuovo nome del file + + + + Rename file + Rinomina file + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Il file %1 non è stato sincronizzato perché contiene caratteri non consentiti in questo sistema. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + I seguenti caratteri non sono consentiti nel sistema: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Non hai il permesso di rinominare questo file. Chiedi all'autore del file di rinominarlo. + + + + Filename contains illegal characters: %1 + Il nome del file contiene caratteri non consentiti: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Impossibile rinominare il file. Assicurati di essere connesso al server. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Impossibile rinominare il file perché ne esiste già uno con lo stesso nome sul server. Scegli un altro nome. + + OCC::LegalNotice @@ -2414,7 +2490,7 @@ I log saranno scritti in %1 <nobr>Il file '%1'<br/>non può essere aperto in scrittura.<br/><br/>Il risultato del log <b>non</b> può essere salvato!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>Il file "%1"<br/>non può essere aperto in scrittura.<br/><br/>Il risultato del log <b>non</b> può essere salvato!</nobr> @@ -2457,6 +2533,11 @@ I log saranno scritti in %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Una nuova versione del client %1 è disponibile, ma il processo di aggiornamento non è riuscito.</p><p><b>%2</b> è stato scaricato. La versione installata è %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Una nuova versione del client %1 è disponibile, ma il processo di aggiornamento non è riuscito.</p><p><b>%2</b> è stato scaricato. La versione installata è la %3. Se confermi di riavviare ed aggiornare, il computer potrebbe riavviarsi per completare l'installazione.</p> + Ask again later @@ -2626,6 +2707,12 @@ I log saranno scritti in %1 New %1 Update Ready Un nuovo aggiornamento di %1 è pronto + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Un nuovo aggiornamento di %1 sta per essere installato. L'aggiornamento potrebbe richiedere privilegi aggiuntivi durante l'avanzamento. + New %1 update ready @@ -2633,9 +2720,8 @@ I log saranno scritti in %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Un nuovo aggiornamento di %1 sta per essere installato. L'aggiornamento potrebbe richiedere privilegi aggiuntivi durante l'avanzamento. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Un nuovo aggiornamento di %1 sta per essere installato. L'aggiornamento potrebbe richiedere privilegi aggiuntivi durante l'avanzamento. Il computer potrebbe riavviarsi per completare l'installazione. @@ -2672,6 +2758,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Il nuovo %1 è disponibile. Fai clic <a href='%2'>qui</a> per scaricare l'aggiornamento. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Impossibile scaricare l'aggiornamento. Apri <a href='%1'>%1</a> per scaricare l'aggiornamento a mano. + Could not download update. Please open %1 to download the update manually. @@ -2682,6 +2773,11 @@ for additional privileges during the process. Could not check for new updates. Impossibile verificare la presenza di nuovi aggiornamenti. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Un nuovo %1 è disponibile. Apri <a href='%2'>%2</a> per scaricare l'aggiornamento. + New %1 is available. Please open %2 to download the update. @@ -2978,37 +3074,37 @@ Non è consigliabile utilizzarlo. Tempo scaduto durante il tentativo di connessione a %1 su %2. - + Trying to connect to %1 at %2 … Tentativo di connessione a %1 su %2... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. La richiesta autenticata al server è stata rediretta a '%1'. L'URL è errato, il server non è configurato correttamente. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. La richiesta autenticata al server è stata rediretta a "%1". L'URL è errato, il server non è configurato correttamente. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Accesso negato dal server. Per verificare di avere i permessi appropriati, <a href="%1">fai clic qui</a> per accedere al servizio con il tuo browser. - + There was an invalid response to an authenticated WebDAV request Ricevuta una risposta non valida a una richiesta WebDAV autenticata - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> La cartella di sincronizzazione locale %1 esiste già, impostata per la sincronizzazione.<br/><br/> - + Creating local sync folder %1 … Creazione della cartella locale di sincronizzazione %1... @@ -3018,84 +3114,84 @@ Non è consigliabile utilizzarlo. ok - + OK OK - + failed. non riuscita. - + Could not create local folder %1 Impossibile creare la cartella locale %1 - + No remote folder specified! Nessuna cartella remota specificata! - + Error: %1 Errore: %1 - + creating folder on Nextcloud: %1 creazione cartella su Nextcloud: %1 - + Remote folder %1 created successfully. La cartella remota %1 è stata creata correttamente. - + The remote folder %1 already exists. Connecting it for syncing. La cartella remota %1 esiste già. Connessione in corso per la sincronizzazione - - + + The folder creation resulted in HTTP error code %1 La creazione della cartella ha restituito un codice di errore HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> La creazione della cartella remota non è riuscita poiché le credenziali fornite sono errate!<br/>Torna indietro e verifica le credenziali.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">La creazione della cartella remota non è riuscita probabilmente perché le credenziali fornite non sono corrette.</font><br/>Torna indietro e controlla le credenziali inserite.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Creazione della cartella remota %1 non riuscita con errore <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Una connessione di sincronizzazione da %1 alla cartella remota %2 è stata stabilita. - + Successfully connected to %1! Connesso con successo a %1! - + Connection to %1 could not be established. Please check again. La connessione a %1 non può essere stabilita. Prova ancora. - + Folder rename failed Rinomina della cartella non riuscita @@ -3105,28 +3201,28 @@ Non è consigliabile utilizzarlo. Impossibile rimuovere o creare una copia di sicurezza della cartella poiché la cartella o un file in essa contenuto è aperta in un altro programma. Chiudi la cartella o il file e premi Riprova o annulla la configurazione. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Impossibile rimuovere o copiare la cartella poiché la cartella o un file contenuto in essa è aperto in un altro programma. Chiudi la cartella o il file e premi Riprova o annulla la configurazione. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Cartella locale %1 creata correttamente!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Procedura guidata di connessione di %1 - Add %1 account Aggiungi account %1 + + + %1 Connection Wizard + Procedura guidata di connessione di %1 + Skip folders configuration @@ -3159,24 +3255,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Rimani al sicuro - - OCC::OwncloudWizardResultPage - - - Everything set up! - Configurazione completata! - - - - Open Local Folder - Apri cartella locale - - - - Open %1 in Browser - Apri %1 nel browser - - OCC::PollJob @@ -3187,6 +3265,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Il fie contiene spazi finali e non può essere rinominato, perchè esiste già un file con lo stesso nome sul server. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Il fie contiene spazi finali e non può essere rinominato, perchè esiste già un file con lo stesso nome in locale. + Symbolic links are not supported in syncing. @@ -3202,16 +3290,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. I nomi del file che terminano con un punto non sono supportati su questo file system. - - - File names containing the character "%1" are not supported on this file system. - I nomi del file che contengono il carattere "%1" non sono supportati su questo file system. - File names containing the character '%1' are not supported on this file system. I nomi del file che contengono il carattere '%1' non sono supportati su questo file system. + + + File names containing the character "%1" are not supported on this file system. + I nomi del file che contengono il carattere "%1" non sono supportati su questo file system. + File name contains at least one invalid character @@ -3338,7 +3426,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Il server ha risposto con un errore durante la lettura della cartella '% 1' : %2 - + Server replied with an error while reading directory "%1" : %2 Il server ha risposto con un errore durante la lettura della cartella "%1" : %2 @@ -3953,11 +4041,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Consenti la modifica - - - Allow editing - Consenti la modifica - Read only @@ -3978,6 +4061,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Proteggi con password + + + Allow editing + Consenti la modifica + + + + View only + Solo in lettura + Allow upload and editing @@ -3993,16 +4086,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Rilascio file (solo caricamento) - - - Note to recipient - Nota al destinatario - Unshare Rimuovi condivisione + + + Link name + Nome collegamento + + + + Note to recipient + Nota al destinatario + Password protect @@ -4014,15 +4112,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Imposta data di scadenza - - Delete share link - Elimina collegamento di condivisione + + Delete link + Elimina collegamento Add another link Aggiungi un altro collegamento + + + Delete share link + Elimina collegamento di condivisione + Confirm Link Share Deletion @@ -4072,7 +4175,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Nessun risultato per '%1' - + No results for "%1" Nessun risultato per "%1" @@ -4176,12 +4279,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Condividi con %1 - Context menu share @@ -4208,6 +4305,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Condividi tramite %1 + + + + Activity + Attività + Copy private link to clipboard @@ -4279,6 +4382,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Elimina + + + Share with %1 + parameter is Nextcloud + Condividi con %1 + OCC::SslButton @@ -4424,6 +4533,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Impossibile collegarsi in modo sicuro a <i>%1</i>: + + + Additional errors: + Errori aggiuntivi: + with Certificate %1 @@ -4598,6 +4712,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Sono disponibili solo %1, servono almeno %2 per iniziare + + + Aborted + Interrotto + @@ -4750,27 +4869,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Caratteri non validi, rinomina "%1" + + + Synchronization will resume shortly. + La sincronizzazione riprenderà a breve. + File name contains at least one invalid character Il nome del file contiene almeno un carattere non valido - - Aborted - Interrotto - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Lo spazio su disco è basso: gli scaricamenti che potrebbero ridurre lo spazio libero sotto %1 saranno saltati. - + There is insufficient space available on the server for some uploads. Spazio disponibile insufficiente sul server per alcuni caricamenti. + + OCC::SyncStatusSummary + + + + Offline + Non in linea + + + + + + All synced! + Tutto sincronizzato! + + + + Some files couldn't be synced! + Alcuni file non possono essere sincronizzati! + + + + See below for errors + Vedi sotto gli errori + + + + Syncing + Sincronizzazione + + + + Sync paused + Sincronizzazione sospesa + + + + Some files could not be synced! + Alcuni file non possono essere sincronizzati! + + + + See below for warnings + Vedi sotto gli avvisi + + + + %1 of %2 · %3 left + %1 di %2 · %3 rimasti + + + + %1 of %2 + %1 di %2 + + + + Syncing file %1 of %2 + Sincronizzazione file %1 di %2 + + OCC::Systray @@ -4846,6 +5026,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Questa versione è stata fornita da %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Recupero dei fornitori non riuscito. + + + + Failed to fetch search providers for '%1'. Error: %2 + Recupero dei fornitori di ricerca per '%1'. Errore: %2 + + + + Search has failed for '%2'. + Ricerca di '%2' fallita. + + + + Search has failed for '%1'. Error: %2 + Ricerca di '%1' fallita. Errore: %2 + + OCC::User @@ -4903,24 +5106,108 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - La funzionalità di filesystem virtuale richiede un file system NTFS, %1 sta utilizzando %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Impossibile recuperare gli stati preimpostati. Assicurati di essere connesso al server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Scaricamento del file cifrato end-to-end non riuscito + + Could not fetch user status. Make sure you are connected to the server. + Impossibile recuperare gli stati dell'utente. Assicurati di essere connesso al server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Sembra che tu stia tentando di scaricare un file virtuale criptato end-to-end. Al momento, non è possibile scaricare implicitamente questi file. Per aggirare questo problema, vai nelle impostazioni e contrassegna la cartella cifrata con "Rendi sempre disponibile in locale". + + User status feature is not supported. You will not be able to set your user status. + La funzionalità dello stato dell'utente non è supportata. Non potrai impostare il tuo stato utente. + + + + Emojis feature is not supported. Some user status functionality may not work. + La funzionalità emoji non è supportata. Alcune caratteristiche dello stato utente potrebbero non funzionare. + + + + Could not set user status. Make sure you are connected to the server. + Impossibile impostare lo stato dell'utente. Assicurati di essere connesso al server. + + + + Could not clear user status message. Make sure you are connected to the server. + Impossibile cancellare il messaggio di stato dell'utente. Assicurati di essere connesso al server. + + + + + Don't clear + Non cancellare + + + + 30 minutes + 30 minuti + + + + + 1 hour + 1 ora + + + + 4 hours + 4 ore + + + + + Today + Oggi + + + + + This week + Questa settimana + + + + Less than a minute + Meno di un minuto + + + + 1 minute + 1 minuto + + + + %1 minutes + %1 minuti + + + + %1 hours + %1 ore + + + + 1 day + 1 giorno + + + + %1 days + %1 giorni + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + La funzionalità di filesystem virtuale richiede un file system NTFS, %1 sta utilizzando %2 @@ -5437,14 +5724,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Accedi al tuo %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - L'intero account è sincronizzato con la cartella locale - - QObject @@ -5537,6 +5816,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss Connessione al database non riuscita. + + UnifiedSearchInputContainer + + + Search files, messages, events … + Cerca file, messaggi, eventi … + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Carica più risultati + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Scheletro dei risultati di ricerca. + + + + UnifiedSearchResultListItem + + + Load more results + Carica più risultati + + UserLine @@ -5551,29 +5862,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - Lo stato attuale dell'utente è in linea + Account connected + Account connesso - Current user status is do not disturb - Lo stato attuale dell'utente è non disturbare + Account not connected + Account non connesso - Account connected - Account connesso + Current user status is online + Lo stato attuale dell'utente è in linea - Account not connected - Account non connesso + Current user status is do not disturb + Lo stato attuale dell'utente è non disturbare Account actions Azioni account + + + Remove Account + Rimuovi account + + + + Set status + Imposta stato + @@ -5586,17 +5907,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Accedi - - - Remove Account - Rimuovi account - Remove account Rimuovi account + + UserStatusSelector + + + Online status + Stato in linea + + + + Online + In linea + + + + Away + Assente + + + + Do not disturb + Non disturbare + + + + Invisible + Invisibile + + + + Status message + Messaggio di stato + + + + What is your status? + Qual è il tuo stato? + + + + Clear status message after + Cancella il messaggio di stato dopo + + + + Clear status message + Cancella il messaggio di stato + + + + Set status message + Imposta il messaggio di stato + + Utility @@ -5658,12 +6027,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. L'intestazione del codice di controllo non è valida. - + The checksum header contained an unknown checksum type '%1' L'intestazione di controllo conteneva un tipo di codice di controllo '%1' sconosciuto @@ -5673,17 +6042,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Il file scaricato non verifica il codice di controllo, sarà ripristinato. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Il file scaricato non verifica il codice di controllo, sarà ripristinato. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" L'intestazione di controllo conteneva un tipo di codice di controllo "%1" sconosciuto - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" Il file scaricato non verifica il codice di controllo, sarà ripristinato. "%1" != "%2" @@ -5712,6 +6081,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Sospendi la sincronizzazione per tutto + + + Set user status + Imposta lo stato utente + Add account @@ -5747,12 +6121,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb Lo stato attuale dell'utente è non disturbare - - - - Show more actions - Mostra altre azioni - Share %1 @@ -5813,6 +6181,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Apri finestra di condivisione + + + Unified search results list + Lista unificata dei risultati di ricerca + + + + + Show more actions + Mostra altre azioni + + + + %1 - File activity + %1 - Attività file + main.cpp @@ -6112,6 +6496,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Accedi tramite il tuo browser (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Configurazione completata! + + + + Open Local Folder + Apri cartella locale + + + + Open %1 in Browser + Apri %1 nel browser + + OCC::ShibbolethCredentials @@ -6164,6 +6566,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Accedi + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + L'intero account è sincronizzato con la cartella locale + + OCC::UserStatus @@ -6187,4 +6597,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss In linea + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Scaricamento del file cifrato end-to-end non riuscito + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Sembra che tu stia tentando di scaricare un file virtuale criptato end-to-end. Al momento, non è possibile scaricare implicitamente questi file. Per aggirare questo problema, vai nelle impostazioni e contrassegna la cartella cifrata con "Rendi sempre disponibile in locale". + + \ No newline at end of file diff --git a/translations/client_ja.ts b/translations/client_ja.ts index cbefd8f25861..c82aab9a63c8 100644 --- a/translations/client_ja.ts +++ b/translations/client_ja.ts @@ -12,23 +12,36 @@ Open %1 locally - + ローカルで %1 を開く + + + + Open share dialog + 共有ダイアログを開く + + + + Share %1 + %1 を共有 Show more actions - + その他の操作を表示 - - Open share dialog - + + View activity + アクティビティ表示 + + + ActivityList - - Share %1 - + + Activity list + アクティビティリスト @@ -41,7 +54,7 @@ Checking for changes in "%1" - + %1 の更新を確認しています @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + %1を%2に移動できませんでした @@ -147,7 +160,7 @@ Error removing "%1": %2 - + 削除中のエラー "%1": %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + フォルダー %1を削除できませんでした @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + このフォルダでは仮想ファイル機能が有効になっているようです。現時点では、エンドツーエンドで暗号化された仮想ファイルをバックグラウンドで暗黙的にダウンロードすることはできません。仮想ファイルとエンドツーエンド暗号化を最大限に活用するには、暗号化されたフォルダーに「ローカルで常に利用可能にする」というマークが付いていることを確認してください。 @@ -592,7 +605,7 @@ This action will abort any currently running synchronization. %1 as %2 - + %1 に %2 @@ -602,7 +615,7 @@ This action will abort any currently running synchronization. Connected to %1. - %1 に接続中 + %1 で接続しています。 @@ -842,7 +855,7 @@ This action will abort any currently running synchronization. Enter username and password for "%1" at %2. - + %2 で "%1" のユーザー名とパスワードを入力してください。 @@ -1098,7 +1111,7 @@ This can be an issue with your OpenSSL libraries. The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + ログインURLがHTTPSで始まっているにもかかわらず、ポーリングURLがHTTPSで始まっていません。セキュリティ上の問題がある可能性があるため、ログインできません。管理者に連絡してください。 @@ -1116,7 +1129,7 @@ This can be an issue with your OpenSSL libraries. There was an error accessing the "token" endpoint: <br><em>%1</em> - + "トークン"のエンドポイントへアクセス中にエラーが発生しました: <br><em>%1</em> @@ -1133,7 +1146,7 @@ This can be an issue with your OpenSSL libraries. The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + ログインURLはHTTPSで始まっているにもかかわらず、返されたサーバーURLがHTTPSではありません。セキュリティ上の問題がある可能性があるため、ログインできません。管理者に連絡してください。 @@ -1144,32 +1157,32 @@ This can be an issue with your OpenSSL libraries. ブラウザーを開くことができませんでした。リンクをブラウザーにコピーしてください。 - + Waiting for authorization 承認を待機中 - + Polling for authorization 承認を問い合わせ中 - + Starting authorization 承認を開始 - + Link copied to clipboard. リンクをクリップボードにコピーしました。 - + Reopen Browser ブラウザーを再度開く - + Copy Link リンクをコピー @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi これは、同期クライアントはすぐにローカルの変更をアップロードしない場合がありますが、代わりにローカルの変更をスキャンし(デフォルトでは2時間ごとに)時折それらをアップロードすることを意味します。 %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + ローカル同期フォルダー '%1'内のすべてのファイルが削除されました。この削除はサーバーに同期され、復元されない限りそのファイルは使用できなくなります。 +このアクションをサーバーと同期してもよろしいですか? +これが操作ミスであり、ファイルを維持することにした場合、ファイルはサーバーから再同期されます。 @@ -1396,40 +1418,25 @@ Continuing the sync as normal will cause all your files to be overwritten by an コンフリクト時にローカルファイルを保持 - - All files in the sync folder '%1' folder were deleted on the server. + + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - 同期フォルダー '%1'フォルダー内のすべてのファイルがサーバー上で削除されました。 + 同期フォルダー "%1"フォルダー内のすべてのファイルがサーバー上で削除されました。 これらの削除はローカル同期フォルダーと同期され、復元する権限がない限り、ファイルは使用できなくなります。 ファイルを復元したい場合、権限があればサーバーと再同期されます。 ファイルを削除することにした場合、所有者でない限り、ファイルは利用できなくなります。 - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. + + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - ローカル同期フォルダー '%1'内のすべてのファイルが削除されました。この削除はサーバーに同期され、復元されない限りそのファイルは使用できなくなります。 + ローカル同期フォルダー "%1" 内のすべてのファイルが削除されました。この削除はサーバーに同期され、復元されない限りそのファイルは使用できなくなります。 このアクションをサーバーと同期してもよろしいですか? これが操作ミスであり、ファイルを維持することにした場合、ファイルはサーバーから再同期されます。 - - - All files in the sync folder "%1" folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - Remove All Files? @@ -1440,6 +1447,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files すべてのファイルを削除 + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + 同期フォルダー '%1'フォルダー内のすべてのファイルがサーバー上で削除されました。 +これらの削除はローカル同期フォルダーと同期され、復元する権限がない限り、ファイルは使用できなくなります。 +ファイルを復元したい場合、権限があればサーバーと再同期されます。 +ファイルを削除することにした場合、所有者でない限り、ファイルは利用できなくなります。 + Keep files @@ -1489,7 +1507,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + 古い同期ジャーナル "%1" が見つかりましたが、削除できませんでした。それを現在使用しているアプリケーションが存在しないか確認してください。 @@ -1677,12 +1695,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + リモート "%1" での変更を確認中 Checking for changes in local "%1" - + ローカル "%1" での変更を確認中 @@ -1843,7 +1861,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + "%1" 以下に新しいフォルダーの名前を入力: @@ -2156,7 +2174,7 @@ Note that this selects only what pool upgrades are taken from, and that there ar Reading from keychain failed with error: "%1" - + キーチェーンからの読み取りが次のエラーで失敗しました: "%1" @@ -2199,7 +2217,7 @@ Note that this selects only what pool upgrades are taken from, and that there ar This entry is provided by the system at "%1" and cannot be modified in this view. - + このエントリーは、システム "%1" から提供されています。この画面では変更できません。 @@ -2251,7 +2269,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Cannot write changes to "%1". - + ”%1” を更新できません @@ -2269,6 +2287,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from 新しい除外パターンを追加 + + OCC::InvalidFilenameDialog + + + Invalid filename + 無効なファイル名 + + + + The file could not be synced because it contains characters which are not allowed on this system. + このシステムで許可されていない文字が含まれているため、ファイルを同期できませんでした。 + + + + Error + エラー + + + + Please enter a new name for the file: + このファイルの新しいファイル名を入力してください: + + + + New filename + 新しいファイル名 + + + + Rename file + ファイル名を変更 + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + 名前にこのシステムで許可されていない文字が含まれているため、ファイル%1を同期できませんでした。 + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + 次の文字はシステムで許可されていません: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + このファイルの名前を変更する権限がありません。ファイルの作成者に名前の変更を依頼してください。 + + + + Filename contains illegal characters: %1 + ファイル名に不正な文字が含まれています: %1 + + + + Could not rename file. Please make sure you are connected to the server. + ファイルの名前を変更できませんでした。サーバーに接続していることを確認してください。 + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + 同じ名前のファイルがサーバーにすでに存在するため、ファイルの名前を変更できません。別の名前を選んでください。 + + OCC::LegalNotice @@ -2409,9 +2490,9 @@ Logs will be written to %1 <nobr>ファイル '%1'<br/>を書き込み用で開けませんでした。<br/><br/>ログ出力を<b>保存できません</b>でした!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> - + <nobr>ファイル "%1"<br/>を書き込み用で開けませんでした。<br/><br/>ログ出力を<b>保存できません</b>でした!</nobr> @@ -2450,7 +2531,12 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> - <p>クライアントの新しいバージョンが利用可能ですが、更新に失敗しました。</p><p><b>%2 </b>がダウンロードされました。インストールされているバージョンは%3 です。</p> + <p>%1 クライアントの新しいバージョンが利用可能ですが、更新に失敗しました。</p><p><b>%2 </b>がダウンロードされました。インストールされているバージョンは %3 です。</p> + + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>クライアントの新しいバージョン%1 が利用可能ですが、更新に失敗しました。</p><p><b>%2</b> がダウンロードされています。インストールされているバージョンは %3 です。アップデートをチェックしてください。インストールを完了させるには再起動が必要な場合があります。</p> @@ -2621,16 +2707,21 @@ Logs will be written to %1 New %1 Update Ready 新しい %1 アップデートの準備完了 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + %1 の新しいアップデートのインストール準備ができました。アップデートのインストール中、追加の権限が必要な場合があります。 + New %1 update ready - + 新しいアップデート %1 の準備ができました - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - %1 の新しいアップデートのインストール準備ができました。アップデートのインストール中、追加の権限が必要な場合があります。 + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + 新しいアップデート %1 のインストール準備ができました。アップデートのインストール中、追加の権限が必要な場合があります。インストールを完了するために、コンピュータの再起動が必要な場合があります。 @@ -2667,6 +2758,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. 新しい %1 が利用可能です。アップデートをダウンロードするには、<a href='%2'>ここ</a>をクリックしてください。 + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + アップデートをダウンロードできませんでした。手動でアップデートするには、<a href='%1'>%1</a> をクリックしてください。 + Could not download update. Please open %1 to download the update manually. @@ -2677,6 +2773,11 @@ for additional privileges during the process. Could not check for new updates. アップデートを確認できませんでした。 + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + 新しい %1 が利用可能です。アップデートをダウンロードするには、<a href='%2'>%2</a>をクリックしてください。 + New %1 is available. Please open %2 to download the update. @@ -2765,12 +2866,12 @@ for additional privileges during the process. %1 folder "%2" is synced to local folder "%3" - + %1 のフォルダー "%2" はローカルフォルダー "%3" と同期しています Sync the folder "%1" - + "%1" フォルダーを同期 @@ -2973,37 +3074,37 @@ It is not advisable to use it. %2 の %1 へ接続を試みた際にタイムアウトしました。 - + Trying to connect to %1 at %2 … %2 の %1 へ接続を試みています… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. サーバーへの認証リクエストは '%1' へリダイレクトされました。URLは不正です、サーバーの設定に誤りがあります。 - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + サーバーへの認証リクエストは "%1" へリダイレクトされました。URLが正しくありません。サーバーが間違って設定されています。 - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. サーバーによってアクセスが拒否されています。適切なアクセス権があるか検証するには、<a href="%1">ここをクリック</a>してブラウザーでサービスにアクセスしてください。 - + There was an invalid response to an authenticated WebDAV request 認証済みの WebDAV 要求に対する無効な応答がありました - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> ローカルの同期フォルダー %1 はすでに存在するため、同期の設定をしてください。<br/><br/> - + Creating local sync folder %1 … ローカル同期フォルダー %1 を作成中… @@ -3013,84 +3114,84 @@ It is not advisable to use it. OK - + OK OK - + failed. 失敗。 - + Could not create local folder %1 ローカルフォルダー %1 を作成できませんでした - + No remote folder specified! リモートフォルダーが指定されていません! - + Error: %1 エラー: %1 - + creating folder on Nextcloud: %1 Nextcloud上にフォルダーを作成中:%1 - + Remote folder %1 created successfully. リモートフォルダー %1 は正常に生成されました。 - + The remote folder %1 already exists. Connecting it for syncing. リモートフォルダー %1 はすでに存在します。同期のために接続しています。 - - + + The folder creation resulted in HTTP error code %1 フォルダーの作成はHTTPのエラーコード %1 で終了しました - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> 指定された資格情報が間違っているため、リモートフォルダーの作成に失敗しました!<br/>前に戻って資格情報を確認してください。</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">おそらく資格情報が間違っているため、リモートフォルダーの作成に失敗しました。</font><br/>前に戻り、資格情報をチェックしてください。</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. リモートフォルダー %1 の作成がエラーで失敗しました。<tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. %1 からリモートディレクトリ %2 への同期接続を設定しました。 - + Successfully connected to %1! %1への接続に成功しました! - + Connection to %1 could not be established. Please check again. %1 への接続を確立できませんでした。もう一度確認してください。 - + Folder rename failed フォルダー名の変更に失敗しました。 @@ -3100,28 +3201,28 @@ It is not advisable to use it. フォルダーまたはその中にあるファイルが他のプログラムで開かれているため、フォルダーの削除やバックアップができません。フォルダーまたはファイルを閉じてから再試行するか、セットアップをキャンセルしてください。 - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. フォルダーまたはその中のファイルが別のプログラムで開かれているため、フォルダーを削除およびバックアップできません。フォルダーまたはファイルを閉じて、再試行を押すか、セットアップをキャンセルしてください。 - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>ローカルの同期フォルダー %1 は正常に作成されました!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 接続ウィザード - Add %1 account アカウント「%1」 を追加 + + + %1 Connection Wizard + %1 接続ウィザード + Skip folders configuration @@ -3160,24 +3261,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss セキュリティーを確保 - - OCC::OwncloudWizardResultPage - - - Everything set up! - すべてセットアップされました! - - - - Open Local Folder - ローカルフォルダーを開く - - - - Open %1 in Browser - %1 をブラウザーで開く - - OCC::PollJob @@ -3188,6 +3271,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + ファイルに末尾のスペースが含まれていますが、同じ名前のファイルがサーバーに既に存在するため、名前を変更できませんでした。 + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + ファイルに末尾のスペースが含まれていますが、同じ名前のファイルが既にローカルに存在するため、名前を変更できませんでした。 + Symbolic links are not supported in syncing. @@ -3203,16 +3296,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. ピリオドで終わるファイル名はこのファイルシステムでサポートされていません。 - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. ファイル名に含まれる文字 '%1' はこのファイルシステムでサポートされていません。 + + + File names containing the character "%1" are not supported on this file system. + ファイル名に含まれる文字 "%1" はこのファイルシステムでサポートされていません。 + File name contains at least one invalid character @@ -3339,9 +3432,9 @@ This is a new, experimental mode. If you decide to use it, please report any iss サーバーがディレクトリ '%1' の読み取り中にエラーで応答しました: %2 - + Server replied with an error while reading directory "%1" : %2 - + サーバーでディレクトリ "%1" を読み取り中にエラーになりました: %2 @@ -3954,11 +4047,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing 編集を許可 - - - Allow editing - 編集を許可 - Read only @@ -3979,6 +4067,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect パスワード保護 + + + Allow editing + 編集を許可 + + + + View only + 表示のみ + Allow upload and editing @@ -3994,16 +4092,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) ファイルドロップ(アップロードのみ) - - - Note to recipient - 受取人への注意 - Unshare 共有解除 + + + Link name + リンク名 + + + + Note to recipient + 受取人への注意 + Password protect @@ -4015,15 +4118,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss 有効期限を設定 - - Delete share link - 共有リンクを削除 + + Delete link + リンクを削除 Add another link 別のリンクを追加 + + + Delete share link + 共有リンクを削除 + Confirm Link Share Deletion @@ -4073,9 +4181,9 @@ This is a new, experimental mode. If you decide to use it, please report any iss '%1' は見つかりませんでした - + No results for "%1" - + "%1" は見つかりませんでした @@ -4177,12 +4285,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - %1 と共有 - Context menu share @@ -4209,6 +4311,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 %1 経由で共有 + + + + Activity + アクティビティ + Copy private link to clipboard @@ -4280,6 +4388,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete 削除 + + + Share with %1 + parameter is Nextcloud + %1 と共有 + OCC::SslButton @@ -4425,6 +4539,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: <i>%1</i> にセキュアに接続できません: + + + Additional errors: + + with Certificate %1 @@ -4599,6 +4718,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() %1 しか空き容量がありません、開始するためには少なくとも %2 は必要です。 + + + Aborted + 中断しました + @@ -4751,27 +4875,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" 無効な文字です、"%1" を変更してください。 + + + Synchronization will resume shortly. + + File name contains at least one invalid character ファイル名に1文字以上の無効な文字が含まれています - - Aborted - 中断しました - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. ディスク容量が少ない:%1以下の空き容量を減らすダウンロードはスキップされました。 - + There is insufficient space available on the server for some uploads. いくつかのアップロードのために、サーバーに十分なスペースがありません。 + + OCC::SyncStatusSummary + + + + Offline + オフライン + + + + + + All synced! + すべて同期されました! + + + + Some files couldn't be synced! + いくつかのファイルが同期できませんでした! + + + + See below for errors + 以下のエラーを確認してください + + + + Syncing + 同期中 + + + + Sync paused + 同期を一時停止 + + + + Some files could not be synced! + + + + + See below for warnings + 以下の警告を確認してください + + + + %1 of %2 · %3 left + %1 / %2 · 残り %3 + + + + %1 of %2 + %1 / %2 + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4847,6 +5032,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>このリリースは%1によって提供されました</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4904,24 +5112,108 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - ヴァーチャルファイルシステム機能にはNTFSファイルシステムが必要です。%1 は %2 を使用しています。 + + Could not fetch predefined statuses. Make sure you are connected to the server. + 事前定義されたステータスを取得できませんでした。サーバーに接続していることを確認してください。 - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - エンドツーエンドの暗号化ファイルがダウンロードできませんでした + + Could not fetch user status. Make sure you are connected to the server. + ユーザーステータスを取得できませんでした。サーバーに接続していることを確認してください。 - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - エンドツーエンドで暗号化された仮想ファイルをダウンロードしようとしているようです。現在、このようなファイルのバックグラウンドでの暗黙的なダウンロードはサポートされていません。この問題を回避するには、設定に移動し、暗号化されたフォルダに「ローカルで常に利用可能にする」のマークを付けます。 + + User status feature is not supported. You will not be able to set your user status. + ユーザーステータス機能はサポートされていません。ユーザーステータスを設定することはできません。 + + + + Emojis feature is not supported. Some user status functionality may not work. + 絵文字機能はサポートされていません。一部のユーザーステータス機能が機能しない場合があります。 + + + + Could not set user status. Make sure you are connected to the server. + ユーザーステータスを設定できませんでした。サーバーに接続していることを確認してください。 + + + + Could not clear user status message. Make sure you are connected to the server. + ユーザーステータスメッセージをクリアできませんでした。サーバーに接続していることを確認してください。 + + + + + Don't clear + 消去しない + + + + 30 minutes + 30分 + + + + + 1 hour + 1 時間 + + + + 4 hours + 4時間 + + + + + Today + 今日 + + + + + This week + 今週 + + + + Less than a minute + 1分以内 + + + + 1 minute + 1 分 + + + + %1 minutes + %1 秒 + + + + %1 hours + %1 時間 + + + + 1 day + 1日 + + + + %1 days + %1 日 + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + ヴァーチャルファイルシステム機能にはNTFSファイルシステムが必要です。%1 は %2 を使用しています。 @@ -5130,7 +5422,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in remote "%1" - + リモート "%1" での変更を確認中 @@ -5140,7 +5432,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in local "%1" - + ローカル "%1" での変更を確認中 @@ -5438,14 +5730,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss あなたの %1 へログイン - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - すべてのアカウントはローカルフォルダーと同期されます - - QObject @@ -5517,7 +5801,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Do not disturb - おやすみモード + 取り込み中 @@ -5538,6 +5822,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss データベースに接続できません + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5552,29 +5868,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - 現在のユーザーステータスはオンラインです + Account connected + アカウント接続済 - Current user status is do not disturb - 現在のユーザーステータスは取り込み中です + Account not connected + アカウントは接続していません - Account connected - アカウント接続済 + Current user status is online + 現在のユーザーステータスはオンラインです - Account not connected - アカウントは接続していません + Current user status is do not disturb + 現在のユーザーステータスは取り込み中です Account actions アカウント操作 + + + Remove Account + アカウントを削除 + + + + Set status + ステータスを設定 + @@ -5587,17 +5913,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in ログイン - - - Remove Account - アカウントを削除 - Remove account アカウント削除 + + UserStatusSelector + + + Online status + オンラインステータス + + + + Online + オンライン + + + + Away + 離席中 + + + + Do not disturb + 取り込み中 + + + + Invisible + オフライン + + + + Status message + ステータスメッセージ + + + + What is your status? + 現在のオンラインステータスは? + + + + Clear status message after + メッセージ有効期限 + + + + Clear status message + ステータスメッセージを消去 + + + + Set status message + ステータスメッセージを設定 + + Utility @@ -5659,12 +6033,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. チェックサムヘッダーの形式が正しくありません。 - + The checksum header contained an unknown checksum type '%1' チェックサムヘッダーには未知のチェックサムタイプ '%1'が含まれていました @@ -5674,19 +6048,19 @@ This is a new, experimental mode. If you decide to use it, please report any iss ダウンロードしたファイルがチェックサムと一致しません。再開されます。 - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' ダウンロードしたファイルがチェックサムと一致しないため、再度ダウンロードされます。 '%1'!= '%2' - + The checksum header contained an unknown checksum type "%1" - + チェックサムヘッダーに不明なチェックサムタイプ "%1" が含まれていました - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" - + ダウンロードしたファイルがチェックサムと一致しないため、再度ダウンロードされます。 "%1" != "%2" @@ -5713,6 +6087,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all 全ての同期を一時停止 + + + Set user status + ステータスを設定 + Add account @@ -5748,12 +6127,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb 現在のユーザーステータスは取り込み中です - - - - Show more actions - その他のアクションを表示 - Share %1 @@ -5814,6 +6187,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog 共有ダイアログを開く + + + Unified search results list + + + + + + Show more actions + その他のアクションを表示 + + + + %1 - File activity + %1 - ファイルアクティビティ + main.cpp @@ -6113,6 +6502,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss ブラウザーにログイン (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + すべてセットアップされました! + + + + Open Local Folder + ローカルフォルダーを開く + + + + Open %1 in Browser + %1 をブラウザーで開く + + OCC::ShibbolethCredentials @@ -6165,6 +6572,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss ログイン + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + すべてのアカウントはローカルフォルダーと同期されます + + OCC::UserStatus @@ -6188,4 +6603,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss オンライン + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + エンドツーエンドの暗号化ファイルがダウンロードできませんでした + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + エンドツーエンドで暗号化された仮想ファイルをダウンロードしようとしているようです。現在、このようなファイルのバックグラウンドでの暗黙的なダウンロードはサポートされていません。この問題を回避するには、設定に移動し、暗号化されたフォルダに「ローカルで常に利用可能にする」のマークを付けます。 + + \ No newline at end of file diff --git a/translations/client_ko.ts b/translations/client_ko.ts index 475b5e635a57..04a200ccbdc4 100644 --- a/translations/client_ko.ts +++ b/translations/client_ko.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1144,32 +1157,32 @@ OpenSSL 라이브러리 이슈일 수 있습니다. 브라우저를 열 수 없습니다. 링크를 브라우저로 복사하십시오. - + Waiting for authorization 인증 대기 중 - + Polling for authorization 인증 폴링 중 - + Starting authorization 인증 시작하는 중 - + Link copied to clipboard. 링크가 클립보드에 복사되었습니다. - + Reopen Browser 브라우저를 다시 열기 - + Copy Link 링크 복사 @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi 이는 동기화 클라이언트가 로컬 변경 사항을 즉시 업로드하지 않고 대신 로컬 변경 사항만 스캔하고 가끔(기본적으로 2 시간마다) 업로드함을 의미합니다. %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + 동기화 폴더 '%1'의 모든 파일이 삭제되었습니다. 이 삭제는 서버와 동기화되므로 해당 파일을 복원하지 않는 한 사용할 수 없습니다. +이 동작을 서버와 동기화하시겠습니까? +이 동작이 우연이고 파일을 유지하고자 할 경우, 서버로부터 재동기화 될 것입니다. @@ -1398,27 +1420,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an 로컬 파일을 충돌 상태로 유지 - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - 동기화 폴더 '%1'의 모든 파일이 서버에서 삭제되었습니다. -이러한 삭제는 로컬 동기화 폴더와 동기화되므로 복원할 권한이 없으면 해당 파일을 사용할 수 없습니다. -파일을 복원하기로 결정한 경우, 파일을 복원할 수 있는 권한이 있으면 파일이 서버와 다시 동기화됩니다. -파일을 삭제하기로 결정한 경우 소유자가 아닌 한 해당 파일을 사용할 수 없습니다. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - 동기화 폴더 '%1'의 모든 파일이 삭제되었습니다. 이 삭제는 서버와 동기화되므로 해당 파일을 복원하지 않는 한 사용할 수 없습니다. -이 동작을 서버와 동기화하시겠습니까? -이 동작이 우연이고 파일을 유지하고자 할 경우, 서버로부터 재동기화 될 것입니다. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1426,7 +1428,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1442,6 +1444,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files 모두 삭제 + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + 동기화 폴더 '%1'의 모든 파일이 서버에서 삭제되었습니다. +이러한 삭제는 로컬 동기화 폴더와 동기화되므로 복원할 권한이 없으면 해당 파일을 사용할 수 없습니다. +파일을 복원하기로 결정한 경우, 파일을 복원할 수 있는 권한이 있으면 파일이 서버와 다시 동기화됩니다. +파일을 삭제하기로 결정한 경우 소유자가 아닌 한 해당 파일을 사용할 수 없습니다. + Keep files @@ -2273,6 +2286,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from 새 무시 패턴 추가: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2413,7 +2489,7 @@ Logs will be written to %1 쓰기 위해 <nobr>파일 '%1'<br/>을 열 수 없습니다.<br/><br/>로그 출력이 <b>저장되지 않습니다!</b></nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2456,6 +2532,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>%1 클라이언트의 새 버전을 사용할 수 있지만, 업데이트 과정에 실패했습니다.</p><p><b>%2</b>이(가) 다운로드 되었습니다. 설치된 버전은 %3입니다.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2627,6 +2708,13 @@ Logs will be written to %1 New %1 Update Ready 새 %1 업데이트 준비됨 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + %1에 대한 새로운 업데이트가 설치 될 예정입니다. 업데이터가 +프로세스 중에 추가 권한을 요청할 수 있습니다. + New %1 update ready @@ -2634,10 +2722,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - %1에 대한 새로운 업데이트가 설치 될 예정입니다. 업데이터가 -프로세스 중에 추가 권한을 요청할 수 있습니다. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2674,6 +2760,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. 새 %1을(를) 사용할 수 있습니다. <a href='%2'>여기</a>를 클릭하여 업데이트를 다운로드하십시오. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2684,6 +2775,11 @@ for additional privileges during the process. Could not check for new updates. 새 업데이트를 확인할 수 없습니다. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2981,37 +3077,37 @@ It is not advisable to use it. %2에서 %1와 연결을 시도하는 중 시간이 만료되었습니다. - + Trying to connect to %1 at %2 … %2에서 %1와 연결을 시도하는 중... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. 서버에 대한 인증 된 요청이 '%1'로 리디렉션되었습니다. URL이 잘못되어 서버가 잘못 구성되었습니다. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. 서버에서 액세스가 금지되었습니다. 올바른 액세스 권한이 있는지 확인하려면 <a href="%1">여기</a>를 클릭하여 브라우저로 서비스에 액세스하십시오. - + There was an invalid response to an authenticated WebDAV request 인증된 WebDAV 요청에 대한 응답이 잘못되었습니다. - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> 로컬 동기화 폴더 %1이 이미 존재하며, 동기화 하도록 설정했습니다.<br/><br/> - + Creating local sync folder %1 … 로컬 동기화 폴더 %1 생성 중... @@ -3021,84 +3117,84 @@ It is not advisable to use it. 확인 - + OK 확인 - + failed. 실패 - + Could not create local folder %1 로컬 폴더 %1을 만들 수 없음 - + No remote folder specified! 원격 폴더가 지정되지 않음 - + Error: %1 오류: %1 - + creating folder on Nextcloud: %1 Nextcloud에 폴더 생성 중: %1 - + Remote folder %1 created successfully. 원격 폴더 %1ㅣ 성공적으로 생성되었습니다. - + The remote folder %1 already exists. Connecting it for syncing. 원격 폴더 %1이 이미 존재합니다. 동기화를 위해 연결합니다. - - + + The folder creation resulted in HTTP error code %1 폴더 생성으로 인해 HTTP 오류 코드 %1이 발생했습니다. - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> 제공된 자격 증명이 잘못되어 원격 폴더 생성에 실패했습니다.<br/>돌아가서 자격 증명을 확인하십시오.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">제공된 자격 증명이 잘못되어 원격 폴더 생성에 실패했을 수 있습니다.</font><br/>돌아가서 자격 증명을 확인하십시오.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. 원격 폴더 %1 생성이 오류 <tt>%2</tt>로 인해 실패했습니다. - + A sync connection from %1 to remote directory %2 was set up. %1에서 원격 디렉토리 %2에 대한 동기화 연결이 설정되었습니다. - + Successfully connected to %1! %1와 성공적으로 연결되었습니다. - + Connection to %1 could not be established. Please check again. %1와 연결을 수립할 수 없습니다. 다시 확인해주십시오. - + Folder rename failed 폴더 이름을 바꿀 수 없음 @@ -3108,28 +3204,28 @@ It is not advisable to use it. 폴더 나 폴더의 파일이 다른 프로그램에서 열려있어 폴더를 제거하고 백업 할 수 없습니다. 폴더 혹은 파일을 닫고 다시 시도하거나 설정을 취소하십시오. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. 폴더 나 폴더의 파일이 다른 프로그램에서 열려있어 폴더를 제거하고 백업 할 수 없습니다. 폴더 혹은 파일을 닫고 다시 시도하거나 설정을 취소하십시오. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>로컬 동기화 폴더 %1이 성공적으로 생성되었습니다!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Connection Wizard - Add %1 account %1 계정 추가 + + + %1 Connection Wizard + %1 Connection Wizard + Skip folders configuration @@ -3168,24 +3264,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 안전하게 머무르기 - - OCC::OwncloudWizardResultPage - - - Everything set up! - 모두 설정되었습니다! - - - - Open Local Folder - 로컬 폴더 열기 - - - - Open %1 in Browser - 브라우저에서 %1 열기 - - OCC::PollJob @@ -3196,6 +3274,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3211,16 +3299,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. 마침표로 끝나는 파일 이름은 이 파일 시스템에서 지원되지 않습니다. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. '%1'을 포함하는 파일 이름은 이 파일 시스템에서 지원되지 않습니다. + + + File names containing the character "%1" are not supported on this file system. + + File name contains at least one invalid character @@ -3347,7 +3435,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss 서버가 디렉토리 '%1'을(를) 읽는 중 오류에 대응함: %2 - + Server replied with an error while reading directory "%1" : %2 @@ -3962,11 +4050,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing 편집 허용 - - - Allow editing - Allow editing - Read only @@ -3987,6 +4070,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect 암호 보호 + + + Allow editing + Allow editing + + + + View only + + Allow upload and editing @@ -4002,16 +4095,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) File drop (upload only) - - - Note to recipient - 받는 사람 메모 - Unshare 공유 해제 + + + Link name + + + + + Note to recipient + 받는 사람 메모 + Password protect @@ -4023,15 +4121,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss 만료기한 설정 - - Delete share link - 공유 링크 삭제 + + Delete link + Add another link 다른 링크 추가 + + + Delete share link + 공유 링크 삭제 + Confirm Link Share Deletion @@ -4081,7 +4184,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss '%1'에 대한 결과 없음 - + No results for "%1" @@ -4185,12 +4288,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - %1 님과 공유 - Context menu share @@ -4217,6 +4314,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 %1(으)로 공유 + + + + Activity + + Copy private link to clipboard @@ -4288,6 +4391,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete 삭제 + + + Share with %1 + parameter is Nextcloud + %1 님과 공유 + OCC::SslButton @@ -4433,6 +4542,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: <i>%1</i>에 안전하게 연결할 수 없습니다: + + + Additional errors: + + with Certificate %1 @@ -4607,6 +4721,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() %1 만 사용할 수 있습니다. 시작하려면 %2 이상이 필요합니다 + + + Aborted + 중단됨 + @@ -4759,27 +4878,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" 잘못된 문자입니다. "%1"의 이름을 바꾸십시오. + + + Synchronization will resume shortly. + + File name contains at least one invalid character 파일 이름에 유효하지 않은 문자가 하나 이상 있습니다. - - Aborted - 중단됨 - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. 디스크 공간이 부족합니다. 여유 공간이 %1 미만으로 남으면 다운로드를 건너 뜁니다. - + There is insufficient space available on the server for some uploads. 일부 업로드를 위해 서버에 사용 가능한 공간이 부족합니다. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4855,6 +5035,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>이 릴리스는 %1에 의해 제공되었습니다.</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4912,26 +5115,110 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - 가상 파일시스템 기능은 NTFS 파일 시스템이 요구됩니다. %1은(는) %2을(를) 사용중 + + Could not fetch predefined statuses. Make sure you are connected to the server. + - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + 가상 파일시스템 기능은 NTFS 파일 시스템이 요구됩니다. %1은(는) %2을(를) 사용중 + + OCC::WebEnginePage @@ -5446,14 +5733,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 내 %1로 로그인 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - 전체 계정이 로컬 폴더에 동기화됩니다. - - QObject @@ -5546,6 +5825,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5560,29 +5871,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - 현재 사용자 상태가 오프라인임 + Account connected + 계정 연결됨 - Current user status is do not disturb - 현재 사용자 상태가 방해 금지임 + Account not connected + 계정이 연결되지 않음 - Account connected - 계정 연결됨 + Current user status is online + 현재 사용자 상태가 오프라인임 - Account not connected - 계정이 연결되지 않음 + Current user status is do not disturb + 현재 사용자 상태가 방해 금지임 Account actions 계정 동작 + + + Remove Account + 계정 삭제 + + + + Set status + + @@ -5595,17 +5916,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in 로그인 - - - Remove Account - 계정 삭제 - Remove account 계정 삭제 + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5667,12 +6036,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. 체크섬 헤더가 잘못되었습니다. - + The checksum header contained an unknown checksum type '%1' 체크섬 헤더에 알 수 없는 체크섬 유형 '% 1'이 있습니다. @@ -5682,17 +6051,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 다운로드 한 파일이 체크섬과 일치하지 않아 다시 시작됩니다. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' 다운로드 한 파일이 체크섬과 일치하지 않아 다시 시작됩니다. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5721,6 +6090,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all 전체 동기화 일시 정지 + + + Set user status + + Add account @@ -5756,12 +6130,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb 현재 사용자 상태가 방해 금지임 - - - - Show more actions - 더 많은 활동 보기 - Share %1 @@ -5822,6 +6190,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + 더 많은 활동 보기 + + + + %1 - File activity + + main.cpp @@ -6121,6 +6505,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss 브라우저에서 로그인 (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + 모두 설정되었습니다! + + + + Open Local Folder + 로컬 폴더 열기 + + + + Open %1 in Browser + 브라우저에서 %1 열기 + + OCC::ShibbolethCredentials @@ -6173,6 +6575,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss 로그인 + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + 전체 계정이 로컬 폴더에 동기화됩니다. + + OCC::UserStatus @@ -6196,4 +6606,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 접속 중 + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_lt_LT.ts b/translations/client_lt_LT.ts index 2b21435d6bc8..b45c313e4874 100644 --- a/translations/client_lt_LT.ts +++ b/translations/client_lt_LT.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1138,32 +1151,32 @@ This can be an issue with your OpenSSL libraries. Nepavyko atverti naršyklės, nukopijuokite nuorodą į savo naršyklę. - + Waiting for authorization Laukiama prieigos teisių - + Polling for authorization Pieigos teisių apklausa - + Starting authorization Prieigos teisių inicijavimas - + Link copied to clipboard. Nuoroda nukopijuota į iškarpinę. - + Reopen Browser - + Copy Link @@ -1329,6 +1342,13 @@ This means that the synchronization client might not upload local changes immedi Tai reiškia, kad sinchronizacijos klientas gali iš karto neįkelti lokalių pakeitimų, o tik juos nuskaityti. Įkėlimas bus atliekamas tam tikrais laiko tarpais (pagal numatytuosius nustatymus kas dvi valandas). + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1388,22 +1408,7 @@ Jei tęsite sinchronizavimą, Jūsų ankstesni failai bus perrašyti senesniais. Laikyti vietinius failus kaip konfliktinius - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1411,7 +1416,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1427,6 +1432,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Šalinti visus failus + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2257,6 +2270,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Pridėti naują nepaisymo šabloną: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2394,7 +2470,7 @@ Logs will be written to %1 <nobr>Failas '%1'<br/>negali būti atidarytas rašymui.<br/><br/>Įvykių žurnalo išvestis <b>negali</b>būti išsaugota!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2437,6 +2513,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Yra prieinama nauja %1 kliento programos versija, bet atnaujinimas patyrė nesėkmę.</p><p><b>%2</b> atsiųsta. Įdiegta versija yra %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2606,6 +2687,13 @@ Logs will be written to %1 New %1 Update Ready Yra paruoštas naujas %1 atnaujinimas + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Baigiamas % 1 atnaujinimas. Proceso metu Jūsų gali paprašyti +papildomų teisių. + New %1 update ready @@ -2613,10 +2701,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Baigiamas % 1 atnaujinimas. Proceso metu Jūsų gali paprašyti -papildomų teisių. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2653,6 +2739,11 @@ papildomų teisių. New %1 is available. Please click <a href='%2'>here</a> to download the update. Yra prieinama nauja %1. Spustelėkite <a href='%2'>čia</a> norėdami atsisiųsti atnaujinimą. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2663,6 +2754,11 @@ papildomų teisių. Could not check for new updates. Nepavyko patikrinti ar yra atnaujinimų. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2959,37 +3055,37 @@ Patariama jo nenaudoti. %2 prisijungimui prie %1 laikas pasibaigė. - + Trying to connect to %1 at %2 … Bandoma prisijungti prie %1 ties %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Nustatytos tapatybės užklausa į serverį buvo peradresuota į "%1". Blogas URL adresas, serveris sukonfigūruotas neteisingai. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Prieigą apribojo serveris. Norėdami įsitikinti, kad turite tinkamą prieigą, <a href="%1">spustelėkite čia</a>ir paslauga bus atidaryta jūsų naršyklėje. - + There was an invalid response to an authenticated WebDAV request Neteisingas atsakymas į patvirtintą „WebDAV“ užklausą - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Sinchronizavimo aplankas %1 jau yra kompiuteryje, ruošiama sinchronizuoti.<br/><br/> - + Creating local sync folder %1 … Kuriamas vietinis sinchronizavimo aplankas %1… @@ -2999,84 +3095,84 @@ Patariama jo nenaudoti. gerai - + OK - + failed. nepavyko. - + Could not create local folder %1 Nepavyko sukurti vietinio aplanko %1 - + No remote folder specified! Nenurodytas nuotolinis aplankas! - + Error: %1 Klaida: %1 - + creating folder on Nextcloud: %1 kuriamas aplankas Nextcloud: %1 - + Remote folder %1 created successfully. Nuotolinis aplankas %1 sėkmingai sukurtas. - + The remote folder %1 already exists. Connecting it for syncing. Serverio aplankas %1 jau yra. Prisijunkite jį sinchronizavimui. - - + + The folder creation resulted in HTTP error code %1 Aplanko sukūrimas sąlygojo HTTP klaidos kodą %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Nepavyko sukurti aplanko serveryje dėl neteisingų prisijungimo duomenų! <br/>Grįžkite ir įsitinkite, kad prisijungimo duomenys teisingai.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Nepavyko sukurti aplanko serveryje dėl neteisingų prisijungimo duomenų.</font><br/>Grįžkite ir įsitinkite, kad prisijungimo duomenys teisingai.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Nepavyko sukurti aplanko %1 serveryje, klaida <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Sinchronizavimo ryšys su %1 su nuotoliniu katalogu %2 buvo nustatytas. - + Successfully connected to %1! Sėkmingai prisijungta prie %1! - + Connection to %1 could not be established. Please check again. Susijungti su %1 nepavyko. Pabandykite dar kartą. - + Folder rename failed Nepavyko pervadinti aplanką @@ -3086,28 +3182,28 @@ Patariama jo nenaudoti. Nepavyko pašalinti arba padaryti atsarginės aplanko ar failo kopijos, nes jie atidaryti kitoje programoje. Prašome užverti aplanką ir failą, ir bandyti diegti dar kartą. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Sinchronizavimo aplankas %1 kompiuteryje buvo sėkmingai sukurtas! </b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 ryšio vediklis - Add %1 account + + + %1 Connection Wizard + %1 ryšio vediklis + Skip folders configuration @@ -3140,24 +3236,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Viskas nustatyta! - - - - Open Local Folder - Atverti vietinį aplanką - - - - Open %1 in Browser - Atverti %1 naršyklėje - - OCC::PollJob @@ -3168,6 +3246,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3185,12 +3273,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3319,7 +3407,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3934,11 +4022,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Leisti keisti - - - Allow editing - Leisti redaguoti - Read only @@ -3959,6 +4042,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Apsaugota slaptažodžiu + + + Allow editing + Leisti redaguoti + + + + View only + + Allow upload and editing @@ -3974,16 +4067,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Failų įmetimas (tik įkėlimas) - - - Note to recipient - Pastaba gavėjui - Unshare Nustoti bendrinti + + + Link name + + + + + Note to recipient + Pastaba gavėjui + Password protect @@ -3995,15 +4093,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Nustatyti galiojimo pabaigos datą - - Delete share link - Ištrinti bendrinimo nuorodą + + Delete link + Add another link Pridėti dar vieną nuorodą + + + Delete share link + Ištrinti bendrinimo nuorodą + Confirm Link Share Deletion @@ -4053,7 +4156,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss „%1“ negrąžino jokių rezultatų - + No results for "%1" @@ -4157,12 +4260,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Dalintis su %1 - Context menu share @@ -4189,6 +4286,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Bendrinti per %1 + + + + Activity + + Copy private link to clipboard @@ -4260,6 +4363,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Ištrinti + + + Share with %1 + parameter is Nextcloud + Dalintis su %1 + OCC::SslButton @@ -4405,6 +4514,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Nepavyksta saugiai prisijungti prie <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4579,6 +4693,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Leidžiami tik %1, būtina bent %2, kad galėtumėte pradėti + + + Aborted + + @@ -4731,27 +4850,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Neteisingi simboliai, pervadinkite "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Failo pavadinime yra bent vienas neleistinas simbolis - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Mažai vietos diske: atsisiuntimai, kurie sumažintų vietą iki %1 buvo praleisti. - + There is insufficient space available on the server for some uploads. Kai kuriems įkėlimams serveryje neužteks vietos. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4827,6 +5007,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Šį išleidimą pateikė %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4884,23 +5087,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5418,14 +5705,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Prisijunkite prie savo %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Visa paskyra yra sinchronizuota su kompiuterio aplanku - - QObject @@ -5518,6 +5797,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5532,29 +5843,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Paskyra prijungta - Current user status is do not disturb - + Account not connected + Paskyra neprijungta - Account connected - Paskyra prijungta + Current user status is online + - Account not connected - Paskyra neprijungta + Current user status is do not disturb + Account actions Veiksmai su paskyra + + + Remove Account + Šalinti paskyrą + + + + Set status + + @@ -5567,17 +5888,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Prisijungti - - - Remove Account - Šalinti paskyrą - Remove account Šalinti paskyrą + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5639,12 +6008,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Kontrolinės sumos antraštė yra netaisyklinga. - + The checksum header contained an unknown checksum type '%1' Kontrolinės sumos antraštėje buvo nežinomas kontrolinės sumos tipas "%1" @@ -5654,17 +6023,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Atsisiųstas failas neatitinka kontrolinės sumos, jis bus pratęstas. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5693,6 +6062,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5728,12 +6102,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - Rodyti daugiau veiksmų - Share %1 @@ -5794,6 +6162,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Atverti bendrinimo dialogą + + + Unified search results list + + + + + + Show more actions + Rodyti daugiau veiksmų + + + + %1 - File activity + + main.cpp @@ -6093,6 +6477,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Prisijunkite prie savo naršyklės („Login Flow v2“) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Viskas nustatyta! + + + + Open Local Folder + Atverti vietinį aplanką + + + + Open %1 in Browser + Atverti %1 naršyklėje + + OCC::ShibbolethCredentials @@ -6145,6 +6547,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Prisijungti + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Visa paskyra yra sinchronizuota su kompiuterio aplanku + + OCC::UserStatus @@ -6168,4 +6578,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_lv.ts b/translations/client_lv.ts index c95cca0d85c8..dcf3d6ea2e7e 100644 --- a/translations/client_lv.ts +++ b/translations/client_lv.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1379,22 +1399,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Saglabāt lokālās datnes kā konfliktu - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1402,7 +1407,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1418,6 +1423,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2242,6 +2255,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2377,7 +2453,7 @@ Logs will be written to %1 Datni '%1'<br/>nevar atvērt rakstīšanai.<br/><br/>Žurnāla izvads var būt<b>nesaglabāts</b> !</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2420,6 +2496,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2589,6 +2670,12 @@ Logs will be written to %1 New %1 Update Ready + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + + New %1 update ready @@ -2596,8 +2683,7 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. @@ -2635,6 +2721,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2645,6 +2736,11 @@ for additional privileges during the process. Could not check for new updates. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2940,37 +3036,37 @@ It is not advisable to use it. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> - + Creating local sync folder %1 … @@ -2980,84 +3076,84 @@ It is not advisable to use it. - + OK - + failed. - + Could not create local folder %1 - + No remote folder specified! - + Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. - + The remote folder %1 already exists. Connecting it for syncing. - - + + The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! - + Connection to %1 could not be established. Please check again. - + Folder rename failed @@ -3067,12 +3163,12 @@ It is not advisable to use it. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> @@ -3080,13 +3176,13 @@ It is not advisable to use it. OCC::OwncloudWizard - - %1 Connection Wizard + + Add %1 account - - Add %1 account + + %1 Connection Wizard @@ -3121,24 +3217,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - - - - - Open Local Folder - - - - - Open %1 in Browser - - - OCC::PollJob @@ -3149,6 +3227,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3166,12 +3254,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3300,7 +3388,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3810,7 +3898,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss share label - + koplietošanas etiķete @@ -3915,11 +4003,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Atļaut rediģēšanu - Read only @@ -3940,6 +4023,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Aizsargāts ar paroli + + + Allow editing + Atļaut rediģēšanu + + + + View only + + Allow upload and editing @@ -3955,16 +4048,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Datņu mešana (tikai augšupielādei) - - - Note to recipient - - Unshare Atcelt koplietošanu + + + Link name + + + + + Note to recipient + + Password protect @@ -3976,13 +4074,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss Uzstādīt beigu termiņu - - Delete share link + + Delete link Add another link + Pievienot citu saiti + + + + Delete share link @@ -4034,7 +4137,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + No results for "%1" @@ -4138,12 +4241,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4170,6 +4267,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4241,6 +4344,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Dzēst + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4384,6 +4493,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4558,6 +4672,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() + + + Aborted + + @@ -4711,26 +4830,87 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - File name contains at least one invalid character + + Synchronization will resume shortly. - - Aborted + + File name contains at least one invalid character - + Disk space is low: Downloads that would reduce free space below %1 were skipped. - + There is insufficient space available on the server for some uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4806,6 +4986,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Šo izlaidumu piegādāja %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4863,23 +5066,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5397,14 +5684,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Viss jūsu konts ir sinhronizēts ar lokālo mapi - - QObject @@ -5497,6 +5776,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5511,22 +5822,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5534,6 +5845,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Konta darbības + + + Remove Account + + + + + Set status + + @@ -5546,17 +5867,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Pieteikties - - - Remove Account - - Remove account Noņemt kontu + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5618,12 +5987,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Kontrolsummas galvene ir nepareiza. - + The checksum header contained an unknown checksum type '%1' Kontrolsummas galvene saturēja nezināmu kontrolsummas tipu '%1' @@ -5633,17 +6002,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Lejupielādētajai datnei nesakrīt kontrolsumma, tā tiks pārrēķināta. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5672,6 +6041,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5707,12 +6081,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5773,6 +6141,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6072,6 +6456,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + + + + + Open Local Folder + + + + + Open %1 in Browser + + + OCC::ShibbolethCredentials @@ -6124,6 +6526,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Viss jūsu konts ir sinhronizēts ar lokālo mapi + + OCC::UserStatus @@ -6147,4 +6557,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_mk.ts b/translations/client_mk.ts index a7d6f023c0fb..0b361350b1a4 100644 --- a/translations/client_mk.ts +++ b/translations/client_mk.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1138,32 +1151,32 @@ This can be an issue with your OpenSSL libraries. Неможе да се отвори прелистувачот, копирајте го линкот и отворете со прелистувач. - + Waiting for authorization Чекање за авторизација - + Polling for authorization Прозивка за авторизација - + Starting authorization Започнува авторизацијата - + Link copied to clipboard. Линкот е копиран во клипборд. - + Reopen Browser Повторно отвори го прелистувачот - + Copy Link Копирај линк @@ -1328,6 +1341,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1381,22 +1401,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Зачувај ги локалните датотеки како конфликтни - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1404,7 +1409,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1420,6 +1425,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Отстрани ги сите датотеки + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2249,6 +2262,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Додади нов шаблон за игнорирање: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2384,7 +2460,7 @@ Logs will be written to %1 - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2427,6 +2503,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Нова верзија на %1 клиент е достапна но процесот за ажурирање беше неуспењен.</p><p><b>%2</b> е превземен. Инсталираната верзија е %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2596,6 +2677,13 @@ Logs will be written to %1 New %1 Update Ready Ново %1 ажурирање + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Достапно е ажурирање за %1. При процесот за ажурирање моеж +ќе бидете прашани за да дозволите додатни привилегии. + New %1 update ready @@ -2603,10 +2691,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Достапно е ажурирање за %1. При процесот за ажурирање моеж -ќе бидете прашани за да дозволите додатни привилегии. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2643,6 +2729,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Нова %1 е достапна. Кликнете <a href='%3'>овде</a> за да го преземете ажурирањето. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2653,6 +2744,11 @@ for additional privileges during the process. Could not check for new updates. Неможе да се провери за ажурирање. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2949,37 +3045,37 @@ It is not advisable to use it. Истече времето за поврзување на %1 во %2. - + Trying to connect to %1 at %2 … Обид за поврзување со %1 во %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Локалната папка %1 веќе постои, поставете ја за синхронизација.<br/><br/> - + Creating local sync folder %1 … Креирање на локална папка за синхронизација %1 … @@ -2989,84 +3085,84 @@ It is not advisable to use it. добро - + OK - + failed. неуспешно. - + Could not create local folder %1 Неможе да се креира локалната папка %1 - + No remote folder specified! Нема избрано папка на серверот! - + Error: %1 Грешка: %1 - + creating folder on Nextcloud: %1 Креирање папка: %1 - + Remote folder %1 created successfully. Папката %1 е успрешно креирана на серверот. - + The remote folder %1 already exists. Connecting it for syncing. Папката %1 веќе постои на серверот. Поврзете се за да ја синхронизирате. - - + + The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Креирањето на папката на серверот беше неуспешно бидејќи акредитивите се неточни!<br/>Вратете се назад и проверете ги вашите акредитиви.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Креирањето на папката на серверот беше неуспешно највероватно бидејќи акредитивите се неточни.</font><br/>Вратете се назад и проверете ги вашите акредитиви.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Креирање на папка %1 на серверот беше неуспешно со грешка <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! Успешно поврзување со %1! - + Connection to %1 could not be established. Please check again. Врската со %1 неможе да се воспостави. Пробајте покасно. - + Folder rename failed Неуспешно преименување на папка @@ -3076,28 +3172,28 @@ It is not advisable to use it. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Локална папка за синхронизација %1 е успешно креирана!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 параматри за поврзување - Add %1 account Додади %1 сметка + + + %1 Connection Wizard + %1 параматри за поврзување + Skip folders configuration @@ -3130,24 +3226,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Бидете безбедени - - OCC::OwncloudWizardResultPage - - - Everything set up! - Се е подесено! - - - - Open Local Folder - Отвори ја локалната папка - - - - Open %1 in Browser - Отвори ја %1 во прелистувач - - OCC::PollJob @@ -3158,6 +3236,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3175,12 +3263,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3309,7 +3397,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Серверот одговори со грешка при читање на папката '%1' : %2 - + Server replied with an error while reading directory "%1" : %2 @@ -3924,11 +4012,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Овозможи уредување - - - Allow editing - Овозможи уредување - Read only @@ -3949,6 +4032,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Заштити со лозинка + + + Allow editing + Овозможи уредување + + + + View only + + Allow upload and editing @@ -3964,16 +4057,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Испуши датотека (само за прикачување) - - - Note to recipient - Белешка до примачот - Unshare Не споделувај + + + Link name + + + + + Note to recipient + Белешка до примачот + Password protect @@ -3985,15 +4083,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Постави рок на траење - - Delete share link - Избриши го линкот за споделување + + Delete link + Add another link Додади линк + + + Delete share link + Избриши го линкот за споделување + Confirm Link Share Deletion @@ -4043,7 +4146,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Нема резултати за '%1' - + No results for "%1" @@ -4147,12 +4250,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Сподели со %1 - Context menu share @@ -4179,6 +4276,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Сподели преку %1 + + + + Activity + + Copy private link to clipboard @@ -4250,6 +4353,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Избриши + + + Share with %1 + parameter is Nextcloud + Сподели со %1 + OCC::SslButton @@ -4395,6 +4504,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Неможе да се обезбеди безбедна врска до <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4569,6 +4683,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Достапно е %1, потребно е %2 за почеток + + + Aborted + Откажано + @@ -4721,27 +4840,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Невалидни карактери, ве молиме преименувајте "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Името на датотеката соджи невалиден карактер - - Aborted - Откажано - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Има малку простор на дискот: Преземањата ќе доведат да просторот на дискот се намали под %1 поради тоа се прескокнува. - + There is insufficient space available on the server for some uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4817,6 +4997,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Ова издание е обезбедено од %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4874,23 +5077,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5408,14 +5695,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Најави се на твојот %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Вашата сметка е синхронизирана во локална папка - - QObject @@ -5508,6 +5787,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5522,29 +5833,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Сметката е поврзана - Current user status is do not disturb - + Account not connected + Сметката не е поврзана - Account connected - Сметката е поврзана + Current user status is online + - Account not connected - Сметката не е поврзана + Current user status is do not disturb + Account actions + + + Remove Account + Отстрани сметка + + + + Set status + + @@ -5557,17 +5878,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Најава - - - Remove Account - Отстрани сметка - Remove account Отстрани сметка + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5629,12 +5998,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5644,17 +6013,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5683,6 +6052,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Паузирај ја синхронизацијата за сите + + + Set user status + + Add account @@ -5718,12 +6092,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - Прикажи повеќе акции - Share %1 @@ -5784,6 +6152,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + Прикажи повеќе акции + + + + %1 - File activity + + main.cpp @@ -6083,6 +6467,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Најавете се од вашиот прелистувач (Следење на проток v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Се е подесено! + + + + Open Local Folder + Отвори ја локалната папка + + + + Open %1 in Browser + Отвори ја %1 во прелистувач + + OCC::ShibbolethCredentials @@ -6135,6 +6537,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Најава + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Вашата сметка е синхронизирана во локална папка + + OCC::UserStatus @@ -6158,4 +6568,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_nb_NO.ts b/translations/client_nb_NO.ts index 9b11aed81948..8d58a9001296 100644 --- a/translations/client_nb_NO.ts +++ b/translations/client_nb_NO.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1138,32 +1151,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser Gjenåpne nettleser - + Copy Link Kopier lenke @@ -1327,6 +1340,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1382,22 +1402,7 @@ Hvis synkroniseringen fortsetter som normalt, vil alle filene dine bli overskrev Behold lokale filer som konflikt - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1405,7 +1410,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1421,6 +1426,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2247,6 +2260,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2382,7 +2458,7 @@ Logs will be written to %1 <nobr>Fil '%1'<br/>kan ikke åpnes for skriving.<br/><br/>Loggen kan <b>ikke</b> lagres!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2425,6 +2501,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2594,6 +2675,13 @@ Logs will be written to %1 New %1 Update Ready Ny %1-oppdatering er klar + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + En ny oppdatering for %1 er i ferd med å bli installert. Oppdateringen +kan be om flere rettigheter under behandlingen. + New %1 update ready @@ -2601,10 +2689,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - En ny oppdatering for %1 er i ferd med å bli installert. Oppdateringen -kan be om flere rettigheter under behandlingen. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2641,6 +2727,11 @@ kan be om flere rettigheter under behandlingen. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2651,6 +2742,11 @@ kan be om flere rettigheter under behandlingen. Could not check for new updates. Klarte ikke å se etter nye oppdateringer. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2946,37 +3042,37 @@ It is not advisable to use it. Tidsavbrudd ved oppkobling mot %1 på %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Autentisert forespørsel til serveren ble omdirigert til '%1'. URL-en er ugyldig, serveren er feilkonfigurert. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Tilgang forbudt av serveren. For å sjekke om du har gyldig tilgang, <a href="%1">klikk her</a> for å aksessere tjenesten med nettleseren din. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Lokal synkroniseringsmappe %1 finnes allerede. Setter den opp for synkronisering.<br/><br/> - + Creating local sync folder %1 … @@ -2986,84 +3082,84 @@ It is not advisable to use it. ok - + OK - + failed. feilet. - + Could not create local folder %1 Klarte ikke å opprette lokal mappe %1 - + No remote folder specified! Ingen ekstern mappe spesifisert! - + Error: %1 Feil: %1 - + creating folder on Nextcloud: %1 oppretter mappe på Nextcloud: %1 - + Remote folder %1 created successfully. Ekstern mappe %1 ble opprettet. - + The remote folder %1 already exists. Connecting it for syncing. Ekstern mappe %1 finnes allerede. Kobler den til for synkronisering. - - + + The folder creation resulted in HTTP error code %1 Oppretting av mappe resulterte i HTTP-feilkode %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Oppretting av ekstern mappe feilet fordi påloggingsinformasjonen er feil!<br/>Gå tilbake og sjekk brukernavnet og passordet ditt.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Oppretting av ekstern mappe feilet, sannsynligvis fordi oppgitt påloggingsinformasjon er feil.</font><br/>Vennligst gå tilbake og sjekk ditt brukernavn og passord.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Oppretting av ekstern mappe %1 feilet med feil <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. En synkroniseringsforbindelse fra %1 til ekstern mappe %2 ble satt opp. - + Successfully connected to %1! Forbindelse til %1 opprettet! - + Connection to %1 could not be established. Please check again. Klarte ikke å etablere forbindelse til %1. Sjekk igjen. - + Folder rename failed Omdøping av mappe feilet @@ -3073,28 +3169,28 @@ It is not advisable to use it. Kan ikke fjerne og sikkerhetskopiere mappen fordi mappen eller en fil i mappen er åpen i et annet program. Lukk mappen eller filen og prøv igjen, eller avbryt oppsettet. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Oppretting av lokal synkroniseringsmappe %1 vellykket!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Veiviser for tilkobling - Add %1 account + + + %1 Connection Wizard + %1 Veiviser for tilkobling + Skip folders configuration @@ -3127,24 +3223,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Alt er satt opp! - - - - Open Local Folder - Åpne lokal mappe - - - - Open %1 in Browser - Åpne %1 i nettleser - - OCC::PollJob @@ -3155,6 +3233,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3172,12 +3260,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3306,7 +3394,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3921,11 +4009,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Tillat redigering - - - Allow editing - Tillat redigering - Read only @@ -3946,6 +4029,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Passordbeskytt + + + Allow editing + Tillat redigering + + + + View only + + Allow upload and editing @@ -3961,16 +4054,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Filkasse (kun opplasting) - - - Note to recipient - Melding til mottaker - Unshare Opphev deling + + + Link name + + + + + Note to recipient + Melding til mottaker + Password protect @@ -3982,15 +4080,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Sett utløpsdato - - Delete share link - Slett lenke til deling + + Delete link + Add another link Legg til en ny lenke + + + Delete share link + Slett lenke til deling + Confirm Link Share Deletion @@ -4040,7 +4143,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ingen resultater for '%1' - + No results for "%1" @@ -4144,12 +4247,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Del med %1 - Context menu share @@ -4176,6 +4273,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4247,6 +4350,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Slett + + + Share with %1 + parameter is Nextcloud + Del med %1 + OCC::SslButton @@ -4392,6 +4501,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Kan ikke koble sikkert til <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4566,6 +4680,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Bare %1 er tilgjengelig, trenger minst %2 for å begynne + + + Aborted + + @@ -4718,24 +4837,85 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Ugyldige tegn, gi et annet navn til "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Filnavnet inneholder minst ett ulovlig tegn - - Aborted + + Disk space is low: Downloads that would reduce free space below %1 were skipped. - - Disk space is low: Downloads that would reduce free space below %1 were skipped. + + There is insufficient space available on the server for some uploads. + + + OCC::SyncStatusSummary - - There is insufficient space available on the server for some uploads. + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 @@ -4814,6 +4994,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4871,23 +5074,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5405,14 +5692,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Hele kontoen din er synkronisert til den lokale mappen - - QObject @@ -5505,6 +5784,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5519,22 +5830,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Konto er koblet - Current user status is do not disturb + Account not connected - Account connected - Konto er koblet + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5542,6 +5853,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Kontoaktiviteter + + + Remove Account + + + + + Set status + + @@ -5554,17 +5875,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Logg inn - - - Remove Account - - Remove account Fjern konto + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5626,12 +5995,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5641,17 +6010,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5680,6 +6049,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5715,12 +6089,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5781,6 +6149,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6080,6 +6464,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + Alt er satt opp! + + + + Open Local Folder + Åpne lokal mappe + + + + Open %1 in Browser + Åpne %1 i nettleser + + OCC::ShibbolethCredentials @@ -6132,6 +6534,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Logg inn + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Hele kontoen din er synkronisert til den lokale mappen + + OCC::UserStatus @@ -6155,4 +6565,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_nl.ts b/translations/client_nl.ts index 9acd555aa7be..c9a243542c38 100644 --- a/translations/client_nl.ts +++ b/translations/client_nl.ts @@ -14,12 +14,6 @@ Open %1 locally %1 lokaal openen - - - - Show more actions - Toon meer acties - Open share dialog @@ -30,6 +24,25 @@ Share %1 Deel %1 + + + + Show more actions + Toon meer acties + + + + View activity + Activiteit bekijken + + + + ActivityList + + + Activity list + Activiteitlijst + CloudProviderWrapper @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Controleren op wijzigingen in '%1' @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + Kon "%1" niet verplaatsen naar "%2" @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Fout bij verwijderen '%1': %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Kan map "%1" niet verwijderen @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Het lijkt erop dat de functie Virtuele bestanden voor deze map is ingeschakeld. Momenteel is het niet mogelijk om impliciet virtuele bestanden te downloaden die end-to-end versleuteld zijn. Om de beste ervaring met virtuele bestanden en end-to-end-versleuteling te krijgen, raden we aan om ervoor te zorgen dat de versleutelde map is gemarkeerd met "Altijd lokaal beschikbaar maken". @@ -841,7 +854,7 @@ Dit zal alle synchronisaties, die op dit moment bezig zijn, afbreken. Enter username and password for "%1" at %2. - + Geef gebruikersnaam en wachtwoord op voor "%1" bij %2. @@ -1115,7 +1128,7 @@ Dit kan een probleem zijn met je OpenSSL-bibliotheken. There was an error accessing the "token" endpoint: <br><em>%1</em> - + Er trad een fout op bij het benaderen van het "token" endpoint: <br><em>%1</em> @@ -1143,32 +1156,32 @@ Dit kan een probleem zijn met je OpenSSL-bibliotheken. Kon de browser niet openen, kopieer de link naar je browser. - + Waiting for authorization Wachten op autorisatie - + Polling for authorization Controleren op autorisatie - + Starting authorization Starten autorisatie - + Link copied to clipboard. Link gekopieerd naar het klembord. - + Reopen Browser Heropen browser - + Copy Link Kopiëren link @@ -1336,6 +1349,14 @@ This means that the synchronization client might not upload local changes immedi Dit betekent dat de synchronisatieclient misschien niet meteen lokale wijzigingen uploadt maar slechts periodiek scant op lokale wijzigingen en die uploadt (standaard eens per twee uur). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Alle bestanden in je lokale syncmap '%1' werden verwijderd. Deze verwijderingen worden gesynchroniseerd naar je server, waardoor de bestanden niet beschikbaar zijn, tenzij ze worden teruggezet. Weet je zeker dat je deze acties wilt synchroniseren met de server? +Als dit een ongelukje was en je de bestanden wilt behouden, worden ze opnieuw gesynchroniseerd met de server. @@ -1397,38 +1418,23 @@ Doorgaan met deze synchronisatie overschrijft al je bestanden door een eerdere v Behoud lokale bestanden als conflict - - All files in the sync folder '%1' folder were deleted on the server. + + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Alle bestanden in de syncmap '%1' map werden verwijderd van de server. + Alle bestanden in de syncmap"'%1" map werden verwijderd van de server. Deze verwijderingen worden gesynchroniseerd naar je lokale syncmap, waardoor deze bestanden niet meer beschikbaar zijn, tenzij je het recht hebt om ze te herstellen. Als je de bestanden wilt behouden, worden ze opnieuw gesynchroniseerd met de server als je die autorisatie hebt. Als je de bestanden wilt verwijderen, worden ze niet beschikbaar, tenzij je de eigenaar bent. - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Alle bestanden in je lokale syncmap '%1' werden verwijderd. Deze verwijderingen worden gesynchroniseerd naar je server, waardoor de bestanden niet beschikbaar zijn, tenzij ze worden teruggezet. Weet je zeker dat je deze acties wilt synchroniseren met de server? -Als dit een ongelukje was en je de bestanden wilt behouden, worden ze opnieuw gesynchroniseerd met de server. - - - - All files in the sync folder "%1" folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - + Alle bestanden in je lokale syncmap "%1" werden verwijderd. Deze verwijderingen worden gesynchroniseerd naar je server, waardoor de bestanden niet beschikbaar zijn, tenzij ze worden teruggezet. Weet je zeker dat je deze acties wilt synchroniseren met de server? +Als dit een ongelukje was en je de bestanden wilt behouden, worden ze opnieuw gesynchroniseerd met de server. @@ -1440,6 +1446,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Alle bestanden verwijderen + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Alle bestanden in de syncmap '%1' map werden verwijderd van de server. +Deze verwijderingen worden gesynchroniseerd naar je lokale syncmap, waardoor deze bestanden niet meer beschikbaar zijn, tenzij je het recht hebt om ze te herstellen. +Als je de bestanden wilt behouden, worden ze opnieuw gesynchroniseerd met de server als je die autorisatie hebt. +Als je de bestanden wilt verwijderen, worden ze niet beschikbaar, tenzij je de eigenaar bent. + Keep files @@ -1489,7 +1506,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Een oud synchronisatieverslag "%1" is gevonden maar kan niet worden verwijderd. Zorg ervoor dat geen applicatie dit bestand gebruikt. @@ -1678,12 +1695,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Controleren op wijzigingen in externe "%1" Checking for changes in local "%1" - + Controleren op wijzigingen in lokale "%1" @@ -1843,7 +1860,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + Voer de naam van de hieronder te maken nieuwe map in "%1": @@ -2162,7 +2179,7 @@ Account: %3 Reading from keychain failed with error: "%1" - + Het lezen van de sleutelketen is mislukt met fout: "%1" @@ -2205,7 +2222,7 @@ Account: %3 This entry is provided by the system at "%1" and cannot be modified in this view. - + Dit gegeven is door het systeem vastgelegd op "%1" en kan niet worden aangepast in deze weergave. @@ -2257,7 +2274,7 @@ Onderdelen die gewist mogen worden, worden verwijderd als ze verhinderen dat een Cannot write changes to "%1". - + Kan geen wijzigingen wegschrijven naar "%1". @@ -2275,6 +2292,69 @@ Onderdelen die gewist mogen worden, worden verwijderd als ze verhinderen dat een Voeg nieuw negeerpatroon toe: + + OCC::InvalidFilenameDialog + + + Invalid filename + Ongeldige bestandsnaam + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + Fout + + + + Please enter a new name for the file: + + + + + New filename + Nieuwe bestandsnaam + + + + Rename file + Bestand hernoemen + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Het bestand %1 kan niet worden gesynchroniseerd omdat de naam tekens bevat die niet zijn toegestaan op dit systeem. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + De volgende tekens zijn niet toegestaan op het systeem: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Je bent niet gemachtigd om de naam van dit bestand te hernoemen. Vraag de auteur van het bestand om het te hernoemen. + + + + Filename contains illegal characters: %1 + Bestandsnaam bevat ongeldige tekens: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Kan de naam van het bestand niet hernoemen. Zorg ervoor dat je verbonden bent met de server. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Kan de naam van het bestand niet hernoemen omdat er al een bestand met dezelfde naam op de server bestaat. Kies een andere naam. + + OCC::LegalNotice @@ -2415,7 +2495,7 @@ Logs worden geschreven naar %1 <nobr>Bestand '%1'<br/>kan niet worden geopend voor schrijven.<br/><br/>De logging output kan <b>niet</b> worden weggeschreven!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2458,6 +2538,11 @@ Logs worden geschreven naar %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Er is een nieuwe versie van de %1 Client beschikbaar, maar update is mislukt.</p><p><b>%2</b> is gedownload. De geïnstalleerde versie is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2627,6 +2712,13 @@ Logs worden geschreven naar %1 New %1 Update Ready Nieuwe %1 update is klaar + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Er wordt een nieuwe update voor %1 geïnstalleerd. De updater kan +vragen om extra autorisaties tijdens installatie. + New %1 update ready @@ -2634,10 +2726,8 @@ Logs worden geschreven naar %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Er wordt een nieuwe update voor %1 geïnstalleerd. De updater kan -vragen om extra autorisaties tijdens installatie. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2674,6 +2764,11 @@ vragen om extra autorisaties tijdens installatie. New %1 is available. Please click <a href='%2'>here</a> to download the update. Nieuwe %1 beschikbaar. Klik <a href='%2'>hier</a> om de update te downloaden. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Kon de download niet bijwerken. Open <a href='%1'>%1</a> om de download handmatig bij te werken. + Could not download update. Please open %1 to download the update manually. @@ -2684,6 +2779,11 @@ vragen om extra autorisaties tijdens installatie. Could not check for new updates. Kon niet controleren op updates. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Nieuwe %1 beschikbaar. Open <a href='%2'>%1</a> om de update te downloaden. + New %1 is available. Please open %2 to download the update. @@ -2772,12 +2872,12 @@ vragen om extra autorisaties tijdens installatie. %1 folder "%2" is synced to local folder "%3" - + %1 map "%2" is gesynchroniseerd naar de lokale map "%3" Sync the folder "%1" - + Synchroniseer de map "%1" @@ -2980,37 +3080,37 @@ Het is niet te adviseren om het te gebruiken. Time-out bij verbinden met %1 om %2. - + Trying to connect to %1 at %2 … Probeer te verbinden met %1 om %2 ... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. De geauthentiseerde aanvraag voor de server werd omgeleid naar '%1'. De URL is onjuist, de server is verkeerd geconfigureerd. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + De geauthentiseerde aanvraag voor de server werd omgeleid naar "%1". De URL is onjuist, de server is verkeerd geconfigureerd. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Toegang door server verboden. Om te verifiëren dat je toegang mag hebben, <a href="%1">klik hier</a> om met je browser toegang tot de service te krijgen. - + There was an invalid response to an authenticated WebDAV request Er was een ongeldig antwoord op een geauthenticeerde WebDAV opvraging - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Lokale synch map %1 bestaat al, deze wordt ingesteld voor synchronisatie.<br/><br/> - + Creating local sync folder %1 … Creëren lokale sync map %1 ... @@ -3020,84 +3120,84 @@ Het is niet te adviseren om het te gebruiken. ok - + OK OK - + failed. mislukt. - + Could not create local folder %1 Kon lokale map %1 niet aanmaken - + No remote folder specified! Geen externe map opgegeven! - + Error: %1 Fout: %1 - + creating folder on Nextcloud: %1 aanmaken map op Nextcloud: %1 - + Remote folder %1 created successfully. Externe map %1 succesvol gecreërd. - + The remote folder %1 already exists. Connecting it for syncing. De remote map %1 bestaat al. Verbinden voor synchroniseren. - - + + The folder creation resulted in HTTP error code %1 Het aanmaken van de map resulteerde in HTTP foutcode %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Het aanmaken van de externe map is mislukt, waarschijnlijk omdat je inloggegevens fout waren.<br/>Ga terug en controleer je inloggegevens.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Het aanmaken van de externe map is mislukt, waarschijnlijk omdat je inloggegevens fout waren.</font><br/>ga terug en controleer je inloggevens.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Aanmaken van remote map %1 mislukt met fout <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Er is een sync verbinding van %1 naar remote directory %2 opgezet. - + Successfully connected to %1! Succesvol verbonden met %1! - + Connection to %1 could not be established. Please check again. Verbinding met %1 niet geslaagd. Probeer het nog eens. - + Folder rename failed Hernoemen map mislukt @@ -3107,28 +3207,28 @@ Het is niet te adviseren om het te gebruiken. Kan de map niet verwijderen en backuppen, omdat de map of een bestand daarin, geopend is in een ander programma. Sluit de map of het bestand en drup op Opnieuw of annuleer de installatie. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Kan de map niet verwijderen en backuppen, omdat de map of een bestand daarin, geopend is in een ander programma. Sluit de map of het bestand en drup op Opnieuw of annuleer de installatie. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Lokale synch map %1 is succesvol aangemaakt!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Verbindingswizard - Add %1 account Toevoegen %1 account + + + %1 Connection Wizard + %1 Verbindingswizard + Skip folders configuration @@ -3167,24 +3267,6 @@ Dit is een nieuwe, experimentele modus. Als je besluit het te gebruiken, vragen Blijf veilig - - OCC::OwncloudWizardResultPage - - - Everything set up! - Alles is geïnstalleerd! - - - - Open Local Folder - Open lokale map - - - - Open %1 in Browser - Open %1 in browser - - OCC::PollJob @@ -3195,6 +3277,16 @@ Dit is een nieuwe, experimentele modus. Als je besluit het te gebruiken, vragen OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3210,16 +3302,16 @@ Dit is een nieuwe, experimentele modus. Als je besluit het te gebruiken, vragen File names ending with a period are not supported on this file system. Bestandsnamen die eindigen met een punt worden niet ondersteund door het bestandssysteem. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Bestandsnamen met een '%1' symbool worden niet ondersteund door het bestandssysteem. + + + File names containing the character "%1" are not supported on this file system. + Bestandsnamen met een "%1" symbool worden niet ondersteund door het bestandssysteem. + File name contains at least one invalid character @@ -3346,9 +3438,9 @@ Dit is een nieuwe, experimentele modus. Als je besluit het te gebruiken, vragen Server gaf een foutmelding bij lezen directory '%1' : %2 - + Server replied with an error while reading directory "%1" : %2 - + Server gaf een foutmelding bij lezen directory "%1'": %2 @@ -3964,11 +4056,6 @@ Fout bij instellen pin status Allow Editing Bewerken toestaan - - - Allow editing - Bewerken toestaan - Read only @@ -3989,6 +4076,16 @@ Fout bij instellen pin status Password Protect Wachtwoord beveiligen + + + Allow editing + Bewerken toestaan + + + + View only + + Allow upload and editing @@ -4004,16 +4101,21 @@ Fout bij instellen pin status File drop (upload only) Bestand droppen (alleen uploaden) - - - Note to recipient - Notitie voor ontvanger - Unshare Stop met delen + + + Link name + Linknaam + + + + Note to recipient + Notitie voor ontvanger + Password protect @@ -4025,15 +4127,20 @@ Fout bij instellen pin status Stel vervaldatum in - - Delete share link - Verwijder deellink + + Delete link + Add another link Toevoegen andere link + + + Delete share link + Verwijder deellink + Confirm Link Share Deletion @@ -4083,9 +4190,9 @@ Fout bij instellen pin status Geen resultaten voor '%1' - + No results for "%1" - + Geen resultaten voor "%1" @@ -4187,12 +4294,6 @@ Fout bij instellen pin status OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Delen met %1 - Context menu share @@ -4219,6 +4320,12 @@ Fout bij instellen pin status Share via %1 Delen via %1 + + + + Activity + + Copy private link to clipboard @@ -4290,6 +4397,12 @@ Fout bij instellen pin status Delete Verwijderen + + + Share with %1 + parameter is Nextcloud + Delen met %1 + OCC::SslButton @@ -4435,6 +4548,11 @@ Fout bij instellen pin status Cannot connect securely to <i>%1</i>: Kan niet beveiligd verbinden met <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4609,6 +4727,11 @@ Fout bij instellen pin status Placeholders are postfixed with file sizes using Utility::octetsToString() Slechts %1 beschikbaar, maar heeft minimaal %2 nodig om te starten + + + Aborted + Afgebroken + @@ -4761,27 +4884,88 @@ Fout bij instellen pin status Invalid characters, please rename "%1" Ongeldige tekens, hernoem "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character De bestandsnaam bevat ten minste één ongeldig teken - - Aborted - Afgebroken - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Schijfruimte laa: Downloads die de vrije ruimte tot onder %1 zouden reduceren, zijn overgeslagen. - + There is insufficient space available on the server for some uploads. Onvoldoende schijfruimte op de server voor sommige uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4857,6 +5041,29 @@ Fout bij instellen pin status <p>Deze release is geleverd door %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4914,24 +5121,108 @@ Fout bij instellen pin status - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - De Virtuele bestandssysteemfunctie vereist een NTFS bestandssysteem, %1 gebruikt %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Kan vooraf gedefinieerde statussen niet ophalen. Zorg ervoor dat je verbonden bent met de server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Downloaden begin-tot-eind versleuteld bestand mislukt + + Could not fetch user status. Make sure you are connected to the server. + Kan gebruikersstatus niet ophalen. Zorg ervoor dat je verbonden bent met de server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Het lijkt erop dat je een virtueel bestand probeert te downloaden dat end-to-end-versleuteld is. Het impliciet downloaden van dergelijke bestanden wordt momenteel niet ondersteund. Om dit probleem te omzeilen, ga je naar de instellingen en markeer je de versleutelde map met "Altijd lokaal beschikbaar maken". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + Kan gebruikersstatus niet instellen. Zorg ervoor dat je verbonden bent met de server. + + + + Could not clear user status message. Make sure you are connected to the server. + Kan het gebruikersstatusbericht niet wissen. Zorg ervoor dat je verbonden bent met de server. + + + + + Don't clear + Niet wissen + + + + 30 minutes + 30 minuten + + + + + 1 hour + 1 uur + + + + 4 hours + 4 uren + + + + + Today + Vandaag + + + + + This week + Deze week + + + + Less than a minute + Minder dan een minuut + + + + 1 minute + 1 minuut + + + + %1 minutes + %1 minuten + + + + %1 hours + %1 uren + + + + 1 day + 1 dag + + + + %1 days + %1 dagen + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + De Virtuele bestandssysteemfunctie vereist een NTFS bestandssysteem, %1 gebruikt %2 @@ -5140,7 +5431,7 @@ Fout bij instellen pin status Checking for changes in remote "%1" - + Controleren op wijzigingen in externe "%1" @@ -5150,7 +5441,7 @@ Fout bij instellen pin status Checking for changes in local "%1" - + Controleren op wijzigingen in lokale "%1" @@ -5448,14 +5739,6 @@ Fout bij instellen pin status Inloggen bij %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Je volledige account is gesynchroniseerd met de lokale map - - QObject @@ -5548,6 +5831,38 @@ Fout bij instellen pin status Kon niet verbinden met database. + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5562,29 +5877,39 @@ Fout bij instellen pin status - Current user status is online - Huidige gebruikersstatus is online + Account connected + Account verbonden - Current user status is do not disturb - Huidige gebruikersstatus is niet storen + Account not connected + Account niet verbonden - Account connected - Account verbonden + Current user status is online + Huidige gebruikersstatus is online - Account not connected - Account niet verbonden + Current user status is do not disturb + Huidige gebruikersstatus is niet storen Account actions Accountacties + + + Remove Account + Verwijder Account + + + + Set status + Status instellen + @@ -5597,17 +5922,65 @@ Fout bij instellen pin status Log in Meld u aan - - - Remove Account - Verwijder Account - Remove account Verwijder account + + UserStatusSelector + + + Online status + Online status + + + + Online + Online + + + + Away + Afwezig + + + + Do not disturb + Niet storen + + + + Invisible + Onzichtbaar + + + + Status message + Statusbericht + + + + What is your status? + Wat is je status? + + + + Clear status message after + Statusbericht wissen na + + + + Clear status message + Statusbericht wissen + + + + Set status message + Statusbericht instellen + + Utility @@ -5669,12 +6042,12 @@ Fout bij instellen pin status ValidateChecksumHeader - + The checksum header is malformed. De header van het controlegetal is misvormd. - + The checksum header contained an unknown checksum type '%1' Het header controlegetal bevat een onbekend controlegetal type '%1' @@ -5684,19 +6057,19 @@ Fout bij instellen pin status Het gedownloade bestand komt niet overeen met het controlegetal. Het wordt opnieuw verwerkt. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Het gedownloade bestand komt niet overeen met het controlegetal. Het wordt opnieuw verwerkt. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + Het header controlegetal bevat een onbekend controlegetal type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" - + Het gedownloade bestand komt niet overeen met het controlegetal. Het wordt opnieuw verwerkt. "%1" != "%2" @@ -5723,6 +6096,11 @@ Fout bij instellen pin status Pause sync for all Synchronisatie voor iedereen onderbreken + + + Set user status + Gebruikersstatus instellen + Add account @@ -5758,12 +6136,6 @@ Fout bij instellen pin status Current user status is do not disturb Huidige gebruikersstatus is niet storen - - - - Show more actions - Toon meer acties - Share %1 @@ -5824,6 +6196,22 @@ Fout bij instellen pin status Open share dialog Open het dialoogvenster voor delen + + + Unified search results list + + + + + + Show more actions + Toon meer acties + + + + %1 - File activity + + main.cpp @@ -6123,6 +6511,24 @@ Fout bij instellen pin status Login in je browser (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Alles is geïnstalleerd! + + + + Open Local Folder + Open lokale map + + + + Open %1 in Browser + Open %1 in browser + + OCC::ShibbolethCredentials @@ -6175,6 +6581,14 @@ Fout bij instellen pin status Inloggen + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Je volledige account is gesynchroniseerd met de lokale map + + OCC::UserStatus @@ -6198,4 +6612,17 @@ Fout bij instellen pin status Online + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Downloaden begin-tot-eind versleuteld bestand mislukt + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Het lijkt erop dat je een virtueel bestand probeert te downloaden dat end-to-end-versleuteld is. Het impliciet downloaden van dergelijke bestanden wordt momenteel niet ondersteund. Om dit probleem te omzeilen, ga je naar de instellingen en markeer je de versleutelde map met "Altijd lokaal beschikbaar maken". + + \ No newline at end of file diff --git a/translations/client_oc.ts b/translations/client_oc.ts index e645746c578e..decb9749da25 100644 --- a/translations/client_oc.ts +++ b/translations/client_oc.ts @@ -14,6 +14,16 @@ Open %1 locally Dobrir %1 localement + + + Open share dialog + Dobrir la fenèstra de partiment + + + + Share %1 + Partejar %1 + @@ -21,14 +31,17 @@ Mostrar mai d’accions - - Open share dialog - + + View activity + Veire activitat + + + ActivityList - - Share %1 - Partejar %1 + + Activity list + Lista d’activitats @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Verificacions dels cambiaments dins « %1 » @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + Desplaçament impossible de « %1 » a « %2 » @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Error de supression « %1 » : %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Supression impossibla del dossièr « %1 » @@ -275,7 +288,7 @@ End to end encryption mnemonic - + Mnemonic de chiframent del cap a la fin @@ -321,7 +334,7 @@ Synchronize none - + Res sincronizar @@ -331,7 +344,7 @@ End-to-End Encryption with Virtual Files - + Chiframent del cap a la fin e fichièrs virtuals @@ -587,7 +600,7 @@ This action will abort any currently running synchronization. %1 as %2 - + %1 coma %2 @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. Dobertura impossibla del navigador, mercés de copiar lo ligam dins lo navigador. - + Waiting for authorization En espèra de l’autorizacion - + Polling for authorization - + Starting authorization Aviada de l’autorizacion - + Link copied to clipboard. Ligam copiat al quichapapièrs. - + Reopen Browser Tornar dobrir lo navegador - + Copy Link Copiar ligam @@ -1324,6 +1337,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1377,22 +1397,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1400,7 +1405,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1416,6 +1421,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Suprimir totes los fichièrs + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -1633,12 +1646,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Synchronizing VirtualFiles with local folder - + Sincronizacion VirtualFiles amb lo dossièr local Synchronizing with local folder - + Sincronizacion amb lo dossièr local @@ -2240,6 +2253,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + nom de fichièr invalid + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + Error + + + + Please enter a new name for the file: + Mercés de picar un nom novèl pel fichièr : + + + + New filename + Nom novèl de fichièr + + + + Rename file + Renomenar fichièr + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2375,7 +2451,7 @@ Logs will be written to %1 - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2418,6 +2494,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2587,6 +2668,12 @@ Logs will be written to %1 New %1 Update Ready Nòva mesa a jorn %1 prèsta + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + + New %1 update ready @@ -2594,8 +2681,7 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. @@ -2633,6 +2719,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2643,6 +2734,11 @@ for additional privileges during the process. Could not check for new updates. Verificacion de las mesas a jorn impossibla. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2938,37 +3034,37 @@ It is not advisable to use it. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> - + Creating local sync folder %1 … @@ -2978,84 +3074,84 @@ It is not advisable to use it. D'acòrdi - + OK D’acòrdi - + failed. - + Could not create local folder %1 Impossible de crear lo dossièr local « %s » - + No remote folder specified! - + Error: %1 Error : %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. - + The remote folder %1 already exists. Connecting it for syncing. - - + + The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! - + Connection to %1 could not be established. Please check again. - + Folder rename failed @@ -3065,28 +3161,28 @@ It is not advisable to use it. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - - Add %1 account Apondre compte %1 + + + %1 Connection Wizard + + Skip folders configuration @@ -3119,24 +3215,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Demoratz en seguretat - - OCC::OwncloudWizardResultPage - - - Everything set up! - Tot es prèst ! - - - - Open Local Folder - Dobrir lo dossièr local - - - - Open %1 in Browser - Dobrir %1 dins lo navegador - - OCC::PollJob @@ -3147,6 +3225,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3164,12 +3252,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3298,7 +3386,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3913,11 +4001,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Permetre la modificacion - - - Allow editing - Permetre la modificacion - Read only @@ -3938,6 +4021,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Senhal de proteccion + + + Allow editing + Permetre la modificacion + + + + View only + Veire solament + Allow upload and editing @@ -3953,16 +4046,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) - - - Note to recipient - - Unshare Partejar pas mai + + + Link name + Nom ligam + + + + Note to recipient + + Password protect @@ -3974,15 +4072,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Especificar una data d'expiracion - - Delete share link - + + Delete link + Suprimir ligam Add another link Ajustar un autre ligam + + + Delete share link + + Confirm Link Share Deletion @@ -4032,7 +4135,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cap de resultat per « %1 » - + No results for "%1" @@ -4136,12 +4239,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Partejar amb %1 - Context menu share @@ -4168,6 +4265,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Partejar amb %1 + + + + Activity + Activitat + Copy private link to clipboard @@ -4239,6 +4342,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Suprimir + + + Share with %1 + parameter is Nextcloud + Partejar amb %1 + OCC::SslButton @@ -4384,6 +4493,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4558,6 +4672,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() + + + Aborted + Anullat + @@ -4711,26 +4830,87 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - File name contains at least one invalid character + + Synchronization will resume shortly. - - Aborted - Anullat + + File name contains at least one invalid character + - + Disk space is low: Downloads that would reduce free space below %1 were skipped. - + There is insufficient space available on the server for some uploads. + + OCC::SyncStatusSummary + + + + Offline + Fòra linha + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + %1 de %2 · %3 restants + + + + %1 of %2 + %1 de %2 + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4798,7 +4978,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p><small>Using virtual files plugin: %1</small></p> - + <p><small>Usatge extension pels fichièrs virtuals : %1</small></p> @@ -4806,6 +4986,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Aquesta version es provesida per %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4863,23 +5066,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + Escafar pas + + + + 30 minutes + 30 minutas + + + + + 1 hour + 1 ora + + + + 4 hours + 4 oras + + + + + Today + Uèi + + + + + This week + Aquesta setmana + + + + Less than a minute + Mens d’una setmana + + + + 1 minute + 1 minuta + + + + %1 minutes + %1 minutas + + + + %1 hours + %1 oras + + + + 1 day + 1 jorn + + + + %1 days + %1 jorns + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5397,14 +5684,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Vòstre compte entièr es sincronizat al dossièr local - - QObject @@ -5497,6 +5776,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Cargar mai de resultats + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5511,29 +5822,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Compte connectat - Current user status is do not disturb - + Account not connected + Compte pas connectat - Account connected - Compte connectat + Current user status is online + - Account not connected - Compte pas connectat + Current user status is do not disturb + Account actions Accions del compte + + + Remove Account + Levar compte + + + + Set status + + @@ -5546,17 +5867,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Se connectar - - - Remove Account - Levar compte - Remove account Levar compte + + UserStatusSelector + + + Online status + + + + + Online + En linha + + + + Away + Absent + + + + Do not disturb + Desrengar pas + + + + Invisible + Invisible + + + + Status message + Messatge d’estatut + + + + What is your status? + Quin es vòstre estatut ? + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5618,12 +5987,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5633,17 +6002,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5672,6 +6041,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Suspendre la sincro. per totes + + + Set user status + + Add account @@ -5707,12 +6081,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - Veire mai d’accions - Share %1 @@ -5773,6 +6141,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Dobrir fenèstra de partatge + + + Unified search results list + + + + + + Show more actions + Veire mai d’accions + + + + %1 - File activity + + main.cpp @@ -6072,6 +6456,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Connexion via lo navigador (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Tot es prèst ! + + + + Open Local Folder + Dobrir lo dossièr local + + + + Open %1 in Browser + Dobrir %1 dins lo navegador + + OCC::ShibbolethCredentials @@ -6124,6 +6526,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Se connectar + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Vòstre compte entièr es sincronizat al dossièr local + + OCC::UserStatus @@ -6147,4 +6557,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss En linha + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_pl.ts b/translations/client_pl.ts index 18391bbe52b2..efb5f511ab7c 100644 --- a/translations/client_pl.ts +++ b/translations/client_pl.ts @@ -14,12 +14,6 @@ Open %1 locally Otwórz lokalnie %1 - - - - Show more actions - Pokaż więcej akcji - Open share dialog @@ -30,6 +24,25 @@ Share %1 Udostępnij %1 + + + + Show more actions + Pokaż więcej akcji + + + + View activity + Podgląd aktywności + + + + ActivityList + + + Activity list + Lista aktywności + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - Nie można przenieść "%1" do "%1" + Could not move "%1" to "%2" + Nie można przenieść "%1" do "%2" @@ -1144,32 +1157,32 @@ Może to być problem z bibliotekami OpenSSL. Nie można otworzyć przeglądarki, skopiuj link do swojej przeglądarki. - + Waiting for authorization Oczekiwanie na autoryzację - + Polling for authorization Odpytywanie o autoryzację - + Starting authorization Rozpoczęcie autoryzacji - + Link copied to clipboard. Link skopiowany do schowka. - + Reopen Browser Otwórz ponownie przeglądarkę - + Copy Link Kopiuj link @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Oznacza to, że klient synchronizacji może nie przesyłać natychmiast zmian lokalnych. Zamiast tego będzie skanował tylko zmiany lokalne i przesyłać je sporadycznie (domyślnie co dwie godziny). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Wszystkie pliki w lokalnym katalogu synchronizacji '%1' zostały usunięte. Te usunięcia zostaną zsynchronizowane z Twoim serwerem, co oznacza całkowite ich usunięcie +Czy na pewno chcesz zsynchronizować te działania z serwerem? +Jeśli to był przypadek i zdecydujesz się zachować swoje pliki, zostaną one przywrócone z serwera. @@ -1398,27 +1420,7 @@ Kontynuowanie synchronizacji w normalny sposób spowoduje zastąpienie wszystkic Zachowaj pliki lokalne jako pliki konfliktu - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Wszystkie pliki z katalogu synchronizacji '%1' zostały usunięte z serwera. -W momencie synchronizacji zostaną usunięte z lokalnego katalogu, co spowoduje ich niedostępność, chyba że posiadasz prawo do przywracania. -Jeśli zdecydujesz się przywrócić pliki i posiadasz odpowiednie uprawnienia, zostaną one ponownie wysłane na serwer. -Jeśli zdecydujesz się je usunąć, nie będą już dostępne. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Wszystkie pliki w lokalnym katalogu synchronizacji '%1' zostały usunięte. Te usunięcia zostaną zsynchronizowane z Twoim serwerem, co oznacza całkowite ich usunięcie -Czy na pewno chcesz zsynchronizować te działania z serwerem? -Jeśli to był przypadek i zdecydujesz się zachować swoje pliki, zostaną one przywrócone z serwera. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1429,7 +1431,7 @@ Jeśli zdecydujesz się przywrócić pliki i posiadasz odpowiednie uprawnienia, Jeśli zdecydujesz się je usunąć, nie będą już dostępne. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1447,6 +1449,17 @@ Jeśli to był przypadek i zdecydujesz się zachować swoje pliki, zostaną one Remove all files Usuń wszystkie pliki + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Wszystkie pliki z katalogu synchronizacji '%1' zostały usunięte z serwera. +W momencie synchronizacji zostaną usunięte z lokalnego katalogu, co spowoduje ich niedostępność, chyba że posiadasz prawo do przywracania. +Jeśli zdecydujesz się przywrócić pliki i posiadasz odpowiednie uprawnienia, zostaną one ponownie wysłane na serwer. +Jeśli zdecydujesz się je usunąć, nie będą już dostępne. + Keep files @@ -2277,6 +2290,69 @@ Elementy, dla których usunięcie jest dozwolone, zostaną usunięte, o ile umo Dodaj nowy wzór ignorowania: + + OCC::InvalidFilenameDialog + + + Invalid filename + Nieprawidłowa nazwa pliku + + + + The file could not be synced because it contains characters which are not allowed on this system. + Nie można zsynchronizować pliku, ponieważ zawiera znaki, które nie są dozwolone w tym systemie. + + + + Error + Błąd + + + + Please enter a new name for the file: + Wprowadź nową nazwę pliku: + + + + New filename + Nowa nazwa pliku + + + + Rename file + Zmień nazwę pliku + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Plik %1 nie mógł zostać zsynchronizowany, ponieważ nazwa zawiera znaki, które nie są dozwolone w tym systemie. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Następujące znaki nie są dozwolone w systemie: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Nie masz uprawnień do zmiany nazwy tego pliku. Poproś autora pliku o zmianę jego nazwy. + + + + Filename contains illegal characters: %1 + Nazwa pliku zawiera niedozwolone znaki: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Nie udało się zmienić nazwy pliku. Upewnij się, że masz połączenie z serwerem. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Nie można zmienić nazwy pliku, ponieważ plik o tej nazwie już istnieje na serwerze. Wybierz inną nazwę. + + OCC::LegalNotice @@ -2417,7 +2493,7 @@ Dzienniki zostaną zapisane w %1 <nobr>Plik '%1'<br/>nie może zostać otwarty do zapisu.<br/><br/>Dane wyjściowe dziennika <b>nie</b> mogą być zapisane!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>Plik "%1"<br/>nie może być otwarty do zapisu.<br/><br/>Dane wyjściowe dziennika <b>nie</b> mogą być zapisane!</nobr> @@ -2460,6 +2536,11 @@ Dzienniki zostaną zapisane w %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Dostępna jest nowa wersja klienta %1, ale proces aktualizacji nie powiódł się.</p><p><b>%2</b> został pobrany. Zainstalowana wersja to %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Dostępna jest nowa wersja klienta %1, ale proces aktualizacji nie powiódł się.</p><p><b>%2</b> został pobrany. Zainstalowana wersja to %3. Jeśli potwierdzisz ponowne uruchomienie i aktualizację, komputer może się ponownie uruchomić, aby zakończyć instalację.</p> + Ask again later @@ -2629,6 +2710,13 @@ Dzienniki zostaną zapisane w %1 New %1 Update Ready Nowa aktualizacja %1 jest gotowa + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Nowa aktualizacja dla %1 jest gotowa do instalacji. Aktualizator może zapytać +o dodatkowe uprawnienia podczas procesu aktualizacji. + New %1 update ready @@ -2636,10 +2724,8 @@ Dzienniki zostaną zapisane w %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Nowa aktualizacja dla %1 jest gotowa do instalacji. Aktualizator może zapytać -o dodatkowe uprawnienia podczas procesu aktualizacji. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Nowa aktualizacja dla %1 jest gotowa do instalacji. Aktualizator może zapytać o dodatkowe uprawnienia podczas procesu aktualizacji. Twój komputer może się ponownie uruchomić, aby zakończyć instalację. @@ -2676,6 +2762,11 @@ o dodatkowe uprawnienia podczas procesu aktualizacji. New %1 is available. Please click <a href='%2'>here</a> to download the update. Dostępny jest nowy %1. Kliknij <a href='%2'>tutaj</a>, aby pobrać aktualizację. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Nie można pobrać aktualizacji. Kliknij <a href='%1'>%1</a>, aby ręcznie pobrać aktualizację. + Could not download update. Please open %1 to download the update manually. @@ -2686,6 +2777,11 @@ o dodatkowe uprawnienia podczas procesu aktualizacji. Could not check for new updates. Nie można sprawdzić nowych aktualizacji. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Dostępny jest nowy %1. Kliknij <a href='%2'>%2</a>, aby pobrać aktualizację. + New %1 is available. Please open %2 to download the update. @@ -2982,37 +3078,37 @@ Nie zaleca się korzystania z niego. Przekroczono limit czasu podczas próby połączenia do %1 na %2. - + Trying to connect to %1 at %2 … Próba połączenia z %1 w %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Uwierzytelnione zapytanie do serwera zostało przekierowane do '%1'. Adres URL jest nieprawidłowy, serwer został źle skonfigurowany. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. Uwierzytelnione zapytanie do serwera zostało przekierowane do "%1". Adres URL jest nieprawidłowy, serwer został źle skonfigurowany. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Dostęp zabroniony przez serwer. Aby sprawdzić, czy masz odpowiednie uprawnienia, <a href="%1">kliknij tutaj</a>, aby połączyć się z usługą poprzez przeglądarkę. - + There was an invalid response to an authenticated WebDAV request Wystąpiła nieprawidłowa odpowiedź na żądanie uwierzytelnienia WebDav - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Lokalny katalog synchronizacji %1 już istnieje. Ustawiam go do synchronizacji.<br/><br/> - + Creating local sync folder %1 … Tworzenie lokalnego katalogu synchronizacji %1… @@ -3022,84 +3118,84 @@ Nie zaleca się korzystania z niego. OK - + OK OK - + failed. błąd. - + Could not create local folder %1 Nie można utworzyć katalogu lokalnego %1 - + No remote folder specified! Nie określono katalogu zdalnego! - + Error: %1 Błąd: %1 - + creating folder on Nextcloud: %1 tworzenie katalogu w Nextcloud: %1 - + Remote folder %1 created successfully. Katalog zdalny %1 został pomyślnie utworzony. - + The remote folder %1 already exists. Connecting it for syncing. Zdalny katalog %1 już istnieje. Podłączam go do synchronizowania. - - + + The folder creation resulted in HTTP error code %1 Tworzenie katalogu spowodowało kod błędu HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - Nie udało się utworzyć zdalnego katalogu ponieważ podane poświadczenia są nieprawidłowe!<br/>Wróć i sprawdź poświadczenia.</p> + Nie udało się utworzyć zdalnego katalogu ponieważ podane poświadczenia są nieprawidłowe!<br/>Powróć i sprawdź poświadczenia.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - <p><font color="red">Tworzenie katalogu zdalnego nie powiodło się. Prawdopodobnie dostarczone poświadczenia są nieprawidłowe.</font><br/>Wróć i sprawdź poświadczenia.</p> + <p><font color="red">Tworzenie katalogu zdalnego nie powiodło się. Prawdopodobnie dostarczone poświadczenia są nieprawidłowe.</font><br/>Powróć i sprawdź poświadczenia.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Tworzenie katalogu zdalnego %1 nie powiodło się z powodu błędu <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Połączenie synchronizacji z %1 do katalogu zdalnego %2 zostało utworzone. - + Successfully connected to %1! Udane połączenie z %1! - + Connection to %1 could not be established. Please check again. Nie można nawiązać połączenia z %1. Sprawdź ponownie. - + Folder rename failed Zmiana nazwy katalogu nie powiodła się @@ -3109,28 +3205,28 @@ Nie zaleca się korzystania z niego. Nie można usunąć i wykonać kopii zapasowej katalogu, ponieważ katalog lub plik znajdujący się w nim jest otwarty w innym programie. Zamknij katalog lub plik i naciśnij przycisk "Ponów próbę" lub anuluj konfigurację. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Nie można usunąć oraz wykonać kopii zapasowej katalogu, ponieważ katalog lub plik znajdujący się w nim jest otwarty w innym programie. Zamknij katalog lub plik i naciśnij przycisk "Ponów próbę" lub anuluj konfigurację. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Utworzenie lokalnego katalogu synchronizowanego %1 zakończone pomyślnie!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Kreator połączeń %1 - Add %1 account Dodaj konto %1 + + + %1 Connection Wizard + Kreator połączeń %1 + Skip folders configuration @@ -3169,24 +3265,6 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Bądź bezpieczny - - OCC::OwncloudWizardResultPage - - - Everything set up! - Wszystko skonfigurowane! - - - - Open Local Folder - Otwórz katalog lokalny - - - - Open %1 in Browser - Otwórz %1 w przeglądarce - - OCC::PollJob @@ -3197,6 +3275,16 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Plik zawiera już spacje i nie można zmienić jego nazwy, ponieważ plik o tej samej nazwie już istnieje na serwerze. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Plik zawiera już spacje i nie można zmienić jego nazwy, ponieważ plik o tej nazwie już istnieje lokalnie. + Symbolic links are not supported in syncing. @@ -3212,16 +3300,16 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł File names ending with a period are not supported on this file system. Nazwy plików kończące się kropką nie są obsługiwane w tym systemie plików. - - - File names containing the character "%1" are not supported on this file system. - Nazwy plików zawierające znak "%1" nie są obsługiwane w tym systemie plików. - File names containing the character '%1' are not supported on this file system. Nazwy plików zawierające znak '%1' nie są obsługiwane w tym systemie plików. + + + File names containing the character "%1" are not supported on this file system. + Nazwy plików zawierające znak "%1" nie są obsługiwane w tym systemie plików. + File name contains at least one invalid character @@ -3348,7 +3436,7 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Serwer odpowiedział z błędem podczas odczytu katalogu '%1' : %2 - + Server replied with an error while reading directory "%1" : %2 Serwer odpowiedział z błędem podczas odczytu katalogu "%1" : %2 @@ -3961,12 +4049,7 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Allow Editing - Zezwalaj na edycję - - - - Allow editing - Zezwalaj na edycję + Zezwalaj na edytowanie @@ -3976,7 +4059,7 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Allow Upload && Editing - Zezwalaj na wysyłanie i edycję + Zezwalaj na wysyłanie i edytowanie @@ -3988,10 +4071,20 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Password Protect Ochrona hasłem + + + Allow editing + Zezwalaj na edytowanie + + + + View only + Tylko podgląd + Allow upload and editing - Zezwalaj na przesyłanie i edycję + Zezwalaj na wysyłanie i edytowanie @@ -4003,16 +4096,21 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł File drop (upload only) Upuszczanie pliku (tylko wysyłanie) - - - Note to recipient - Informacja dla odbiorcy - Unshare Zatrzymaj udostępnianie + + + Link name + Nazwa linku + + + + Note to recipient + Informacja dla odbiorcy + Password protect @@ -4024,15 +4122,20 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Ustaw datę ważności - - Delete share link - Usuń link udostępnienia + + Delete link + Usuń link Add another link Dodaj kolejny link + + + Delete share link + Usuń link udostępnienia + Confirm Link Share Deletion @@ -4082,7 +4185,7 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Brak wyników dla '%1' - + No results for "%1" Brak wyników dla "%1" @@ -4186,12 +4289,6 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Udostępnij %1 - Context menu share @@ -4218,6 +4315,12 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Share via %1 Udostępnij przez %1 + + + + Activity + Aktywność + Copy private link to clipboard @@ -4289,6 +4392,12 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Delete Usuń + + + Share with %1 + parameter is Nextcloud + Udostępnij %1 + OCC::SslButton @@ -4434,6 +4543,11 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Cannot connect securely to <i>%1</i>: Nie można nawiązać bezpiecznego połączenia z <i>%1</i>: + + + Additional errors: + Dodatkowe błędy: + with Certificate %1 @@ -4608,6 +4722,11 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Placeholders are postfixed with file sizes using Utility::octetsToString() Dostępnych jest tylko %1, aby rozpocząć, potrzebujesz co najmniej %2 + + + Aborted + Przerwany + @@ -4760,27 +4879,88 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Invalid characters, please rename "%1" Nieprawidłowe znaki, zmień nazwę "%1" + + + Synchronization will resume shortly. + Synchronizacja zostanie wkrótce wznowiona. + File name contains at least one invalid character Nazwa pliku zawiera co najmniej jeden nieprawidłowy znak - - Aborted - Przerwany - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Brak miejsca na dysku: Pominięto pobieranie plików, które zmniejszyłyby ilość wolnego miejsca poniżej %1. - + There is insufficient space available on the server for some uploads. Na serwerze nie ma wystarczającej ilości miejsca na niektóre wysłane pliki. + + OCC::SyncStatusSummary + + + + Offline + Offline + + + + + + All synced! + Wszystko zsynchronizowane! + + + + Some files couldn't be synced! + Nie udało się zsynchronizować niektórych plików! + + + + See below for errors + Zobacz błędy poniżej + + + + Syncing + Synchronizacja + + + + Sync paused + Synchronizacja wstrzymana + + + + Some files could not be synced! + Nie udało się zsynchronizować niektórych plików! + + + + See below for warnings + Zobacz ostrzeżenia poniżej + + + + %1 of %2 · %3 left + %1 z %2 · pozostało %3 + + + + %1 of %2 + %1 z %2 + + + + Syncing file %1 of %2 + Synchronizowanie pliku %1 z %2 + + OCC::Systray @@ -4856,6 +5036,29 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł <p>To wydanie zostało dostarczone przez %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Nie udało się pobrać dostawców. + + + + Failed to fetch search providers for '%1'. Error: %2 + Nie udało się pobrać dostawców wyszukiwania dla '%1'. Błąd: %2 + + + + Search has failed for '%2'. + Wyszukiwanie nie powiodło się dla '%2'. + + + + Search has failed for '%1'. Error: %2 + Wyszukiwanie nie powiodło się dla '%1'. Błąd: %2 + + OCC::User @@ -4913,24 +5116,108 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Funkcja wirtualnego systemu plików wymaga systemu plików NTFS, %1 używa %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Nie udało się pobrać wstępnie zdefiniowanych statusów. Upewnij się, że masz połączenie z serwerem. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Pobieranie pliku zaszyfrowanego end-to-end nie powiodło się + + Could not fetch user status. Make sure you are connected to the server. + Nie udało się pobrać statusu użytkownika. Upewnij się, że masz połączenie z serwerem. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Wygląda na to, że próbujesz pobrać plik wirtualny, który jest zaszyfrowany end-to-end. Bezpośrednie pobieranie takich plików nie jest obecnie obsługiwane. Aby rozwiązać ten problem, przejdź do ustawień i zaznacz zaszyfrowany katalog za pomocą opcji "Dostępne zawsze lokalnie". + + User status feature is not supported. You will not be able to set your user status. + Funkcja statusu użytkownika nie jest obsługiwana. Nie będziesz mógł ustawić swojego statusu użytkownika. + + + + Emojis feature is not supported. Some user status functionality may not work. + Funkcja emoji nie jest obsługiwana. Niektóre funkcje statusu użytkownika mogą nie działać. + + + + Could not set user status. Make sure you are connected to the server. + Nie udało się ustawić statusu użytkownika. Upewnij się, że masz połączenie z serwerem. + + + + Could not clear user status message. Make sure you are connected to the server. + Nie udało się wyczyścić komunikatu o statusie użytkownika. Upewnij się, że masz połączenie z serwerem. + + + + + Don't clear + Nie czyść + + + + 30 minutes + 30 minut + + + + + 1 hour + 1 godzina + + + + 4 hours + 4 godziny + + + + + Today + Dzisiaj + + + + + This week + W tym tygodniu + + + + Less than a minute + Mniej niż minuta + + + + 1 minute + 1 minuta + + + + %1 minutes + %n minut + + + + %1 hours + %n godzin + + + + 1 day + 1 dzień + + + + %1 days + %1 dni + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Funkcja wirtualnego systemu plików wymaga systemu plików NTFS, %1 używa %2 @@ -5447,14 +5734,6 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Zaloguj się do %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Twoje całe konto zostało zsynchronizowane z katalogiem lokalnym - - QObject @@ -5465,7 +5744,7 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł %n day ago - %n dzień temu%n dni temu%n dni temu%n dzień temu + %n dzień temu%n dni temu%n dni temu%n dni temu @@ -5480,7 +5759,7 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł %n hour ago - %n godzinę temu%n godziny temu%n godzin temu%n godzin temu + %n godzina temu%n godziny temu%n godzin temu%n godzin temu @@ -5500,7 +5779,7 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł %n minute ago - %n minuta temu%n minuty temu%n minut temu%n minuta temu + %n minuta temu%n minuty temu%n minut temu%n minut temu @@ -5547,6 +5826,38 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Nie udało się połączyć z bazą danych. + + UnifiedSearchInputContainer + + + Search files, messages, events … + Szukaj plików, wiadomości, wydarzeń… + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Załaduj więcej wyników + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Szkielet wyników wyszukiwania. + + + + UnifiedSearchResultListItem + + + Load more results + Załaduj więcej wyników + + UserLine @@ -5561,29 +5872,39 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł - Current user status is online - Aktualny status użytkownika to "Online" + Account connected + Połączono z kontem - Current user status is do not disturb - Aktualny status użytkownika to "Nie przeszkadzać" + Account not connected + Konto nie jest połączone - Account connected - Połączono z kontem + Current user status is online + Aktualny status użytkownika to "Online" - Account not connected - Konto nie jest połączone + Current user status is do not disturb + Aktualny status użytkownika to "Nie przeszkadzać" Account actions Czynności na koncie + + + Remove Account + Usuń konto + + + + Set status + Ustaw status + @@ -5596,17 +5917,65 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Log in Zaloguj - - - Remove Account - Usuń konto - Remove account Usuń konto + + UserStatusSelector + + + Online status + Status online + + + + Online + Online + + + + Away + Bezczynny + + + + Do not disturb + Nie przeszkadzać + + + + Invisible + Niewidoczny + + + + Status message + Komunikat statusu + + + + What is your status? + Jaki jest Twój status? + + + + Clear status message after + Wyczyść komunikat statusu po + + + + Clear status message + Wyczyść komunikat statusu + + + + Set status message + Ustaw komunikat statusu + + Utility @@ -5668,12 +6037,12 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł ValidateChecksumHeader - + The checksum header is malformed. Nagłówek sumy kontrolnej jest nieprawidłowy. - + The checksum header contained an unknown checksum type '%1' Nagłówek sumy kontrolnej zawierał nieznany typ sumy kontrolnej '%1' @@ -5683,17 +6052,17 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Pobrany plik nie odpowiada sumie kontrolnej, zostanie wznowiony. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Pobrany plik nie odpowiada sumie kontrolnej, zostanie wznowiony. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" Nagłówek sumy kontrolnej zawierał nieznany typ sumy kontrolnej "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" Pobrany plik nie odpowiada sumie kontrolnej, zostanie wznowiony. "%1" != "%2" @@ -5722,6 +6091,11 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Pause sync for all Wstrzymaj synchronizację dla wszystkich + + + Set user status + Ustaw status użytkownika + Add account @@ -5757,12 +6131,6 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Current user status is do not disturb Aktualny status użytkownika to "Nie przeszkadzać" - - - - Show more actions - Pokaż więcej akcji - Share %1 @@ -5823,6 +6191,22 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Open share dialog Otwórz okno udostępnienia + + + Unified search results list + Ujednolicona lista wyników wyszukiwania + + + + + Show more actions + Pokaż więcej akcji + + + + %1 - File activity + %1 — Aktywność pliku + main.cpp @@ -6122,6 +6506,24 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Zaloguj się w przeglądarce (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Wszystko skonfigurowane! + + + + Open Local Folder + Otwórz katalog lokalny + + + + Open %1 in Browser + Otwórz %1 w przeglądarce + + OCC::ShibbolethCredentials @@ -6174,6 +6576,14 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Zaloguj + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Twoje całe konto zostało zsynchronizowane z katalogiem lokalnym + + OCC::UserStatus @@ -6197,4 +6607,17 @@ To nowy, eksperymentalny tryb. Jeśli zdecydujesz się z niego skorzystać, zgł Online + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Pobieranie pliku zaszyfrowanego end-to-end nie powiodło się + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Wygląda na to, że próbujesz pobrać plik wirtualny, który jest zaszyfrowany end-to-end. Bezpośrednie pobieranie takich plików nie jest obecnie obsługiwane. Aby rozwiązać ten problem, przejdź do ustawień i zaznacz zaszyfrowany katalog za pomocą opcji "Dostępne zawsze lokalnie". + + \ No newline at end of file diff --git a/translations/client_pt.ts b/translations/client_pt.ts index 67ea94b009c6..0d86670fcffc 100644 --- a/translations/client_pt.ts +++ b/translations/client_pt.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1136,32 +1149,32 @@ This can be an issue with your OpenSSL libraries. Não foi possível abrir o Browser, por favor copie o link para o seu Browser. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1326,6 +1339,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1381,22 +1401,7 @@ Continuando a sincronização fará com que todos os seus ficheiros sejam substi Manter Ficheiros Locais como Conflito - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1404,7 +1409,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1420,6 +1425,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2246,6 +2259,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Adicione um novo padrão de ignorar: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2381,7 +2457,7 @@ Logs will be written to %1 <nobr>O ficheiro '%1'<br/>não pode ser aberto para gravação.<br/><br/>O ficheiro de registo de saída <b>não</b> pode ser guardado!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2424,6 +2500,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2593,6 +2674,13 @@ Logs will be written to %1 New %1 Update Ready Nova Atualização %1 Pronta + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Está prestes a ser instalada uma nova atualização para %1. O atualizador +poderá pedir por privilégios adicionais durante o processo. + New %1 update ready @@ -2600,10 +2688,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Está prestes a ser instalada uma nova atualização para %1. O atualizador -poderá pedir por privilégios adicionais durante o processo. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2640,6 +2726,11 @@ poderá pedir por privilégios adicionais durante o processo. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2650,6 +2741,11 @@ poderá pedir por privilégios adicionais durante o processo. Could not check for new updates. Não foi possível procurar por novas atualizações. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2945,37 +3041,37 @@ It is not advisable to use it. Tempo expirou enquanto tentava ligar a %1 em %2. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. O pedido de autenticação para o servidor foi redirecionado para '%1'. O URL é mau, o servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acesso proibido pelo servidor. Para verificar que tem o acesso adequado, <a href="%1">clique aqui</a> para aceder ao serviço com o seu navegador. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> A pasta de sincronização local %1 já existe, a configurar para sincronizar.<br/><br/> - + Creating local sync folder %1 … @@ -2985,84 +3081,84 @@ It is not advisable to use it. ok - + OK - + failed. Falhou. - + Could not create local folder %1 Não foi possível criar a pasta local %1 - + No remote folder specified! Não foi indicada a pasta remota! - + Error: %1 Erro: %1 - + creating folder on Nextcloud: %1 a criar a pasta na Nextcloud: %1 - + Remote folder %1 created successfully. Criação da pasta remota %1 com sucesso! - + The remote folder %1 already exists. Connecting it for syncing. A pasta remota %1 já existe. Ligue-a para sincronizar. - - + + The folder creation resulted in HTTP error code %1 A criação da pasta resultou num erro HTTP com o código %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> A criação da pasta remota falhou, provavelmente por ter introduzido as credenciais erradas.<br/>Por favor, verifique as suas credenciais.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">A criação da pasta remota falhou, provavelmente por ter introduzido as credenciais erradas.</font><br/>Por favor, verifique as suas credenciais.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. A criação da pasta remota %1 falhou com o erro <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. A sincronização de %1 com a pasta remota %2 foi criada com sucesso. - + Successfully connected to %1! Conectado com sucesso a %1! - + Connection to %1 could not be established. Please check again. Não foi possível ligar a %1 . Por Favor verifique novamente. - + Folder rename failed Erro ao renomear a pasta @@ -3072,28 +3168,28 @@ It is not advisable to use it. Não é possível remover e fazer backup à pasta porque a pasta ou um ficheiro nesta está aberto em outro programa. Por favor, feche a pasta ou o ficheiro e clique novamente ou cancele a configuração. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Pasta de sincronização local %1 criada com sucesso!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Assistente de ligação %1 - Add %1 account + + + %1 Connection Wizard + Assistente de ligação %1 + Skip folders configuration @@ -3126,24 +3222,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Configuração concluida! - - - - Open Local Folder - Abrir a pasta local - - - - Open %1 in Browser - Abrir %1 no Navegador - - OCC::PollJob @@ -3154,6 +3232,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3171,12 +3259,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3305,7 +3393,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3920,11 +4008,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Permitir edição - - - Allow editing - Permitir edição - Read only @@ -3945,6 +4028,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Proteger com palavra-passe + + + Allow editing + Permitir edição + + + + View only + + Allow upload and editing @@ -3960,16 +4053,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Pasta de carregamento apenas - - - Note to recipient - Nota para o destinatário - Unshare Cancelar partilha + + + Link name + + + + + Note to recipient + Nota para o destinatário + Password protect @@ -3981,15 +4079,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Definir a data de expiração - - Delete share link - Apagar hiperligação de partilha + + Delete link + Add another link Adicionar outra hiperligação + + + Delete share link + Apagar hiperligação de partilha + Confirm Link Share Deletion @@ -4039,7 +4142,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Sem resultados para '%1' - + No results for "%1" @@ -4143,12 +4246,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Partilhar com %1 - Context menu share @@ -4175,6 +4272,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4246,6 +4349,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Eliminar + + + Share with %1 + parameter is Nextcloud + Partilhar com %1 + OCC::SslButton @@ -4391,6 +4500,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Não é possível ligar com segurança a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4565,6 +4679,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Apenas %1 estão disponíveis, é preciso um mínimo de %2 para começar + + + Aborted + + @@ -4717,27 +4836,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Carateres inválidos, por favor, renomeie "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character O nome de ficheiro contém pelo menos um caráter inválido - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. O espaço em disco é baixo: Downloads que reduzam o espaço abaixo de %1 serão ignorados. - + There is insufficient space available on the server for some uploads. Não há espaço livre suficiente no servidor para alguns uploads. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4813,6 +4993,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Esta versão foi fornecida por %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4870,23 +5073,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5404,14 +5691,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - A sua conta está sincronizada na pasta local - - QObject @@ -5504,6 +5783,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5518,22 +5829,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Conta ligada - Current user status is do not disturb + Account not connected - Account connected - Conta ligada + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5541,6 +5852,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + + + + + Set status + + @@ -5553,17 +5874,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Iniciar sessão - - - Remove Account - - Remove account Remover conta + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5625,12 +5994,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. O cabeçalho de "checksum" está com problemas. - + The checksum header contained an unknown checksum type '%1' O cabeçalho checksum continha um tipo de checksum desconhecido '%1' @@ -5640,17 +6009,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss O ficheiro transferido não corresponde ao "checksum", este irá ser retomado. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5679,6 +6048,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5714,12 +6088,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5780,6 +6148,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6079,6 +6463,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Faça login através do browser (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Configuração concluida! + + + + Open Local Folder + Abrir a pasta local + + + + Open %1 in Browser + Abrir %1 no Navegador + + OCC::ShibbolethCredentials @@ -6131,6 +6533,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Iniciar sessão + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + A sua conta está sincronizada na pasta local + + OCC::UserStatus @@ -6154,4 +6564,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_pt_BR.ts b/translations/client_pt_BR.ts index bd36b87b96c3..c38be1458cb9 100644 --- a/translations/client_pt_BR.ts +++ b/translations/client_pt_BR.ts @@ -14,12 +14,6 @@ Open %1 locally Abrir %1 localmente - - - - Show more actions - Mais ações - Open share dialog @@ -30,6 +24,25 @@ Share %1 Compartilhar %1 + + + + Show more actions + Mais ações + + + + View activity + Ver atividade + + + + ActivityList + + + Activity list + Lista de atividades + CloudProviderWrapper @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Verificando as mudanças em "%1" @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + Não foi possível mover "%1" para"%2" @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Erro ao remover "%1": %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Não foi possível remover a pasta "%1" @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Parece que o recurso Arquivos Virtuais está ativado nesta pasta. No momento, não é possível baixar implicitamente arquivos virtuais criptografados de ponta a ponta. Para obter a melhor experiência com arquivos virtuais e criptografia de ponta a ponta, certifique-se de que a pasta criptografada esteja marcada com "Tornar sempre disponível localmente". @@ -842,7 +855,7 @@ Esta ação irá cancelar qualquer sincronização atualmente em execução. Enter username and password for "%1" at %2. - + Digite o nome de usuário e a senha para "%1" em %2. @@ -1116,7 +1129,7 @@ Isso pode ser um problema com suas bibliotecas OpenSSL. There was an error accessing the "token" endpoint: <br><em>%1</em> - + Ocorreu um erro ao acessar o endpoint "token": <br><em>%1</em> @@ -1144,32 +1157,32 @@ Isso pode ser um problema com suas bibliotecas OpenSSL. Não foi possível abrir o Navegador, copie o link para o seu Navegador. - + Waiting for authorization Aguardando autorização - + Polling for authorization Votando autorização - + Starting authorization Iniciando autorização - + Link copied to clipboard. Link copiado para a área de transferência. - + Reopen Browser Reabrir Navegador - + Copy Link Copiar o Link @@ -1313,7 +1326,7 @@ Isso pode ser um problema com suas bibliotecas OpenSSL. Please go in the settings to select it if you wish to download it. - Por favor, vá nas configurações para selecioná-lo se desejar baixá-lo. + Por favor, vá às configurações para selecioná-la se desejar baixá-la. @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Isso significa que o cliente de sincronização pode não fazer upload de alterações locais imediatamente e em vez disso, apenas verificar alterações locais e enviá-las ocasionalmente (a cada duas horas, por padrão).. %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Todos os arquivos em sua pasta de sincronização local '%1' foram excluídos. Essas exclusões serão sincronizadas com seu servidor, tornando esses arquivos indisponíveis a menos que sejam restaurados . +Tem certeza de que deseja sincronizar essas ações com o servidor? +Se isso foi um acidente e você decidir manter seus arquivos, eles serão sincronizados novamente a partir do servidor. @@ -1371,7 +1393,7 @@ Se essa ação não foi intencional, você pode restaurar os dados perdidos agor Restore deleted files - Restaurar arquivos excluídos + Restaurar arquivos apagado @@ -1398,39 +1420,22 @@ Continuar a sincronização como normal fará com que todos os seus arquivos sej Manter Arquivos Locais como Conflito - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Todos os arquivos na pasta de sincronização '%1' foram excluídos do servidor. -Essas exclusões serão sincronizadas com sua pasta de sincronização local, tornando esses arquivos indisponíveis, a menos que você tenha o direito de restaurá-los. -Se você decidir restaurar os arquivos, eles serão sincronizados novamente com o servidor se você tiver direitos para fazer isso. -Se você decidir excluir os arquivos, eles ficarão indisponíveis para você, a menos que você seja o proprietário. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Todos os arquivos em sua pasta de sincronização local '%1' foram excluídos. Essas exclusões serão sincronizadas com seu servidor, tornando esses arquivos indisponíveis a menos que sejam restaurados . -Tem certeza de que deseja sincronizar essas ações com o servidor? -Se isso foi um acidente e você decidir manter seus arquivos, eles serão sincronizados novamente a partir do servidor. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - + Todos os arquivos da pasta de sincronização "%1" foram excluídos do servidor. +Essas exclusões serão sincronizadas com sua pasta de sincronização local, tornando esses arquivos indisponíveis, a menos que você tenha o direito de restaurá-los. +Se você decidir restaurar os arquivos, eles serão sincronizados novamente com o servidor, se você tiver direitos para fazê-lo. +Se você decidir excluir os arquivos, eles ficarão indisponíveis para você, a menos que você seja o proprietário. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - + Todos os arquivos em sua pasta de sincronização local "%1" foram excluídos. Essas exclusões serão sincronizadas com seu servidor, tornando esses arquivos indisponíveis a menos que sejam restaurados. Tem certeza de que deseja sincronizar essas ações com o servidor? Se isso foi um acidente e você decidir manter seus arquivos, eles serão sincronizados novamente a partir do servidor. @@ -1442,6 +1447,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Remover todos os arquivos + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Todos os arquivos na pasta de sincronização '%1' foram excluídos do servidor. +Essas exclusões serão sincronizadas com sua pasta de sincronização local, tornando esses arquivos indisponíveis, a menos que você tenha o direito de restaurá-los. +Se você decidir restaurar os arquivos, eles serão sincronizados novamente com o servidor se você tiver direitos para fazer isso. +Se você decidir excluir os arquivos, eles ficarão indisponíveis para você, a menos que você seja o proprietário. + Keep files @@ -1491,7 +1507,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Um antigo diário de sincronização "%1" foi encontrado, mas não pôde ser removido. Certifique-se de que nenhum aplicativo o esteja usando no momento. @@ -1679,12 +1695,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Verificando mudanças no controle remoto "%1" Checking for changes in local "%1" - + Verificando se há mudanças no local "%1" @@ -1839,12 +1855,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below '%1': - Entre com o nome da nova pasta a ser criada abaixo '%1': + Insira o nome da nova pasta a ser criada abaixo de '%1': Enter the name of the new folder to be created below "%1": - + Digite o nome da nova pasta a ser criada abaixo de "%1": @@ -2159,7 +2175,7 @@ Observe que isso seleciona apenas quais upgrades de pool são retirados, e que n Reading from keychain failed with error: "%1" - + A leitura das chaves falhou com o erro: "%1" @@ -2202,7 +2218,7 @@ Observe que isso seleciona apenas quais upgrades de pool são retirados, e que n This entry is provided by the system at "%1" and cannot be modified in this view. - + Esta entrada é fornecida pelo sistema em "%1" e não pode ser modificada nesta exibição. @@ -2254,7 +2270,7 @@ Os itens em que a exclusão é permitida serão excluídos se impedirem a remoç Cannot write changes to "%1". - + Não é possível gravar alterações em "%1". @@ -2272,6 +2288,69 @@ Os itens em que a exclusão é permitida serão excluídos se impedirem a remoç Adicionar um novo padrão a ignorar: + + OCC::InvalidFilenameDialog + + + Invalid filename + Nome de arquivo inválido + + + + The file could not be synced because it contains characters which are not allowed on this system. + O arquivo não pôde ser sincronizado porque contém caracteres que não são permitidos neste sistema. + + + + Error + Erro + + + + Please enter a new name for the file: + Insira um novo nome para o arquivo: + + + + New filename + Novo nome de arquivo + + + + Rename file + Renomear arquivo + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + O arquivo %1 não pôde ser sincronizado porque o nome contém caracteres que não são permitidos neste sistema. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Os seguintes caracteres não são permitidos no sistema: * "| &?,;: \ / ~ <> + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Você não tem permissão para renomear este arquivo. Peça ao autor do arquivo para renomeá-lo. + + + + Filename contains illegal characters: %1 + O nome do arquivo contém caracteres ilegais: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Não foi possível renomear o arquivo. Verifique se você está conectado ao servidor. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Não é possível renomear o arquivo porque já existe um arquivo com o mesmo nome no servidor. Escolha outro nome. + + OCC::LegalNotice @@ -2411,9 +2490,9 @@ Logs serão gravados em %1 <nobr>Arquivo '%1'<br/>não pode ser aberto para escrita.<br/><br/>A saída de log <b>não</b> pode ser salva!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> - + <nobr>O arquivo "%1"<br/>não pode ser aberto para escrita .<br/><br/>A saída do log <b>não pode</b> ser salva!</nobr> @@ -2454,6 +2533,11 @@ Logs serão gravados em %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Uma nova versão do cliente %1 está disponível, mas o processo de atualização falhou.</p><p><b>%2</b> foi baixado. A versão instalada é %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Uma nova versão do cliente %1 está disponível, mas o processo de atualização falhou.</p><p><b>%2</b> foi baixado. A versão instalada é %3. Se você confirmar a reinicialização e atualização, seu computador pode reiniciar para completar a instalação.</p> + Ask again later @@ -2613,7 +2697,7 @@ Logs serão gravados em %1 <h1>Wrong user</h1><p>You logged-in with user <em>%1</em>, but must login with user <em>%2</em>.<br>Please log out of %3 in another tab, then <a href='%4'>click here</a> and log in as user %2</p> - <h1>Usuário errado</h1><p>Você fez logon com o usuário <em>%1</em>, mas deve fazer com o usuário <em>%2</em>.<br>Faça o logout de %3 em outra guia, então<a href='%4'>clique aqui</a> e faça o login como usuário%2</p> + <h1>Usuário incorreto</h1><p>Você fez logon com o usuário <em>%1</em>, mas deve fazer com o usuário <em>%2</em>.<br>Faça o logout de %3 em outra guia, então<a href='%4'>clique aqui</a> e faça o login como o usuário %2</p> @@ -2623,6 +2707,13 @@ Logs serão gravados em %1 New %1 Update Ready Nova Atualização %1 Pronta + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Uma nova atualização para %1 está para ser instalada. O atualizador +pode solicitar por privilégios adicionais durante o processo. + New %1 update ready @@ -2630,10 +2721,8 @@ Logs serão gravados em %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Uma nova atualização para %1 está para ser instalada. O atualizador -pode solicitar por privilégios adicionais durante o processo. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Uma nova atualização para %1 está prestes a ser instalada. O atualizador pode solicitar privilégios adicionais durante o processo. Seu computador pode reiniciar para completar a instalação. @@ -2670,6 +2759,11 @@ pode solicitar por privilégios adicionais durante o processo. New %1 is available. Please click <a href='%2'>here</a> to download the update. Novo %1 está disponível. Clique <a href='%2'>aqui</a> para baixar a atualização. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Não foi possível baixar a atualização. Por favor abra <a href='%1'>%1</a>para baixar a atualização manualmente. + Could not download update. Please open %1 to download the update manually. @@ -2680,6 +2774,11 @@ pode solicitar por privilégios adicionais durante o processo. Could not check for new updates. Não foi possível verificar novas atualizações. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Novo %1 está disponível. Por favor Abra <a href='%2'>%2</a> para baixar a atualização. + New %1 is available. Please open %2 to download the update. @@ -2768,7 +2867,7 @@ pode solicitar por privilégios adicionais durante o processo. %1 folder "%2" is synced to local folder "%3" - + %1 pasta "%2" está sincronizada com a pasta local "%3" @@ -2976,37 +3075,37 @@ Não é aconselhado usá-la. Atingido o tempo limite ao tentar conectar com %1 em %2. - + Trying to connect to %1 at %2 … Tentando conectar em %1 às %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. A solicitação de autenticação ao servidor foi direcionada para '%1'. A URL está errada, o servidor está mal configurado. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + A solicitação autenticada para o servidor foi redirecionada para "%1". O URL está incorreto, o servidor está configurado incorretamente. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Acesso proibido pelo servidor. Para verificar se você tem acesso adequado, <a href="%1">clique aqui</a> para acessar o serviço com seu navegador. - + There was an invalid response to an authenticated WebDAV request Houve uma resposta inválida para uma solicitação autenticada do WebDAV - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Pasta de sincronização local %1 já existe, configurando-a para sincronização. <br/><br/> - + Creating local sync folder %1 … Criando pasta de sincronização local %1… @@ -3016,84 +3115,84 @@ Não é aconselhado usá-la. ok - + OK OK - + failed. falhou. - + Could not create local folder %1 Não foi possível criar pasta local %1 - + No remote folder specified! Nenhuma pasta remota foi especificada! - + Error: %1 Erro: %1 - + creating folder on Nextcloud: %1 criando pasta no Nextcloud: %1 - + Remote folder %1 created successfully. Pasta remota %1 criada com sucesso. - + The remote folder %1 already exists. Connecting it for syncing. A pasta remota %1 já existe. Conectando-a para sincronizar. - - + + The folder creation resulted in HTTP error code %1 A criação da pasta resultou em um erro HTTP de código %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> A criação da pasta remota falhou porque as credenciais fornecidas estão erradas!<br/>Por favor, volte e verifique suas credenciais.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">A criação da pasta remota falhou provavelmente devido a credenciais incorretas</font><br/>Por favor, volte e verifique suas credenciais.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. A criação da pasta remota %1 falhou com erro <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Uma conexão de sincronização de %1 para o diretório remoto %2 foi realizada. - + Successfully connected to %1! Conectado com sucesso a %1! - + Connection to %1 could not be established. Please check again. A conexão a %1 não foi estabelecida. Por favor, verifique novamente. - + Folder rename failed Falha ao renomear pasta @@ -3103,28 +3202,28 @@ Não é aconselhado usá-la. Não é possível remover e fazer backup da pasta porque a pasta ou um arquivo estão abertos em outro programa. Feche a pasta ou arquivo e tente novamente ou cancele a operação. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Não foi possível remover e fazer o backup da pasta porque a pasta ou algum arquivo presente dentro desta pasta está aberto em outro programa. Por favor feche o arquivo ou a pasta e tente novamente ou cancele a operação. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Pasta de sincronização local %1 criada com sucesso!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Assistente de Conexão %1 - Add %1 account Adicionar conta %1  + + + %1 Connection Wizard + Assistente de Conexão %1 + Skip folders configuration @@ -3164,24 +3263,6 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Fique seguro - - OCC::OwncloudWizardResultPage - - - Everything set up! - Tudo configurado! - - - - Open Local Folder - Abrir Pasta Local - - - - Open %1 in Browser - Abrir %1 no Navegador - - OCC::PollJob @@ -3192,6 +3273,16 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + O arquivo contém espaços à direita e não pôde ser renomeado, porque um arquivo com o mesmo nome já existe no servidor. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + O arquivo contém espaços à direita e não pôde ser renomeado, porque um arquivo com o mesmo nome já existe localmente. + Symbolic links are not supported in syncing. @@ -3207,16 +3298,16 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr File names ending with a period are not supported on this file system. File names ending with a period are not supported on this file system. - - - File names containing the character "%1" are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. Nomes de arquivos contendo o caracter '%1' não são suportados neste sistema de arquivos. + + + File names containing the character "%1" are not supported on this file system. + Nomes de arquivos contendo o caractere "%1" não são suportados neste sistema de arquivos. + File name contains at least one invalid character @@ -3343,9 +3434,9 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr O servidor respondeu com um erro ao ler o diretório '%1' : %2 - + Server replied with an error while reading directory "%1" : %2 - + O servidor respondeu com um erro ao ler o diretório "%1" : %2 @@ -3408,7 +3499,7 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr File was deleted from server - O arquivo foi excluído do servidor + O arquivo foi apagado do servidor @@ -3502,7 +3593,7 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Error removing '%1': %2; - Erro removendo '%1': %2; + Erro ao remover '%1': %2; @@ -3958,11 +4049,6 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Allow Editing Permitir Edição - - - Allow editing - Permitir edição - Read only @@ -3983,6 +4069,16 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Password Protect Proteger com Senha + + + Allow editing + Permitir edição + + + + View only + Somente visualização + Allow upload and editing @@ -3998,16 +4094,21 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr File drop (upload only) Soltar arquivo (somente envio) - - - Note to recipient - Observação ao destinatário - Unshare Descompartilhar + + + Link name + Nome do link + + + + Note to recipient + Observação ao destinatário + Password protect @@ -4019,15 +4120,20 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Definir data de vencimento - - Delete share link - Excluir o link de compartilhamento + + Delete link + Excluir link Add another link Adicionar outro link + + + Delete share link + Excluir o link de compartilhamento + Confirm Link Share Deletion @@ -4077,7 +4183,7 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Sem resultados para '%1' - + No results for "%1" Nenhum resultado para "%1" @@ -4181,12 +4287,6 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Compartilhar com %1 - Context menu share @@ -4213,6 +4313,12 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Share via %1 Compartilhar via %1 + + + + Activity + Atividade + Copy private link to clipboard @@ -4284,6 +4390,12 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Delete Excluir + + + Share with %1 + parameter is Nextcloud + Compartilhar com %1 + OCC::SslButton @@ -4429,6 +4541,11 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Cannot connect securely to <i>%1</i>: Não é possível conectar com segurança a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4603,6 +4720,11 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Placeholders are postfixed with file sizes using Utility::octetsToString() Apenas %1 está disponível, é preciso pelo menos %2 para começar + + + Aborted + Cancelado + @@ -4755,27 +4877,88 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Invalid characters, please rename "%1" Caracteres inválidos, favor renomear "%1" + + + Synchronization will resume shortly. + A sincronização será retomada em breve. + File name contains at least one invalid character O nome do arquivo contém pelo menos um caractere inválido - - Aborted - Cancelado - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. O espaço em disco é pequeno: Os downloads que reduziriam o espaço livre abaixo de %1 foram ignorados. - + There is insufficient space available on the server for some uploads. Não há espaço disponível no servidor para alguns envios. + + OCC::SyncStatusSummary + + + + Offline + Desligado + + + + + + All synced! + Tudo sincronizado! + + + + Some files couldn't be synced! + Alguns arquivos não puderam ser sincronizados! + + + + See below for errors + Veja abaixo para erros + + + + Syncing + Sincronizando + + + + Sync paused + Sincronização pausada + + + + Some files could not be synced! + Alguns arquivos não puderam ser sincronizados! + + + + See below for warnings + Veja abaixo para avisos + + + + %1 of %2 · %3 left + %1 de %2 · %3 faltando + + + + %1 of %2 + %1 de %2 + + + + Syncing file %1 of %2 + Sincronizando arquivo %1 de %2 + + OCC::Systray @@ -4851,6 +5034,29 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr <p>Esta versão foi fornecida por %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Falha ao buscar provedores. + + + + Failed to fetch search providers for '%1'. Error: %2 + Falha ao buscar provedores de pesquisa para '%1'. Erro: %2 + + + + Search has failed for '%2'. + A pesquisa por '%2' falhou. + + + + Search has failed for '%1'. Error: %2 + A pesquisa por '%1' falhou. Erro: %2 + + OCC::User @@ -4908,24 +5114,108 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - O recurso de sistema de arquivos virtual requer um sistema de arquivos NTFS, %1 está usando %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Não foi possível buscar status predefinidos. Certifique-se de estar conectado ao servidor. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Falha ao baixar o arquivo criptografado ponta-a-ponta + + Could not fetch user status. Make sure you are connected to the server. + Não foi possível buscar o status do usuário. Certifique-se de estar conectado ao servidor. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Parece que você está tentando baixar um arquivo virtual criptografado de ponta a ponta. O download implícito de tais arquivos não é suportado no momento. Para contornar esse problema, vá para as configurações e marque a pasta criptografada com "Tornar sempre disponível localmente". + + User status feature is not supported. You will not be able to set your user status. + O recurso de status do usuário não é compatível. Você não poderá definir seu status de usuário. + + + + Emojis feature is not supported. Some user status functionality may not work. + O recurso emojis não é compatível. Algumas funcionalidades de status do usuário podem não funcionar. + + + + Could not set user status. Make sure you are connected to the server. + Não foi possível definir o status do usuário. Certifique-se de estar conectado ao servidor. + + + + Could not clear user status message. Make sure you are connected to the server. + Não foi possível limpar a mensagem de status do usuário. Certifique-se de estar conectado ao servidor. + + + + + Don't clear + Não limpe + + + + 30 minutes + 30 minutos + + + + + 1 hour + 1 hora + + + + 4 hours + 4 horas + + + + + Today + Hoje + + + + + This week + Est semana + + + + Less than a minute + Menos de um minuto + + + + 1 minute + 1 minuto + + + + %1 minutes + %1 minutos + + + + %1 hours + %1 horas + + + + 1 day + 1 dia + + + + %1 days + %1 dias + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + O recurso de sistema de arquivos virtual requer um sistema de arquivos NTFS, %1 está usando %2 @@ -5134,7 +5424,7 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Checking for changes in remote "%1" - + Verificando mudanças no controle remoto "%1" @@ -5144,7 +5434,7 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Checking for changes in local "%1" - + Verificando mudanças no local "%1" @@ -5288,7 +5578,7 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr &Local Folder - &Pasta Local + Pasta &Local @@ -5442,14 +5732,6 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Fazer login em seu %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Toda a sua conta está sincronizada com a pasta local - - QObject @@ -5542,6 +5824,38 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Falha ao conectar banco de dados + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Carregar mais resultados + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Esqueleto do resultado da pesquisa. + + + + UnifiedSearchResultListItem + + + Load more results + Carregar mais resultados + + UserLine @@ -5556,29 +5870,39 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr - Current user status is online - Online é o status atual do usuário + Account connected + Conta conectada - Current user status is do not disturb - Não Perturbe é o status atual do usuário + Account not connected + Conta não conectada - Account connected - Conta conectada + Current user status is online + Online é o status atual do usuário - Account not connected - Conta não conectada + Current user status is do not disturb + Não Perturbe é o status atual do usuário Account actions Ações da conta + + + Remove Account + Remover conta + + + + Set status + Definir status + @@ -5591,17 +5915,65 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Log in Entrar - - - Remove Account - Remover conta - Remove account Remover conta + + UserStatusSelector + + + Online status + Status online + + + + Online + Online + + + + Away + Longe + + + + Do not disturb + Não perturbe + + + + Invisible + Invisível + + + + Status message + Mensagem de status + + + + What is your status? + Qual é o seu status? + + + + Clear status message after + Limpar mensagem de status após + + + + Clear status message + Limpar mensagem de status + + + + Set status message + Definir mensagem de status + + Utility @@ -5663,12 +6035,12 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr ValidateChecksumHeader - + The checksum header is malformed. O cabeçalho do checksum está malformado. - + The checksum header contained an unknown checksum type '%1' O cabeçalho do checksum continha um tipo de soma de verificação '%1' desconhecido @@ -5678,19 +6050,19 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr O arquivo baixado não corresponde ao checksum, ele será retomado. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' O arquivo baixado não corresponde à soma de verificação, ele será retomado. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + O cabeçalho da soma de verificação continha um tipo de soma de verificação desconhecido "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" - + O arquivo baixado não corresponde à soma de verificação, ele será retomado. "%1"! = "%2" @@ -5717,6 +6089,11 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Pause sync for all Pausar a sincronização para todos + + + Set user status + Definir o status do usuário + Add account @@ -5752,12 +6129,6 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Current user status is do not disturb Não Perturbe é o status atual do usuário - - - - Show more actions - Mostrar mais ações - Share %1 @@ -5818,6 +6189,22 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Open share dialog Abrir janela de compartilhamento + + + Unified search results list + Lista unificada de resultados de pesquisa + + + + + Show more actions + Mostrar mais ações + + + + %1 - File activity + %1 - Atividade de arquivo + main.cpp @@ -6117,6 +6504,24 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Faça login no seu navegador (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Tudo configurado! + + + + Open Local Folder + Abrir Pasta Local + + + + Open %1 in Browser + Abrir %1 no Navegador + + OCC::ShibbolethCredentials @@ -6158,7 +6563,7 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Synchronisation Log - Log de Sincronização + Histórico de sincronização @@ -6169,6 +6574,14 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Entrar + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Toda a sua conta está sincronizada com a pasta local + + OCC::UserStatus @@ -6192,4 +6605,17 @@ Este é um novo modo experimental. Se você decidir usá-lo, relate quaisquer pr Conectado + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Falha ao baixar o arquivo criptografado ponta-a-ponta + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Parece que você está tentando baixar um arquivo virtual criptografado de ponta a ponta. O download implícito de tais arquivos não é suportado no momento. Para contornar esse problema, vá para as configurações e marque a pasta criptografada com "Tornar sempre disponível localmente". + + \ No newline at end of file diff --git a/translations/client_ro.ts b/translations/client_ro.ts index 7fd64e83964e..f95616a05639 100644 --- a/translations/client_ro.ts +++ b/translations/client_ro.ts @@ -4,7 +4,7 @@ Activity action button - + Butonul de acțiune a activităților @@ -12,22 +12,35 @@ Open %1 locally - + Deschis %1 local + + + + Open share dialog + Deschide dialogul de partajare + + + + Share %1 + Partajează %1 Show more actions - + Arată mai multe acțiuni - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -41,48 +54,48 @@ Checking for changes in "%1" - + Se verifică pentru schimbări în "%1" Checking for changes in '%1' - + Se verifică pentru schimbări în "%1" Syncing %1 of %2 (%3 left) - + Se sincronizează %1 din %2 (au mai rămas %3) Syncing %1 of %2 - + Se sincronizează %1 din %2 Syncing %1 (%2 left) - + Se sincronizează %1 (au mai rămas %2) Syncing %1 - + Se sincronizează %1 No recently changed files - + Nu există fișiere modificate recent Sync paused - + Sincronizarea este oprită momentan Syncing - + Se sincronizează @@ -92,7 +105,7 @@ Recently changed - + Modificate recent @@ -117,7 +130,7 @@ Quit sync client - + Ieși din clientul de sincronizare @@ -130,34 +143,34 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" Moving to the trash is not implemented on this platform - + Mutarea în coșul de gunoi nu este posibilă pe această platformă Could not move '%1' to '%2' - + Nu s-au putut modifica '%1' din '%2' Error removing "%1": %2 - + A apărut o eroare în "%1": %2 Error removing '%1': %2 - + A apărut o eroare la mutarea '%1': %2 Could not remove folder "%1" - + Nu s-a putut muta folderul "%1" @@ -185,7 +198,7 @@ Logo - + Logo @@ -195,12 +208,12 @@ Switch to your browser to connect your account - + Folosiți brawserul pentru a vă conecta la contul dumneavoastră An error occurred while connecting. Please try again. - + A apărut o eroare în timpul conectării. Va rugăm încercați din nou. @@ -208,12 +221,12 @@ Pick a local folder on your computer to sync - + Selectează un director de pe calculatorul tău pentru a fi sincronizat &Choose … - + &Alege ... @@ -254,7 +267,7 @@ Server replied "%1 %2" to "%3 %4" - + Răspunsul serverului "%1 %2" to "%3 %4" @@ -262,12 +275,12 @@ Wrong HTTP code returned by server. Expected 204, but received "%1 %2". - + Codul HTTP trimis de server este greșit. Era de așteptat codul 204, dar s-a primit "%1 %2". "%1 Failed to unlock encrypted folder %2". - + "%1 Nu s-a putut debloca dosarul criptat %2". @@ -275,12 +288,12 @@ End to end encryption mnemonic - + Fraza de memorare pentru criptarea end-to-end To protect your Cryptographic Identity, we encrypt it with a mnemonic of 12 dictionary words. Please note these down and keep them safe. They will be needed to add other devices to your account (like your mobile phone or laptop). - + Pentru a proteja identitatea ta criptografică noi o criptăm cu o frază de memorare ce conține 12 cuvinte provenite din dictionar (în engleză). Vă rugăm să notați aceste cuvinte și să letineți într-un loc sigur. Acestea vor fi necesare pentru a adăuga alte dispozitive la contul dumneavoastră (de exemplu telefonul mobil sau laptopul). @@ -288,7 +301,7 @@ Unchecked folders will be <b>removed</b> from your local file system and will not be synchronized to this computer anymore - + Dosarele neselectate vor fi <b> șterse </b> de pe systemul dumneavoastră și nu vor mai fi sincronizate cu acest calculator @@ -311,7 +324,7 @@ Storage space: … - + Spațiu de stocare: ... @@ -331,22 +344,22 @@ End-to-End Encryption with Virtual Files - + Criptare end-to-end folosind Fișiere Virtuale You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Se pare că ai activată opțiunea de Fișiere Virtuale pentru acest dosar. În acest moment nu este posibil să descarci în mod implicit astfel de fișiere. Pentru cea mai bună experiență folosind opțiunea de Fișiere Virtuale și criptare end-to-end asigurăte că ai marcat dosarul cu "Disponibil mereu local". Don't encrypt folder - + Nu cripta dosarul Encrypt folder - + Criptează dosarul @@ -357,7 +370,7 @@ Display mnemonic - + Afișează fraza menmonică @@ -393,7 +406,7 @@ Show E2E mnemonic - + Afișează fraza mnemonică @@ -403,23 +416,24 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Se pare că ai activată opțiunea de Fișiere Virtuale pentru acest dosar. În acest moment nu este posibil să descarci în mod implicit astfel de fișiere. Pentru cea mai bună experiență folosind opțiunea de Fișiere Virtuale și criptare end-to-end asigurăte că ai marcat dosarul cu "Disponibil mereu local". You cannot encrypt a folder with contents, please remove the files. Wait for the new sync, then encrypt it. - + Nu se poate cripta un dosar cu conținut, vă rugăm să ștergeți fișierele. +Așteaptă pentru sincronizare, apoi criptează dosarul. Encryption failed - + Criptarea a eșuat Could not encrypt folder because the folder does not exist anymore - + Nu se poate cripta acest dosar deoarece nu există @@ -478,22 +492,22 @@ Wait for the new sync, then encrypt it. Remove folder sync connection - + Elimină conexiunea de sincronizare pentru acest dosar Disable virtual file support … - + Dezactivează suportul pentru fișiere virtuale ... Enable virtual file support %1 … - + Activează suportul pentru fișiere virtuale %1 ... (experimental) - + (experimental) @@ -503,27 +517,27 @@ Wait for the new sync, then encrypt it. <p>Could not create local folder <i>%1</i>.</p> - + <p>Nu s-a putut creea un dosar local <i>%1</i>.</p> Confirm Folder Sync Connection Removal - + Confirmă eliminarea conexiunii de sincronizare <p>Do you really want to stop syncing the folder <i>%1</i>?</p><p><b>Note:</b> This will <b>not</b> delete any files.</p> - + <p>Dorești să oprești sincronizarea dosarului <i>%1</i>?</p><p><b>Notă:</b> Această funcție <b>nu</b>va șterge nici-un fișier.</p> Remove Folder Sync Connection - + Elimină conexiunea de sincronizare Disable virtual file support? - + Dezactivează suportul pentru fișiere virtuale? @@ -532,12 +546,16 @@ Wait for the new sync, then encrypt it. The only advantage of disabling virtual file support is that the selective sync feature will become available again. This action will abort any currently running synchronization. - + Această acțiune va dezactiva suportul pentru fișiere virtuale. Drept consecință conținutul dosarelor ce sunt marcate cu "disponibile numai online" va fi descărcat. + +Singurul avantaj al dezactivării acestei funcții este că funcția de sincronizare selectivă devine disponibilă. + +Această acțiune va opri toate sincronizările în derulare din acest moment. Disable support - + Dezactivează suportul @@ -547,12 +565,12 @@ This action will abort any currently running synchronization. The syncing operation is running.<br/>Do you want to terminate it? - + Operațiunea de sincronizare este în derulare. <br/>Dorești să o oprești ? %1 (%3%) of %2 in use. Some folders, including network mounted or shared folders, might have different limits. - + %1 (%3%) din %2 în folosire. Unele fișiere, inclusiv dosarele partajate prin rețea, ar putea avea limite diferite. @@ -562,7 +580,7 @@ This action will abort any currently running synchronization. Currently there is no storage usage information available. - + În acest moment nu există informații legate de folosirea spațiului de stocare. @@ -572,12 +590,12 @@ This action will abort any currently running synchronization. %1 as <i>%2</i> - + %1 ca <i>%2</i> The server version %1 is old and unsupported! Proceed at your own risk. - + Versiunea serverului %1 este veche și nu mai este menținut! Continuă pe propriul tău risc. @@ -587,12 +605,12 @@ This action will abort any currently running synchronization. %1 as %2 - + %1 ca %2 The server version %1 is unsupported! Proceed at your own risk. - + Versiunea serverului %1 este veche și nu mai este menținut!ă Continuă pe propriul tău risc. @@ -617,57 +635,57 @@ This action will abort any currently running synchronization. Obtaining authorization from the browser. <a href='%1'>Click here</a> to re-open the browser. - + Se obține autorizarea de la browser. <a href='%1'>Click aici</a> pentru a redeschide browser-ul. Connecting to %1 … - + Se conectează la %1 ... No connection to %1 at %2. - + Nu există nici-o conexiune către %1 la %2. Server configuration error: %1 at %2. - + Eroare de configurare a serverulu: %1 la %2. No %1 connection configured. - + Nu există nici-o conexiune configurată la %1. There are folders that were not synchronized because they are too big: - + Există dosare ce nu au fost sincronizate deoarece au o dimenziune prea mare: There are folders that were not synchronized because they are external storages: - + Există dosare ce nu sunt sincronizate deoarece se află pe stocarea externă: There are folders that were not synchronized because they are too big or external storages: - + Există dosare ce nu au fost sinscronizate deoarece acestea sunt prea mari sau se află pe stocarea externă: Confirm Account Removal - + Confirmați ștergerea contului <p>Do you really want to remove the connection to the account <i>%1</i>?</p><p><b>Note:</b> This will <b>not</b> delete any files.</p> - + <p>Doriți să ștergeți conexiunea la acest cont <i>%1</i>?</p><p><b>Notă:</b>Această acțiune <b>nu</b>va șterge nici-un fișier.</p> Remove connection - + Șterge conexiunea @@ -675,7 +693,7 @@ This action will abort any currently running synchronization. Signed out - + Deconectat @@ -710,12 +728,12 @@ This action will abort any currently running synchronization. Asking Credentials - + Întrebare despre acreditări Unknown account state - + Nu se cunoaște starea contului @@ -723,17 +741,17 @@ This action will abort any currently running synchronization. Files from the ignore list as well as symbolic links are not synced. - + Fișierele din lista de ignorare precum și legăturile simbolice nu sunt sincronizate. For more activities please open the Activity app. - + Pentru mai multe activități vă rugăm deschideți aplicația de activități. Files from the ignore list as well as symbolic links are not synced. This includes: - + Fișierele din lista de ignorare precum și legăturile simbolice nu sunt sincronizate. Acestea includ: @@ -741,37 +759,37 @@ This action will abort any currently running synchronization. SSL client certificate authentication - + Certificatul SSL de autentificare a clientului This server probably requires a SSL client certificate. - + Acest server cel mai probabil necesită un certificat SSL. Certificate & Key (pkcs12): - + Certificat & cheie (pkcs12): Certificate & Key (pkcs12) : - + Certificate & Key (pkcs12): Browse … - + Navighează ... Certificate password: - + Parola certificatului: An encrypted pkcs12 bundle is strongly recommended as a copy will be stored in the configuration file. - + Este recomandată folosirea unei chei pkcs12 deoarece o copie va fii păstrată în fișierul de configurare. @@ -781,7 +799,7 @@ This action will abort any currently running synchronization. Certificate files (*.p12 *.pfx) - + Fișierele certificat (*.p12 *.pfx) @@ -789,42 +807,42 @@ This action will abort any currently running synchronization. Continuing will mean <b>deleting these settings</b>. - + Dacă continuați aceste setări <b>vor fi șterse</b>. Continuing will mean <b>ignoring these settings</b>. - + Dacă continuați aceste setări <b>vor fi ignorate</b>. Some settings were configured in newer versions of this client and use features that are not available in this version.<br><br>%1<br><br>The current configuration file was already backed up to <i>%2</i>. - + Unele setări au fost configurate în versiuni mai noi ale acetui client folosind niște opțiuni ce nu sunt disponibile în această versiune. <br><br> %1<br><br>Fișierul de configurare a fost deja copiat la <i>%2</i>. Quit - + Ieșire Continue - + Continuare Error accessing the configuration file - + A apărut o eroare în accesarea fișierului de ocnfigurare There was an error while accessing the configuration file at %1. Please make sure the file can be accessed by your user. - + A apărut o eroare în accesarea fișierului de configurare la %1. Vă rugăm să vă asigurați că fișierul poate fi accesat de către acest utilizator. Quit %1 - + Ieșire %1 @@ -837,12 +855,12 @@ This action will abort any currently running synchronization. Enter username and password for "%1" at %2. - + Introdu numele de utilizator și parola pentru "%1" la %2. Enter username and password for '%1' at %2. - + Introdu numele de utilizator și parola pentru '%1' la %2. @@ -860,7 +878,7 @@ This action will abort any currently running synchronization. Error writing metadata to the database - + A apărut o eroare în timpul scrierii de metadata în baza de date @@ -868,12 +886,12 @@ This action will abort any currently running synchronization. Please enter your end to end encryption passphrase:<br><br>User: %2<br>Account: %3<br> - + Vă rugăm să introduceți fraza de criptare end to end: <br><br>Utilizator:%2<br>Cont:%3<br> Enter E2E passphrase - + Introduceți fraza E2E @@ -881,29 +899,29 @@ This action will abort any currently running synchronization. Sync Conflict - + Conflict în sincronizare Conflicting versions of %1. - + Conflict de versiuni pentru %1. Which version of the file do you want to keep?<br/>If you select both versions, the local file will have a number added to its name. - + Ce versiune a fișierului dorești să fie păstrată? <br/>Dacă selectezi ambele versiuni, fișierul local va avea un număr adăugat în denumirea sa. Local version - + Versiunea locală Click to open the file - + Click pentru a deschide fișierul @@ -920,7 +938,7 @@ This action will abort any currently running synchronization. <a href="%1">Open local version</a> - + <a href="%1">Deschide versiunea locală</a> @@ -930,7 +948,7 @@ This action will abort any currently running synchronization. <a href="%1">Open server version</a> - + <a href="%1">Deschide versiunea serverului</a> @@ -946,22 +964,22 @@ This action will abort any currently running synchronization. Open server version - + Deschide versiunea serverului Keep both versions - + Păstrează ambele versiuni Keep local version - + Păstrează ambele versiuni Keep server version - + Păstrează versiunea serverului @@ -969,12 +987,12 @@ This action will abort any currently running synchronization. Do you want to delete the directory <i>%1</i> and all its contents permanently? - + Dorești să ștergi dosarul <i>%1</i>și tot conținutul permanent ? Do you want to delete the file <i>%1</i> permanently? - + Doreși să ștergi fișierul <i>%1</i>permanent ? @@ -993,7 +1011,9 @@ This action will abort any currently running synchronization. Moving file failed: %1 - + Mutarea fișierului a eșuat: + +%1 @@ -1006,32 +1026,32 @@ This action will abort any currently running synchronization. Authentication error: Either username or password are wrong. - + Eroare de autentificare: Fie numele de utilizator fie parola sunt greșite. Timeout - + Timeout timeout - + timeout The provided credentials are not correct - + Informațiile de autentificare nu sunt corecte The configured server for this client is too old - + Serverul configurat pentru acest client este prea vechi Please update to the latest server and restart the client. - + Vă rugăm să instalați ultima versiune a serverului și să reporniți clientul @@ -1039,13 +1059,13 @@ This action will abort any currently running synchronization. The server file discovery reply is missing data. - + Răspunsul serverului are date lipsă Server error: PROPFIND reply is not XML formatted! - + Eroare de server: PROPFIND reply is not XML formatted! @@ -1053,27 +1073,27 @@ This action will abort any currently running synchronization. Error while opening directory %1 - + A apărut o eroare în timpul deschiderii dosarului %1 Directory not accessible on client, permission denied - + Dosarul nu este accesibil pe acest client, accesul este refuzat Directory not found: %1 - + Dosarul nu a fost găsit: %1 Filename encoding is not valid - + Encodarea numelui fisierului nu este validă Error while reading directory %1 - + A apărut o eroare in timpul citirii dosarului %1 @@ -1082,7 +1102,8 @@ This action will abort any currently running synchronization. Could not generate the metadata for encryption, Unlocking the folder. This can be an issue with your OpenSSL libraries. - + Nu s-a putut genera metadata pentru criptare, se deblochează dosarul +Aceasta poate fi o problemă cu librariile OpenSSL. @@ -1090,42 +1111,42 @@ This can be an issue with your OpenSSL libraries. The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + Deși URL-ul începe cu HTTPS, adresa URL-ului de pooling nu începe cu HTTPS. Autentificarea nu va fii posibilă deoarece ar putea exista o problemă de securitate. Vă rugăm contactați administartorul dumneavoastră. Error returned from the server: <em>%1</em> - + Răspunsul serverului conține o eroare: <em>%1</em> There was an error accessing the 'token' endpoint: <br><em>%1</em> - + A apărut o eroare in accesarea punctului final 'token': <br><em>%1</em> There was an error accessing the "token" endpoint: <br><em>%1</em> - + A apărut o eroare in accesarea punctului final 'token': <br><em>%1</em> Could not parse the JSON returned from the server: <br><em>%1</em> - + Nu sa putut analiza fișierul JSON provenit de la server: <br><em>%1</em> The reply from the server did not contain all expected fields - + Răspunsul de la server nu conține toate informațiile așteptate The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + Deși URL-ul începe cu HTTPS, adresa URL-ului de pooling nu începe cu HTTPS. Autentificarea nu va fii posibilă deoarece ar putea exista o problemă de securitate. Vă rugăm contactați administartorul dumneavoastră. @@ -1133,37 +1154,37 @@ This can be an issue with your OpenSSL libraries. Unable to open the Browser, please copy the link to your Browser. - + Nu se poate deschide Browserul Web. Vă rugăm să copiați linkul în Browserul dumneavoastră. - + Waiting for authorization - + Se așteaptă autorizarea - + Polling for authorization - + Se votează pentru autorizare - + Starting authorization - + Se pornește autorizarea - + Link copied to clipboard. Linkul a fost copiat în clipboard. - + Reopen Browser - + Re-deschide Browser-ul - + Copy Link - + Copiază link @@ -1171,17 +1192,17 @@ This can be an issue with your OpenSSL libraries. Local folder %1 does not exist. - + Dosarul local %1 nu există. %1 should be a folder but is not. - + %1 ar trebui să fie un dosar dar nu este. %1 is not readable. - + %1 nu poate fi citit. @@ -1197,7 +1218,7 @@ This can be an issue with your OpenSSL libraries. %1 and %n other file(s) have been downloaded. - + %1 și %n alt fișier a fost descărcat. %1 și %n alte fișiere au fost descărcate. %1 și %n de alte fișiere au fost descărcate. @@ -1208,18 +1229,18 @@ This can be an issue with your OpenSSL libraries. %1 and %n other file(s) have been added. - + %1 și un alt fișier a fost adăugat. %1 și %n alte fișiere au fost adăugate. %1 și %n de alte fișiere au fost adăugate. %1 has been added. %1 names a file. - + %1 a fost adăugat. %1 and %n other file(s) have been updated. - + %1 și %n alt fișier a fost actualizat. %1 și %n alte fișiere au fost actualizate. %1 și %n de alte fișiere au fost actualizate. @@ -1230,7 +1251,7 @@ This can be an issue with your OpenSSL libraries. %1 has been renamed to %2 and %n other file(s) have been renamed. - + %1 a fost redenumit în %2 și un alt fișier a fost redenumit.%1 a fost redenumit în %2 și %n alte fișiere au fost redenumite.%1 a fost redenumit în %2 și %n de alte fișiere au fost redenumite. @@ -1241,7 +1262,7 @@ This can be an issue with your OpenSSL libraries. %1 has been moved to %2 and %n other file(s) have been moved. - + %1 a fost mostat în %2 și %n ale fișiee a fost mutat.%1 a fost mostat în %2 și %n alte fișiere au fost mutate.%1 a fost mostat în %2 și %n de alte fișiere au fost mutate. @@ -1251,69 +1272,70 @@ This can be an issue with your OpenSSL libraries. %1 has and %n other file(s) have sync conflicts. - + %1 are și %n alt fișier are conflicte de sincronizare.%1 are și %n alte fișiere au conflicte de sincronizare.%1 are și %n de alte fișiere au conflicte de sincronizare. %1 has a sync conflict. Please check the conflict file! - + %1 are un conflict. Vă rugăm să verificați fișierul cu conflicte! %1 and %n other file(s) could not be synced due to errors. See the log for details. - + %1 și %n alt fișier nu au putut fi sincronizat datorită unor erori. Vă rugăm verificați fisierele log pentru mai multe detalii.%1 și %n alte fișiere nu au putut fi sincronizate datorită unor erori. Vă rugăm verificați fisierele log pentru mai multe detalii.%1 și %n de alte fișiere nu au putut fi sincronizate datorită unor erori. Vă rugăm verificați fisierele log pentru mai multe detalii. %1 could not be synced due to an error. See the log for details. - + %1 nu a putut fi sincronizat datorită unei erori. Vă rugăm să verificați fișierele log pentru mai multe detalii. %1 and %n other file(s) are currently locked. - + %1 și %n alt fișier este în acest moment blocat.%1 și %n alte fișiere sunt în acest moment blocate.%1 și %n de alte fișiere sunt în acest moment blocate. %1 is currently locked. - + %1 este în acest moment blocat. Sync Activity - + Activitate de sincronizare Could not read system exclude file - + Nu sa putut citi fișierul de excludere A new folder larger than %1 MB has been added: %2. - + Un nou fisier mai mare de %1 MB a fost adăugat: %2. A folder from an external storage has been added. - + Un dosar dintr-o locație externă de stocare a fost adăugat. + Please go in the settings to select it if you wish to download it. - + Vă rugăm să selectați în setări dacă doriți să descărcați acest fișier. The folder %1 was created but was excluded from synchronization previously. Data inside it will not be synchronized. - + Dosarul %1 a fost creeat dar a fost exclus, în trecut de la sincronizare. Conținutul nu va fii sincronizat. The file %1 was created but was excluded from synchronization previously. It will not be synchronized. - + Fisierul %1 a fost creeat dar a fost exclus, în trecut de la sincronizare. Acest nu va fii sincronizat. @@ -1322,7 +1344,20 @@ This can be an issue with your OpenSSL libraries. This means that the synchronization client might not upload local changes immediately and will instead only scan for local changes and upload them occasionally (every two hours by default). %1 - + Schimbările in dosarele sincronizate nu pot fi urmărite în mod fiabil. + +Acest lucru înseamnă că aplicația de sincronizare ar putea să nu încarce schimbările locale imediat dar va scana doar schimbările locale și va încărca aceste schimbări în anumte ocazii (timpul predefinit este o data la 2 ore). + +%1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Toate fisierele din dosarul local de sincronizare '%1' au fost șterse. Aceste acțiuni vor fi sincronizate cu serverul tău, drept urmare aceste fisiere vor deveni indisponibile. +Ești sigur că dorești să sincronizezi toate aceste acțiuni cu serverul ? +Dacă această acțiune a fost un accident și dorești să pastrezi fișierele, acestea pot fi resincronizate de pe server. @@ -1330,14 +1365,19 @@ This means that the synchronization client might not upload local changes immedi These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. - + Toate fișierele din dosarul de sincronizare '%1' au fost șterse de pe acest server. +Această acțiune va fi sincronizată cu dosarul dumneavoastră local, drept urmare aceste fisiere vor deveni neaccesibile dacă nu ai dreptul de restaurare. +Dacă decizi să restaurezi aceste fișiere, acestea vor fi resincronizate cu serverul, dacă ai permisiunea pentru a face acest lucru. +Dacă decizi să ștergi aceste fișiere, acestea vor deveni indisponibile pentru tine, doar dacă tu ești proprietarul. All files got deleted from your local sync folder '%1'. These files will be deleted from the server and will not be available on your other devices if they will not be restored. If this action was unintended you can restore the lost data now. - + Toate fișierele au fost șterse din dosarul local de sincronizare '%1'. +Acesre fișiere vor fi șterse de pe server și nu vor fi disponibile pe alte dispozitive dacă nu veți restaura aceste fișiere. +Dacă această acțiune nu este intenționată atunci se pot recupera datele șterse chiar acum. @@ -1369,30 +1409,15 @@ Continuing the sync as normal will cause all your files to be overwritten by an Normal Synchronisation - + Sincronizare normală Keep Local Files as Conflict - + Păstrează fișierele locale ca și conflicte - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1400,7 +1425,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1409,11 +1434,19 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove All Files? - + Ștergeți toate fișierele ? Remove all files + Șterge toate fișierele + + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. @@ -1427,7 +1460,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Create new folder - + Creează un dosar nou @@ -1447,7 +1480,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Could not create a folder! Check your write permissions. - + Nu s-a putut creea un dosar nou! Vă rugăm să verificați permisiunile de scriere. @@ -1455,42 +1488,42 @@ If this was an accident and you decide to keep your files, they will be re-synce Could not reset folder state - + Nu s-a putut reseta starea dosarului An old sync journal '%1' was found, but could not be removed. Please make sure that no application is currently using it. - + Un jurnal de sicronizare vechi '%1' a fost găsit, dar acesta nu a putut fi șters. Vă rugăm să vă asigurați că acest jurnal nu este folosit de o aplicație. An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Un jurnal de sicronizare vechi '%1' a fost găsit, dar acesta nu a putut fi șters. Vă rugăm să vă asigurați că acest jurnal nu este folosit de o aplicație. (backup) - + copie de siguranță (backup) (backup %1) - + copia de siguranță %1 (backup) Undefined State. - + Stare nedefinită Waiting to start syncing. - + Se așteaptă pentru a începe sincronizarea. Preparing for sync. - + Se pregătește sincronizarea. @@ -1500,72 +1533,72 @@ If this was an accident and you decide to keep your files, they will be re-synce Sync was successful, unresolved conflicts. - + Sincronizarea a reușit, conflicte nerezolvate. Sync finished with unresolved conflicts. - + Sincronizarea a reușit cu conflicte nenrezolvate. Last Sync was successful. - + Ultima sincronizare a fost un succes. Setup Error. - + Eroare de configurare, User Abort. - + Anulați utilizatorul. Sync is paused. - + Sincronizarea este oprită. %1 (Sync is paused) - + %1 (Sincronizarea este oprită) No valid folder selected! - + Nu este selectat un dosar valid! The selected path does not exist! - + Calea selectaă nu există! The selected path is not a folder! - + Calea selectaă nu este un dosar! You have no permission to write to the selected folder! - + Nu ai permisiunea de a scrie în dosarul selectat! The local folder %1 already contains a folder used in a folder sync connection. Please pick another one! - + Dosarul local %1 conține deja un dosar folosit pentru sincronizare. Vă rugăm să alegeți un dosar diferit! The local folder %1 is already contained in a folder used in a folder sync connection. Please pick another one! - + Dosarul local %1 conține deja un dosar folosit pentru sincronizare. Vă rugăm să alegeți un dosar diferit! There is already a sync from the server to this local folder. Please pick another local folder! - + Deja există un dosar de sincronizare de la acest sever către acest server. Vă rugăm să selectați un dosar local diferit! @@ -1573,12 +1606,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Add Folder Sync Connection - + Adaugă o conexiune de sincronizare pentru un dosar Synchronized with local folder (%1) - + Sincronizat cu dosarul local (%1) @@ -1591,39 +1624,39 @@ If this was an accident and you decide to keep your files, they will be re-synce You need to be connected to add a folder - + Trebuie să fii conectat pentru a adăuga un dosar Click this button to add a folder to synchronize. - + Click pe acest buton pentru a adăuga un folder pentru a fii sincronizat. %1 (%2) Example text: "File.txt (23KB)" - + %1 (%2) Error while loading the list of folders from the server. - + A apărut o eroare în momentul descărcării listei de dosare de pe server. Fetching folder list from server … - + Se descarcă lista de dosare de pe server ... There are unresolved conflicts. Click for details. - + Există conflicte nerezolvate. Click pentru mai multe detalii. Virtual file support is enabled. - + Suportul pentru fișiere virtuale este pornit. @@ -1633,37 +1666,37 @@ If this was an accident and you decide to keep your files, they will be re-synce Synchronizing VirtualFiles with local folder - + Se sincronizează fișiere virtuale cu dosarul local Synchronizing with local folder - + Se sincronizează cu dosarul local Checking for changes in remote '%1' - + Se verifică schimbările pe dosarul '%1' Checking for changes in local '%1' - + Se verifică schimbările pe dosarul local '%1' Checking for changes in remote "%1" - + Se verifică schimbările pe dosarul '%1' Checking for changes in local "%1" - + Se verifică schimbările în dosarul local '%1' Reconciling changes - + Se reconciliază schimbările @@ -1681,7 +1714,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Syncing %1 Example text: "Syncing 'foo.txt', 'bar.txt'" - + Se sincronizează %1 @@ -1698,7 +1731,7 @@ If this was an accident and you decide to keep your files, they will be re-synce ↓ %1/s - + ↓ %1/s @@ -1727,18 +1760,18 @@ If this was an accident and you decide to keep your files, they will be re-synce %5 left, %1 of %2, file %3 of %4 Example text: "5 minutes left, 12 MB of 345 MB, file 6 of 7" - + %5 dreapta, %1 sau %2, fișier %3 sau %4 %1 of %2, file %3 of %4 Example text: "12 MB of 345 MB, file 6 of 7" - + %1 din %2, dișier %3 sau %4 file %1 of %2 - + fișier %1 sau %2 @@ -1748,12 +1781,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Waiting for %n other folder(s) … - + Se așteaptă pentru %n alt dosar ...Se așteaptă pentru %n alte dosare ...Se așteaptă pentru %n de alte dosare ... Preparing to sync … - + Se pregăteste sincronizarea ... @@ -1761,7 +1794,7 @@ If this was an accident and you decide to keep your files, they will be re-synce The watcher did not receive a test notification. - + Observatorul nu a primit o notificare de testare. @@ -1769,7 +1802,7 @@ If this was an accident and you decide to keep your files, they will be re-synce This problem usually happens when the inotify watches are exhausted. Check the FAQ for details. - + Această problemă apare atunci când API-ul inotify nu mai funcționează corespunzător. Verifică secțiunea FAQ pentru mai multe detalii. @@ -1777,12 +1810,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Add Folder Sync Connection - + Adaugă conexiunea de sincronizare pentru dosar Add Sync Connection - + Aadaugă conexiune de sincronizare @@ -1790,12 +1823,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Click to select a local folder to sync. - + Click pentru a selecta un dosar local pentru a-l sincroniza. Enter the path to the local folder. - + Introduceți calea către dosarul local. @@ -1813,52 +1846,52 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below '%1': - + Introduceți numele noului dosar ce va fii creat mai joi '%1'. Enter the name of the new folder to be created below "%1": - + Introduceți numele noului dosar ce va fii creat mai joi '%1'. Folder was successfully created on %1. - + Dosarul a fost creeat cu succes pe %1. Authentication failed accessing %1 - + Autentificarea a eșuat în momentul accesării %1 Failed to create the folder on %1. Please check manually. - + Nu se poate creea un dosar pe %1. Vă rugăm să verificați manual. Failed to list a folder. Error: %1 - + A apărut o eroare in timpul listării dosarului. Eroare: %1 Choose this to sync the entire account - + Apasă aici pentru a sincroniza tot contul This folder is already being synced. - + Acest dosar este deja sincronizat You are already syncing <i>%1</i>, which is a parent folder of <i>%2</i>. - + Deja sincronizezi <i>%1</i>, care este un dosar păritnte pentru <i>%2</i>. You are already syncing <i>%1</i>, which is a subfolder of <i>%2</i>. - + Deja sincronizezi <i>%1</i>,. care este un subdosar al <i>%2</i>. @@ -1867,23 +1900,23 @@ If this was an accident and you decide to keep your files, they will be re-synce Use virtual files instead of downloading content immediately %1 - + Folosește fișiere virtuale în loc să descarci continutul imediat %1 (experimental) - + (experimental) Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + Fișierele virtuale nu sunt suportate pentru partițiile Wwindows ca dosar local. Vă rugăm să alegeți un subdosar valid. Virtual files are not available for the selected folder - + Fișierele virtuale nu sunt disponibile pentru dosarul selectat @@ -1891,12 +1924,12 @@ If this was an accident and you decide to keep your files, they will be re-synce <b>Warning:</b> %1 - + <b>Atenție</b> %1 <b>Warning:</b> - + <b>Atenție:</b> @@ -1904,12 +1937,12 @@ If this was an accident and you decide to keep your files, they will be re-synce No E-Tag received from server, check Proxy/Gateway - + Nu s-a primit nici-un E-Tag de la server, verifică setările pentru Proxy/Gateway We received a different E-Tag for resuming. Retrying next time. - + Am primit un E-Tag diferit pentru a relua activitatea. Se reîncearcă data viitoare. @@ -1938,7 +1971,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Legal notice - + Aviz juridic @@ -1953,7 +1986,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Use &Monochrome Icons - + Folosește pictograme &Monochrome @@ -1963,12 +1996,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Show Server &Notifications - + Arată notificările serverului Updates - + Actualizări @@ -2240,6 +2273,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2375,7 +2471,7 @@ Logs will be written to %1 - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2418,6 +2514,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2587,6 +2688,12 @@ Logs will be written to %1 New %1 Update Ready + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + + New %1 update ready @@ -2594,8 +2701,7 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. @@ -2633,6 +2739,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2643,6 +2754,11 @@ for additional privileges during the process. Could not check for new updates. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2938,37 +3054,37 @@ It is not advisable to use it. - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> - + Creating local sync folder %1 … @@ -2978,84 +3094,84 @@ It is not advisable to use it. ok - + OK - + failed. eșuat! - + Could not create local folder %1 - + No remote folder specified! - + Error: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. - + The remote folder %1 already exists. Connecting it for syncing. - - + + The folder creation resulted in HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. - + Successfully connected to %1! - + Connection to %1 could not be established. Please check again. - + Folder rename failed @@ -3065,12 +3181,12 @@ It is not advisable to use it. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> @@ -3078,13 +3194,13 @@ It is not advisable to use it. OCC::OwncloudWizard - - %1 Connection Wizard + + Add %1 account - - Add %1 account + + %1 Connection Wizard @@ -3119,24 +3235,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - - - - - Open Local Folder - - - - - Open %1 in Browser - - - OCC::PollJob @@ -3147,6 +3245,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3164,12 +3272,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3298,7 +3406,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3913,11 +4021,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - Permite editarea - Read only @@ -3938,6 +4041,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Protejare cu parolă + + + Allow editing + Permite editarea + + + + View only + + Allow upload and editing @@ -3953,16 +4066,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Aruncă fișierul (numai încărcare) - - - Note to recipient - Notă către destinatar - Unshare Anulare partajare + + + Link name + + + + + Note to recipient + Notă către destinatar + Password protect @@ -3974,15 +4092,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Specifică data expirării - - Delete share link - Șterge linkul partajat + + Delete link + Add another link Adaugă un alt link + + + Delete share link + Șterge linkul partajat + Confirm Link Share Deletion @@ -4032,7 +4155,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Niciun rezultat pentru '%1' - + No results for "%1" @@ -4136,12 +4259,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Partajat cu %1 - Context menu share @@ -4168,6 +4285,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4239,6 +4362,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Șterge + + + Share with %1 + parameter is Nextcloud + Partajat cu %1 + OCC::SslButton @@ -4382,6 +4511,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4556,6 +4690,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() + + + Aborted + + @@ -4708,24 +4847,85 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Numele fișierului conține cel puțin un caracter invalid - - Aborted + + Disk space is low: Downloads that would reduce free space below %1 were skipped. - - Disk space is low: Downloads that would reduce free space below %1 were skipped. + + There is insufficient space available on the server for some uploads. + + + OCC::SyncStatusSummary - - There is insufficient space available on the server for some uploads. + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 @@ -4804,6 +5004,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4861,23 +5084,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5395,14 +5702,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - - - QObject @@ -5495,6 +5794,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5509,22 +5840,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Cont conectat - Current user status is do not disturb + Account not connected - Account connected - Cont conectat + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5532,6 +5863,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + + + + + Set status + + @@ -5544,17 +5885,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Autentificare - - - Remove Account - - Remove account Sterge contul + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5616,12 +6005,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5631,17 +6020,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5670,6 +6059,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5705,12 +6099,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5771,6 +6159,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6070,6 +6474,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + + + + + Open Local Folder + + + + + Open %1 in Browser + + + OCC::ShibbolethCredentials @@ -6122,6 +6544,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + + + OCC::UserStatus @@ -6145,4 +6575,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_ru.ts b/translations/client_ru.ts index f21b1f75c717..ad8cc5c711da 100644 --- a/translations/client_ru.ts +++ b/translations/client_ru.ts @@ -12,22 +12,35 @@ Open %1 locally - + Открыть «%1» на ПК + + + + Open share dialog + Открыть диалог публикации + + + + Share %1 + Опубликовать «%1» Show more actions - + Дополнительные действия - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -41,12 +54,12 @@ Checking for changes in "%1" - + Проверка изменений в «%1» Checking for changes in '%1' - Проверка наличия изменений в «%1» + Проверка изменений в «%1» @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Ошибка удаления «%1»: %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Не удалось удалить папку «%1» @@ -331,22 +344,22 @@ End-to-End Encryption with Virtual Files - + Оконечное шифрование виртуальных файлов You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Для этой папки используется механизм виртуальных файлов. В настоящее время не придерживается «прозрачное» получение с сервера виртуальных файлов, зашифрованных с использованием оконечного шифрования. Для работы с такими файлами используйте пункт "Хранить на устройстве». Don't encrypt folder - + Не шифровать папку Encrypt folder - + Зашифровать папку @@ -403,7 +416,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Для этой папки используется механизм виртуальных файлов. В настоящее время не придерживается «прозрачное» получение с сервера виртуальных файлов, зашифрованных с использованием оконечного шифрования. Для работы с такими файлами используйте пункт "Хранить на устройстве». @@ -414,12 +427,12 @@ Wait for the new sync, then encrypt it. Encryption failed - + Ошибка шифрования Could not encrypt folder because the folder does not exist anymore - + Не удалось зашифровать папку, она более не существует @@ -591,7 +604,7 @@ This action will abort any currently running synchronization. %1 as %2 - + %1: %2 @@ -755,7 +768,7 @@ This action will abort any currently running synchronization. Certificate & Key (pkcs12): - + Сертификат и ключ (pkcs12): @@ -841,7 +854,7 @@ This action will abort any currently running synchronization. Enter username and password for "%1" at %2. - + Введите имя пользователя и пароль для «1» на %2. @@ -1017,7 +1030,7 @@ This action will abort any currently running synchronization. Timeout - + Тайм-аут @@ -1097,7 +1110,7 @@ This can be an issue with your OpenSSL libraries. The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + При запросе процедуры авторизации с использованием HTTPS получен ответ без использования HTTPS. Продолжение процедуры авторизации будет прервано, так как такой вход небезопасен. Сообщите о ситуации системному администратору. @@ -1115,7 +1128,7 @@ This can be an issue with your OpenSSL libraries. There was an error accessing the "token" endpoint: <br><em>%1</em> - + Ошибка при доступе к механизму обработки токенов: <br><em>%1</em> @@ -1132,7 +1145,7 @@ This can be an issue with your OpenSSL libraries. The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + При запросе процедуры авторизации с использованием HTTPS получен адрес сервера, не использующего HTTPS. Продолжение процедуры авторизации будет прервано, так как такой вход небезопасен. Сообщите о ситуации системному администратору. @@ -1143,32 +1156,32 @@ This can be an issue with your OpenSSL libraries. Не удалось открыть браузер, скопируйте ссылку и перейдите по ней в своём браузере. - + Waiting for authorization Ожидание авторизации - + Polling for authorization Получение параметров для авторизации - + Starting authorization Начало авторизации - + Link copied to clipboard. Ссылка скопирована в буфер обмена. - + Reopen Browser Повторно открыть браузер - + Copy Link Скопировать ссылку @@ -1226,7 +1239,7 @@ This can be an issue with your OpenSSL libraries. %1 and %n other file(s) have been updated. - Обновлёны «%1» и ещё один файл.Обновлёны «%1» и ещё %n файла.Обновлёны «%1» и ещё %n файлов.Обновлёны «%1» и ещё %n файлов. + Обновлены «%1» и ещё один файл.Обновлены «%1» и ещё %n файла.Обновлены «%1» и ещё %n файлов.Обновлены «%1» и ещё %n файла. @@ -1335,6 +1348,15 @@ This means that the synchronization client might not upload local changes immedi Это означает, что приложение для синхронизации не может выполнять синхронизацию локальных изменений с сервером немедленно. Вместо этого будет выполняться периодическое (по умолчанию каждые два часа) сканирование локальных папок и синхронизация обнаруженных изменений с сервером. %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Из локальной синхронизируемой папки «%1» удалены все файлы. Информация об удалении будет отправлена на сервер, таким образом сделав файлы недоступными, если только не восстанавливать их из резервной копии. +Действительно выполнить синхронизировать с этими изменениями? +Если это произошло случайно, и вы решите сохранить файлы, они будут повторно скачаны с сервера. @@ -1394,8 +1416,8 @@ Continuing the sync as normal will cause all your files to be overwritten by an Сохранить локальные файлы как конфликтующие - - All files in the sync folder '%1' folder were deleted on the server. + + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. @@ -1405,29 +1427,14 @@ If you decide to delete the files, they will be unavailable to you, unless you a При выборе «Удалить файлы», файлы станут недоступны, кроме случая, когда вы являетесь их владельцем. - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. + + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. Из локальной синхронизируемой папки «%1» удалены все файлы. Информация об удалении будет отправлена на сервер, таким образом сделав файлы недоступными, если только не восстанавливать их из резервной копии. Действительно выполнить синхронизировать с этими изменениями? Если это произошло случайно, и вы решите сохранить файлы, они будут повторно скачаны с сервера. - - - All files in the sync folder "%1" folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - Remove All Files? @@ -1438,6 +1445,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Удалить все файлы + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Из синхронизируемой папки «%1» на стороне сервера удалены все файлы. +При синхронизации будет выполнено удаление локальной копии файлов, что сделает их недоступными при отсутствии прав на восстановление удалённых файлов. +При выборе «Сохранить файлы» и наличии соответствующих прав доступа, файлы будут повторно переданы на сервер. +При выборе «Удалить файлы», файлы станут недоступны, кроме случая, когда вы являетесь их владельцем. + Keep files @@ -1487,7 +1505,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Найден старый журнал синхронизации «%1», но он не может быть удалён. Убедитесь, что файл журнала не открыт в другом приложении. @@ -1675,12 +1693,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Проверка изменений на сервере «%1» Checking for changes in local "%1" - + Проверка изменений в локальной папке «%1» @@ -1840,7 +1858,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + Введите имя папки для создания внутри «%1»: @@ -1870,7 +1888,7 @@ If this was an accident and you decide to keep your files, they will be re-synce This folder is already being synced. - Этот каталог уже выбран для синхронизации. + Синхронизация этой папки уже настроена. @@ -1900,7 +1918,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + В ОС Windows механизм виртуальных файлов не поддерживается для корневой уровня файловой системы. Для продолжения выберите папку на диске, а не сам диск. @@ -2155,12 +2173,12 @@ Note that this selects only what pool upgrades are taken from, and that there ar Reading from keychain failed with error: "%1" - + Чтение связки ключей завершилось ошибкой: «%1» Reading from keychain failed with error: '%1' - Чтение из брелока завершилось с ошибкой: '%1' + Чтение связки ключей завершилось ошибкой: «%1» @@ -2198,12 +2216,12 @@ Note that this selects only what pool upgrades are taken from, and that there ar This entry is provided by the system at "%1" and cannot be modified in this view. - + Эта пункт добавлен системой «'%1» и не может быть изменён. This entry is provided by the system at '%1' and cannot be modified in this view. - Эта запись сделана системой в '%1' и не может быть изменена в этом представлении. + Эта пункт добавлен системой «'%1» и не может быть изменён. @@ -2249,7 +2267,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from Cannot write changes to "%1". - + Невозможно записать изменения в «%1». @@ -2267,6 +2285,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Введите шаблон для исключения файлов из синхронизации: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2283,7 +2364,7 @@ Items where deletion is allowed will be deleted if they prevent a directory from <p>Copyright 2017-2021 Nextcloud GmbH<br />Copyright 2012-2021 ownCloud GmbH</p> - + <p>© Nextcloud GmbH, 2017—2021<br />© ownCloud GmbH, 2012—2021</p> @@ -2407,9 +2488,9 @@ Logs will be written to %1 <nobr>Файл '%1'<br/>не может быть открыт на запись.<br/><br/>Журнал <b>не может</b> быть сохранён!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> - + <nobr>Файл «%1»<br/>не может быть открыт на запись.<br/><br/>Журнал <b>не может</b> быть сохранён!</nobr> @@ -2450,6 +2531,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Новая версия %1 клиента доступна, но произошёл сбой в процессе обновления.</p><p><b>%2</b> был загружен. Установлена версия %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Новая версия %1 клиента доступна, но произошёл сбой в процессе обновления.</p><p><b>%2</b> был загружен. Установлена версия %3. При подтверждении перезапуска и обновления, для завершения установки компьютер может быть перезагружен.</p> + Ask again later @@ -2584,7 +2670,7 @@ Logs will be written to %1 There was an error accessing the "token" endpoint: <br><em>%1</em> - + Ошибка при доступе к механизму обработки токенов: <br><em>%1</em> @@ -2619,11 +2705,6 @@ Logs will be written to %1 New %1 Update Ready Доступно обновление %1 - - - New %1 update ready - - A new update for %1 is about to be installed. The updater may ask @@ -2631,6 +2712,16 @@ for additional privileges during the process. Новое обновление %1 в процессе установки. Установщик может запросить дополнительные разрешения во время обновления. + + + New %1 update ready + Доступно обновление %1 + + + + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Обновление %1 готово к установке. Приложение установки может запросить дополнительные разрешения во время работы. Для завершения установки может потребоваться перезагрузка компьютера. + Downloading version %1. Please wait … @@ -2666,6 +2757,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. Новый %1 доступен. Пожалуйста нажмите <a href='%2'>здесь</a> чтобы загрузить обновление. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2676,6 +2772,11 @@ for additional privileges during the process. Could not check for new updates. Не удалось проверить наличие новых обновлений. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2694,7 +2795,7 @@ for additional privileges during the process. No updates available. Your installation is at the latest version. - Обновлений в настоящий момент нет. У вас установлена самая последняя версия программы. + Обновлений в настоящий момент нет. У вас установлена самая последняя версия приложения. @@ -2759,17 +2860,17 @@ for additional privileges during the process. Virtual files are not supported for Windows partition roots as local folder. Please choose a valid subfolder under drive letter. - + В ОС Windows механизм виртуальных файлов не поддерживается для корневой уровня файловой системы. Для продолжения выберите папку на диске, а не сам диск. %1 folder "%2" is synced to local folder "%3" - + %1 каталог «%2» синхронизирован с локальной папкой «%3» Sync the folder "%1" - + Синхронизировать папку «%1» @@ -2973,37 +3074,37 @@ It is not advisable to use it. Превышено время ожидания соединения к %1 на %2. - + Trying to connect to %1 at %2 … Попытка подключения к серверу %1 по адресу %2... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Запрос авторизации с сервера перенаправлен на «%1». Ссылка неверна, сервер неправильно настроен. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Запрос авторизации с сервера перенаправлен на «%1». Ссылка неверна, сервер неправильно настроен. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Доступ запрещён сервером. Чтобы доказать, что у Вас есть права доступа, <a href="%1">нажмите здесь</a> для входа через Ваш браузер. - + There was an invalid response to an authenticated WebDAV request Получен неверный ответ на авторизованный запрос WebDAV - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Локальный каталог синхронизации %1 уже существует, используем его для синхронизации.<br/><br/> - + Creating local sync folder %1 … Создание локальной папки синхронизации %1... @@ -3013,115 +3114,115 @@ It is not advisable to use it. OK - + OK - + ОК - + failed. не удалось. - + Could not create local folder %1 Не удалось создать локальный каталог синхронизации %1 - + No remote folder specified! Не указан удалённый каталог! - + Error: %1 Ошибка: %1 - + creating folder on Nextcloud: %1 создание папки на сервере Nextcloud: %1 - + Remote folder %1 created successfully. Папка «%1» на сервере успешно создана. - + The remote folder %1 already exists. Connecting it for syncing. Папка «%1» уже существует на сервере. Выполняется подключение для синхронизации. - - + + The folder creation resulted in HTTP error code %1 Создание каталога завершилось с HTTP-ошибкой %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Не удалось создать удаленный каталог, так как представленные параметры доступа неверны!<br/>Пожалуйста, вернитесь назад и проверьте учетные данные.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Не удалось создать удаленный каталог, возможно, указанные учетные данные неверны.</font><br/>Вернитесь назад и проверьте учетные данные.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Удаленный каталог %1 не создан из-за ошибки <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Установлено соединение синхронизации %1 к удалённому каталогу %2. - + Successfully connected to %1! Соединение с %1 успешно установлено. - + Connection to %1 could not be established. Please check again. Не удалось соединиться с %1. Попробуйте снова. - + Folder rename failed Ошибка переименования папки Can't remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - Невозможно удалить каталог и создать его резервную копию, каталог или файл в ней открыт в другой программе. Закройте каталог или файл и нажмите "Повторить попытку", либо прервите мастер настройки. + Невозможно удалить каталог и создать его резервную копию, каталог или файл в ней открыт в другом приложении. Закройте каталог или файл и нажмите «Повторить попытку», либо прервите работу мастера настройки. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - Невозможно удалить каталог и создать его резервную копию, каталог или файл в ней открыт в другой программе. Закройте каталог или файл и нажмите "Повторить попытку", либо прервите мастер настройки. + Невозможно удалить каталог и создать его резервную копию, каталог или файл в ней открыт в другом приложении. Закройте каталог или файл и нажмите «Повторить попытку», либо прервите работу мастера настройки. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Локальная папка синхронизации «%1» успешно создана.</b></font> OCC::OwncloudWizard + + + Add %1 account + Создание учётной записи %1 + %1 Connection Wizard Мастер подключения %1 - - - Add %1 account - Добавить %1 учётную запись - Skip folders configuration @@ -3157,25 +3258,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Stay safe - Остаться в безопасности - - - - OCC::OwncloudWizardResultPage - - - Everything set up! - Всё готово! - - - - Open Local Folder - Открыть локальную папку - - - - Open %1 in Browser - Открыть «%1» в браузере + Не рисковать @@ -3188,6 +3271,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3205,12 +3298,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. - + File names containing the character '%1' are not supported on this file system. + Используемая файловая система не поддерживает имена файлов, содержащие символ «%1». - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. Используемая файловая система не поддерживает имена файлов, содержащие символ «%1». @@ -3286,17 +3379,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Conflict when uploading some files to a folder. Those, conflicted, are going to get cleared! - + Передача файлов в папку на сервере привела к конфликту версий. Файлы, вызвавшие конфликт версий, будут удалены. Conflict when uploading a folder. It's going to get cleared! - + Передача папки на сервер привела к конфликту версии. Папка, вызвавшая конфликт версии, будет удалена. Conflict when uploading a file. It's going to get removed! - + Передача файла на сервер привела к конфликту версии. Файл, вызвавший конфликт версии, будет удалён. @@ -3339,9 +3432,9 @@ This is a new, experimental mode. If you decide to use it, please report any iss Ошибка сервера при попытке прочитать каталог «%1»: %2 - + Server replied with an error while reading directory "%1" : %2 - + Ошибка сервера при попытке прочитать каталог «%1»: %2 @@ -3354,12 +3447,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Ошибка обновления метаданных: %1 File is currently in use - + Файл используется @@ -3419,7 +3512,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss The downloaded file is empty, but the server said it should have been %1. - + Скачанный файл пуст, хотя сервер сообщил, что его размер должен составлять %1 @@ -3434,12 +3527,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Ошибка обновления метаданных: %1 The file %1 is currently in use - + Файл «%1» используется @@ -3470,7 +3563,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Could not create folder %1 - + Не удалось создать папку «%1» @@ -3480,12 +3573,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Ошибка обновления метаданных: %1 The file %1 is currently in use - + Файл «%1» используется @@ -3526,12 +3619,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Ошибка обновления метаданных: %1 The file %1 is currently in use - + Файл «%1» используется @@ -3542,7 +3635,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to rename file - + Не удалось переименовать файл @@ -3581,12 +3674,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error writing metadata to the database: %1 - + Ошибка записи метаданных в базу данных: %1 The file %1 is currently in use - + Файл «%1» используется @@ -3604,12 +3697,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Ошибка обновления метаданных: %1 The file %1 is currently in use - + Файл «%1» используется @@ -3638,7 +3731,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Upload of %1 exceeds the quota for the folder - Передача «%1» на сервер превысит заданную для папки квоту + При передаче «%1» на сервер будет превышена квота, установленная для папки @@ -3668,12 +3761,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Error updating metadata: %1 - + Ошибка обновления метаданных: %1 The file %1 is currently in use - + Файл «%1» используется @@ -3922,7 +4015,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Note - + Примечание @@ -3932,7 +4025,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Set password - + Установить пароль @@ -3947,18 +4040,13 @@ This is a new, experimental mode. If you decide to use it, please report any iss Expires - + Срок действия Allow Editing Разрешить редактирование - - - Allow editing - Разрешить редактирование - Read only @@ -3979,6 +4067,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Защитить паролем + + + Allow editing + Разрешить редактирование + + + + View only + + Allow upload and editing @@ -3994,36 +4092,46 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Хранилище (только приём файлов) - - - Note to recipient - Примечание для получателя - Unshare Закрыть доступ - - Password protect - Защитить паролем + + Link name + - + + Note to recipient + Примечание для получателя + + + + Password protect + Защитить паролем + + + Set expiration date Установить срок действия - - Delete share link - Удалить ссылку + + Delete link + Add another link Добавить другую ссылку + + + Delete share link + Удалить ссылку + Confirm Link Share Deletion @@ -4070,27 +4178,27 @@ This is a new, experimental mode. If you decide to use it, please report any iss No results for '%1' - Нет результатов для '%1' + Отсутствуют результаты поиска «%1» - + No results for "%1" - + Отсутствуют результаты поиска «%1» Password for share required - + Создаваемый общий ресурс требуется защитить паролем Please enter a password for your email share: - + Задайте пароль для публикации ссылки по эл. почты: I shared something with you - Я поделился с тобой + Вам предоставлен доступ @@ -4108,7 +4216,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Can edit - + Разрешить редактировать @@ -4118,7 +4226,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password: - + Пароль: @@ -4163,7 +4271,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password protect - + Защитить паролем @@ -4177,12 +4285,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Предоставить доступ %1 - Context menu share @@ -4209,6 +4311,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 %1 — Предоставление общего доступа + + + + Activity + + Copy private link to clipboard @@ -4280,6 +4388,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Удалить + + + Share with %1 + parameter is Nextcloud + Предоставить доступ %1 + OCC::SslButton @@ -4425,6 +4539,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Не удалось осуществить безопасное подключение к <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4599,6 +4718,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Только %1 доступно, нужно как минимум %2 чтобы начать + + + Aborted + Отменено + @@ -4751,27 +4875,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Недопустимые символы, пожалуйста, переименуйте "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Имя файла содержит по крайней мере один некорректный символ - - Aborted - Отменено - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Мало места на диске: Скачивания, которые сократят свободное место ниже %1, будут пропущены. - + There is insufficient space available on the server for some uploads. На сервере недостаточно места для некоторых закачек. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4839,7 +5024,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p><small>Using virtual files plugin: %1</small></p> - + <p><small>Используемый модуль поддержки виртуальных файлов: %1</small></p> @@ -4847,6 +5032,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Этот выпуск подготовлен %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4904,24 +5112,108 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Для использования виртуальной файловой системы требуется NTFS, %1 использует %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Не удалось получить шаблоны статусов с сервера, убедитесь, что подключение установлено. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - + + Could not fetch user status. Make sure you are connected to the server. + Не удалось получить статус пользователя с сервера, убедитесь, что подключение установлено. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - + + User status feature is not supported. You will not be able to set your user status. + Функция статусов пользователей не поддерживается сервером. + + + + Emojis feature is not supported. Some user status functionality may not work. + Поддержка эмодзи не используется на севере, некоторые возможности статусов могут не работать. + + + + Could not set user status. Make sure you are connected to the server. + Не удалось установить статус на сервере. Убедитесь, что подключение установлено. + + + + Could not clear user status message. Make sure you are connected to the server. + Не удалось удалить описание статуса на сервере. Убедитесь, что подключение установлено. + + + + + Don't clear + Не очищать + + + + 30 minutes + 30 минут + + + + + 1 hour + 1 час + + + + 4 hours + 4 часа + + + + + Today + Сегодня + + + + + This week + На этой неделе + + + + Less than a minute + Меньше минуты + + + + 1 minute + Одна минута + + + + %1 minutes + %n минут(ы) + + + + %1 hours + %n часов(а) + + + + 1 day + 1 день + + + + %1 days + %n дней + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Для использования виртуальной файловой системы требуется NTFS, %1 использует %2 @@ -5130,7 +5422,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in remote "%1" - + Проверка изменений на сервере «%1» @@ -5140,7 +5432,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Checking for changes in local "%1" - + Проверка изменений в локальной папке «%1» @@ -5439,14 +5731,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Войти в %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Все объекты на стороне сервера полностью синхронизированы с локальной папкой - - QObject @@ -5513,22 +5797,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Away - + Отошёл Do not disturb - + Не беспокоить Offline - + Не в сети Online - + В сети @@ -5536,6 +5820,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss Failed to connect database. + Не удалось подключиться к базе данных + + + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results @@ -5553,29 +5869,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - Текущий статус пользователя - в сети + Account connected + Аккаунт подключен - Current user status is do not disturb - Текущий статус пользователя - не беспокоить + Account not connected + Учётная запись не подключена - Account connected - Аккаунт подключен + Current user status is online + Текущий статус пользователя - в сети - Account not connected - Учётная запись не подключена + Current user status is do not disturb + Текущий статус пользователя - не беспокоить Account actions Действия над аккаунтом + + + Remove Account + Удалить учётную запись + + + + Set status + Установить статус + @@ -5588,17 +5914,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Войти - - - Remove Account - Удалить учётную запись - Remove account Удалить учётную запись + + UserStatusSelector + + + Online status + Статус работы в сети + + + + Online + В сети + + + + Away + Отошёл + + + + Do not disturb + Не беспокоить + + + + Invisible + Невидимый + + + + Status message + Описание статуса + + + + What is your status? + Опишите свой статус + + + + Clear status message after + Убрать описание статуса через + + + + Clear status message + Убрать описание статуса + + + + Set status message + Описать статус + + Utility @@ -5660,12 +6034,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Неверная контрольная сумма заголовка. - + The checksum header contained an unknown checksum type '%1' Заголовок контрольной суммы содержит контрольную сумму неизвестного типа: «%1» @@ -5675,19 +6049,19 @@ This is a new, experimental mode. If you decide to use it, please report any iss Скачанный файл не соответствует контрольной сумме, операция будет возобновлена. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Вычисленная контрольная сумма файла не соответствует ожидаемой, операция будет возобновлена: «%1»<>«%2» - + The checksum header contained an unknown checksum type "%1" - + Заголовок контрольной суммы содержит контрольную сумму неизвестного типа: «%1» - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" - + Вычисленная контрольная сумма файла не соответствует ожидаемой, операция будет возобновлена: %1 != %2 @@ -5714,6 +6088,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Приостановить синхронизацию всех учётных записей + + + Set user status + Задать статус + Add account @@ -5749,12 +6128,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb Текущий статус пользователя - не беспокоить - - - - Show more actions - Дополнительные действия - Share %1 @@ -5815,6 +6188,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Открыть диалог настройки общего доступа + + + Unified search results list + + + + + + Show more actions + Дополнительные действия + + + + %1 - File activity + + main.cpp @@ -5831,7 +6220,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss %1 requires on a working system tray. If you are running XFCE, please follow <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">these instructions</a>. Otherwise, please install a system tray application such as "trayer" and try again. - + Для работы %1 требуется системный лоток значков. При использовании XFCE, следуйте <a href="http://docs.xfce.org/xfce/xfce4-panel/systray">этим инструкциям</a>. В противном случае, установите приложение панели системных значков, например, 'trayer', и попробуйте ещё раз. @@ -6039,7 +6428,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Make always available locally - Сделать доступным автономно + Хранить на устройстве @@ -6114,6 +6503,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Выполнить вход в браузере (процедура входа версии 2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Всё готово! + + + + Open Local Folder + Открыть локальную папку + + + + Open %1 in Browser + Открыть «%1» в браузере + + OCC::ShibbolethCredentials @@ -6166,6 +6573,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Вход в систему + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Все объекты на стороне сервера полностью синхронизированы с локальной папкой + + OCC::UserStatus @@ -6189,4 +6604,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss В сети + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Не удалось получить зашифрованный файл + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + В настоящее время не придерживается «прозрачное» получение с сервера виртуальных файлов, зашифрованных с использованием оконечного шифрования. Для работы с такими файлами используйте пункт "Хранить на устройстве». + + \ No newline at end of file diff --git a/translations/client_sc.ts b/translations/client_sc.ts index bd3bca8e00b1..81877c5fc682 100644 --- a/translations/client_sc.ts +++ b/translations/client_sc.ts @@ -14,12 +14,6 @@ Open %1 locally Aberi %1 in locale - - - - Show more actions - Mustra àteras atziones - Open share dialog @@ -30,6 +24,25 @@ Share %1 Cumpartzi %1 + + + + Show more actions + Mustra àteras atziones + + + + View activity + + + + + ActivityList + + + Activity list + + CloudProviderWrapper @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" No at fatu a tramudare "%1" a "%2" @@ -1144,32 +1157,32 @@ Custu podet èssere un'errore de is librerias tuas OpenSSL. Non faghet a abèrrere su navigadore, pro praghere, còpia su ligòngiu a su navigadore tuo. - + Waiting for authorization Isetende s'autorizatzione - + Polling for authorization Pedida autorizatzione - + Starting authorization Aviamentu de s'autorizatzione - + Link copied to clipboard. Ligòngiu copiadu in punta de billete. - + Reopen Browser Torra a abèrrere su navigadore - + Copy Link Còpia ligòngiu @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi Custu bolet nàrrere chi sa sincronizatzione de su cliente diat pòdere non carrigare sùbitu is modìficas locales e, imbetzes, at a esecutare isceti s'iscansione de is modìficas locales e cando non cando ddas at a carrigare (ogni duas oras, in modalidade predefinida) %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Totu is archìvios in sa cartella de sincronizatzione '%1' sunt eliminados in su serbidore. +Ses seguru chi boles sincronizare custas atziones cun su serbidore? +Si custu fiat un'errore e detzides de mantènnere is archìvios tuos, custos ddos at a torrare a sincronizare su serbidore. @@ -1398,27 +1420,7 @@ Sighende sa sincronizatzione comente norma s'ant a subraiscrìere totu is a Mantene archìvios locales comente cunflitu - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Totu is archìvios in sa cartella de sincronizatzione '%1' sunt istados eliminados in su serbidore. -Sa cantzelladura at a èssere sincronizada cun sa cartella de sincronizatzione locale tua, gasi chi custos archìvios no ant a èssere prus a disponimentu, francu chi apas su permissu pro ddos pòdere ripristinare. -Si detzides de ripristinare is archìvios, custos ant a èssere sincronizados torra cun su serbidore, si tenes is diritos pro ddu fàghere. -Si detzides de cantzellare is archìvios, non ant a èssere prus a disponimentu, francu chi sias tue su mere. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Totu is archìvios in sa cartella de sincronizatzione '%1' sunt eliminados in su serbidore. -Ses seguru chi boles sincronizare custas atziones cun su serbidore? -Si custu fiat un'errore e detzides de mantènnere is archìvios tuos, custos ddos at a torrare a sincronizare su serbidore. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1429,7 +1431,7 @@ Si detzides de ripristinare is archìvios, custos ant a èssere sincronizados to Si detzides de cantzellare is archìvios, non ant a èssere prus a disponimentu, francu chi sias tue su mere. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1448,6 +1450,17 @@ Si custu fiat un'errore e detzides de mantènnere is archìvios tuos, custo Remove all files Boga totu is archìvios? + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Totu is archìvios in sa cartella de sincronizatzione '%1' sunt istados eliminados in su serbidore. +Sa cantzelladura at a èssere sincronizada cun sa cartella de sincronizatzione locale tua, gasi chi custos archìvios no ant a èssere prus a disponimentu, francu chi apas su permissu pro ddos pòdere ripristinare. +Si detzides de ripristinare is archìvios, custos ant a èssere sincronizados torra cun su serbidore, si tenes is diritos pro ddu fàghere. +Si detzides de cantzellare is archìvios, non ant a èssere prus a disponimentu, francu chi sias tue su mere. + Keep files @@ -2278,6 +2291,69 @@ Is elementos in ue est permitidu ant a èssere cantzellados si impedint de catza Agiunghe unu modellu de esclusione: + + OCC::InvalidFilenameDialog + + + Invalid filename + Nùmene de archìviu non bàlidu + + + + The file could not be synced because it contains characters which are not allowed on this system. + No at fatu a sincronizare cust'archìviu, ca cuntenet caràteres no permìtidos in custu sistema. + + + + Error + Errore + + + + Please enter a new name for the file: + Inserta•nche unu nùmene pro s'archìviu: + + + + New filename + Nùmene nou de s'archìviu + + + + Rename file + Torra a numenare s'archìviu + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + No at fatu a sincronizare s'archìviu %1, ca su nùmene cuntenet caràteres no permìtidos in custu sistema. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Custos caràteres no sunt permìtidos in su sistema: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + No tenes su permissu de torrare a numenare cust'archìviu. Pedi a chie at creadu s'archìviu de ddu torrare a numenare. + + + + Filename contains illegal characters: %1 + Su nùmene de s'archìviu cuntenet caràteres no amìtidos: %1 + + + + Could not rename file. Please make sure you are connected to the server. + No at fatu a torrare a numenare s'archìviu. Controlla si tenes connessione a su serbidore. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + No at fatu a torrare a numenare s'archìviu, ca in su serbidore nd'at giai un'àteru cun su matessi nùmene. Sèbera un'àteru nùmene. + + OCC::LegalNotice @@ -2417,7 +2493,7 @@ Logs ant a èssere iscritos in %1 <nobr>S'archìviu '%1'<br/>no at fatu a ddu abèrrere in s'iscritura.<br/><br/>Su resurtadu de su log <b>no</b> at a èssere sarvadu!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>S'archìviu '%1'<br/>no faghet a dd'abèrrere pro s'iscritura.<br/><br/>Su resurtadu de su log <b>no</b> podet èssere sarvadu!</nobr> @@ -2460,6 +2536,11 @@ Logs ant a èssere iscritos in %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Una versione noa de su cliente %1 est a disponimentu, ma su protzessu de agiornamentu no est andadu bene.</p><p><b>%2</b> iscarrigadu. Sa versione installada est %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Una versione noa de su Client %1 est a disponimentu, ma su protzessu de agiornamentu no est andadu bene.</p><p><b>%2</b> est istadu iscarrigadu. Sa versione installada est %3. Si cunfirmas de torrare a aviare e agiornare, su computer tuo s'at a pòdere torrare a aviare pro cumpletare s'installatzione.</p> + Ask again later @@ -2629,6 +2710,13 @@ Logs ant a èssere iscritos in %1 New %1 Update Ready Un'agionamentu nou de %1 est prontu + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Un'agiornamentu nou de %1 est pro èssere installadu. S'agiornamentu diat pòdere pedire +privilègios in prus durante su protzessu. + New %1 update ready @@ -2636,10 +2724,8 @@ Logs ant a èssere iscritos in %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Un'agiornamentu nou de %1 est pro èssere installadu. S'agiornamentu diat pòdere pedire -privilègios in prus durante su protzessu. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Un'agiornamentu nou pro %1 est acanta de èssere installadu. S'agiornamentu podet pedire privilègios aditzionales in s'interis de su protzessu. Su computer s'at a pòdere torrare a aviare pro cumpletare s'installatzione. @@ -2676,6 +2762,11 @@ privilègios in prus durante su protzessu. New %1 is available. Please click <a href='%2'>here</a> to download the update. Su %1 est a disponimentu. Incarca <a href='%2'>inoghe</a> pro iscarrigare s'agiornamentu. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + No at fatu a iscarrigare s'agiornamentu. Aberi <a href='%1'>%1</a> pro iscarrigare s'agiornamentu a manu. + Could not download update. Please open %1 to download the update manually. @@ -2686,6 +2777,11 @@ privilègios in prus durante su protzessu. Could not check for new updates. No at fatu a controllare is agiornamentos noos. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Unu nou %1 est a disponimentu. Aberi <a href='%2'>%2</a> pro iscarrigare s'agiornamentu. + New %1 is available. Please open %2 to download the update. @@ -2982,37 +3078,37 @@ Si cunsìgiat de non ddu impreare. Tempus iscàdidu proende a si connètere a %1 in %2. - + Trying to connect to %1 at %2 … Intentu de connessione a %1 in %2... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Sa dimanda autenticada a su serbidore s'est torrada a deretare a '%1'. Su URL est isballiadu, su serbidore no est cunfiguradu in manera curreta. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. Sa dimanda autenticada a su serbidore s'est torrada a deretare a '%1'. Su URL est isballiadu, su serbidore no est cunfiguradu in manera curreta. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Atzessu negadu dae su serbidore. Pro èssere seguros de àere is permissos giustos, <a href="%1">incarca inoghe</a> pro intrare a su sevìtziu cun su navigadore tuo. - + There was an invalid response to an authenticated WebDAV request Retzida una risposta non bàlida a una dimanda WebDAV autenticada - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Sa cartella de sincronizatzione locale %1 b'est giai, impostada pro sa sincronizatzione.<br/><br/> - + Creating local sync folder %1 … Creatzione dae sa cartella locale de sincronizatzione %1... @@ -3022,84 +3118,84 @@ Si cunsìgiat de non ddu impreare. ok - + OK AB - + failed. faddidu. - + Could not create local folder %1 No at fatu a creare sa cartella %1 - + No remote folder specified! Peruna cartella remota ispetzificada! - + Error: %1 Errore: %1 - + creating folder on Nextcloud: %1 creende una cartella in Nextcloud: %1 - + Remote folder %1 created successfully. Sa creatzione de sa cartella remota %1 est andada bene . - + The remote folder %1 already exists. Connecting it for syncing. Sa cartella remota %1 b'est giai. Connetende·dda pro dda sincronizare. - - + + The folder creation resulted in HTTP error code %1 Sa creatzione de sa cartella at torradu un'errore HTTP còdighe %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Sa creatzione de sa cartella remota est faddida ca mancari is credentziales sunt isballiadas.<br/>Torra in segus e controlla is credentziales.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Sa creatzione de sa cartella remota no est andada bene ca mancari is credentziales sunt isballiadas.</font><br/>Torra in segus e controlla is credentziales tuas.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Creatzione de sa cartella remota %1 faddida cun errore <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Istabilida una connessione de sincronizatzione dae %1 a sa cartella remota %2. - + Successfully connected to %1! Connessione a %1 renèssida! - + Connection to %1 could not be established. Please check again. Sa connessione a %1 non faghet a dda istabilire. Proa torra. - + Folder rename failed No at fatu a torrare a numenare sa cartella @@ -3109,28 +3205,28 @@ Si cunsìgiat de non ddu impreare. Non faghet a nche bogare o creare una còpia de seguesa de sa cartella ca sa cartella o un'archìviu in intro de issa est abertu in un àteru programma. Serra sa cartella o s'archìviu e incarca Proa torra o annulla sa cunfiguratzione. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. No at fatu a catzare o copiare sa cartella ca sa cartella o s'archìviu in intro est abertu in un àteru programma. Serra sa cartella o s'archìviu e incarca Proa torra o annulla s'impostatzione. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Cartella locale %1 creada in manera curreta!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Protzedura ghiada de connessione de %1 - Add %1 account Agiunghe contu %1 + + + %1 Connection Wizard + Protzedura ghiada de connessione de %1 + Skip folders configuration @@ -3168,24 +3264,6 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Abarra in su seguru - - OCC::OwncloudWizardResultPage - - - Everything set up! - Cunfiguratzione cumpretada! - - - - Open Local Folder - Aberi cartella locale - - - - Open %1 in Browser - Aberi %1 in su Navigadore - - OCC::PollJob @@ -3196,6 +3274,16 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3211,16 +3299,16 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal File names ending with a period are not supported on this file system. Is nùmenes chi agabbant cun unu puntu non sunt suportados in custu archìviu de sistema. - - - File names containing the character "%1" are not supported on this file system. - Is archìvios cun in intro su caràtere "%1" non sunt suportados in custu archìviu de su sistema. - File names containing the character '%1' are not supported on this file system. Is archìvios cun in intro su caràtere '%1' non sunt suportados in custu archìviu de su sistema. + + + File names containing the character "%1" are not supported on this file system. + Is archìvios cun in intro su caràtere "%1" non sunt suportados in custu archìviu de su sistema. + File name contains at least one invalid character @@ -3347,7 +3435,7 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Su serbidore at dadu errore leghende sa cartella '%1' : %2 - + Server replied with an error while reading directory "%1" : %2 Su serbidore nd'at torradu un'errore leghende sa cartella "%1" : %2 @@ -3962,11 +4050,6 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Allow Editing Permite de modificare - - - Allow editing - Cunsenti sa modìfica - Read only @@ -3987,6 +4070,16 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Password Protect Bàrdia crae + + + Allow editing + Cunsenti sa modìfica + + + + View only + Isceti in visualizatzione + Allow upload and editing @@ -4002,16 +4095,21 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal File drop (upload only) Tìsina archìviu (isceti pro carrigare) - - - Note to recipient - Nota pro sa persone destinatària - Unshare Annulla sa cumpartzidura + + + Link name + Nùmene ligòngiu + + + + Note to recipient + Nota pro sa persone destinatària + Password protect @@ -4023,15 +4121,20 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Imposta data de iscadèntzia - - Delete share link - Cantzella ligòngiu de cumpartzidura + + Delete link + Cantzella ligòngiu Add another link Agiunghe un'àteru ligòngiu + + + Delete share link + Cantzella ligòngiu de cumpartzidura + Confirm Link Share Deletion @@ -4081,7 +4184,7 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Perunu resurtadu pro '%1' - + No results for "%1" Perunu resurtadu pro "%1" @@ -4185,12 +4288,6 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Cumpartzi cun %1 - Context menu share @@ -4217,6 +4314,12 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Share via %1 Cumpartzi tràmite %1 + + + + Activity + + Copy private link to clipboard @@ -4288,6 +4391,12 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Delete Cantzella + + + Share with %1 + parameter is Nextcloud + Cumpartzi cun %1 + OCC::SslButton @@ -4433,6 +4542,11 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Cannot connect securely to <i>%1</i>: Non faghet a su connètere in manera segura a <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4607,6 +4721,11 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Placeholders are postfixed with file sizes using Utility::octetsToString() Sunt disponìbiles isceti %1, serbint isceti %2 pro cumintzare + + + Aborted + Firmadu + @@ -4759,27 +4878,88 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Invalid characters, please rename "%1" Caràteres non bàlidos, torra a numenare "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Su nùmene de s'archìviu cuntenet a su mancu unu caràtere imbàlidu - - Aborted - Firmadu - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Su logu in su discu est pagu: is iscarrigamentos chi diant pòdere minimare su logu lìberu suta de %1 s'ant a lassare. - + There is insufficient space available on the server for some uploads. Non b'at logu in su serbidore pro unos cantos carrigamentos. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4855,6 +5035,29 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal <p>Custa versione est dispensada dae %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4912,24 +5115,108 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Sa funtzionalidade de s'archìviu de sistema rechedet unu archìviu de sistema NTFS, %1 est impreende %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + No at fatu a recuperare is istados predefinidos. Controlla si tenes connessione a su serbidore. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - No at fatu a iscarrigare s'archìviu tzifradu cun end-to-end + + Could not fetch user status. Make sure you are connected to the server. + No at fatu a recuperare s'istadu de s'utente. Controlla si tenes connessione a su serbidore. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Parit chi ses proende a iscarrigare un'archìviu virtuale tzifradu end-to-end. S'iscarrigamentu implìtzitu de custos archìvios no est suportadu pro immoe. Pro probassare custu problema, in is impostatziones marca sa cartella tzifrada cun "Pone semper a disponimentu in manera locale". + + User status feature is not supported. You will not be able to set your user status. + S'istadu de s'utente no est suportadu. No as a pòdere impostare s'istatus de utente tuo. + + + + Emojis feature is not supported. Some user status functionality may not work. + Sa funtzione de is carigheddas no est suportada. Calecuna caraterìstica de s'istadu de s'utente diat pòdere no funtzionare. + + + + Could not set user status. Make sure you are connected to the server. + No at fatu a impostare s'istadu de s'utente. Controlla si tenes connessione a su serbidore. + + + + Could not clear user status message. Make sure you are connected to the server. + No at fatu a limpiare su messàgiu de istadu de s'utente. Controlla si tenes connessione a su serbidore. + + + + + Don't clear + Non nche ddu lìmpies + + + + 30 minutes + 30 minutos + + + + + 1 hour + 1 ora + + + + 4 hours + 4 oras + + + + + Today + Oe + + + + + This week + Custa chida + + + + Less than a minute + Mancu unu minutu a immoe + + + + 1 minute + 1 minutu + + + + %1 minutes + %1 minutos + + + + %1 hours + %1 oras + + + + 1 day + 1 die + + + + %1 days + %1 dies + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Sa funtzionalidade de s'archìviu de sistema rechedet unu archìviu de sistema NTFS, %1 est impreende %2 @@ -5446,14 +5733,6 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Intra in su %1 tuo - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Totu su contu est sincronizadu cun sa cartella locale - - QObject @@ -5546,6 +5825,38 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal No at fatu a si connètere sa base de datos. + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5560,29 +5871,39 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal - Current user status is online - S'istadu atuale de s'utente est in lìnia + Account connected + Contu connètidu - Current user status is do not disturb - S'istadu atuale de s'utente est chi non si cheret istorbadu + Account not connected + Contu non connètidu - Account connected - Contu connètidu + Current user status is online + S'istadu atuale de s'utente est in lìnia - Account not connected - Contu non connètidu + Current user status is do not disturb + S'istadu atuale de s'utente est chi non si cheret istorbadu Account actions Atziones de su contu + + + Remove Account + Boga·nche su contu + + + + Set status + Imposta istadu + @@ -5595,17 +5916,65 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Log in Intra - - - Remove Account - Boga·nche su contu - Remove account Boga·nche su contu + + UserStatusSelector + + + Online status + Istadu in lìnia + + + + Online + In lìnia + + + + Away + Ausente + + + + Do not disturb + No istorbes + + + + Invisible + Invisìbile + + + + Status message + Messàgiu de istadu + + + + What is your status? + Cale est s'istadu tuo? + + + + Clear status message after + Lìmpia su messàgiu de istadu a pustis + + + + Clear status message + Lìmpia su messàgiu de istadu + + + + Set status message + Imposta messàgiu de istadu + + Utility @@ -5667,12 +6036,12 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal ValidateChecksumHeader - + The checksum header is malformed. S'intestatzione de su còdighe de controllu. - + The checksum header contained an unknown checksum type '%1' S'intestatzione de controllu cunteniat una genia de còdighe de controllu '%1' disconnotu @@ -5682,17 +6051,17 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal S'archìviu iscarrigadu non torrat cun su còdighe de controllu, at a èssere ripristinadu. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' S'archìviu iscarrigadu non torrat cun su còdighe de controllu, at a èssere ripristinadu. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" S'intestatzione de controllu cunteniat una genia de còdighe de controllu "%1" disconnotu - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" S'archìviu iscarrigadu non torrat cun su còdighe de controllu, at a èssere ripristinadu. "%1" != "%2" @@ -5721,6 +6090,11 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Pause sync for all Pone in pasu sincronizatzione pro totu + + + Set user status + Imposta istadu de s'utente + Add account @@ -5756,12 +6130,6 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Current user status is do not disturb S'istadu atuale de s'utente est chi non si cheret istorbadu - - - - Show more actions - Mustra àteras atziones - Share %1 @@ -5822,6 +6190,22 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Open share dialog Aberi bentana de cumpartzidura + + + Unified search results list + + + + + + Show more actions + Mustra àteras atziones + + + + %1 - File activity + + main.cpp @@ -6121,6 +6505,24 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Intra tràmite su navigadore tuo (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Cunfiguratzione cumpretada! + + + + Open Local Folder + Aberi cartella locale + + + + Open %1 in Browser + Aberi %1 in su Navigadore + + OCC::ShibbolethCredentials @@ -6173,6 +6575,14 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal Intra + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Totu su contu est sincronizadu cun sa cartella locale + + OCC::UserStatus @@ -6196,4 +6606,17 @@ Custa est una modalidade noa, isperimentale. Si detzides de dda impreare, sinnal In lìnia + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + No at fatu a iscarrigare s'archìviu tzifradu cun end-to-end + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Parit chi ses proende a iscarrigare un'archìviu virtuale tzifradu end-to-end. S'iscarrigamentu implìtzitu de custos archìvios no est suportadu pro immoe. Pro probassare custu problema, in is impostatziones marca sa cartella tzifrada cun "Pone semper a disponimentu in manera locale". + + \ No newline at end of file diff --git a/translations/client_sk.ts b/translations/client_sk.ts index 0822e2c8e74c..93c7b4da5caa 100644 --- a/translations/client_sk.ts +++ b/translations/client_sk.ts @@ -14,12 +14,6 @@ Open %1 locally Otvoriť %1 lokálne - - - - Show more actions - Zobraziť ďalšie akcie - Open share dialog @@ -30,6 +24,25 @@ Share %1 Zdieľať %1 + + + + Show more actions + Zobraziť ďalšie akcie + + + + View activity + Zobraziť aktivitu + + + + ActivityList + + + Activity list + Zoznam aktivít + CloudProviderWrapper @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" Nie je možne presunúť "%1" do "%2" @@ -1144,32 +1157,32 @@ Môže to byť problém s knižnicami OpenSSL. Nedarí sa otvoriť prehliadač, je preto potrebné skopírovať do neho odkaz ručne. - + Waiting for authorization Čakanie na autorizáciu - + Polling for authorization Čaká sa na autorizáciu - + Starting authorization Zahajuje sa autorizácia - + Link copied to clipboard. Odkaz bol skopírovaný do schránky. - + Reopen Browser Znovu otvoriť prehliadač - + Copy Link Kopírovať odkaz @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi To znamená, že klient synchronizácie nemusí okamžite odovzdať lokálne zmeny a namiesto toho bude len vyhľadávať miestne zmeny a odovzdávať len príležitostne (štandardne každé dve hodiny) . % 1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + Všetky súbory vo vašej lokálnej synchronizovanom priečinku '%1' boli vymazané. Tieto súbory budú vymazané aj na serveri a teda už viac nebudú dostupné až kým ich neobnovíte. +Ste si istí, že chcete tieto akcie synchronizovať so serverom? +Ak to bol omyl a rozhodnete sa tieto súbory ponechať, budú opäť synchronizované zo servera. @@ -1398,27 +1420,7 @@ Pokračovaním v synchronizácii spôsobí prepísanie všetkých vašich súbor Ponechať lokálne súbory ako konfliktné - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - Všetky súbory v synchronizačnom priečinku '%1' boli na serveri vymazané. -Tieto zmeny budú synchronizované do lokálneho synchronizačného priečinka, takže už tieto vymazané súbory nebudú dostupné, ak máte oprávnenie pre ich obnovu. -Ak sa rozhodnete lokálne súbory ponechať, budú znovu synchronizované so serverom ak na to máte oprávnenie. -Ak sa rozhodnete súbory vymazať tak následne už nebudú dostupné, ak nie ste vlastník. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - Všetky súbory vo vašej lokálnej synchronizovanom priečinku '%1' boli vymazané. Tieto súbory budú vymazané aj na serveri a teda už viac nebudú dostupné až kým ich neobnovíte. -Ste si istí, že chcete tieto akcie synchronizovať so serverom? -Ak to bol omyl a rozhodnete sa tieto súbory ponechať, budú opäť synchronizované zo servera. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1429,7 +1431,7 @@ Ak sa rozhodnete lokálne súbory ponechať, budú znovu synchronizované so ser Ak sa rozhodnete súbory vymazať tak následne už nebudú dostupné, ak nie ste vlastník. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1447,6 +1449,17 @@ Ak to bol omyl a rozhodnete sa tieto súbory ponechať, budú opäť synchronizo Remove all files Odstrániť všetky súbory + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Všetky súbory v synchronizačnom priečinku '%1' boli na serveri vymazané. +Tieto zmeny budú synchronizované do lokálneho synchronizačného priečinka, takže už tieto vymazané súbory nebudú dostupné, ak máte oprávnenie pre ich obnovu. +Ak sa rozhodnete lokálne súbory ponechať, budú znovu synchronizované so serverom ak na to máte oprávnenie. +Ak sa rozhodnete súbory vymazať tak následne už nebudú dostupné, ak nie ste vlastník. + Keep files @@ -2277,6 +2290,69 @@ Položky, pri ktorých je povolené odstraňovanie sa vymažú, ak bránia odstr Pridať nový vzor ignorovaného súboru: + + OCC::InvalidFilenameDialog + + + Invalid filename + Neplatné meno súboru + + + + The file could not be synced because it contains characters which are not allowed on this system. + Súbor nemôže byť synchronizovaný, pretože obsahuje znaky ktoré nie sú na tomto systéme podporované. + + + + Error + Chyba + + + + Please enter a new name for the file: + Prosím zadajte nový názov súboru: + + + + New filename + Nový názov súboru + + + + Rename file + Premenovať súbor + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Súbor %1 nemôže byť synchronizovaný, pretože obsahuje znaky ktoré nie sú na tomto systéme podporované. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Nasledujúce znaky nie sú na systéme povolené: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Nemáte oprávnenie premenovať tento súbor. Prosím požiadajte vlastníka súboru o premenovanie. + + + + Filename contains illegal characters: %1 + Názov súboru obsahuje neplatné znaky: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Nemôžem premenovať súbor. Prosím uistite sa že ste pripojený k serveru. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Nemôžem premenovať súbor pretože súbor s rovnakým menom už na serveri existuje. Prosím vyberte iné meno. + + OCC::LegalNotice @@ -2417,7 +2493,7 @@ Záznamy udalostí sa budú zapisovať do %1 <nobr>Súbor '%1'<br/>nesmie byť otvorený pre proces úprav.</br/><br/>Systémový záznam (log) <b>nemôže</b> byť uložený!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>Súbor "%1"<br/>nie je možné otvoriť pre úpravu.<br/><br/>Systémový záznam - log <b>nemôže</b> byť uložený!</nobr> @@ -2460,6 +2536,11 @@ Záznamy udalostí sa budú zapisovať do %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Je dostupná nová verzia klienta %1.</p><p><b>%2</b> je dostupná na stiahnutie. Nainštalovaná verzia je %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>K dispozícii je nová verzia klienta %1, ale proces aktualizácie zlyhal. </p><p><b>%2</b> bolo stiahnuté. Nainštalovaná verzia je %3. Ak potvrdíte reštart a aktualizáciu, váš počítač sa môže reštartovať a dokončiť inštaláciu.</p> + Ask again later @@ -2629,6 +2710,13 @@ Záznamy udalostí sa budú zapisovať do %1 New %1 Update Ready Pripravená je nová aktualizácia %1 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Nainštaluje sa nová aktualizácia pre %1. V priebehu aktualizácie +môžu byť vyžadované dodatočné oprávnenia. + New %1 update ready @@ -2636,10 +2724,8 @@ Záznamy udalostí sa budú zapisovať do %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Nainštaluje sa nová aktualizácia pre %1. V priebehu aktualizácie -môžu byť vyžadované dodatočné oprávnenia. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Chystá sa inštalácia novej aktualizácie pre %1. Aktualizátor môže počas procesu požiadať o ďalšie oprávnenia. Na dokončenie inštalácie sa váš počítač môže reštartovať. @@ -2676,6 +2762,11 @@ môžu byť vyžadované dodatočné oprávnenia. New %1 is available. Please click <a href='%2'>here</a> to download the update. Je dostupná nová %1. Pre stiahnutie kliknite <a href='%2'> tu </a> pre stiahnutie aktualizácie. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Nemôžem stiahnuť aktualizáciu. Kliknite, prosím, na <a href='%1'>%1</a> pre ručné stiahnutie aktualizácie. + Could not download update. Please open %1 to download the update manually. @@ -2686,6 +2777,11 @@ môžu byť vyžadované dodatočné oprávnenia. Could not check for new updates. Nemôžem skontrolovať dostupnosť aktualizácie. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Je dostupná nová %1. Pre stiahnutie kliknite <a href='%2'>%2</a> pre stiahnutie aktualizácie. + New %1 is available. Please open %2 to download the update. @@ -2981,37 +3077,37 @@ It is not advisable to use it. Časový limit vypršal pri pokuse o pripojenie k %1 na %2. - + Trying to connect to %1 at %2 … Pokus o pripojenie k %1 na %2... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Overená požiadavka na server bola presmerovaná na '%1'. URL je zlá, server nie je správne nakonfigurovaný. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. Overená požiadavka na server bola presmerovaná na "%1". URL je zlá, server nie je správne nakonfigurovaný. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Prístup zamietnutý serverom. Po overení správnych prístupových práv, <a href="%1">kliknite sem</a> a otvorte službu v svojom prezerači. - + There was an invalid response to an authenticated WebDAV request Neplatná odpoveď na overenú WebDAV požiadavku - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Lokálny synchronizačný priečinok %1 už existuje, prebieha jeho nastavovanie pre synchronizáciu.<br/><br/> - + Creating local sync folder %1 … Vytváranie lokálneho priečinka pre synchronizáciu %1... @@ -3021,84 +3117,84 @@ It is not advisable to use it. v poriadku - + OK OK - + failed. neúspešné. - + Could not create local folder %1 Nemožno vytvoriť lokálny priečinok %1 - + No remote folder specified! Vzdialený priečinok nie je nastavený! - + Error: %1 Chyba: %1 - + creating folder on Nextcloud: %1 Vytvára sa priečinok v Nextcloud: %1 - + Remote folder %1 created successfully. Vzdialený priečinok %1 bol úspešne vytvorený. - + The remote folder %1 already exists. Connecting it for syncing. Vzdialený priečinok %1 už existuje. Prebieha jeho pripájanie pre synchronizáciu. - - + + The folder creation resulted in HTTP error code %1 Vytváranie priečinka skončilo s HTTP chybovým kódom %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Proces vytvárania vzdialeného priečinka zlyhal, lebo použité prihlasovacie údaje nie sú správne!<br/>Prosím skontrolujte si vaše údaje a skúste to znovu.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Vytvorenie vzdialeného priečinka pravdepodobne zlyhalo kvôli nesprávnym prihlasovacím údajom.</font><br/>Prosím choďte späť a skontrolujte ich.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Vytvorenie vzdialeného priečinka %1 zlyhalo s chybou <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Synchronizačné spojenie z %1 do vzdialeného priečinka %2 bolo práve nastavené. - + Successfully connected to %1! Úspešne pripojené s %1! - + Connection to %1 could not be established. Please check again. Pripojenie k %1 nemohlo byť iniciované. Prosím skontrolujte to znovu. - + Folder rename failed Premenovanie priečinka zlyhalo @@ -3108,28 +3204,28 @@ It is not advisable to use it. Nemožno odstrániť a zazálohovať priečinok, pretože priečinok alebo súbor je otvorený v inom programe. Prosím zatvorte priečinok nebo súbor a skúste to znovu alebo zrušte akciu. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Nemožno odstrániť a zazálohovať priečinok, pretože priečinok alebo súbor je otvorený v inom programe. Prosím zatvorte priečinok alebo súbor a skúste to znovu alebo zrušte akciu. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Lokálny synchronizačný priečinok %1 bol úspešne vytvorený!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Asistent pripojenia - Add %1 account Pridať %1 účet + + + %1 Connection Wizard + %1 Asistent pripojenia + Skip folders configuration @@ -3168,24 +3264,6 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Zostať v bezpečí - - OCC::OwncloudWizardResultPage - - - Everything set up! - Všetko je nastavené! - - - - Open Local Folder - Otvoriť lokálny priečinok - - - - Open %1 in Browser - Otvoriť %1 v prehliadači - - OCC::PollJob @@ -3196,6 +3274,16 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Súbor obsahuje medzery na konci a nemožno ho premenovať, pretože súbor s rovnakým názvom už na serveri existuje. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Súbor obsahuje medzery na konci a nemožno ho premenovať, pretože súbor s rovnakým názvom už lokálne existuje. + Symbolic links are not supported in syncing. @@ -3213,12 +3301,12 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. Názvy súborov obsahujúce znak "%1" nie sú na tomto súborovom systéme podporované. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. Názvy súborov obsahujúce znak "%1" nie sú na tomto súborovom systéme podporované. @@ -3347,7 +3435,7 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Server odpovedal chybne počas čítania adresára '%1' : %2 - + Server replied with an error while reading directory "%1" : %2 Server odpovedal chybne počas načítania priečinka "%1" : %2 @@ -3962,11 +4050,6 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Allow Editing Umožniť úpravy - - - Allow editing - Povoliť úpravy - Read only @@ -3987,6 +4070,16 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Password Protect Chrániť heslom + + + Allow editing + Povoliť úpravy + + + + View only + Iba pre čítanie + Allow upload and editing @@ -4002,16 +4095,21 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v File drop (upload only) Odovzdávanie súborov (len nahrávanie) - - - Note to recipient - Poznámka pre príjemcu - Unshare Zneprístupniť + + + Link name + Názov odkazu + + + + Note to recipient + Poznámka pre príjemcu + Password protect @@ -4023,15 +4121,20 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Nastaviť dátum expirácie - - Delete share link - Zmazať sprístupnený odkaz + + Delete link + Zmazať odkaz Add another link Pridať ďalší odkaz + + + Delete share link + Zmazať sprístupnený odkaz + Confirm Link Share Deletion @@ -4081,7 +4184,7 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Žiadne výsledky pre '%1' - + No results for "%1" Žiadne výsledky pre "%1" @@ -4185,12 +4288,6 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Sprístupniť %1 - Context menu share @@ -4217,6 +4314,12 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Share via %1 Sprístupniť prostredníctvom %1 + + + + Activity + Aktivity + Copy private link to clipboard @@ -4288,6 +4391,12 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Delete Zmazať + + + Share with %1 + parameter is Nextcloud + Sprístupniť %1 + OCC::SslButton @@ -4433,6 +4542,11 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Cannot connect securely to <i>%1</i>: Nie je možné sa bezpečne pripojiť k <i>%1</i>: + + + Additional errors: + Ďalšie chyby: + with Certificate %1 @@ -4607,6 +4721,11 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Placeholders are postfixed with file sizes using Utility::octetsToString() Je dostupných len %1, pre spustenie je potrebných aspoň %2 + + + Aborted + Prerušiť + @@ -4759,27 +4878,88 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Invalid characters, please rename "%1" Neplatné znaky, premenujte prosím "%1" + + + Synchronization will resume shortly. + Synchronizácia bude čoskoro pokračovať. + File name contains at least one invalid character Názov súboru obsahuje nevhodný znak - - Aborted - Prerušiť - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Na disku dochádza voľné miesto. Sťahovanie, ktoré by zmenšilo voľné miesto pod %1 bude vynechané. - + There is insufficient space available on the server for some uploads. Na serveri nie je pre niektoré z nahrávaných súborov dostatok voľného miesta. + + OCC::SyncStatusSummary + + + + Offline + Odpojený + + + + + + All synced! + Všetko synchronizované! + + + + Some files couldn't be synced! + Niektoré súbory nebolo možné synchronizovať! + + + + See below for errors + Chyby nájdete nižšie + + + + Syncing + Synchronizuje sa + + + + Sync paused + Synchronizácia je pozastavená + + + + Some files could not be synced! + Niektoré súbory nebolo možné synchronizovať! + + + + See below for warnings + Varovania nájdete nižšie + + + + %1 of %2 · %3 left + %1 z %2 · %3 ostáva + + + + %1 of %2 + %1 z %2 + + + + Syncing file %1 of %2 + Synchronizuje sa súbor %1 z %2 + + OCC::Systray @@ -4855,6 +5035,29 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v <p>Toto vydanie bolo poskytnuté %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Nepodarilo sa načítať poskytovateľov. + + + + Failed to fetch search providers for '%1'. Error: %2 + Nepodarilo sa načítať poskytovateľov vyhľadávania pre „%1“. Chyba: %2 + + + + Search has failed for '%2'. + Vyhľadávanie '%2' zlyhalo. + + + + Search has failed for '%1'. Error: %2 + Vyhľadávanie '%1' zlyhalo. Chyba: %2 + + OCC::User @@ -4912,24 +5115,108 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Funkcia Virtuálneho súborového systému vyžaduje NTFS, %1 používa %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + Preddefinované stavy sa nepodarilo načítať. Uistite sa, že ste pripojení k serveru. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Stiahovanie end-to-end šifrovaného súboru zlyhalo + + Could not fetch user status. Make sure you are connected to the server. + Nemôžem načítať stav uživateľa. Uistite sa že ste pripojený k serveru. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Zdá sa, že sa pokúšate stiahnuť virtuálny súbor, ktorý je end-to-end šifrovaný. Implicitné sťahovanie takýchto súborov nie je momentálne podporované. Ak chcete tento problém obísť, prejdite do nastavení a označte zašifrovaný priečinok ako „Sprístupniť vždy lokálne“. + + User status feature is not supported. You will not be able to set your user status. + Funkcia stavu užívateľa nie je podporovaná. Nebudete môcť nastaviť svoj užívateľský stav. + + + + Emojis feature is not supported. Some user status functionality may not work. + Funkcia emotikonov nie je podporovaná. Niektoré funkcie stavu uživateľa nemusia fungovať. + + + + Could not set user status. Make sure you are connected to the server. + Nemôžem nastaviť stav uživateľa. Uistite sa že ste pripojený k serveru. + + + + Could not clear user status message. Make sure you are connected to the server. + Nemôžem vymazať stav uživateľa. Uistite sa že ste pripojený k serveru. + + + + + Don't clear + Nemazať + + + + 30 minutes + 30 minút + + + + + 1 hour + 1 hodina + + + + 4 hours + 4 hodiny + + + + + Today + Dnes + + + + + This week + Tento týždeň + + + + Less than a minute + Menej ako minúta + + + + 1 minute + 1 minúta + + + + %1 minutes + %1 minút + + + + %1 hours + %1 hodín + + + + 1 day + 1 deň + + + + %1 days + %1 dní + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Funkcia Virtuálneho súborového systému vyžaduje NTFS, %1 používa %2 @@ -5446,14 +5733,6 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Prihlásenie do vášho %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Celý váš účet bol zosynchronizovaný z lokálnym priečinkom - - QObject @@ -5546,6 +5825,38 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Nepodarilo sa pripojiť k databáze. + + UnifiedSearchInputContainer + + + Search files, messages, events … + Vyhľadať súbory, správy, udalosti ... + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Načítať viac výsledkov + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Kostra výsledkov vyhľadávania. + + + + UnifiedSearchResultListItem + + + Load more results + Načítať viac výsledkov + + UserLine @@ -5560,29 +5871,39 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v - Current user status is online - Stav aktuálneho užívateľa je pripojený + Account connected + Účet pripojený - Current user status is do not disturb - Stav aktuálneho užívateľa je nerušiť + Account not connected + Účet nie je pripojený - Account connected - Účet pripojený + Current user status is online + Stav aktuálneho užívateľa je pripojený - Account not connected - Účet nie je pripojený + Current user status is do not disturb + Stav aktuálneho užívateľa je nerušiť Account actions Možnosti účtu + + + Remove Account + Odobrať účet + + + + Set status + Nastaviť stav + @@ -5595,17 +5916,65 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Log in Prihlásiť sa - - - Remove Account - Odobrať účet - Remove account Odobrať účet + + UserStatusSelector + + + Online status + Stav pripojenia + + + + Online + Pripojené + + + + Away + Preč + + + + Do not disturb + Nerušiť + + + + Invisible + Neviditeľný + + + + Status message + Správa o stave + + + + What is your status? + Aký je váš stav? + + + + Clear status message after + Vyčistiť správu o stave po + + + + Clear status message + Vyčistiť správu o stave + + + + Set status message + Nastaviť správu o stave + + Utility @@ -5667,12 +6036,12 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v ValidateChecksumHeader - + The checksum header is malformed. Hlavička kontrolného súčtu je poškodená. - + The checksum header contained an unknown checksum type '%1' Hlavička kontrolného súčtu obsahovala neznámy typ kontrolného súčtu „%1“ @@ -5682,17 +6051,17 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Stiahnutý súbor nemá správny kontrolný súčet, bude stiahnutý znovu. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Stiahnutý súbor nemá správny kontrolný súčet, bude stiahnutý znovu. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" Hlavička kontrolného súčtu obsahovala neznámy typ kontrolného súčtu „%1“ - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" Stiahnutý súbor nemá správny kontrolný súčet, bude stiahnutý znovu. "%1" != "%2" @@ -5721,6 +6090,11 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Pause sync for all Pozastaviť synchronizáciu pre všetky účty + + + Set user status + Nastaviť status užívateľa + Add account @@ -5756,12 +6130,6 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Current user status is do not disturb Stav aktuálneho užívateľa je nerušiť - - - - Show more actions - Zobraziť ďalšie akcie - Share %1 @@ -5822,6 +6190,22 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Open share dialog Otvoriť dialógové okno sprístupnenia + + + Unified search results list + Jednotný zoznam výsledkov vyhľadávania + + + + + Show more actions + Zobraziť ďalšie akcie + + + + %1 - File activity + %1 - Aktivita súboru + main.cpp @@ -6121,6 +6505,24 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Prihlásenie v prehliadači (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Všetko je nastavené! + + + + Open Local Folder + Otvoriť lokálny priečinok + + + + Open %1 in Browser + Otvoriť %1 v prehliadači + + OCC::ShibbolethCredentials @@ -6173,6 +6575,14 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Prihlásiť sa + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Celý váš účet bol zosynchronizovaný z lokálnym priečinkom + + OCC::UserStatus @@ -6196,4 +6606,17 @@ Toto je nový experimentálny režim. Ak sa ho rozhodnete použiť, nahláste v Pripojený + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Stiahovanie end-to-end šifrovaného súboru zlyhalo + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Zdá sa, že sa pokúšate stiahnuť virtuálny súbor, ktorý je end-to-end šifrovaný. Implicitné sťahovanie takýchto súborov nie je momentálne podporované. Ak chcete tento problém obísť, prejdite do nastavení a označte zašifrovaný priečinok ako „Sprístupniť vždy lokálne“. + + \ No newline at end of file diff --git a/translations/client_sl.ts b/translations/client_sl.ts index fe69296e40c2..32b876200983 100644 --- a/translations/client_sl.ts +++ b/translations/client_sl.ts @@ -12,23 +12,36 @@ Open %1 locally - + Odpri datoteko %1 krajevno + + + + Open share dialog + Odpri pogovorno okno souporabe + + + + Share %1 + Omogoči souporabo %1 Show more actions - + Pokaži več možnosti - - Open share dialog - + + View activity + Pokaži dejavnost + + + ActivityList - - Share %1 - + + Activity list + Seznam dejavnosti @@ -41,7 +54,7 @@ Checking for changes in "%1" - + Preverjanje sprememb v »%1« @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - + Could not move "%1" to "%2" + Ni mogoče premakniti » %1 « v » %2 «. @@ -147,7 +160,7 @@ Error removing "%1": %2 - + Prišlo je do napake med odstranjevanjem »%1«: %2 @@ -157,7 +170,7 @@ Could not remove folder "%1" - + Mape »%1« ni mogoče odstraniti. @@ -336,7 +349,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Kaže, da imate na tej mapi omogočeno možnost navideznih datotek. Trenutno ni mogoče neposredno prejeti tovrstnih datotek, če so šifrirane po protokolu E2E. Za najenostavnejše delo z navideznimi datotekami poskrbite, da je šifrirana mapa označena kot »Vedno na voljo krajevno«. @@ -403,7 +416,7 @@ You seem to have the Virtual Files feature enabled on this folder. At the moment, it is not possible to implicitly download virtual files that are End-to-End encrypted. To get the best experience with Virtual Files and End-to-End Encryption, make sure the encrypted folder is marked with "Make always available locally". - + Kaže, da imate na tej mapi omogočeno možnost navideznih datotek. Trenutno ni mogoče neposredno prejeti tovrstnih datotek, če so šifrirane po protokolu E2E. Za najenostavnejše delo z navideznimi datotekami poskrbite, da je šifrirana mapa označena kot »Vedno na voljo krajevno«. @@ -415,12 +428,12 @@ S prazno mapo počakajte na konec usklajevanja, potem jo znova šifrirajte. Encryption failed - + Šifriranje je spodletelo Could not encrypt folder because the folder does not exist anymore - + Mape ni mogoče šifrirati, ker ne obstaja več. @@ -592,7 +605,7 @@ S tem dejanjem prav tako prekinete vsa trenutna usklajevanja v izvajanju. %1 as %2 - + %1 z računom %2 @@ -842,7 +855,7 @@ S tem dejanjem prav tako prekinete vsa trenutna usklajevanja v izvajanju. Enter username and password for "%1" at %2. - + Vpišite uporabniško ime in geslo za »%1« z računom %2. @@ -1098,7 +1111,7 @@ Morda je napaka v knjužnicah OpenSSL. The polling URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + Naslov URL za preverjanje se ne začne s HTTPS, kljub temu, da se naslov URL za prijavo je. Prijava ne bo mogoča, ker je to lahko varnostna težava. Stopite v stik s skrbnikom sistema. @@ -1116,7 +1129,7 @@ Morda je napaka v knjužnicah OpenSSL. There was an error accessing the "token" endpoint: <br><em>%1</em> - + Prišlo je do napake med dostopom do končne točke »žetona«: <br><em>%1</em>. @@ -1133,7 +1146,7 @@ Morda je napaka v knjužnicah OpenSSL. The returned server URL does not start with HTTPS despite the login URL started with HTTPS. Login will not be possible because this might be a security issue. Please contact your administrator. - + Vrnjen naslov URL strežnika se ne začne s HTTPS, kljub temu, da se naslov URL za prijavo je. Prijava ne bo mogoča, ker je to lahko varnostna težava. Stopite v stik s skrbnikom sistema. @@ -1144,32 +1157,32 @@ Morda je napaka v knjužnicah OpenSSL. Ni mogoče samodejno odpreti brskalnika, odprite ga ročno in kopirajte povezavo. - + Waiting for authorization Poteka čakanje na overitev … - + Polling for authorization Preverjanje za overitev - + Starting authorization Poteka začenjanje overitve… - + Link copied to clipboard. Povezava je kopirana v odložišče - + Reopen Browser Ponovno odpri brskalnik - + Copy Link Kopiraj povezavo @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi To pomeni, da odjemalec usklajevanja ne pošilja krajevnih sprememb takoj in morda le preverja za spremembe, te pa nato občasno pošilja v oblak (privzeto vsaki dve uri). %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1398,39 +1420,24 @@ Z nadaljevanjem usklajevanja bodo vse trenutne datoteke zato prepisane s starej Ohrani krajevne datoteke kot datoteke v sporu - - All files in the sync folder '%1' folder were deleted on the server. + + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. If you decide to delete the files, they will be unavailable to you, unless you are the owner. Vse datoteke v usklajevani mapi »%1« so bile na strežniku izbrisane. Sprememba bo usklajena tudi s krajevno mapo na disku, zato bodo te datoteke, če ni ustreznih dovoljenj za obnovitev, izgubljene. V kolikor se odločite te datoteke ohraniti, in so na voljo ustrezna dovoljenja, bodo spet usklajene s strežnikom. -Nasprotno, če potrdite izbris in niste lastnik datotek, te ne bodo več na voljo. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - All files in the sync folder "%1" folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - +Nasprotno, če potrdite izbris in niste lastnik datotek, te ne bodo več dosegljive. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. - + Vse datoteke v usklajevani mapi »%1« so bile izbrisane. Sprememba bo usklajena s strežnikom, zato bodo datoteke, če ni ustreznih dovoljenj za obnovitev, nedostopne. +Ali ste prepričani, da želite posodobiti spremembe s strežnikom? +Če je prišlo do napake in se odločite datoteke ohraniti, bodo te ponovno usklajene s strežnika. @@ -1442,6 +1449,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Odstrani vse datoteke + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + Vse datoteke v usklajevani mapi »%1« so bile na strežniku izbrisane. +Sprememba bo usklajena tudi s krajevno mapo na disku, zato bodo te datoteke, če ni ustreznih dovoljenj za obnovitev, izgubljene. +V kolikor se odločite te datoteke ohraniti, in so na voljo ustrezna dovoljenja, bodo spet usklajene s strežnikom. +Nasprotno, če potrdite izbris in niste lastnik datotek, te ne bodo več na voljo. + Keep files @@ -1491,7 +1509,7 @@ If this was an accident and you decide to keep your files, they will be re-synce An old sync journal "%1" was found, but could not be removed. Please make sure that no application is currently using it. - + Obstaja star dnevnik usklajevanja »%1«, ki pa ga ni mogoče odstraniti. Preverite, ali je datoteka morda v uporabi. @@ -1679,12 +1697,12 @@ If this was an accident and you decide to keep your files, they will be re-synce Checking for changes in remote "%1" - + Poteka preverjanje za spremembe na oddaljenem mestu »%1« Checking for changes in local "%1" - + Poteka preverjanje za krajevne spremembe v »%1« @@ -1844,7 +1862,7 @@ If this was an accident and you decide to keep your files, they will be re-synce Enter the name of the new folder to be created below "%1": - + Vpišite ime mape, ki bo ustvarjena kot podrejena »%1«: @@ -2159,7 +2177,7 @@ Zavedati se je treba, da izbor določa le različice programske opreme za nadgra Reading from keychain failed with error: "%1" - + Branje iz ključa je spodletelo z napako: »%1« @@ -2202,7 +2220,7 @@ Zavedati se je treba, da izbor določa le različice programske opreme za nadgra This entry is provided by the system at "%1" and cannot be modified in this view. - + Ta vnos je ponujen pri »%1« in ga v tem pogledu ni mogoče spreminjati. @@ -2254,7 +2272,7 @@ Predmeti v mapah, ki jih je dovoljeno izbrisati, bodo odstranjeni, če prepreču Cannot write changes to "%1". - + Ni mogoče zapisati sprememb v »%1«. @@ -2272,6 +2290,69 @@ Predmeti v mapah, ki jih je dovoljeno izbrisati, bodo odstranjeni, če prepreču Dodaj novo masko za neusklajevanje: + + OCC::InvalidFilenameDialog + + + Invalid filename + Neveljavno ime datoteke + + + + The file could not be synced because it contains characters which are not allowed on this system. + Datoteke ni mogoče uskladiti, ker so v imenu datoteke znaki, ki jih sistem ne podpira. + + + + Error + Napaka + + + + Please enter a new name for the file: + Novo ime datoteke: + + + + New filename + Novo ime datoteke + + + + Rename file + Preimenuj datoteko + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Datoteke %1 ni mogoče uskladiti, ker so v imenu datoteke znaki, ki jih sistem ne podpira. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Na tem sistemu niso dovoljeni znaki: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Za preimenovanje te datoteke ni ustreznih dovoljenj. Datoteko lahko spremeni le avtor. + + + + Filename contains illegal characters: %1 + V imenu datoteke so neveljavni znaki: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Datoteke ni mogoče preimenovati. Prepričajte se, da ste povezani s strežnikom. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Datoteke ni mogoče preimenovati, ker datoteka z istim imenom na strežniku že obstaja. Izbrati je treba drugo ime. + + OCC::LegalNotice @@ -2410,9 +2491,9 @@ Logs will be written to %1 <nobr>Datoteke »%1«<br/>ni mogoče odpreti za pisanje.<br/><br/>Dnevniškega zapisa <b>ni mogoče</b> shraniti!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> - + <nobr>Datoteke »%1«<br/>ni mogoče odpreti za pisanje.<br/><br/>Dnevniškega zapisa <b>ni mogoče</b> shraniti!</nobr> @@ -2453,6 +2534,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Na voljo je nova različica programa %1, vendar je posodobitev spodletela.</p><p>Program <b>%2</b> je že prejet. Nameščena je različica %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Na voljo je nova različica programa %1, vendar je posodobitev spodletela.</p><p>Program <b>%2</b> je sicer že prejet. Trenutno nameščeno različico %3 je morda mogoče namestiti, če potrdite ponovni zagon sistema.</p> + Ask again later @@ -2587,7 +2673,7 @@ Logs will be written to %1 There was an error accessing the "token" endpoint: <br><em>%1</em> - + Prišlo je do napake med dostopom do končne točke »žetona«: <br><em>%1</em>. @@ -2622,11 +2708,6 @@ Logs will be written to %1 New %1 Update Ready Na voljo je posodobitev %1 - - - New %1 update ready - - A new update for %1 is about to be installed. The updater may ask @@ -2634,6 +2715,16 @@ for additional privileges during the process. Nameščena bo najnovejša posodobitev %1. Program lahko zahteva skrbniška dovoljenja za dokončanje opravila. + + + New %1 update ready + Na voljo je posodobitev %1 + + + + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + Nameščena bo najnovejša posodobitev %1. Program lahko zahteva skrbniška dovoljenja za dokončanje opravila, prav tako se lahko računalnik ponovno zažene za dokončanje namestitve. + Downloading version %1. Please wait … @@ -2669,6 +2760,11 @@ zahteva skrbniška dovoljenja za dokončanje opravila. New %1 is available. Please click <a href='%2'>here</a> to download the update. Na voljo je različica %1. Kliknite na <a href='%2'>povezavo</a> za prejem posodobitve. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Posodobitve ni mogoče prejeti. Odprite <a href='%1'>%1</a> za prejem in ročno namestitev. + Could not download update. Please open %1 to download the update manually. @@ -2679,6 +2775,11 @@ zahteva skrbniška dovoljenja za dokončanje opravila. Could not check for new updates. Ni mogoče preveriti za nove posodobitve. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Na voljo je različica %1. Kliknite na <a href='%2'>%2</a> za prejem posodobitve. + New %1 is available. Please open %2 to download the update. @@ -2767,12 +2868,12 @@ zahteva skrbniška dovoljenja za dokončanje opravila. %1 folder "%2" is synced to local folder "%3" - + %1 mapa »%2« je usklajena s krajevno mapo »%3« Sync the folder "%1" - + Uskladi mapo » %1 « @@ -2975,37 +3076,37 @@ Uporaba možnosti ni priporočljiva. Povezovanje na %1 pri %2 je časovno poteklo. - + Trying to connect to %1 at %2 … Poteka poskus povezave z %1 na %2 ... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Zahteva za overitev s strežnikom je bila preusmerjena na »%1«. Naslov URL ni veljaven ali pa strežnik ni ustrezno nastavljen. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Zahteva za overitev s strežnikom je bila preusmerjena na »%1«. Naslov URL ni veljaven ali pa strežnik ni ustrezno nastavljen. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Strežnik ne dovoli dostopa. Če želite preveriti, ali imate ustrezna dovoljenja, <a href="%1">kliknite</a> za dostop do te storitve z brskalnikom. - + There was an invalid response to an authenticated WebDAV request Zaznan je neveljaven odziv za zahtevo overitve WebDAV - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Krajevna usklajevana mapa %1 že obstaja. Nastavljena bo za usklajevanje.<br/><br/> - + Creating local sync folder %1 … Poteka ustvarjanje mape za krajevno usklajevanje %1 ... @@ -3015,84 +3116,84 @@ Uporaba možnosti ni priporočljiva. je v redu - + OK V redu - + failed. je spodletelo. - + Could not create local folder %1 Krajevne mape %1 ni mogoče ustvariti. - + No remote folder specified! Ni navedene oddaljene mape! - + Error: %1 Napaka: %1 - + creating folder on Nextcloud: %1 ustvarjanje mape v oblaku Nextcoud: %1 - + Remote folder %1 created successfully. Oddaljena mapa %1 je uspešno ustvarjena. - + The remote folder %1 already exists. Connecting it for syncing. Oddaljena mapa %1 že obstaja. Vzpostavljena bo povezava za usklajevanje. - - + + The folder creation resulted in HTTP error code %1 Ustvarjanje mape je povzročilo napako HTTP %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Ustvarjanje mape na oddaljenem naslovu je spodletelo zaradi napačnih poveril. <br/>Vrnite se in preverite zahtevana gesla.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Ustvarjanje oddaljene mape je spodletelo. Najverjetneje je vzrok v neustreznih poverilih.</font><br/>Vrnite se na predhodno stran in jih preverite.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Ustvarjanje oddaljene mape %1 je spodletelo z napako <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Vzpostavljena je povezava za usklajevanje med %1 in oddaljeno mapo %2. - + Successfully connected to %1! Povezava s strežnikom %1 je uspešno vzpostavljena! - + Connection to %1 could not be established. Please check again. Povezave z %1 ni mogoče vzpostaviti. Preveriti je treba nastavitve. - + Folder rename failed Preimenovanje mape je spodletelo @@ -3102,28 +3203,28 @@ Uporaba možnosti ni priporočljiva. Mape ni mogoče odstraniti niti ni mogoče ustvariti varnostne kopije, ker je mapa, oziroma dokument v njej, odprt v drugem programu. Zaprite mapo oziroma dokument, ali pa prekinite namestitev. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Mape ni mogoče odstraniti niti ni mogoče ustvariti varnostne kopije, ker je mapa, oziroma dokument v njej, odprt v drugem programu. Zaprite mapo oziroma dokument, ali pa prekinite namestitev. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Krajevno usklajena mapa %1 je uspešno ustvarjena!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Čarovnik za povezavo %1 - Add %1 account Dodaj račun %1 + + + %1 Connection Wizard + Čarovnik za povezavo %1 + Skip folders configuration @@ -3162,24 +3263,6 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Ostanite varni - - OCC::OwncloudWizardResultPage - - - Everything set up! - Vse je pripravljeno za uporabo! - - - - Open Local Folder - Odpri krajevno mapo - - - - Open %1 in Browser - Odpri %1 v brskalniku - - OCC::PollJob @@ -3190,6 +3273,16 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Ime datoteke vsebuje nepotrebne končne presledke in ga ni mogoče preimenovati, saj datoteka z istim imenom na strežniku že obstaja. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Ime datoteke vsebuje nepotrebne končne presledke in ga ni mogoče preimenovati, saj datoteka z istim imenom krajevno že obstaja. + Symbolic links are not supported in syncing. @@ -3207,12 +3300,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o - File names containing the character "%1" are not supported on this file system. - + File names containing the character '%1' are not supported on this file system. + Imena datotek, ki vsebujejo znak »%1«, na tem sistemu niso podprta. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. Imena datotek, ki vsebujejo znak »%1«, na tem sistemu niso podprta. @@ -3288,17 +3381,17 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Conflict when uploading some files to a folder. Those, conflicted, are going to get cleared! - + Zaznan je spor pri nalaganju nekaterih datotek v mapo. Spori bodo samodejno počiščeni! Conflict when uploading a folder. It's going to get cleared! - + Zaznan je spor pri pošiljanju mape. Mapa bo počiščena! Conflict when uploading a file. It's going to get removed! - + Zaznan je spor pri pošiljanju datoteke. Datoteka bo odstranjena! @@ -3341,9 +3434,9 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Odziv strežnika vključuje napako med branjem mape »%1«: %2 - + Server replied with an error while reading directory "%1" : %2 - + Odziv strežnika vključuje napako med branjem mape »%1«: %2 @@ -3356,12 +3449,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Error updating metadata: %1 - + Prišlo je do napake posodabljanja metapodatkov: %1 File is currently in use - + Datoteka je trenutno v uporabi. @@ -3421,7 +3514,7 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o The downloaded file is empty, but the server said it should have been %1. - + Prejeta datoteka je prazna, čeprav je na strežniku velikosti %1. @@ -3436,12 +3529,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Error updating metadata: %1 - + Prišlo je do napake posodabljanja metapodatkov: %1 The file %1 is currently in use - + Datoteka %1 je trenutno v uporabi. @@ -3482,12 +3575,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Error updating metadata: %1 - + Prišlo je do napake posodabljanja metapodatkov: %1 The file %1 is currently in use - + Datoteka %1 je trenutno v uporabi. @@ -3528,12 +3621,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Error updating metadata: %1 - + Prišlo je do napake posodabljanja metapodatkov: %1 The file %1 is currently in use - + Datoteka %1 je trenutno v uporabi. @@ -3544,7 +3637,7 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Failed to rename file - + Preimenovanje datoteke je spodletelo @@ -3583,12 +3676,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Error writing metadata to the database: %1 - + Napaka zapisovanja metapodatkov v podatkovno zbirko: %1 The file %1 is currently in use - + Datoteka %1 je trenutno v uporabi. @@ -3606,12 +3699,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Error updating metadata: %1 - + Prišlo je do napake posodabljanja metapodatkov: %1 The file %1 is currently in use - + Datoteka %1 je trenutno v uporabi. @@ -3670,12 +3763,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Error updating metadata: %1 - + Prišlo je do napake posodabljanja metapodatkov: %1 The file %1 is currently in use - + Datoteka %1 je trenutno v uporabi. @@ -3956,11 +4049,6 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Allow Editing Dovoli urejanje - - - Allow editing - Dovoli urejanje - Read only @@ -3981,6 +4069,16 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Password Protect Zaščiti z geslom + + + Allow editing + Dovoli urejanje + + + + View only + Le ogled + Allow upload and editing @@ -3996,16 +4094,21 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o File drop (upload only) Poteg datotek v okno (samo nalaganje) - - - Note to recipient - Sporočilo za prejemnika - Unshare Prekini souporabo + + + Link name + Ime povezave + + + + Note to recipient + Sporočilo za prejemnika + Password protect @@ -4017,15 +4120,20 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Nastavi datum preteka - - Delete share link - Izbriši povezavo za souporabo + + Delete link + Izbriši povezavo Add another link Dodaj novo povezavo + + + Delete share link + Izbriši povezavo za souporabo + Confirm Link Share Deletion @@ -4075,9 +4183,9 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Za iskalni niz »%1« ni zadetkov - + No results for "%1" - + Za iskalni niz »%1« ni zadetkov @@ -4179,12 +4287,6 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Omogoči souporabo z %1 - Context menu share @@ -4212,9 +4314,15 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Souporaba prek %1 - - Copy private link to clipboard - Kopiraj zasebno povezavo v odložišče + + + Activity + Dejavnosti + + + + Copy private link to clipboard + Kopiraj zasebno povezavo v odložišče @@ -4282,6 +4390,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Delete Izbriši + + + Share with %1 + parameter is Nextcloud + Omogoči souporabo z %1 + OCC::SslButton @@ -4427,6 +4541,11 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Cannot connect securely to <i>%1</i>: Ni mogoče vzpostaviti varne povezave s strežnikom <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4601,6 +4720,11 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Placeholders are postfixed with file sizes using Utility::octetsToString() Na voljo je le %1, za zagon pa je zahtevanih vsaj %2 + + + Aborted + Preklicano + @@ -4753,27 +4877,88 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Invalid characters, please rename "%1" Uporabljen je neveljaven znak; predmet »%1« je treba preimenovati. + + + Synchronization will resume shortly. + Usklajevanje se bo v kratkem nadaljevalo. + File name contains at least one invalid character Ime datoteke vsebuje vsaj en neveljaven znak. - - Aborted - Preklicano - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Zmanjkuje prostora na disku: prejem predmetov, ki bi zmanjšali prostor na disku pod %1 bo prekinjen. - + There is insufficient space available on the server for some uploads. Za usklajevanje je na strežniku premalo prostora. + + OCC::SyncStatusSummary + + + + Offline + Začasno nepovezan + + + + + + All synced! + Vse je usklajeno! + + + + Some files couldn't be synced! + Nekaterih datotek ni mogoče uskladiti! + + + + See below for errors + Več podrobnosti o napakah je zabeleženih spodaj + + + + Syncing + Poteka usklajevanje + + + + Sync paused + Usklajevanje je v premoru + + + + Some files could not be synced! + + + + + See below for warnings + Več podrobnosti o opozorilih je zabeleženih spodaj + + + + %1 of %2 · %3 left + %1 od %2 – %3 v teku + + + + %1 of %2 + %1 od %2 + + + + Syncing file %1 of %2 + Poteka usklajevanje %1 od %2 + + OCC::Systray @@ -4849,6 +5034,29 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o <p>Objavo je omogočila skupina %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4906,25 +5114,109 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Navidezni datotečni sistem zahteva uporabo NTFS, Na %1 pa je v uporabi %2. + + Could not fetch predefined statuses. Make sure you are connected to the server. + Ni mogoče pridobiti določenih stanj. Prepričajte se, da ste povezani s strežnikom. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. + Ni mogoče pridobiti stanja uporabnika. Prepričajte se, da ste povezani s strežnikom. + + + + User status feature is not supported. You will not be able to set your user status. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + Ne počisti + + + + 30 minutes + 30 minut + + + + + 1 hour + 1 ura + + + + 4 hours + 4 ure + + + + + Today + Danes + + + + + This week + Ta teden + + + + Less than a minute + Manj kot minuta + + + + 1 minute + 1 minuta + + + + %1 minutes + %1 minut + + + + %1 hours + %1 ur + + + + 1 day + 1 dan + + + + %1 days + %1 dni + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Navidezni datotečni sistem zahteva uporabo NTFS, Na %1 pa je v uporabi %2. + OCC::WebEnginePage @@ -5440,14 +5732,6 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Povežite se v vaš %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Naveden račun je v celoti usklajen s krajevno mapo - - QObject @@ -5514,22 +5798,22 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Away - + Ne spremljam Do not disturb - + Ne pustim se motiti Offline - + Začasno brez povezave Online - + Na voljo @@ -5537,6 +5821,38 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Failed to connect database. + Vzpostavljanje povezave s podatkovno zbirko je spodletelo. + + + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results @@ -5554,29 +5870,39 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o - Current user status is online - Trenutno je uporabnik povezan + Account connected + Račun je povezan - Current user status is do not disturb - Trenutno uporabnik ne želi motenj + Account not connected + Račun ni povezan - Account connected - Račun je povezan + Current user status is online + Trenutno je uporabnik povezan - Account not connected - Račun ni povezan + Current user status is do not disturb + Trenutno uporabnik ne želi motenj Account actions Dejanja računa + + + Remove Account + Odstrani račun + + + + Set status + Nastavi stanje + @@ -5589,17 +5915,65 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Log in Log in - - - Remove Account - Odstrani račun - Remove account Odstrani račun + + UserStatusSelector + + + Online status + Povezano stanje + + + + Online + Na voljo + + + + Away + Ne spremljam + + + + Do not disturb + Ne pustim se motiti + + + + Invisible + Drugim nevidno + + + + Status message + Sporočilo stanja + + + + What is your status? + Kako želite nastaviti stanje? + + + + Clear status message after + Počisti sporočilo stanja po + + + + Clear status message + Počisti sporočilo stanja + + + + Set status message + Nastavi sporočilo stanja + + Utility @@ -5661,12 +6035,12 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o ValidateChecksumHeader - + The checksum header is malformed. Glava nadzorne vsote je napačno oblikovana. - + The checksum header contained an unknown checksum type '%1' Glava nadzorne vsote vsebuje neznano vrsto zapisa »%1«. @@ -5676,17 +6050,17 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Prejeta datoteka ni skladna z nadzorno vsoto te datoteke, zato bo prenos ponovljen. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' Prejeta datoteka ni skladna z nadzornim številom, zato bo prenos ponovljen. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5715,6 +6089,11 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Pause sync for all Ustavi usklajevanje za vse + + + Set user status + Nastavi stanje uporabnika + Add account @@ -5750,12 +6129,6 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Current user status is do not disturb Trenutno uporabnik ne želi motenj - - - - Show more actions - Pokaži več možnosti - Share %1 @@ -5814,7 +6187,23 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Open share dialog - Odpri pogovorno okno souporebe + Odpri pogovorno okno souporabe + + + + Unified search results list + + + + + + Show more actions + Pokaži več možnosti + + + + %1 - File activity + @@ -6115,6 +6504,24 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Prijava v brskalniku (potek prijave 2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Vse je pripravljeno za uporabo! + + + + Open Local Folder + Odpri krajevno mapo + + + + Open %1 in Browser + Odpri %1 v brskalniku + + OCC::ShibbolethCredentials @@ -6167,6 +6574,14 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Log in + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Naveden račun je v celoti usklajen s krajevno mapo + + OCC::UserStatus @@ -6190,4 +6605,17 @@ To je nov preizkusni način. Če ga boste uporabili, pošljite tudi poročila o Na voljo + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Prejemanje datoteke, šifrirane E2E je spodletelo + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Kaže, da poskušate prejeti navidezno datoteko, ki je šifrirana po metodi E2E. Trenutno za tovrstne datoteke to še ni mogoče. Za najenostavnejše delo z navideznimi datotekami poskrbite, da je šifrirana mapa označena kot »Vedno na voljo krajevno«. + + \ No newline at end of file diff --git a/translations/client_sr.ts b/translations/client_sr.ts index fbfe5939b9b9..7439b38e0d96 100644 --- a/translations/client_sr.ts +++ b/translations/client_sr.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1138,32 +1151,32 @@ This can be an issue with your OpenSSL libraries. Не могу да отворим веб читач, копирајте везу директно у Ваш веб читач. - + Waiting for authorization Чекам на ауторизацију - + Polling for authorization Испитујем има ли ауторизације - + Starting authorization Започињем ауторизацију - + Link copied to clipboard. Веза копирана у оставу - + Reopen Browser - + Copy Link @@ -1332,6 +1345,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1392,22 +1412,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Чувај локалне фајлове као конфликтне - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1415,7 +1420,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1431,6 +1436,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2259,6 +2272,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Додајте нови шаблон за игнорисање: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2396,7 +2472,7 @@ Logs will be written to %1 <nobr>Фајл „%1“<br/>није уписив.<br/><br/>Записник се <b>не може</b> сачувати!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2439,6 +2515,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2608,6 +2689,13 @@ Logs will be written to %1 New %1 Update Ready Ново %1 ажурирање спремно + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Ново ажурирање за %1 ће се инсталирати. Можда ће бити +потребне додатне дозволе током процеса. + New %1 update ready @@ -2615,10 +2703,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Ново ажурирање за %1 ће се инсталирати. Можда ће бити -потребне додатне дозволе током процеса. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2655,6 +2741,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2665,6 +2756,11 @@ for additional privileges during the process. Could not check for new updates. Не могу да проверим нова ажурирања. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2961,37 +3057,37 @@ It is not advisable to use it. Време је истекло у покушају повезивања са %1 на %2. - + Trying to connect to %1 at %2 … Покушавам да се повежем са %1 на %2… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Аутентификован захтев серверу је преусмерен на %1. УРЛ је лош, сервер је лоше подешен. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Сервер није дозволио приступ. Да проверите имате ли исправан приступ, <a href="%1">кликните овде</a> да бисте приступили услузи из прегледача. - + There was an invalid response to an authenticated WebDAV request Добијен је неисправан одговор на аутентификовани ВебДАВ захтев - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Локална фасцикла %1 већ постоји. Одређујем је за синхронизацију.<br/><br/> - + Creating local sync folder %1 … Правим локалну фасциклу синхронизације %1… @@ -3001,84 +3097,84 @@ It is not advisable to use it. у реду - + OK - + failed. неуспешно - + Could not create local folder %1 Не могу да направим локалну фасциклу %1 - + No remote folder specified! Није наведена удаљена фасцикла! - + Error: %1 Грешка: %1 - + creating folder on Nextcloud: %1 правим фасциклу на Некстклауду: % 1 - + Remote folder %1 created successfully. Удаљена фасцикла %1 је успешно направљена. - + The remote folder %1 already exists. Connecting it for syncing. Удаљена фасцикла %1 већ постоји. Повезујем се ради синхронизовања. - - + + The folder creation resulted in HTTP error code %1 Прављење фасцикле довело је до ХТТП грешке са кодом %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Прављење удаљене фасцикле није успело због погрешних акредитива!<br/>Идите назад и проверите ваше акредитиве.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Прављење удаљене фасцикле није успело због погрешних акредитива.</font><br/>Идите назад и проверите ваше акредитиве.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Прављење удаљене фасцикле %1 није успело због грешке <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. Веза за синхронизацију %1 до удаљеног директоријума %2 је подешена. - + Successfully connected to %1! Успешно повезан са %1! - + Connection to %1 could not be established. Please check again. Не може се успоставити веза са %1. Проверите поново. - + Folder rename failed Преименовање није успело @@ -3088,28 +3184,28 @@ It is not advisable to use it. Не могу да уклоним и направим резервну копију фасцикле јер су фасцикла или фајл отворени у другом програму. Затворите фасциклу или фајл и покушајте поново или одустаните од подешавања. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Локална фасцикла за синхронизовање %1 је успешно направљена!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 чаробњак повезивања - Add %1 account + + + %1 Connection Wizard + %1 чаробњак повезивања + Skip folders configuration @@ -3142,24 +3238,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Све је подешено! - - - - Open Local Folder - Отвори локалну фасциклу - - - - Open %1 in Browser - Отвори %1 у прегледачу - - OCC::PollJob @@ -3170,6 +3248,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3187,12 +3275,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3321,7 +3409,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3936,11 +4024,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Дозволи мењање - - - Allow editing - Дозволи уређивање - Read only @@ -3961,6 +4044,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Заштита лозинком + + + Allow editing + Дозволи уређивање + + + + View only + + Allow upload and editing @@ -3976,16 +4069,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Превлачење фајлова (само за отпремање) - - - Note to recipient - Напомена примаоцу - Unshare Укини дељење + + + Link name + + + + + Note to recipient + Напомена примаоцу + Password protect @@ -3997,15 +4095,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Постави датум истека - - Delete share link - Обриши везу дељења + + Delete link + Add another link Додај још једну везу + + + Delete share link + Обриши везу дељења + Confirm Link Share Deletion @@ -4055,7 +4158,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Нема резултата за '%1' - + No results for "%1" @@ -4159,12 +4262,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Подели са %1 - Context menu share @@ -4191,6 +4288,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Подели преко %1 + + + + Activity + + Copy private link to clipboard @@ -4262,6 +4365,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Избриши + + + Share with %1 + parameter is Nextcloud + Подели са %1 + OCC::SslButton @@ -4407,6 +4516,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Не могу да се безбедно повежем са <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4581,6 +4695,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Доступно је само %1, треба бар %2 за започињање + + + Aborted + + @@ -4733,27 +4852,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Неисправан карактер, преименујте „%1“ + + + Synchronization will resume shortly. + + File name contains at least one invalid character Назив садржи бар један недозвољен карактер - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Мало простора на диску: преузимања која би смањила слободно место испод %1 су прескочена. - + There is insufficient space available on the server for some uploads. Нема довољно места на серверу за нека отпремања. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4829,6 +5009,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Ово издање је обезбедио %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4886,23 +5089,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5420,14 +5707,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Целокупан налог је синхронизован са локалном фасциклом - - QObject @@ -5520,6 +5799,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5534,22 +5845,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Налог повезан - Current user status is do not disturb + Account not connected - Account connected - Налог повезан + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5557,6 +5868,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions Акције налога + + + Remove Account + + + + + Set status + + @@ -5569,17 +5890,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Пријава - - - Remove Account - - Remove account Уклони налог + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5641,12 +6010,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Заглавље контролне суме је лоше формирано. - + The checksum header contained an unknown checksum type '%1' Заглавље контролне суме садржи непознати тип контролне суме '%1' @@ -5656,17 +6025,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Преузети фајл се не поклапа с контролном сумом. Биће настављено. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5695,6 +6064,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5730,12 +6104,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5796,6 +6164,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6095,6 +6479,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Пријавите се из веб читача (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Све је подешено! + + + + Open Local Folder + Отвори локалну фасциклу + + + + Open %1 in Browser + Отвори %1 у прегледачу + + OCC::ShibbolethCredentials @@ -6147,6 +6549,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Пријава + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Целокупан налог је синхронизован са локалном фасциклом + + OCC::UserStatus @@ -6170,4 +6580,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_sv.ts b/translations/client_sv.ts index 24cdb3937cee..968afd78a87f 100644 --- a/translations/client_sv.ts +++ b/translations/client_sv.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1140,32 +1153,32 @@ Det kan vara problem med dina OpenSSL-bibliotek. Det går inte att öppna webbläsaren, kopiera länken till din webbläsare. - + Waiting for authorization Väntar på auktorisation - + Polling for authorization Kontrollerar auktorisation - + Starting authorization Startar auktorisation - + Link copied to clipboard. Länken kopierad till urklipp. - + Reopen Browser - + Copy Link @@ -1334,6 +1347,13 @@ Det betyder att synkroniseringsklienten inte kan ladda upp lokala ändringar ome %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1394,22 +1414,7 @@ Om du fortsätter synkroniseringen kommer alla dina filer återställas med en Behåll lokala filer som konflikt - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1417,7 +1422,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1433,6 +1438,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files Ta bort alla filer + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2261,6 +2274,69 @@ Objekt där radering är tillåtet raderas om de förhindrar att en mapp tas bor Lägg till ett nytt ignorera mönster: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2398,7 +2474,7 @@ Loggar kommer att skrivas till %1 <nobr>Filen '%1'<br/>kan inte öppnas för skrivning.<br/><br/>Loggtexten kan <b>inte</b> sparas!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2441,6 +2517,11 @@ Loggar kommer att skrivas till %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>En ny version av %1 klienten är tillgänglig men uppdateringsprocessen misslyckades.</p><p><b>%2</b> har laddats ner. Den installerade versionen är %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2610,6 +2691,13 @@ Loggar kommer att skrivas till %1 New %1 Update Ready Ny %1 uppdatering tillgänglig + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + En ny uppdatering för %1 kommer installeras. Programmet kan be om +ytterligare rättigheter under processen. + New %1 update ready @@ -2617,10 +2705,8 @@ Loggar kommer att skrivas till %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - En ny uppdatering för %1 kommer installeras. Programmet kan be om -ytterligare rättigheter under processen. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2657,6 +2743,11 @@ ytterligare rättigheter under processen. New %1 is available. Please click <a href='%2'>here</a> to download the update. Ny %1 är tillgänglig. Klicka <a href='%2'>här</a> för att ladda ner uppdateringen. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2667,6 +2758,11 @@ ytterligare rättigheter under processen. Could not check for new updates. Kunde inte söka efter uppdateringar. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2963,37 +3059,37 @@ Det är inte lämpligt att använda den. Försök att ansluta till %1 på %2 tog för lång tid. - + Trying to connect to %1 at %2 … Försöker ansluta till %1 på %2 ... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Den autentiserade begäran till servern omdirigerades till "%1". Den webbadressen är ogiltig, servern är felkonfigurerad. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Åtkomst förbjuden av servern. För att bekräfta att du har korrekta rättigheter, <a href="%1">klicka här</a> för att ansluta till tjänsten med din webb-läsare. - + There was an invalid response to an authenticated WebDAV request Det var ett ogiltigt svar på en verifierad WebDAV-begäran - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Den lokala synkroniseringsmappen % 1 finns redan, aktiverar den för synkronisering.<br/><br/> - + Creating local sync folder %1 … Skapar lokal synkroniseringsmapp %1 ... @@ -3003,84 +3099,84 @@ Det är inte lämpligt att använda den. ok - + OK - + failed. misslyckades. - + Could not create local folder %1 Kunde inte skapa lokal mapp %1 - + No remote folder specified! Ingen fjärrmapp specificerad! - + Error: %1 Fel: %1 - + creating folder on Nextcloud: %1 skapar mapp på Nextcloud: %1 - + Remote folder %1 created successfully. Fjärrmapp %1 har skapats. - + The remote folder %1 already exists. Connecting it for syncing. Fjärrmappen %1 finns redan. Ansluter den för synkronisering. - - + + The folder creation resulted in HTTP error code %1 Skapande av mapp resulterade i HTTP felkod %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Det gick inte att skapa mappen efter som du inte har tillräckliga rättigheter!<br/>Vänligen återvänd och kontrollera dina rättigheter. - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Misslyckades skapa fjärrmappen, troligen p.g.a felaktiga inloggningsuppgifter.</font><br/>Kontrollera dina inloggningsuppgifter.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Misslyckades skapa fjärrmapp %1 med fel <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. En synkroniseringsanslutning från %1 till fjärrmappen %2 har skapats. - + Successfully connected to %1! Ansluten till %1! - + Connection to %1 could not be established. Please check again. Anslutningen till %1 kunde inte etableras. Vänligen kontrollera och försök igen. - + Folder rename failed Omdöpning av mapp misslyckades @@ -3090,28 +3186,28 @@ Det är inte lämpligt att använda den. Kan inte ta bort och göra en säkerhetskopia av mappen på grund av att mappen eller en fil i den används av ett annat program. Vänligen stäng mappen eller filen och försök igen eller avbryt installationen. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Lokal synkroniseringsmapp %1 skapad!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 Anslutningsguiden - Add %1 account + + + %1 Connection Wizard + %1 Anslutningsguiden + Skip folders configuration @@ -3144,24 +3240,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Allt är konfigurerat! - - - - Open Local Folder - Öppnar lokal mapp - - - - Open %1 in Browser - Öppna %1 i webbläsare - - OCC::PollJob @@ -3172,6 +3250,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3189,12 +3277,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3323,7 +3411,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3938,11 +4026,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Tillåt redigering - - - Allow editing - Tillåt redigering - Read only @@ -3963,6 +4046,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Lösenordsskydda + + + Allow editing + Tillåt redigering + + + + View only + + Allow upload and editing @@ -3978,16 +4071,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Göm fillista (endast uppladdning) - - - Note to recipient - Notering till mottagare - Unshare Sluta dela + + + Link name + + + + + Note to recipient + Notering till mottagare + Password protect @@ -3999,15 +4097,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Välj utgångsdatum - - Delete share link - Ta bort delad länk + + Delete link + Add another link Lägg till en annan länk + + + Delete share link + Ta bort delad länk + Confirm Link Share Deletion @@ -4057,7 +4160,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Inga resultat för '%1' - + No results for "%1" @@ -4161,12 +4264,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Dela med %1 - Context menu share @@ -4193,6 +4290,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Dela via %1 + + + + Activity + + Copy private link to clipboard @@ -4264,6 +4367,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Ta bort + + + Share with %1 + parameter is Nextcloud + Dela med %1 + OCC::SslButton @@ -4409,6 +4518,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Kan inte ansluta säkert till <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4583,6 +4697,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Endast %1 tillgängligt, behöver minst %2 för att starta + + + Aborted + Avbruten + @@ -4735,27 +4854,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Otillåtna tecken, var vänlig byt namn på "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Filnamnet innehåller minst ett ogiltigt tecken - - Aborted - Avbruten - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Diskutrymmet är lågt: Hämtningar som skulle reducera det fria utrymmet under %1 hoppas över. - + There is insufficient space available on the server for some uploads. Det finns inte tillräckligt med utrymme på servern för vissa uppladdningar. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4831,6 +5011,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Denna release levererades av %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4888,23 +5091,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5422,14 +5709,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Logga in på ditt %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Hela ditt konto är synkroniserat mot den lokala mappen - - QObject @@ -5522,6 +5801,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5536,29 +5847,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Konto anslutet - Current user status is do not disturb - + Account not connected + Konto inte anslutet - Account connected - Konto anslutet + Current user status is online + - Account not connected - Konto inte anslutet + Current user status is do not disturb + Account actions Kontoåtgärder + + + Remove Account + Ta bort konto + + + + Set status + + @@ -5571,17 +5892,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Logga in - - - Remove Account - Ta bort konto - Remove account Ta bort konto + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5643,12 +6012,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Kontrollsummans header är felformaterad. - + The checksum header contained an unknown checksum type '%1' Kontrollsummans header innehåller en okänd kontrollsumma av typ '%1' @@ -5658,17 +6027,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Den hämtade filen matchar inte kontrollsumman, den kommer att återupptas. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5697,6 +6066,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all Pausa synkronisering för alla + + + Set user status + + Add account @@ -5732,12 +6106,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - Visa fler åtgärder - Share %1 @@ -5798,6 +6166,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog Öppna delningsdialogen + + + Unified search results list + + + + + + Show more actions + Visa fler åtgärder + + + + %1 - File activity + + main.cpp @@ -6097,6 +6481,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Logga in i din webbläsare (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Allt är konfigurerat! + + + + Open Local Folder + Öppnar lokal mapp + + + + Open %1 in Browser + Öppna %1 i webbläsare + + OCC::ShibbolethCredentials @@ -6149,6 +6551,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Logga in + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Hela ditt konto är synkroniserat mot den lokala mappen + + OCC::UserStatus @@ -6172,4 +6582,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_th.ts b/translations/client_th.ts index ab7d47c79b1d..c7c923480b4c 100644 --- a/translations/client_th.ts +++ b/translations/client_th.ts @@ -14,12 +14,6 @@ Open %1 locally - - - - Show more actions - แสดงการกระทำเพิ่มเติม - Open share dialog @@ -30,6 +24,25 @@ Share %1 แชร์ %1 + + + + Show more actions + แสดงการกระทำเพิ่มเติม + + + + View activity + + + + + ActivityList + + + Activity list + + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - ไม่สามารถย้าย "%1" ไปยัง "%1" + Could not move "%1" to "%2" + @@ -1138,32 +1151,32 @@ This can be an issue with your OpenSSL libraries. - + Waiting for authorization - + Polling for authorization - + Starting authorization - + Link copied to clipboard. - + Reopen Browser - + Copy Link @@ -1328,6 +1341,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1383,22 +1403,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an เก็บไฟล์ในเครื่องเป็นข้อขัดแย้ง - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1406,7 +1411,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1422,6 +1427,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2248,6 +2261,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2383,7 +2459,7 @@ Logs will be written to %1 <nobr>ไฟล์ '%1'<br/>ไม่สามารถเปิดขึ้นมาเพื่อเขียนข้อมูลได้<br/><br/>ผลลัพธ์ของไฟล์ log <b>ไม่สามารถ</b> บันทึกข้อมูลได้!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2426,6 +2502,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2595,6 +2676,12 @@ Logs will be written to %1 New %1 Update Ready มี %1 พร้อมอัพเดทใหม่ + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + อัปเดตใหม่สำหรับ %1 กำลังจะถูกติดตั้ง ตัวอัปเดตอาจขอเข้าถึงสิทธิประโยชน์เพิ่มเติมในระหว่างกระบวนการ + New %1 update ready @@ -2602,9 +2689,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - อัปเดตใหม่สำหรับ %1 กำลังจะถูกติดตั้ง ตัวอัปเดตอาจขอเข้าถึงสิทธิประโยชน์เพิ่มเติมในระหว่างกระบวนการ + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2641,6 +2727,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2651,6 +2742,11 @@ for additional privileges during the process. Could not check for new updates. ไม่สามารถตรวจสอบการอัปเดตใหม่ + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2946,37 +3042,37 @@ It is not advisable to use it. หมดเวลาขณะที่พยายามเชื่อมต่อไปยัง %1 ที่ %2 - + Trying to connect to %1 at %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. คำขอการรับรองความถูกต้องไปยังเซิร์ฟเวอร์ที่ถูกเปลี่ยนเส้นทางไปยัง - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. การเข้าถึงถูกระงับโดยเซิร์ฟเวอร์ เพื่อตรวจสอบว่าคุณมีการเข้าถึงที่เหมาะสม <a href="%1">คลิกที่นี่</a> เพื่อรเข้าถึงบริการกับเบราว์เซอร์ของคุณ - + There was an invalid response to an authenticated WebDAV request - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> ประสานข้อมูลโฟลเดอร์ต้นทาง %1 มีอยู่แล้ว กรุณาตั้งค่าเพื่อถ่ายข้อมูล <br/<br/> - + Creating local sync folder %1 … @@ -2986,84 +3082,84 @@ It is not advisable to use it. ตกลง - + OK - + failed. ล้มเหลว - + Could not create local folder %1 ไม่สามารถสร้างผสานข้อมูลโฟลเดอร์ต้นทาง %1... - + No remote folder specified! ไม่มีโฟลเดอร์รีโมทที่ระบุ! - + Error: %1 ข้อผิดพลาด: %1 - + creating folder on Nextcloud: %1 - + Remote folder %1 created successfully. โฟลเดอร์รีโมท %1 ถูกสร้างเรียบร้อยแล้ว - + The remote folder %1 already exists. Connecting it for syncing. โฟลเดอร์รีโมทมี %1 อยู่แล้ว กำลังเชื่อมต่อเพื่อถ่ายโอนข้อมูล - - + + The folder creation resulted in HTTP error code %1 การสร้างโฟลเดอร์ดังกล่าวส่งผลให้เกิดรหัสข้อผิดพลาด HTTP error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> สร้างโฟลเดอร์ระยะไกลล้มเหลวเนื่องจากมีข้อมูลผิดพลาด! - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">การสร้างโฟลเดอร์รีโมทล้มเหลว ซึ่งอาจมีสาเหตุมาจากการกรอกข้อมูลส่วนตัวเพื่อเข้าใช้งานไม่ถูกต้อง.</font><br/>กรุณาย้อนกลับไปแล้วตรวจสอบข้อมูลส่วนตัวของคุณอีกครั้ง.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. การสร้างโฟลเดอร์ระยะไกล %1 ล้มเหลวเนื่องข้อผิดพลาด <tt>%2</tt> - + A sync connection from %1 to remote directory %2 was set up. การเชื่อมต่อเผื่อประสานข้อมูลจาก %1 ไปที่ไดเร็กทอรี่ระยะไกล %2 ได้ถูกติดตั้งแล้ว - + Successfully connected to %1! เชื่อมต่อไปที่ %1! สำเร็จ - + Connection to %1 could not be established. Please check again. การเชื่อมต่อกับ %1 ไม่สามารถดำเนินการได้ กรุณาตรวจสอบอีกครั้ง - + Folder rename failed เปลี่ยนชื่อโฟลเดอร์ล้มเหลว @@ -3073,28 +3169,28 @@ It is not advisable to use it. ไม่สามารถลบและสำรองข้อมูลโฟลเดอร์เพราะโฟลเดอร์หรือไฟล์ในนั้นจะเปิดในโปรแกรมอื่นอยู่ กรุณาปิดโฟลเดอร์หรือไฟล์และกดลองใหม่อีกครั้งหรือยกเลิกการติดตั้ง - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>ประสานข้อมูลโฟลเดอร์ต้นทาง %1 ได้ถูกสร้างขึ้นเรียบร้อยแล้ว!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 ตัวช่วยสร้างการเชื่อมต่อ - Add %1 account + + + %1 Connection Wizard + %1 ตัวช่วยสร้างการเชื่อมต่อ + Skip folders configuration @@ -3127,24 +3223,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - ตั้งค่าทุกอย่าง! - - - - Open Local Folder - เปิดโฟลเดอร์ต้นทาง - - - - Open %1 in Browser - เปิด %1 ในเบราว์เซอร์ - - OCC::PollJob @@ -3155,6 +3233,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3172,12 +3260,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3306,7 +3394,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3921,11 +4009,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing - - - Allow editing - อนุญาตให้แก้ไข - Read only @@ -3946,6 +4029,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect + + + Allow editing + อนุญาตให้แก้ไข + + + + View only + + Allow upload and editing @@ -3962,13 +4055,18 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - Note to recipient + + Unshare - - Unshare + + Link name + + + + + Note to recipient @@ -3982,8 +4080,8 @@ This is a new, experimental mode. If you decide to use it, please report any iss กำหนดวันที่หมดอายุ - - Delete share link + + Delete link @@ -3991,6 +4089,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Add another link + + + Delete share link + + Confirm Link Share Deletion @@ -4040,7 +4143,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss ไม่มีผลลัพธ์สำหรับ '%1' - + No results for "%1" @@ -4144,12 +4247,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - - Context menu share @@ -4176,6 +4273,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 + + + + Activity + + Copy private link to clipboard @@ -4247,6 +4350,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete ลบ + + + Share with %1 + parameter is Nextcloud + + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: ไม่สามารถเชื่อมต่อแบบปลอดภัยไปยัง <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() มีเพียง %1 ที่พร้อมใช้งาน คุณจำเป็นต้องมีไม่น้อยกว่า %2 เพื่อเริ่มใช้งาน + + + Aborted + + @@ -4717,27 +4836,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" ตัวอักษรไม่ถูกต้อง โปรดเปลี่ยนชื่อ "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character มีชื่อแฟ้มอย่างน้อยหนึ่งตัวอักษรที่ไม่ถูกต้อง - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. พื้นที่จัดเก็บเหลือน้อย: การดาวน์โหลดจะช่วยลดพื้นที่ว่างด้านล่าง %1 ที่ถูกข้ามไป - + There is insufficient space available on the server for some uploads. มีพื้นที่ว่างไม่เพียงพอบนเซิร์ฟเวอร์สำหรับการอัพโหลดบางรายการ + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4813,6 +4993,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4870,23 +5073,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5404,14 +5691,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - ทั้งบัญชีของคุณจะถูกประสานข้อมูลกับโฟลเดอร์ต้นทาง - - QObject @@ -5504,6 +5783,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5518,22 +5829,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online + Account connected - Current user status is do not disturb + Account not connected - Account connected + Current user status is online - Account not connected + Current user status is do not disturb @@ -5541,6 +5852,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + + + + + Set status + + @@ -5553,17 +5874,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in เข้าสู่ระบบ - - - Remove Account - - Remove account ลบบัญชี + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5625,12 +5994,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. - + The checksum header contained an unknown checksum type '%1' @@ -5640,17 +6009,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5679,6 +6048,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5714,12 +6088,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5780,6 +6148,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6079,6 +6463,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::OwncloudWizardResultPage + + + Everything set up! + ตั้งค่าทุกอย่าง! + + + + Open Local Folder + เปิดโฟลเดอร์ต้นทาง + + + + Open %1 in Browser + เปิด %1 ในเบราว์เซอร์ + + OCC::ShibbolethCredentials @@ -6131,6 +6533,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + ทั้งบัญชีของคุณจะถูกประสานข้อมูลกับโฟลเดอร์ต้นทาง + + OCC::UserStatus @@ -6154,4 +6564,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_tr.ts b/translations/client_tr.ts index a2956d93f8a2..5bde112d8375 100644 --- a/translations/client_tr.ts +++ b/translations/client_tr.ts @@ -14,12 +14,6 @@ Open %1 locally %1 ögesini yerel olarak aç - - - - Show more actions - Diğer işlemleri görüntüle - Open share dialog @@ -30,6 +24,25 @@ Share %1 %1 ögesini paylaş + + + + Show more actions + Diğer işlemleri görüntüle + + + + View activity + İşlemi görüntüle + + + + ActivityList + + + Activity list + İşlem listesi + CloudProviderWrapper @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" "%1", "%2" üzerine taşınamadı @@ -1144,32 +1157,32 @@ Bu durum OpenSLL kitaplıkları ile ilgili bir sorun olabilir. Web tarayıcı açılamadı. Lütfen bağlantıyı kopyalayıp tarayıcınıza yapıştırın. - + Waiting for authorization İzin verilmesi bekleniyor - + Polling for authorization İzin isteniyor - + Starting authorization İzin vermeye başlanıyor - + Link copied to clipboard. Bağlantı panoya kopyalandı. - + Reopen Browser Tarayıcıyı yeniden aç - + Copy Link Bağlantıyı kopyala @@ -1335,6 +1348,16 @@ This means that the synchronization client might not upload local changes immedi Eşitlenen klasörlerdeki değişiklikler güvenli şekilde izlenemiyor. Bunun sonucunda eşitleme istemcisi yerel değişiklikleri anında yükleyemez. Onun yerine yalnız yerel değişiklikleri tarar ve aralıklarla yükler (varsayılan olarak iki saatte bir). + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + '%1' eşitleme klasöründeki tüm dosyalar sunucudan silindi. +Silinen dosyalar eşitleme sırasında yerel eşitleme klasörünüzden de silinecek ve bu dosyaları geri yüklemedikçe göremeyeceksiniz. +Sunucuda bu eşitleme işlemlerinin yapılmasını istediğinizden emin misiniz? +Bu işlemi yanlışlıkla yaptıysanız ve dosyalarınızı korumak istiyorsanız dosyalar sunucudan yeniden eşitlenecek. @@ -1396,28 +1419,7 @@ Eşitlemeye normal şekilde devam edilirse tüm dosyalar daha eski bir dosya ile Çakıştığında yerel dosyalar korunsun - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - '%1' eşitleme klasöründeki tüm dosyalar silinecek. -Silinen bu dosyalar yerel eşitleme klasörünüzden de silineceğinden, geri yükleme yetkiniz yoksa bu dosyaları kullanamayacaksınız. -Geri yükleme yetkiniz varsa ve geri yüklemeyi seçerseniz, dosyalar sunucu ile yeniden eşitlenir. -Silmeyi seçerseniz, sahibi değilseniz bu dosyaları artık kullanamazsınız. - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - '%1' eşitleme klasöründeki tüm dosyalar sunucudan silindi. -Silinen dosyalar eşitleme sırasında yerel eşitleme klasörünüzden de silinecek ve bu dosyaları geri yüklemedikçe göremeyeceksiniz. -Sunucuda bu eşitleme işlemlerinin yapılmasını istediğinizden emin misiniz? -Bu işlemi yanlışlıkla yaptıysanız ve dosyalarınızı korumak istiyorsanız dosyalar sunucudan yeniden eşitlenecek. - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1428,7 +1430,7 @@ Geri yükleme yetkiniz varsa ve geri yüklemeyi seçerseniz, dosyalar sunucu ile Silmeyi seçerseniz, sahibi değilseniz bu dosyaları artık kullanamazsınız. - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1447,6 +1449,17 @@ Bu işlemi yanlışlıkla yaptıysanız ve dosyalarınızı korumak istiyorsanı Remove all files Tüm dosyalar silinsin + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + '%1' eşitleme klasöründeki tüm dosyalar silinecek. +Silinen bu dosyalar yerel eşitleme klasörünüzden de silineceğinden, geri yükleme yetkiniz yoksa bu dosyaları kullanamayacaksınız. +Geri yükleme yetkiniz varsa ve geri yüklemeyi seçerseniz, dosyalar sunucu ile yeniden eşitlenir. +Silmeyi seçerseniz, sahibi değilseniz bu dosyaları artık kullanamazsınız. + Keep files @@ -2277,6 +2290,69 @@ Silme izni verildiğinde bir klasörün silinmesini engelleyen ögeler silinir. Yeni bir yok sayma modeli ekle: + + OCC::InvalidFilenameDialog + + + Invalid filename + Dosya adı geçersiz + + + + The file could not be synced because it contains characters which are not allowed on this system. + Adında bu sistemde kullanılmasına izin verilmeyen karakterler bulunduğundan dosya eşitlenemedi. + + + + Error + Hata + + + + Please enter a new name for the file: + Lütfen dosya için yeni bir ad yazın: + + + + New filename + Yeni dosya adı + + + + Rename file + Dosyayı yeniden adlandır + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + Adında bu sistemde kullanılmasına izin verilmeyen karakterler bulunduğundan %1 dosyası eşitlenemedi. + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + Sistemde dosya adlarında kullanılmasına izin verilmeyen karakterler: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + Bu dosyayı yeniden adlandırma izniniz yok. Dosya sahibinden dosyanın adını değiştirmesini isteyebilirsiniz. + + + + Filename contains illegal characters: %1 + Dosya adında izin verilmeyen karakterler var: %1 + + + + Could not rename file. Please make sure you are connected to the server. + Dosya yeniden adlandırılamadı. Sunucuya bağlı olduğunuzdan emin olun. + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + Aynı adlı bir dosya sunucu üzerinde zaten var olduğundan dosya yeniden adlandırılamadı. Lütfen başka bir ad seçin. + + OCC::LegalNotice @@ -2417,7 +2493,7 @@ Günlükler %1 üzerine yazılacak <nobr>'%1' dosyası<br/>yazılmak üzere açılamadı.<br/><br/>Günlük çıktısı <b>kaydedilemez</b>!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>"%1" dosyası<br/>yazılmak üzere açılamadı.<br/><br/>Günlük çıktısı <b>kaydedilemez</b>!</nobr> @@ -2460,6 +2536,11 @@ Günlükler %1 üzerine yazılacak <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>Yeni bir %1 istemcisi yayınlanmış ancak güncelleme işlemi yapılamadı.</p><p><b>%2</b> indirildi. Kurulu sürüm: %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>Yeni bir %1 istemcisi yayınlanmış ancak güncelleme işlemi yapılamadı.</p><p><b>%2</b> indirildi. Kurulu sürüm: %3. Yeniden başlatıp güncellemeyi onaylarsanız, kurulumu tamamlamak için bilgisayarınız yeniden başlatılabilir.</p> + Ask again later @@ -2629,6 +2710,13 @@ Günlükler %1 üzerine yazılacak New %1 Update Ready Yeni %1 güncellemesi yayınlanmış + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + %1 için yeni bir güncelleme yüklenmek üzere. İşlem sırasında +güncelleyici başka izinler isteyebilir. + New %1 update ready @@ -2636,10 +2724,8 @@ Günlükler %1 üzerine yazılacak - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - %1 için yeni bir güncelleme yüklenmek üzere. İşlem sırasında -güncelleyici başka izinler isteyebilir. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + %1 için yeni bir güncelleme yüklenmek üzere. İşlem sırasında güncelleyici başka izinler isteyebilir. Kurulumu tamamlamak için bilgisayarınız yeniden başlatılabilir. @@ -2676,6 +2762,11 @@ güncelleyici başka izinler isteyebilir. New %1 is available. Please click <a href='%2'>here</a> to download the update. Yeni %1 yayınlanmış. Lütfen güncellemeyi indirmek için <a href='%2'>buraya tıklayın</a>. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + Güncelleme indirilemedi. Lütfen güncellemeyi elle indirmek için <a href='%1'>%1</a> sitesini açın. + Could not download update. Please open %1 to download the update manually. @@ -2686,6 +2777,11 @@ güncelleyici başka izinler isteyebilir. Could not check for new updates. Güncellemeler denetlenemedi. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + Yeni %1 yayınlanmış. Lütfen güncellemeyi indirmek için <a href='%2'>%2</a> sitesini açın. + New %1 is available. Please open %2 to download the update. @@ -2982,37 +3078,37 @@ Kullanmanız önerilmez. %1 ile %2 zamanında bağlantı kurulurken zaman aşımı. - + Trying to connect to %1 at %2 … %2 üzerindeki %1 ile bağlantı kuruluyor … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Sunucuya yapılan kimlik doğrulama isteği '%1' adresine yönlendirildi. Adres ya da sunucu yapılandırması hatalı. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. Sunucuya yapılan kimlik doğrulama isteği "%1" adresine yönlendirildi. Adres ya da sunucu yapılandırması hatalı. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Erişim sunucu tarafından engellendi. Web tarayıcınız ile hizmete erişerek yeterli izne sahip olup olmadığınızı doğrulamak için <a href="%1">buraya tıklayın</a>. - + There was an invalid response to an authenticated WebDAV request Kimliği doğrulanmış bir WebDAV isteğine geçersiz bir yanıt verildi - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> %1 yerel eşitleme klasörü zaten var, eşitlemeye ayarlanıyor.<br/><br/> - + Creating local sync folder %1 … %1 yerel eşitleme klasörü oluşturuluyor … @@ -3022,84 +3118,84 @@ Kullanmanız önerilmez. tamam - + OK Tamam - + failed. başarısız. - + Could not create local folder %1 %1 yerel klasörü oluşturulamadı - + No remote folder specified! Uzak klasör belirtilmemiş! - + Error: %1 Hata: %1 - + creating folder on Nextcloud: %1 Nextcloud üzerinde klasör oluşturuluyor: %1 - + Remote folder %1 created successfully. %1 uzak klasörü oluşturuldu. - + The remote folder %1 already exists. Connecting it for syncing. Uzak klasör %1 zaten var. Eşitlemek için bağlantı kuruluyor. - - + + The folder creation resulted in HTTP error code %1 Klasör oluşturma işlemi %1 HTTP hata kodu ile sonuçlandı - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Geçersiz kimlik doğrulama bilgileri nedeniyle uzak klasör oluşturulamadı!<br/>Lütfen geri giderek kimlik doğrulama bilgilerinizi denetleyin.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Büyük olasılıkla belirtilen kimlik doğrulama bilgileri hatalı olduğundan uzak klasör oluşturulamadı.</font><br/>Lütfen geri giderek kimlik doğrulama bilgilerinizi doğrulayın.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. %1 uzak klasörü <tt>%2</tt> hatası nedeniyle oluşturulamadı. - + A sync connection from %1 to remote directory %2 was set up. %1 ile %2 uzak klasörü arasında bir eşitleme bağlantısı ayarlandı. - + Successfully connected to %1! %1 ile bağlantı kuruldu! - + Connection to %1 could not be established. Please check again. %1 ile bağlantı kurulamadı. Lütfen yeniden denetleyin. - + Folder rename failed Klasör yeniden adlandırılamadı @@ -3109,28 +3205,28 @@ Kullanmanız önerilmez. Klasör ya da içindeki bir dosya başka bir program tarafından kullanıldığından, bu klasör üzerinde silme ya da yedekleme işlemleri yapılamıyor. Lütfen klasör ya da dosyayı kapatıp yeniden deneyin ya da kurulumu iptal edin. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. Klasör ya da içindeki bir dosya başka bir program tarafından kullanıldığından, bu klasör üzerinde silme ya da yedekleme işlemleri yapılamıyor. Lütfen klasör ya da dosyayı kapatıp yeniden deneyin ya da kurulumu iptal edin. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>%1 yerel eşitleme klasörü oluşturuldu!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 bağlantı yardımcısı - Add %1 account %1 hesabı ekle + + + %1 Connection Wizard + %1 bağlantı yardımcısı + Skip folders configuration @@ -3169,24 +3265,6 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Güvende kalın - - OCC::OwncloudWizardResultPage - - - Everything set up! - Her şey ayarlandı! - - - - Open Local Folder - Yerel klasörü aç - - - - Open %1 in Browser - %1 ögesini tarayıcıda aç - - OCC::PollJob @@ -3197,6 +3275,16 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + Dosya adının sonunda boşluklar bulunuyor ve sunucuda aynı ada sahip bir dosya zaten var olduğundan yeniden adlandırılamadı. + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + Dosya adının sonunda boşluklar bulunuyor ve yerel olarak aynı ada sahip bir dosya zaten var olduğundan yeniden adlandırılamadı. + Symbolic links are not supported in syncing. @@ -3212,16 +3300,16 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş File names ending with a period are not supported on this file system. Nokta ile biten dosya adları bu dosya sisteminde desteklenmiyor. - - - File names containing the character "%1" are not supported on this file system. - "%1" karakterini içeren dosya adları bu sistemde desteklenmiyor. - File names containing the character '%1' are not supported on this file system. '%1' karakterini içeren dosya adları bu sistemde desteklenmiyor. + + + File names containing the character "%1" are not supported on this file system. + "%1" karakterini içeren dosya adları bu sistemde desteklenmiyor. + File name contains at least one invalid character @@ -3348,7 +3436,7 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş !%1' klasörü okunurken sunucu bir hata yanıtı verdi: %2 - + Server replied with an error while reading directory "%1" : %2 "%1" klasörü okunurken sunucu bir hata yanıtı verdi: %2 @@ -3963,11 +4051,6 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Allow Editing Düzenlenebilsin - - - Allow editing - Düzenlenebilsin - Read only @@ -3988,6 +4071,16 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Password Protect Parola koruması + + + Allow editing + Düzenlenebilsin + + + + View only + Yalnız görüntüleme + Allow upload and editing @@ -4003,16 +4096,21 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş File drop (upload only) Dosya bırakma (yalnız yükleme) - - - Note to recipient - Alıcıya not - Unshare Paylaşımdan kaldır + + + Link name + Bağlantı adı + + + + Note to recipient + Alıcıya not + Password protect @@ -4024,15 +4122,20 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Son kullanma tarihini ayarla - - Delete share link - Paylaşım bağlantısını sil + + Delete link + Bağlantıyı sil Add another link Başka bir bağlantı ekle + + + Delete share link + Paylaşım bağlantısını sil + Confirm Link Share Deletion @@ -4082,7 +4185,7 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş '%1' için bir sonuç bulunamadı - + No results for "%1" "%1" için bir sonuç bulunamadı @@ -4186,12 +4289,6 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - %1 ile paylaş - Context menu share @@ -4218,10 +4315,16 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Share via %1 %1 ile paylaş + + + + Activity + İşlem + Copy private link to clipboard - Özel bağlantıyı panoya kopyala + Kişisel bağlantıyı panoya kopyala @@ -4289,6 +4392,12 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Delete Sil + + + Share with %1 + parameter is Nextcloud + %1 ile paylaş + OCC::SslButton @@ -4434,6 +4543,11 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Cannot connect securely to <i>%1</i>: <i>%1</i> ile güvenli bağlantı kurulamadı: + + + Additional errors: + Ek hatalar: + with Certificate %1 @@ -4608,6 +4722,11 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Placeholders are postfixed with file sizes using Utility::octetsToString() Yalnız %1 kullanılabilir, başlatabilmek için en az %2 gerekli + + + Aborted + Vazgeçildi + @@ -4760,27 +4879,88 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Invalid characters, please rename "%1" Karakterler geçersiz, lütfen "%1" ögesini yeniden adlandırın + + + Synchronization will resume shortly. + Eşitleme kısa bir süre sonra sürdürülecek + File name contains at least one invalid character Dosya adında en az bir geçersiz karakter var - - Aborted - Vazgeçildi - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Disk alanı azaldı: Boş alanı %1 değerinin altına düşürecek indirmeler atlandı. - + There is insufficient space available on the server for some uploads. Sunucu üzerinde bazı yüklemeleri kaydetmek için yeterli alan yok. + + OCC::SyncStatusSummary + + + + Offline + Çevrimdışı + + + + + + All synced! + Tümü eşitlendi! + + + + Some files couldn't be synced! + Bazı dosyalar eşitlenemedi! + + + + See below for errors + Hatalar için aşağıya bakın + + + + Syncing + Eşitleniyor + + + + Sync paused + Eşitleme duraklatıldı + + + + Some files could not be synced! + Bazı dosyalar eşitlenemedi! + + + + See below for warnings + Uyarılar için aşağıya bakın + + + + %1 of %2 · %3 left + %1 of %2 · %3 kaldı + + + + %1 of %2 + %1 / %2 + + + + Syncing file %1 of %2 + %1 / %2 dosya eşitleniyor + + OCC::Systray @@ -4856,6 +5036,29 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş <p>Bu sürüm %1 tarafından hazırlanmıştır</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + Hizmet sağlayıcılar alınamadı. + + + + Failed to fetch search providers for '%1'. Error: %2 + '%1' için hizmet sağlayıcılar alınamadı. Hata: %2 + + + + Search has failed for '%2'. + '%2' için arama yapılamadı. + + + + Search has failed for '%1'. Error: %2 + '%1' için arama yapılamadı. Hata: %2 + + OCC::User @@ -4913,24 +5116,108 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - Sanal dosya sistemi özelliği için NTFS dosya sistemi gereklidir. %1, %2 kullanıyor + + Could not fetch predefined statuses. Make sure you are connected to the server. + Hazır durumlar alınamadı. Sunucuya bağlı olduğunuzdan emin olun. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - Uçtan uca şifrelenmiş dosya indirilemedi + + Could not fetch user status. Make sure you are connected to the server. + Kullanıcı durumu alınamadı. Sunucuya bağlı olduğunuzdan emin olun. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - Görünüşe göre uçtan uca şifrelenmiş sanal bir dosyayı indirmeye çalışıyorsunuz. Şu anda bu tür dosyaların örtülü olarak indirilmesi desteklenmiyor. Bu sorunu çözmek için, ayarlar bölümüne giderek, şifrelenmiş klasör için "Her zaman yerel olarak kullanılabilsin" seçeceğini etkinleştirin. + + User status feature is not supported. You will not be able to set your user status. + Kullanıcı durumu özelliği desteklenmiyor. Kullanıcı durumu ayarlanamayabilir. + + + + Emojis feature is not supported. Some user status functionality may not work. + Emoji özelliği desteklenmiyor. Bazı kullanıcı durumu işlevleri çalışmayabilir. + + + + Could not set user status. Make sure you are connected to the server. + Kullanıcı durumu ayarlanamadı. Sunucuya bağlı olduğunuzdan emin olun. + + + + Could not clear user status message. Make sure you are connected to the server. + Kullanıcı durumu iletisi kaldırılamadı. Sunucuya bağlı olduğunuzdan emin olun. + + + + + Don't clear + Kaldırılmasın + + + + 30 minutes + 30 dakika + + + + + 1 hour + 1 saat + + + + 4 hours + 4 saat + + + + + Today + Bugün + + + + + This week + Bu hafta + + + + Less than a minute + 1 dakikadan az + + + + 1 minute + 1 dakika + + + + %1 minutes + %1 dakika + + + + %1 hours + %1 saat + + + + 1 day + 1 gün + + + + %1 days + %1 gün + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + Sanal dosya sistemi özelliği için NTFS dosya sistemi gereklidir. %1, %2 kullanıyor @@ -5447,14 +5734,6 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş %1 oturumunuzu açın - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Tüm hesabınız yerel klasör ile eşitlendi - - QObject @@ -5547,6 +5826,38 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Veritabanı bağlantısı kurulamadı. + + UnifiedSearchInputContainer + + + Search files, messages, events … + Dosya, ileti, etkinlik arayın … + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + Diğer sonuçları yükle + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + Arama sonuçları iskeleti. + + + + UnifiedSearchResultListItem + + + Load more results + Diğer sonuçları yükle + + UserLine @@ -5561,29 +5872,39 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş - Current user status is online - Geçerli kullanıcı durumu çevrimiçi + Account connected + Hesap bağlandı - Current user status is do not disturb - Geçerli kullanıcı durumu rahatsız etmeyin + Account not connected + Hesap bağlanmadı - Account connected - Hesap bağlandı + Current user status is online + Geçerli kullanıcı durumu çevrimiçi - Account not connected - Hesap bağlanmadı + Current user status is do not disturb + Geçerli kullanıcı durumu rahatsız etmeyin Account actions Hesap işlemleri + + + Remove Account + Hesabı sil + + + + Set status + Durumu ayarla + @@ -5596,17 +5917,65 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Log in Oturum aç - - - Remove Account - Hesabı sil - Remove account Hesabı sil + + UserStatusSelector + + + Online status + Çevrimiçi durumu + + + + Online + Çevrimiçi + + + + Away + Uzakta + + + + Do not disturb + Rahatsız etmeyin + + + + Invisible + Görünmez + + + + Status message + Durum iletisi + + + + What is your status? + Durumunuz nedir? + + + + Clear status message after + Durum iletisinin kaldırılma süresi + + + + Clear status message + Durum iletisini kaldır + + + + Set status message + Durum iletisini ayarla + + Utility @@ -5668,12 +6037,12 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş ValidateChecksumHeader - + The checksum header is malformed. Sağlama üst bilgisi bozulmuş. - + The checksum header contained an unknown checksum type '%1' Sağlama üst bilgisinde bulunan '%1' sağlama türü bilinmiyor @@ -5683,17 +6052,17 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş İndirilen dosya sağlama değerine uygun değil, yeniden indirilecek. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' İndirilen dosya sağlama değerine uygun değil, yeniden indirilecek. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" Sağlama üst bilgisinde bulunan "%1" sağlama türü bilinmiyor - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" İndirilen dosya sağlama değerine uygun değil, yeniden indirilecek. "%1" != "%2" @@ -5722,6 +6091,11 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Pause sync for all Tümünü eşitlemeyi duraklat + + + Set user status + Kullanıcı durumunu ayarla + Add account @@ -5757,12 +6131,6 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Current user status is do not disturb Geçerli kullanıcı durumu rahatsız etmeyin - - - - Show more actions - Diğer işlemleri görüntüle - Share %1 @@ -5823,6 +6191,22 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Open share dialog Paylaşma penceresini aç + + + Unified search results list + Birleşik arama sonuçları listesi + + + + + Show more actions + Diğer işlemleri görüntüle + + + + %1 - File activity + %1 - Dosya işlemi + main.cpp @@ -6122,6 +6506,24 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Web tarayıcınızda oturum açın (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Her şey ayarlandı! + + + + Open Local Folder + Yerel klasörü aç + + + + Open %1 in Browser + %1 ögesini tarayıcıda aç + + OCC::ShibbolethCredentials @@ -6174,6 +6576,14 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Oturum aç + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Tüm hesabınız yerel klasör ile eşitlendi + + OCC::UserStatus @@ -6197,4 +6607,17 @@ Bu yeni ve deneysel bir özelliktir. Kullanmaya karar verirseniz, lütfen karş Çevrimiçi + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + Uçtan uca şifrelenmiş dosya indirilemedi + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + Görünüşe göre uçtan uca şifrelenmiş sanal bir dosyayı indirmeye çalışıyorsunuz. Şu anda bu tür dosyaların örtülü olarak indirilmesi desteklenmiyor. Bu sorunu çözmek için, ayarlar bölümüne giderek, şifrelenmiş klasör için "Her zaman yerel olarak kullanılabilsin" seçeceğini etkinleştirin. + + \ No newline at end of file diff --git a/translations/client_uk.ts b/translations/client_uk.ts index 6412fae6c9ff..4a71755affbf 100644 --- a/translations/client_uk.ts +++ b/translations/client_uk.ts @@ -14,6 +14,16 @@ Open %1 locally + + + Open share dialog + + + + + Share %1 + + @@ -21,13 +31,16 @@ - - Open share dialog + + View activity + + + ActivityList - - Share %1 + + Activity list @@ -130,7 +143,7 @@ - Could not move "%1" to "%1" + Could not move "%1" to "%2" @@ -1137,32 +1150,32 @@ This can be an issue with your OpenSSL libraries. Неможливо відкрити переглядач, будь ласка, скопіюйте посилання до вашого переглядача. - + Waiting for authorization Очікування на авторизацію - + Polling for authorization Запит на авторизацію - + Starting authorization Початок авторизації - + Link copied to clipboard. Посилання скопійовано - + Reopen Browser Перезавантажити браузер - + Copy Link Скопіювати посилання @@ -1327,6 +1340,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + + All files in the sync folder '%1' were deleted on the server. @@ -1380,22 +1400,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an Зберегти локальні файли як конфлікт - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1403,7 +1408,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1419,6 +1424,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + + Keep files @@ -2245,6 +2258,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from Додати новий шаблон для ігнорування: + + OCC::InvalidFilenameDialog + + + Invalid filename + + + + + The file could not be synced because it contains characters which are not allowed on this system. + + + + + Error + + + + + Please enter a new name for the file: + + + + + New filename + + + + + Rename file + + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + + + + + Filename contains illegal characters: %1 + + + + + Could not rename file. Please make sure you are connected to the server. + + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + + + OCC::LegalNotice @@ -2380,7 +2456,7 @@ Logs will be written to %1 <nobr>Файл '%1'<br/>не вдається відкрити на запис.<br/><br/>Журнал <b>не</b> можливо зберегти!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> @@ -2423,6 +2499,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + + Ask again later @@ -2592,6 +2673,12 @@ Logs will be written to %1 New %1 Update Ready Доступне оновлення %1 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + Буде встановлено оновлення для %1. Програма оновлення може запитати додаткові привілеї. + New %1 update ready @@ -2599,9 +2686,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - Буде встановлено оновлення для %1. Програма оновлення може запитати додаткові привілеї. + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + @@ -2638,6 +2724,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + + Could not download update. Please open %1 to download the update manually. @@ -2648,6 +2739,11 @@ for additional privileges during the process. Could not check for new updates. Не вдалося перевірити наявність оновлень. + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + + New %1 is available. Please open %2 to download the update. @@ -2944,37 +3040,37 @@ It is not advisable to use it. Перевищено час очікування з'єднання до %1 на %2. - + Trying to connect to %1 at %2 … З'єднання з %1 через %2... - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. Запит аутентифікації до серверу було переадресовано до '%1'. Поганий URL, сервер сконфігуровано неправильно. - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. Доступ заборонений сервером. Щоб довести, що у Вас є права доступу, <a href="%1">клікніть тут</a> для входу через Ваш браузер. - + There was an invalid response to an authenticated WebDAV request Отримано неправильну відповідь на запит авторизації WebDAV. - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> Локальна тека синхронізації %1 вже існує, налаштування її для синхронізації.<br/><br/> - + Creating local sync folder %1 … Створення локальної теки для синхронізації %1... @@ -2984,84 +3080,84 @@ It is not advisable to use it. ok - + OK - + failed. не вдалося. - + Could not create local folder %1 Не вдалося створити локальну теку $1 - + No remote folder specified! Не вказано віддалену теку! - + Error: %1 Помилка: %1 - + creating folder on Nextcloud: %1 створення теки на Nextcloud: %1 - + Remote folder %1 created successfully. Віддалена тека %1 успішно створена. - + The remote folder %1 already exists. Connecting it for syncing. Віддалена тека %1 вже існує. Під'єднання для синхронізації. - - + + The folder creation resulted in HTTP error code %1 Створення теки завершилось HTTP помилкою %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> Створити віддалену теку не вдалося через невірно вказані облікові дані.<br/>Поверніться назад та перевірте облікові дані.</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">Створити віддалену теку не вдалося, можливо, через невірно вказані облікові дані.</font><br/>Будь ласка, поверніться назад та перевірте облікові дані.</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. Не вдалося створити віддалену теку %1 через помилку <tt>%2</tt>. - + A sync connection from %1 to remote directory %2 was set up. З'єднання для синхронізації %1 з віддаленою текою %2 було встановлено. - + Successfully connected to %1! Успішно під'єднано до %1! - + Connection to %1 could not be established. Please check again. Підключення до %1 встановити не вдалося. Будь ласка, перевірте ще раз. - + Folder rename failed Не вдалося перейменувати теку @@ -3071,28 +3167,28 @@ It is not advisable to use it. Неможливо вилучити теку та створити її резервну копію, оскільки тека або файли, що в ній розташовані, використовуються. Будь ласка, закрийте всі програми, що можуть використовувати цю теку та спробуйте ще раз, або скасуйте встановлення. - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>Локальна тека синхронізації %1 успішно створена!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - Майстер з'єднання %1 - Add %1 account + + + %1 Connection Wizard + Майстер з'єднання %1 + Skip folders configuration @@ -3125,24 +3221,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OCC::OwncloudWizardResultPage - - - Everything set up! - Усе налаштовано! - - - - Open Local Folder - Відкрити локальну теку - - - - Open %1 in Browser - Відкрити %1 в Браузері - - OCC::PollJob @@ -3153,6 +3231,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + + Symbolic links are not supported in syncing. @@ -3170,12 +3258,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. @@ -3304,7 +3392,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss - + Server replied with an error while reading directory "%1" : %2 @@ -3919,11 +4007,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing Дозволити редагування - - - Allow editing - Може редагувати - Read only @@ -3944,6 +4027,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect Захищено паролем + + + Allow editing + Може редагувати + + + + View only + + Allow upload and editing @@ -3959,16 +4052,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) Сховище (тільки завантажування) - - - Note to recipient - Примітка для одержувача - Unshare Скасувати загальний доступ + + + Link name + + + + + Note to recipient + Примітка для одержувача + Password protect @@ -3980,15 +4078,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss Встановити термін дії - - Delete share link - Вилучити посилання для спільного використання + + Delete link + Add another link Додати ще одне посилання + + + Delete share link + Вилучити посилання для спільного використання + Confirm Link Share Deletion @@ -4038,7 +4141,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss Відсутні результати для '%1' - + No results for "%1" @@ -4142,12 +4245,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - Поділитися з %1 - Context menu share @@ -4174,6 +4271,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 Поділитися за допомогою %1 + + + + Activity + + Copy private link to clipboard @@ -4245,6 +4348,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete Вилучити + + + Share with %1 + parameter is Nextcloud + Поділитися з %1 + OCC::SslButton @@ -4390,6 +4499,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: Неможливо встановити безпечне з'єднання з <i>%1</i>: + + + Additional errors: + + with Certificate %1 @@ -4564,6 +4678,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() Доступно лише %1, для початку необхідно хоча б %2 + + + Aborted + + @@ -4716,27 +4835,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" Помилкові символи, будь ласка, перейменуйте "%1" + + + Synchronization will resume shortly. + + File name contains at least one invalid character Ім’я файлу містить принаймні один некоректний символ - - Aborted - - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. Закінчується місце на диску. Звантаження, які можуть зменшити вільне місце до 1% буде пропущено. - + There is insufficient space available on the server for some uploads. Недостатньо місця на сервері для окремих завантажень. + + OCC::SyncStatusSummary + + + + Offline + + + + + + + All synced! + + + + + Some files couldn't be synced! + + + + + See below for errors + + + + + Syncing + + + + + Sync paused + + + + + Some files could not be synced! + + + + + See below for warnings + + + + + %1 of %2 · %3 left + + + + + %1 of %2 + + + + + Syncing file %1 of %2 + + + OCC::Systray @@ -4812,6 +4992,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>Цю збірку поставлено %1</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + + + + + Failed to fetch search providers for '%1'. Error: %2 + + + + + Search has failed for '%2'. + + + + + Search has failed for '%1'. Error: %2 + + + OCC::User @@ -4869,23 +5072,107 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed + + Could not fetch user status. Make sure you are connected to the server. - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + User status feature is not supported. You will not be able to set your user status. + + + + + Emojis feature is not supported. Some user status functionality may not work. + + + + + Could not set user status. Make sure you are connected to the server. + + + + + Could not clear user status message. Make sure you are connected to the server. + + + + + + Don't clear + + + + + 30 minutes + + + + + + 1 hour + + + + + 4 hours + + + + + + Today + + + + + + This week + + + + + Less than a minute + + + + + 1 minute + + + + + %1 minutes + + + + + %1 hours + + + + + 1 day + + + + + %1 days + + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 @@ -5403,14 +5690,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - Ваш запис цілком синхронізовано із локальною текою - - QObject @@ -5503,6 +5782,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + UnifiedSearchInputContainer + + + Search files, messages, events … + + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + + + + + UnifiedSearchResultListItem + + + Load more results + + + UserLine @@ -5517,22 +5828,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - + Account connected + Обліковий запис під’єднано - Current user status is do not disturb + Account not connected - Account connected - Обліковий запис під’єднано + Current user status is online + - Account not connected + Current user status is do not disturb @@ -5540,6 +5851,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Account actions + + + Remove Account + + + + + Set status + + @@ -5552,17 +5873,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in Увійти - - - Remove Account - - Remove account Вилучити обліковий запис + + UserStatusSelector + + + Online status + + + + + Online + + + + + Away + + + + + Do not disturb + + + + + Invisible + + + + + Status message + + + + + What is your status? + + + + + Clear status message after + + + + + Clear status message + + + + + Set status message + + + Utility @@ -5624,12 +5993,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. Контрольна сума заголовку неправильно сформовано. - + The checksum header contained an unknown checksum type '%1' Контрольна сума заголовку містила невідомий вид контрольної суми '%1' @@ -5639,17 +6008,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss Контрольна сума звантаженого файлу неправильна, буде продовжено. - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' - + The checksum header contained an unknown checksum type "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" @@ -5678,6 +6047,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all + + + Set user status + + Add account @@ -5713,12 +6087,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb - - - - Show more actions - - Share %1 @@ -5779,6 +6147,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog + + + Unified search results list + + + + + + Show more actions + + + + + %1 - File activity + + main.cpp @@ -6078,6 +6462,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss Увійдіть у вашому переглядачі (процес входу v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + Усе налаштовано! + + + + Open Local Folder + Відкрити локальну теку + + + + Open %1 in Browser + Відкрити %1 в Браузері + + OCC::ShibbolethCredentials @@ -6130,6 +6532,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss Увійти + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + Ваш запис цілком синхронізовано із локальною текою + + OCC::UserStatus @@ -6153,4 +6563,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + + + \ No newline at end of file diff --git a/translations/client_zh_CN.ts b/translations/client_zh_CN.ts index d52517c64933..329793050709 100644 --- a/translations/client_zh_CN.ts +++ b/translations/client_zh_CN.ts @@ -14,12 +14,6 @@ Open %1 locally 在本地打开 %1 - - - - Show more actions - 显示更多操作 - Open share dialog @@ -30,6 +24,25 @@ Share %1 共享 %1 + + + + Show more actions + 显示更多操作 + + + + View activity + 查看动态 + + + + ActivityList + + + Activity list + 动态列表 + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - 无法将 "%1" 移动至 "%1" + Could not move "%1" to "%2" + 无法将 "%1" 移动至 "%2" @@ -1140,32 +1153,32 @@ This can be an issue with your OpenSSL libraries. 无法打开浏览器,请将链接复制到您的浏览器。 - + Waiting for authorization 等待授权 - + Polling for authorization 轮询授权 - + Starting authorization 开始授权 - + Link copied to clipboard. 链接已复制到剪贴板。 - + Reopen Browser 重新打开浏览器 - + Copy Link 复制链接 @@ -1334,6 +1347,13 @@ This means that the synchronization client might not upload local changes immedi %1 + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + 本地同步文件夹“%1”中的所有文件已被删除。这些删除将与您的服务器同步,使这些文件不可用,除非恢复。您确定要与服务器同步这些操作吗?如果这是一个意外,您决定保留您的文件,它们将从服务器重新同步。 + All files in the sync folder '%1' were deleted on the server. @@ -1394,22 +1414,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an 保留本地文件为冲突文件 - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - 同步文件夹 '%1' 文件夹中的所有文件已在服务器上被删除。这些删除将同步到您的本地同步文件夹,使这些文件不可用,除非您有权恢复。如果您决定恢复这些文件,它们将与服务器重新同步,前提是您有这么做的权利。如果您决定删除这些文件,它们对您将不可用,除非您是所有者。 - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - 本地同步文件夹“%1”中的所有文件已被删除。这些删除将与您的服务器同步,使这些文件不可用,除非恢复。您确定要与服务器同步这些操作吗?如果这是一个意外,您决定保留您的文件,它们将从服务器重新同步。 - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1420,7 +1425,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a 如果您决定删除文件,它们将对您不可用,除非您是所有者。 - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1438,6 +1443,14 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files 移除所有文件 + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + 同步文件夹 '%1' 文件夹中的所有文件已在服务器上被删除。这些删除将同步到您的本地同步文件夹,使这些文件不可用,除非您有权恢复。如果您决定恢复这些文件,它们将与服务器重新同步,前提是您有这么做的权利。如果您决定删除这些文件,它们对您将不可用,除非您是所有者。 + Keep files @@ -2268,6 +2281,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from 添加新的忽略模式: + + OCC::InvalidFilenameDialog + + + Invalid filename + 无效文件名 + + + + The file could not be synced because it contains characters which are not allowed on this system. + 不能同步此文件,因为其名称包含了这个系统不允许的字符。 + + + + Error + 错误 + + + + Please enter a new name for the file: + 请输入新文件名: + + + + New filename + 新文件名 + + + + Rename file + 重命名文件 + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + 无法同步文件 %1 ,因它的名称包含了此系统不允许的字符 + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + 此系统不允许下列字符: * " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + 您没有重命名此文件的权限。请文件的作者重新命名它。 + + + + Filename contains illegal characters: %1 + 文件名包含非法字符:%1 + + + + Could not rename file. Please make sure you are connected to the server. + 无法重命名文件。请确保您已连接到服务器。 + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + 无法重命名文件,因为服务器上已经存在同名文件。请换一个名字。 + + OCC::LegalNotice @@ -2405,7 +2481,7 @@ Logs will be written to %1 <nobr>文件 '%1'<br/>不能写入。<br/><br/>将<b>不</b>能保存日志输出!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> 无法打开<nobr>文件 "%1"<br/>进行写入。<br/><br/>日志输出<b>无法</b>被保存!</nobr> @@ -2448,6 +2524,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>新版本的 %1 客户端可用但是更新失败。</p><p><b>%2</b> 已经开放下载。已安装的版本是 %3。</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>%1 客户端有新版本可用但更新过程失败。</p><p><b>%2</b>已下载。已安装版本为 %3。如果您确认重新启动和更新,您的计算机可能需要重启以完成安装。</p> + Ask again later @@ -2617,6 +2698,13 @@ Logs will be written to %1 New %1 Update Ready 新的 %1 更新就绪 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + 新版本 %1 已经可以更新。 +更新过程可能会请求额外的权限。 + New %1 update ready @@ -2624,10 +2712,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - 新版本 %1 已经可以更新。 -更新过程可能会请求额外的权限。 + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + 即将安装 %1 的新更新。更新程序可能会在此过程中要求额外的特权。您的计算机可能需要重新启动以完成安装。 @@ -2664,6 +2750,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. 新的 %1 现在可用。请点击 <a href='%2'>此处</a>以下载更新。 + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + 无法下载更新。请打开 <a href='%1'>%1</a>手动下载更新 + Could not download update. Please open %1 to download the update manually. @@ -2674,6 +2765,11 @@ for additional privileges during the process. Could not check for new updates. 无法检查新更新。 + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + 有新的 %1 可用。请打开 <a href='%2'>%2</a>下载更新 + New %1 is available. Please open %2 to download the update. @@ -2970,37 +3066,37 @@ It is not advisable to use it. 连接到 %1 (%2) 时超时。 - + Trying to connect to %1 at %2 … 尝试连接到 %1 的 %2 … - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. 被发送到服务器的认证请求被重定向到 '%1'。此 URL 无效,服务器配置错误。 - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. 已通过身份验证的服务器请求被重定向到“%1”。URL 错误,服务器配置错误。 - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. 服务器拒绝了访问。<a href="%1">点击这里打开浏览器</a> 来确认您是否有权访问。 - + There was an invalid response to an authenticated WebDAV request 对已认证的 WebDAV 请求的响应无效 - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> 本地同步文件夹 %1 已存在,将使用它来同步。<br/><br/> - + Creating local sync folder %1 … 正在新建本地同步文件夹 %1 … @@ -3010,84 +3106,84 @@ It is not advisable to use it. 成功 - + OK - + failed. 失败 - + Could not create local folder %1 不能创建本地文件夹 %1 - + No remote folder specified! 未指定远程文件夹! - + Error: %1 错误:%1 - + creating folder on Nextcloud: %1 在 Nextcloud 上创建文件夹:%1 - + Remote folder %1 created successfully. 远程文件夹 %1 成功创建。 - + The remote folder %1 already exists. Connecting it for syncing. 远程文件夹 %1 已存在。连接它以供同步。 - - + + The folder creation resulted in HTTP error code %1 创建文件夹出现 HTTP 错误代码 %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> 远程文件夹创建失败,因为提供的凭证有误!<br/>请返回并检查您的凭证。</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">远程文件夹创建失败,可能是由于提供的用户名密码不正确。</font><br/>请返回并检查它们。</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. 创建远程文件夹 %1 失败,错误为 <tt>%2</tt>。 - + A sync connection from %1 to remote directory %2 was set up. 已经设置了一个 %1 到远程文件夹 %2 的同步连接 - + Successfully connected to %1! 成功连接到了 %1! - + Connection to %1 could not be established. Please check again. 无法建立到 %1 的链接,请稍后重试。 - + Folder rename failed 文件夹更名失败 @@ -3097,28 +3193,28 @@ It is not advisable to use it. 无法移除和备份文件夹,由于文件夹或文件正在被另一程序占用。请关闭程序后重试,或取消安装。 - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. 无法删除和备份该文件夹,因为其中的文件夹或文件在另一个程序中打开。请关闭文件夹或文件,然后点击重试或取消安装。 - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>本地同步目录 %1 已成功创建</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 链接向导 - Add %1 account 添加 %1 个账户 + + + %1 Connection Wizard + %1 链接向导 + Skip folders configuration @@ -3151,24 +3247,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 保持安全 - - OCC::OwncloudWizardResultPage - - - Everything set up! - 一切都设置好了! - - - - Open Local Folder - 打开本地文件夹 - - - - Open %1 in Browser - 在浏览器中打开 %1 - - OCC::PollJob @@ -3179,6 +3257,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + 文件名包含尾随空格,无法重命名,因为服务器上已经存在同名文件。 + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + 文件名包含尾随空格,无法重命名,因为本地已经存在同名文件。 + Symbolic links are not supported in syncing. @@ -3194,16 +3282,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. 此文件系统不支持以句点结尾的文件名。 - - - File names containing the character "%1" are not supported on this file system. - 此文件系统不支持包含字符“%1”的文件名 - File names containing the character '%1' are not supported on this file system. 此文件系统不支持包含字符 '%1' 的文件名 + + + File names containing the character "%1" are not supported on this file system. + 此文件系统不支持包含字符“%1”的文件名 + File name contains at least one invalid character @@ -3330,7 +3418,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss 服务器在读取目录 '%1' 时回复了一个错误:%2 - + Server replied with an error while reading directory "%1" : %2 服务器在读取目录 "%1" 时返回了一个错误: %2 @@ -3945,11 +4033,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing 允许编辑 - - - Allow editing - 允许编辑 - Read only @@ -3970,6 +4053,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect 密码保护 + + + Allow editing + 允许编辑 + + + + View only + 仅查看 + Allow upload and editing @@ -3985,16 +4078,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) 文件拖拽(仅上传) - - - Note to recipient - 接收人备注 - Unshare 取消共享 + + + Link name + 链接名称 + + + + Note to recipient + 接收人备注 + Password protect @@ -4006,15 +4104,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss 设置过期日期 - - Delete share link - 删除共享链接 + + Delete link + 删除链接 Add another link 添加其他链接 + + + Delete share link + 删除共享链接 + Confirm Link Share Deletion @@ -4064,7 +4167,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss 没有 '%1' 相关结果 - + No results for "%1" 没有 "%1"相关结果 @@ -4168,12 +4271,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - 共享给 %1 - Context menu share @@ -4200,6 +4297,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 通过 %1 共享 + + + + Activity + 动态 + Copy private link to clipboard @@ -4271,6 +4374,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete 删除 + + + Share with %1 + parameter is Nextcloud + 共享给 %1 + OCC::SslButton @@ -4416,6 +4525,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: 无法安全连接到 <i>%1</i>: + + + Additional errors: + 其他错误: + with Certificate %1 @@ -4590,6 +4704,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() 仅有 %1 有效,至少需要 %2 才能开始 + + + Aborted + 已中断 + @@ -4742,27 +4861,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" 无效的字符,请更改为 “%1” + + + Synchronization will resume shortly. + 同步将很快恢复。 + File name contains at least one invalid character 文件名中存在至少一个非法字符 - - Aborted - 已中断 - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. 硬盘剩余容量过低:下载后将会导致剩余容量低于 %1 的文件将会被跳过。 - + There is insufficient space available on the server for some uploads. 对于某些上传文件来说,服务器端的可用空间不足。 + + OCC::SyncStatusSummary + + + + Offline + 离线 + + + + + + All synced! + 已同步所有文件! + + + + Some files couldn't be synced! + 无法同步某些文件! + + + + See below for errors + 查看下方错误 + + + + Syncing + 同步中 + + + + Sync paused + 同步已暂停 + + + + Some files could not be synced! + 某些文件无法同步! + + + + See below for warnings + 查看下方警告 + + + + %1 of %2 · %3 left + %2 中的 %1 · %3 剩余 + + + + %1 of %2 + %2 中的 %1 + + + + Syncing file %1 of %2 + 正在同步 %2 中的 %1 + + OCC::Systray @@ -4838,6 +5018,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>该版本由 %1 提供</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + 获取提供商失败 + + + + Failed to fetch search providers for '%1'. Error: %2 + 未能获取 ''%1' 的搜索提供商。错误: %2 + + + + Search has failed for '%2'. + 搜索 '%2' 失败 + + + + Search has failed for '%1'. Error: %2 + 搜索“%1”失败。错误:%2 + + OCC::User @@ -4895,24 +5098,108 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - 虚拟文件系统特性需要一个NTFS文件系统,%1 正使用 %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + 无法获取预定义状态。确保您已连接到服务器。 - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - 下载端到端加密文件失败 + + Could not fetch user status. Make sure you are connected to the server. + 无法获取用户状态。确保您已连接到服务器。 - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - 你似乎正尝试下载一个端到端加密的虚拟文件。目前不支持隐式下载此类文件。要解决此问题,请进入设置,并将加密文件夹标记为“始终在本地可用”。 + + User status feature is not supported. You will not be able to set your user status. + 不支持用户状态特性。您将无法设置您的用户状态。 + + + + Emojis feature is not supported. Some user status functionality may not work. + 不支持表情符号功能。某些用户状态功能可能无法工作。 + + + + Could not set user status. Make sure you are connected to the server. + 无法设置用户状态。确保您已连接到服务器。 + + + + Could not clear user status message. Make sure you are connected to the server. + 无法清除用户状态信息。确保您已连接到服务器。 + + + + + Don't clear + 不要清除 + + + + 30 minutes + 30 分钟 + + + + + 1 hour + 1 小时 + + + + 4 hours + 4 小时 + + + + + Today + 今日 + + + + + This week + 本周 + + + + Less than a minute + 不到一分钟 + + + + 1 minute + 1 分钟 + + + + %1 minutes + %1 分钟 + + + + %1 hours + %1 小时 + + + + 1 day + 1 天 + + + + %1 days + %1 天 + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + 虚拟文件系统特性需要一个NTFS文件系统,%1 正使用 %2 @@ -5429,14 +5716,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 登陆到您的 %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - 您的整个账号将被同步到本地文件夹 - - QObject @@ -5529,6 +5808,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss 未能连接至数据库 + + UnifiedSearchInputContainer + + + Search files, messages, events … + 搜索文件、消息、事件... + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + 加载更多结果 + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + 搜索结果骨架 + + + + UnifiedSearchResultListItem + + + Load more results + 加载更多结果 + + UserLine @@ -5543,29 +5854,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - 当前用户状态为“在线” + Account connected + 账号已连接 - Current user status is do not disturb - 当前用户状态为“请勿打扰” + Account not connected + 账号未连接 - Account connected - 账号已连接 + Current user status is online + 当前用户状态为“在线” - Account not connected - 账号未连接 + Current user status is do not disturb + 当前用户状态为“请勿打扰” Account actions 账号操作 + + + Remove Account + 移除账号 + + + + Set status + 设置状态 + @@ -5578,17 +5899,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in 登录 - - - Remove Account - 移除账号 - Remove account 移除账号 + + UserStatusSelector + + + Online status + 在线状态 + + + + Online + 在线 + + + + Away + 离开 + + + + Do not disturb + 勿扰 + + + + Invisible + 不可见 + + + + Status message + 状态消息 + + + + What is your status? + 你什么状态? + + + + Clear status message after + 在指定时间段后清除状态消息 + + + + Clear status message + 清除状态消息 + + + + Set status message + 设置状态消息 + + Utility @@ -5650,12 +6019,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. 校验码头部无效。 - + The checksum header contained an unknown checksum type '%1' 校验码头部包含未知的校验类型 '%1' @@ -5665,17 +6034,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 下载的文件校验信息不匹配,将重新下载。 - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' 下载的文件与校验和不匹配,它将被继续。'%1' != '%2' - + The checksum header contained an unknown checksum type "%1" 校验和头包含未知的校验和类型 "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" 已下载的文件和校验和不匹配,它将被继续下载。"%1" != "%2" @@ -5704,6 +6073,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all 全部暂停同步 + + + Set user status + 设定用户状态 + Add account @@ -5739,12 +6113,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb 当前用户状态为“请勿打扰” - - - - Show more actions - 显示更多操作 - Share %1 @@ -5805,6 +6173,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog 打开共享对话框 + + + Unified search results list + 统一的搜索结果列表 + + + + + Show more actions + 显示更多操作 + + + + %1 - File activity + %1 - 文件动态 + main.cpp @@ -6104,6 +6488,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss 在您的浏览器中登录(Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + 一切都设置好了! + + + + Open Local Folder + 打开本地文件夹 + + + + Open %1 in Browser + 在浏览器中打开 %1 + + OCC::ShibbolethCredentials @@ -6156,6 +6558,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss 登录 + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + 您的整个账号将被同步到本地文件夹 + + OCC::UserStatus @@ -6179,4 +6589,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 在线 + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + 下载端到端加密文件失败 + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + 你似乎正尝试下载一个端到端加密的虚拟文件。目前不支持隐式下载此类文件。要解决此问题,请进入设置,并将加密文件夹标记为“始终在本地可用”。 + + \ No newline at end of file diff --git a/translations/client_zh_HK.ts b/translations/client_zh_HK.ts index a3a4dd6cdf81..2a67eb7adc30 100644 --- a/translations/client_zh_HK.ts +++ b/translations/client_zh_HK.ts @@ -14,12 +14,6 @@ Open %1 locally 在近端打開 %1 - - - - Show more actions - 顯示更多操作 - Open share dialog @@ -30,6 +24,25 @@ Share %1 分享 %1 + + + + Show more actions + 顯示更多操作 + + + + View activity + 檢視活動紀錄 + + + + ActivityList + + + Activity list + 活動紀錄清單 + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - 無法將 "%1" 移動至 "%1" + Could not move "%1" to "%2" + 無法將 "%1" 移動至 "%2" @@ -1144,32 +1157,32 @@ This can be an issue with your OpenSSL libraries. 無法開啟瀏覽器。請將連結複製到瀏覽器中。 - + Waiting for authorization 等候驗證中 - + Polling for authorization 輪詢驗證中 - + Starting authorization 開始驗證 - + Link copied to clipboard. 已複製連結至剪貼板 - + Reopen Browser 重新開啟瀏覽器 - + Copy Link 複製連結 @@ -1336,6 +1349,15 @@ This means that the synchronization client might not upload local changes immedi 客戶端可能無法及時上傳近端的更動,而只能每隔一段時間(預設為2小時)才掃描及上傳一次近端變更。 %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + 近端同步資料夾'%1'中的所有檔案都已刪除。這些刪除將與您的伺服器同步,除非恢復,否則此類檔案將不可用。 +您確定要與伺服器同步這些操作嗎? +如果您意外刪除了檔案並決定保留它們,則它們將從伺服器重新同步。 @@ -1397,27 +1419,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an 將近端檔案視為抵觸檔案 - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - 「%1」資料夾中的所有檔案已從伺服器上移除。 -同步後,這些檔案也會從您的近端資料夾中移除。除非您有復原的權限,否則您將無法讀取這些檔案。 -假如您決定復原這些檔案,只要您擁有權限,這些檔案就會重新和伺服器同步。 -假如您決定移除這些檔案,除非您是檔案的所有者,否則您將無法讀取這些檔案。 - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - 近端同步資料夾'%1'中的所有檔案都已刪除。這些刪除將與您的伺服器同步,除非恢復,否則此類檔案將不可用。 -您確定要與伺服器同步這些操作嗎? -如果您意外刪除了檔案並決定保留它們,則它們將從伺服器重新同步。 - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1428,7 +1430,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a 假如您決定刪除這些檔案,除非您是檔案的所有者,否則您將無法讀取這些檔案。 - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1446,6 +1448,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files 移除所有檔案 + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + 「%1」資料夾中的所有檔案已從伺服器上移除。 +同步後,這些檔案也會從您的近端資料夾中移除。除非您有復原的權限,否則您將無法讀取這些檔案。 +假如您決定復原這些檔案,只要您擁有權限,這些檔案就會重新和伺服器同步。 +假如您決定移除這些檔案,除非您是檔案的所有者,否則您將無法讀取這些檔案。 + Keep files @@ -2276,6 +2289,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from 新增要略過的檔案模式: + + OCC::InvalidFilenameDialog + + + Invalid filename + 檔案名稱無效 + + + + The file could not be synced because it contains characters which are not allowed on this system. + 無法同步檔案,因為檔案名包含此系統不允許的字符。 + + + + Error + 錯誤 + + + + Please enter a new name for the file: + 請輸入新檔案名稱: + + + + New filename + 新檔案名稱 + + + + Rename file + 重新命名檔案 + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + 無法同步檔案 %1,因為檔案名包含此系統不允許的字符。 + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + 系統不允許使用以下字符:* " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + 您無權重命名此檔案。 請要求檔案的擁有者重命名它。 + + + + Filename contains illegal characters: %1 + 檔案名含有非法字符:%1 + + + + Could not rename file. Please make sure you are connected to the server. + 無法重命名檔案。 請確保您已連接到伺服器。 + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + 無法重命名檔案,因為伺服器上已存在同名檔案。 請選擇另一個名字。 + + OCC::LegalNotice @@ -2416,7 +2492,7 @@ Logs will be written to %1 <nobr>檔案 '%1'<br/>無法開啟與寫入<br/><br/>記錄 <b>無法</b> 被儲存</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>檔案 "%1" <br/>無法開啟供寫入。<br/><br/>記錄<b>無法</b>保存!</nobr> @@ -2442,7 +2518,7 @@ Logs will be written to %1 Skip this time - 跳過這次更新 + 跳過此次更新 @@ -2459,6 +2535,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>%1 客戶端有新版本可用,但更新過程失敗。</p><p><b>%2</b> 可供下載, 目前安裝的版本是 %3。</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>%1 客戶端有新版本可用,但更新過程失敗。</p><p><b>%2</b> 已下載。 目前安裝的版本是 %3。如果您確認重新啟動和更新,您的電腦可能會重新啟動以完成安裝。</p> + Ask again later @@ -2628,6 +2709,13 @@ Logs will be written to %1 New %1 Update Ready 新 %1 更新已經就緒 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + 一個新的 %1 更新已經安裝完成。更新也許會詢問 +要求給予權限在安裝的過程中。 + New %1 update ready @@ -2635,10 +2723,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - 一個新的 %1 更新已經安裝完成。更新也許會詢問 -要求給予權限在安裝的過程中。 + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + 一個新的 %1 更新已經安裝完成。更新也許會詢問要求給予權限在安裝的過程中。您的電腦可能會重新啟動以完成安裝。 @@ -2675,6 +2761,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. 新版本 %1 已可以更新,請點選 <a href='%2'>這裡</a> 下載更新。 + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + 無法下載更新。 請打開 <a href='%1'>%1</a> 以手動下載更新。 + Could not download update. Please open %1 to download the update manually. @@ -2685,6 +2776,11 @@ for additional privileges during the process. Could not check for new updates. 無法檢查是否有新更新檔。 + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + 新版本 %1 已可以更新,請點選 <a href='%2'>%2</a> 以下載更新。 + New %1 is available. Please open %2 to download the update. @@ -2908,7 +3004,7 @@ for additional privileges during the process. The link to your %1 web interface when you open it in the browser. %1 will be replaced with the application name - 在瀏覽器中打開 %1 Web 介面的連結。 + 在瀏覽器中開啟您 %1 的網頁界面連結。 @@ -2981,37 +3077,37 @@ It is not advisable to use it. 從 %2 嘗試連線到 %1 逾時。 - + Trying to connect to %1 at %2 … 嘗試以 %1 身分連線到 %2 - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. - 伺服器要求的認證請求被導向 '%1',這個URL可能不安全,此伺服器可能設定有錯。 + 發送到伺服器的已驗證的請求已重定向到 “%1”。 此 URL 有錯,伺服器配置錯誤。 - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. 對伺服器的經過身份驗證的請求已重定向到 “%1”。 URL 有錯誤,伺服器配置亦有錯誤。 - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. 從伺服器存取被拒絕。為了正確驗證您的存取資訊 <a href="%1">請點選這裡</a> 透過瀏覽器來存取服務 - + There was an invalid response to an authenticated WebDAV request 伺服器回應 WebDAV 驗證請求不合法 - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> 近端同步資料夾%1已存在, 將其設置為同步<br/><br/> - + Creating local sync folder %1 … 正在新增本機同步資料夾 %1... @@ -3021,84 +3117,84 @@ It is not advisable to use it. ok - + OK OK - + failed. 失敗 - + Could not create local folder %1 無法建立近端資料夾 %1 - + No remote folder specified! 沒有指定遠端資料夾! - + Error: %1 錯誤: %1 - + creating folder on Nextcloud: %1 正在Nextcloud上新增資料夾:%1 - + Remote folder %1 created successfully. 遠端資料夾%1建立成功! - + The remote folder %1 already exists. Connecting it for syncing. 遠端資料夾%1已存在,連線同步中 - - + + The folder creation resulted in HTTP error code %1 在HTTP建立資料夾失敗, error code %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> 由於帳號或密碼錯誤,遠端資料夾建立失敗<br/>請檢查您的帳號密碼。</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">遠端資料夾建立失敗,也許是因為所提供的帳號密碼錯誤</font><br/>請重新檢查您的帳號密碼</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. 建立遠端資料夾%1發生錯誤<tt>%2</tt>失敗 - + A sync connection from %1 to remote directory %2 was set up. 從%1到遠端資料夾%2的連線已建立 - + Successfully connected to %1! 成功連接到 %1 ! - + Connection to %1 could not be established. Please check again. 無法建立連線%1, 請重新檢查 - + Folder rename failed 重新命名資料夾失敗 @@ -3108,28 +3204,28 @@ It is not advisable to use it. 無法移除與備份此資料夾,因為有其他的程式正在使用其中的資料夾或者檔案。請關閉使用中的資料夾或檔案並重試或者取消設定。 - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. 無法移除與備份此資料夾,因為有其他的程式正在使用其中的資料夾或者檔案。請關閉使用中的資料夾或檔案並重試或者取消設定。 - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>近端同步資料夾 %1 建立成功!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1連線精靈 - Add %1 account 新增 %1 賬戶 + + + %1 Connection Wizard + %1連線精靈 + Skip folders configuration @@ -3168,24 +3264,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 維持穩定 - - OCC::OwncloudWizardResultPage - - - Everything set up! - 一切都準備就緒! - - - - Open Local Folder - 打開近端資料夾 - - - - Open %1 in Browser - 瀏覽器中開啟 %1 - - OCC::PollJob @@ -3196,6 +3274,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + 檔案的名稱包含尾隨空格,無法重命名,因為服務器上已存同名稱的檔案。 + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + 檔案的名稱包含尾隨空格,無法重命名,因為近端上已存在相同名稱的檔案。 + Symbolic links are not supported in syncing. @@ -3211,16 +3299,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss File names ending with a period are not supported on this file system. 此檔案系統不支援以「。」結尾的檔案名。 - - - File names containing the character "%1" are not supported on this file system. - 此檔案系統不支援含 "%1" 字元的檔案名稱。 - File names containing the character '%1' are not supported on this file system. 此檔案系統不支援含「%1」字元的檔案名稱。 + + + File names containing the character "%1" are not supported on this file system. + 此檔案系統不支援含 "%1" 字元的檔案名稱。 + File name contains at least one invalid character @@ -3347,7 +3435,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss 伺服器讀取目錄 '%1' 時發生錯誤:%2 - + Server replied with an error while reading directory "%1" : %2 伺服器在讀取目錄「%1」回覆錯誤:%2 @@ -3962,11 +4050,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing 允許編輯 - - - Allow editing - 允許編輯 - Read only @@ -3987,6 +4070,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect 密碼保護 + + + Allow editing + 允許編輯 + + + + View only + 僅檢視 + Allow upload and editing @@ -4002,16 +4095,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) 拖曳檔案(僅供上傳) - - - Note to recipient - 給接收者的訊息 - Unshare 取消分享 + + + Link name + 連結名稱 + + + + Note to recipient + 給接收者的訊息 + Password protect @@ -4023,15 +4121,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss 設定到期日 - - Delete share link - 刪除分享連結 + + Delete link + 刪除連結 Add another link 新增連結 + + + Delete share link + 刪除分享連結 + Confirm Link Share Deletion @@ -4081,7 +4184,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss '%1' 沒有結果 - + No results for "%1" "%1" 沒有結果 @@ -4185,12 +4288,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - 與%1分享 - Context menu share @@ -4217,6 +4314,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 由 %1 分享 + + + + Activity + 活動紀錄 + Copy private link to clipboard @@ -4288,6 +4391,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete 刪除 + + + Share with %1 + parameter is Nextcloud + 與%1分享 + OCC::SslButton @@ -4433,6 +4542,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: 無法安全的連線到 <i>%1</i>: + + + Additional errors: + 附加錯誤: + with Certificate %1 @@ -4607,6 +4721,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() 目前僅有 %1 可以使用,至少需要 %2 才能開始 + + + Aborted + 已放棄 + @@ -4759,27 +4878,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" 無效的字元,請您重新命名 "%1" + + + Synchronization will resume shortly. + 同步會很快恢復 + File name contains at least one invalid character 檔案名稱含有不合法的字元 - - Aborted - 已放棄 - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. 剩餘空間不足:下載後將使剩餘空間降至低於%1的檔案一律跳過。 - + There is insufficient space available on the server for some uploads. 伺服器上的剩餘空間不足以容納某些要上載的檔案。 + + OCC::SyncStatusSummary + + + + Offline + 離線 + + + + + + All synced! + 已同步所有檔案! + + + + Some files couldn't be synced! + 部分文件無法同步! + + + + See below for errors + 有關警告,請參見下文 + + + + Syncing + 同步中 + + + + Sync paused + 同步已暫停 + + + + Some files could not be synced! + 部份檔案無法同步! + + + + See below for warnings + 有關警告,請參見下文 + + + + %1 of %2 · %3 left + %2 中的 %1.還剩 %3 + + + + %1 of %2 + %2 中的 %1 + + + + Syncing file %1 of %2 + 正在同步 %2 中的 %1 + + OCC::Systray @@ -4855,6 +5035,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss 此版本由%1發佈。 + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + 無法擷取提供者。 + + + + Failed to fetch search providers for '%1'. Error: %2 + 無法擷取 “%1” 的搜尋提供者。 錯誤:%2 + + + + Search has failed for '%2'. + 搜尋 “%2” 失敗。 + + + + Search has failed for '%1'. Error: %2 + 搜尋 “%1” 失敗。 錯誤:%2 + + OCC::User @@ -4912,24 +5115,108 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - 虛擬檔案系統功能需要一個 NTFS 檔案系統,%1 正在使用 %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + 無法擷取預定義狀態。 請確保您已連接到伺服器。 - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - 端到端加密檔案下載失敗 + + Could not fetch user status. Make sure you are connected to the server. + 無法擷取用戶狀態。 請確保您已連接到伺服器。 - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - 似乎您正在嘗試下載經過端到端加密的虛擬檔案。目前不支持隱式下載此類檔案。要變通解決此問題,請轉到設置並將加密的文件夾標記為“使近端始終可用”。 + + User status feature is not supported. You will not be able to set your user status. + 不支持用戶狀態功能。 您將無法設置您的用戶狀態。 + + + + Emojis feature is not supported. Some user status functionality may not work. + 不支持 emoji 功能。 某些用戶狀態功能可能不起作用。 + + + + Could not set user status. Make sure you are connected to the server. + 無法設置用戶狀態。 請確保您已連接到伺服器。 + + + + Could not clear user status message. Make sure you are connected to the server. + 無法清除用戶訊息。 請確保您已連接到伺服器。 + + + + + Don't clear + 不要清除 + + + + 30 minutes + 30 分鐘 + + + + + 1 hour + 1 小時 + + + + 4 hours + 4 小時 + + + + + Today + 今天 + + + + + This week + 本星期 + + + + Less than a minute + 不到一分鐘 + + + + 1 minute + 1 分鐘 + + + + %1 minutes + %1 分鐘 + + + + %1 hours + %1 小時 + + + + 1 day + 1 日 + + + + %1 days + %1 天 + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + 虛擬檔案系統功能需要一個 NTFS 檔案系統,%1 正在使用 %2 @@ -5423,7 +5710,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss This is the link to your %1 web interface when you open it in the browser. - 在瀏覽器中打開它時,這是指向 %1 Web 介面的連結。 + 這是您在瀏覽器中開啟時的 %1 網頁界面連結。 @@ -5446,14 +5733,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 登入到您的 %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - 您整個帳號的資料會與近端資料夾同步 - - QObject @@ -5546,6 +5825,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss 連接數據庫失敗。 + + UnifiedSearchInputContainer + + + Search files, messages, events … + 搜索檔案、訊息、活動 ... + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + 載入更多結果 + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + 搜索結果骨架。 + + + + UnifiedSearchResultListItem + + + Load more results + 載入更多結果 + + UserLine @@ -5560,29 +5871,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - 目前用戶狀態為在線 + Account connected + 賬戶已連結 - Current user status is do not disturb - 目前用戶狀態為請勿打擾 + Account not connected + 未連接到賬戶 - Account connected - 賬戶已連結 + Current user status is online + 目前用戶狀態為在線 - Account not connected - 未連接到賬戶 + Current user status is do not disturb + 目前用戶狀態為請勿打擾 Account actions 賬戶操作 + + + Remove Account + 移除帳號 + + + + Set status + 設置狀態 + @@ -5595,17 +5916,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in 登入 - - - Remove Account - 移除帳號 - Remove account 移除帳號 + + UserStatusSelector + + + Online status + 線上狀態 + + + + Online + 在線 + + + + Away + 離開 + + + + Do not disturb + 請勿打擾 + + + + Invisible + 隱藏 + + + + Status message + 狀態訊息 + + + + What is your status? + 您目前的狀態是什麼呢? + + + + Clear status message after + 繼此之後清除狀態訊息 + + + + Clear status message + 清除狀態訊息 + + + + Set status message + 設定狀態訊息 + + Utility @@ -5667,12 +6036,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. 檢查碼異常。 - + The checksum header contained an unknown checksum type '%1' 檢查碼含有未知的型態 '%1' @@ -5682,17 +6051,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 下載的檔案驗證失敗,將會被還原 - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' 下載的檔案與校驗和不匹配,將會被還原。'%1' != '%2' - + The checksum header contained an unknown checksum type "%1" 檢查碼含有未知的型態 "%1" - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" 下載的檔案與校驗和不匹配,將會被還原。"%1" != "%2" @@ -5721,6 +6090,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all 暫停所有同步 + + + Set user status + 設置用戶狀態 + Add account @@ -5756,12 +6130,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb 目前用戶狀態為請勿打擾 - - - - Show more actions - 顯示更多操作 - Share %1 @@ -5822,6 +6190,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog 開啟分享對話方塊 + + + Unified search results list + 統一搜索結果列表 + + + + + Show more actions + 顯示更多操作 + + + + %1 - File activity + %1 - 檔案活動紀錄 + main.cpp @@ -6121,6 +6505,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss 請在瀏覽器上登入(Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + 一切都準備就緒! + + + + Open Local Folder + 打開近端資料夾 + + + + Open %1 in Browser + 瀏覽器中開啟 %1 + + OCC::ShibbolethCredentials @@ -6144,7 +6546,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss SSL Cipher Debug View - SSL 密碼偵錯介面 + SSL 密碼偵錯界面 @@ -6173,6 +6575,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss 登入 + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + 您整個帳號的資料會與近端資料夾同步 + + OCC::UserStatus @@ -6196,4 +6606,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 在線 + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + 端到端加密檔案下載失敗 + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + 似乎您正在嘗試下載經過端到端加密的虛擬檔案。目前不支持隱式下載此類檔案。要變通解決此問題,請轉到設置並將加密的文件夾標記為“使近端始終可用”。 + + \ No newline at end of file diff --git a/translations/client_zh_TW.ts b/translations/client_zh_TW.ts index 8130233791f9..ef94c7fa25c9 100644 --- a/translations/client_zh_TW.ts +++ b/translations/client_zh_TW.ts @@ -14,12 +14,6 @@ Open %1 locally 在本機開啟 %1 - - - - Show more actions - 顯示更多動作 - Open share dialog @@ -30,6 +24,25 @@ Share %1 分享 %1 + + + + Show more actions + 顯示更多動作 + + + + View activity + 檢視事件 + + + + ActivityList + + + Activity list + 事件清單 + CloudProviderWrapper @@ -130,8 +143,8 @@ - Could not move "%1" to "%1" - 無法移動「%1」到「%1」 + Could not move "%1" to "%2" + 無法將「%1」移動至「%2」 @@ -1144,32 +1157,32 @@ This can be an issue with your OpenSSL libraries. 無法開啟瀏覽器,請將連結複製到瀏覽器中。 - + Waiting for authorization 正在等候授權 - + Polling for authorization 正在輪詢授權 - + Starting authorization 開始授權 - + Link copied to clipboard. 超連結已複製到剪貼簿。 - + Reopen Browser 重新開啟瀏覽器 - + Copy Link 複製連結 @@ -1337,6 +1350,15 @@ This means that the synchronization client might not upload local changes immedi 客戶端可能無法及時上傳本地的更動,而只能每隔一段時間(預設為2小時)才掃描及上傳一次本機變更。 %1 + + + + All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. +Are you sure you want to sync those actions with the server? +If this was an accident and you decide to keep your files, they will be re-synced from the server. + 在您本機同步資料夾「%1」中的所有檔案都已刪除。這些刪除將會與您的伺服器同步,除非復原,否則這些檔案將不可用。 +您確定您想要與伺服器同步那些動作嗎? +如果這是意外,而且您決定保留您的檔案,它們將會自伺服器重新同步。 @@ -1398,27 +1420,7 @@ Continuing the sync as normal will cause all your files to be overwritten by an 將本機檔案視為衝突檔案 - - All files in the sync folder '%1' folder were deleted on the server. -These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. -If you decide to restore the files, they will be re-synced with the server if you have rights to do so. -If you decide to delete the files, they will be unavailable to you, unless you are the owner. - 「%1」資料夾中的所有檔案已從伺服器上移除。 -同步後,這些檔案也會從您的本地資料夾中移除。除非您有復原的權限,否則您將無法讀取這些檔案。 -假如您決定復原這些檔案,只要您擁有權限,這些檔案就會重新和伺服器同步。 -假如您決定移除這些檔案,除非您是檔案的所有者,否則您將無法讀取這些檔案。 - - - - All the files in your local sync folder '%1' were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. -Are you sure you want to sync those actions with the server? -If this was an accident and you decide to keep your files, they will be re-synced from the server. - 在您本機同步資料夾「%1」中的所有檔案都已刪除。這些刪除將會與您的伺服器同步,除非復原,否則這些檔案將不可用。 -您確定您想要與伺服器同步那些動作嗎? -如果這是意外,而且您決定保留您的檔案,它們將會自伺服器重新同步。 - - - + All files in the sync folder "%1" folder were deleted on the server. These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. If you decide to restore the files, they will be re-synced with the server if you have rights to do so. @@ -1429,7 +1431,7 @@ If you decide to delete the files, they will be unavailable to you, unless you a 假如您決定移除這些檔案,除非您是檔案的所有者,否則您將無法讀取這些檔案。 - + All the files in your local sync folder "%1" were deleted. These deletes will be synchronized with your server, making such files unavailable unless restored. Are you sure you want to sync those actions with the server? If this was an accident and you decide to keep your files, they will be re-synced from the server. @@ -1447,6 +1449,17 @@ If this was an accident and you decide to keep your files, they will be re-synce Remove all files 移除所有檔案 + + + All files in the sync folder '%1' folder were deleted on the server. +These deletes will be synchronized to your local sync folder, making such files unavailable unless you have a right to restore. +If you decide to restore the files, they will be re-synced with the server if you have rights to do so. +If you decide to delete the files, they will be unavailable to you, unless you are the owner. + 「%1」資料夾中的所有檔案已從伺服器上移除。 +同步後,這些檔案也會從您的本地資料夾中移除。除非您有復原的權限,否則您將無法讀取這些檔案。 +假如您決定復原這些檔案,只要您擁有權限,這些檔案就會重新和伺服器同步。 +假如您決定移除這些檔案,除非您是檔案的所有者,否則您將無法讀取這些檔案。 + Keep files @@ -2277,6 +2290,69 @@ Items where deletion is allowed will be deleted if they prevent a directory from 新增要忽略的檔案模式 + + OCC::InvalidFilenameDialog + + + Invalid filename + 無效的檔案名稱 + + + + The file could not be synced because it contains characters which are not allowed on this system. + 無法同步檔案,因為其包含了此系統上不允許的字元。 + + + + Error + 錯誤 + + + + Please enter a new name for the file: + 請輸入新檔案名稱: + + + + New filename + 新檔案名稱 + + + + Rename file + 重新命名檔案 + + + + The file %1 could not be synced because the name contains characters which are not allowed on this system. + 無法同步檔案 %1,因為名稱包含了此系統上不允許的字元。 + + + + The following characters are not allowed on the system: * " | & ? , ; : \ / ~ < > + 系統不允許以下字元:* " | & ? , ; : \ / ~ < > + + + + You don't have the permission to rename this file. Please ask the author of the file to rename it. + 您無權重新命名此檔案。請要求檔案的作者重新命名它。 + + + + Filename contains illegal characters: %1 + 檔案名稱包含了非法字元:%1 + + + + Could not rename file. Please make sure you are connected to the server. + 無法重新命名檔案。請確保您已連線至伺服器。 + + + + Cannot rename file because a file with the same name does already exist on the server. Please pick another name. + 無法重新命名檔案,因為伺服器上已有同名檔案。請換一個名字。 + + OCC::LegalNotice @@ -2417,7 +2493,7 @@ Logs will be written to %1 <nobr>檔案「%1」<br/>無法開啟與寫入。<br/><br/>紀錄<b>無法</b>被儲存!</nobr> - + <nobr>File "%1"<br/>cannot be opened for writing.<br/><br/>The log output <b>cannot</b> be saved!</nobr> <nobr>檔案「%1」<br/>無法開啟供寫入。<br/><br/>記錄<b>無法</b>被儲存!</nobr> @@ -2460,6 +2536,11 @@ Logs will be written to %1 <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3.</p> <p>%1 客戶端有新版本了,但更新流程失敗。</p><p><b>%2</b> 已下載。已安裝的版本為 %3。</p> + + + <p>A new version of the %1 Client is available but the updating process failed.</p><p><b>%2</b> has been downloaded. The installed version is %3. If you confirm restart and update, your computer may reboot to complete the installation.</p> + <p>%1 客戶端有新版本可用,但更新過程失敗。</p><p><b>%2</b> 已下載。 目前安裝的版本是 %3。如果您確認重新啟動和更新,您的電腦可能會重新啟動以完成安裝。</p> + Ask again later @@ -2629,6 +2710,13 @@ Logs will be written to %1 New %1 Update Ready 新 %1 更新已經就緒 + + + A new update for %1 is about to be installed. The updater may ask +for additional privileges during the process. + 一個新的 %1 更新已經安裝完成。更新程式也許會 +在更新過程中要求額外的權限。 + New %1 update ready @@ -2636,10 +2724,8 @@ Logs will be written to %1 - A new update for %1 is about to be installed. The updater may ask -for additional privileges during the process. - 一個新的 %1 更新已經安裝完成。更新程式也許會 -在更新過程中要求額外的權限。 + A new update for %1 is about to be installed. The updater may ask for additional privileges during the process. Your computer may reboot to complete the installation. + 一個新的 %1 更新已經安裝完成。更新也許會詢問要求給予權限在安裝的過程中。您的電腦可能會重新啟動以完成安裝。 @@ -2676,6 +2762,11 @@ for additional privileges during the process. New %1 is available. Please click <a href='%2'>here</a> to download the update. 新版本 %1 可更新,請點擊<a href='%2'>此處</a>下載更新。 + + + Could not download update. Please open <a href='%1'>%1</a> to download the update manually. + 無法下載更新。請開啟 <a href='%1'>%1</a> 手動下載更新。 + Could not download update. Please open %1 to download the update manually. @@ -2686,6 +2777,11 @@ for additional privileges during the process. Could not check for new updates. 無法檢查新更新。 + + + New %1 is available. Please open <a href='%2'>%2</a> to download the update. + 新版本 %1 可更新。請開啟 <a href='%2'>%2</a> 下載更新。 + New %1 is available. Please open %2 to download the update. @@ -2982,37 +3078,37 @@ It is not advisable to use it. 從 %2 嘗試連線到 %1 逾時。 - + Trying to connect to %1 at %2 … 嘗試以 %1 身分連線到 %2…… - + The authenticated request to the server was redirected to '%1'. The URL is bad, the server is misconfigured. 伺服器要求的認證請求被導向「%1」。這個網址可能不安全,此伺服器可能設定有錯。 - + The authenticated request to the server was redirected to "%1". The URL is bad, the server is misconfigured. 伺服器要求的認證請求被導向「%1」。這個網址可能不安全,此伺服器可能設定有錯。 - + Access forbidden by server. To verify that you have proper access, <a href="%1">click here</a> to access the service with your browser. 從伺服器存取被拒絕。為了正確驗證您的存取資訊,<a href="%1">請點選這裡</a>透過瀏覽器來存取服務。 - + There was an invalid response to an authenticated WebDAV request 伺服器回應 WebDAV 驗證請求無效 - + Local sync folder %1 already exists, setting it up for sync.<br/><br/> 本機同步資料夾 %1 已存在,將其設定為同步。<br/><br/> - + Creating local sync folder %1 … 正在新增本機同步資料夾 %1…… @@ -3022,84 +3118,84 @@ It is not advisable to use it. OK - + OK 確定 - + failed. 失敗。 - + Could not create local folder %1 無法建立本機資料夾 %1 - + No remote folder specified! 未指定遠端資料夾! - + Error: %1 錯誤:%1 - + creating folder on Nextcloud: %1 正在 Nextcloud 上建立資料夾:%1 - + Remote folder %1 created successfully. 遠端資料夾 %1 成功建立。 - + The remote folder %1 already exists. Connecting it for syncing. 遠端資料夾 %1 已存在。正在連線同步。 - - + + The folder creation resulted in HTTP error code %1 資料夾建立結果為 HTTP 錯誤碼 %1 - + The remote folder creation failed because the provided credentials are wrong!<br/>Please go back and check your credentials.</p> 由於帳號或密碼錯誤,遠端資料夾建立失敗!<br/>請檢查您的帳號密碼。</p> - + <p><font color="red">Remote folder creation failed probably because the provided credentials are wrong.</font><br/>Please go back and check your credentials.</p> <p><font color="red">遠端資料夾建立失敗,也許是因為所提供的帳號密碼錯誤。</font><br/>請重新檢查您的帳號密碼。</p> - - + + Remote folder %1 creation failed with error <tt>%2</tt>. 建立遠端資料夾 %1 時發生錯誤 <tt>%2</tt>。 - + A sync connection from %1 to remote directory %2 was set up. 從 %1 到遠端資料夾 %2 的連線已建立。 - + Successfully connected to %1! 成功連線至 %1! - + Connection to %1 could not be established. Please check again. 無法建立到 %1 的連線。請再檢查一次。 - + Folder rename failed 重新命名資料夾失敗 @@ -3109,28 +3205,28 @@ It is not advisable to use it. 無法移除與備份此資料夾,因為有其他的程式正在使用其中的資料夾或者檔案。請關閉使用中的資料夾或檔案並重試或者取消設定。 - + Cannot remove and back up the folder because the folder or a file in it is open in another program. Please close the folder or file and hit retry or cancel the setup. 無法移除與備份此資料夾,因為有其他的程式正在使用其中的資料夾或者檔案。請關閉使用中的資料夾或檔案並重試或者取消設定。 - + <font color="green"><b>Local sync folder %1 successfully created!</b></font> <font color="green"><b>本機同步資料夾 %1 建立成功!</b></font> OCC::OwncloudWizard - - - %1 Connection Wizard - %1 連線精靈 - Add %1 account 新增 %1 帳號 + + + %1 Connection Wizard + %1 連線精靈 + Skip folders configuration @@ -3169,24 +3265,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 注意安全 - - OCC::OwncloudWizardResultPage - - - Everything set up! - 一切都準備就緒! - - - - Open Local Folder - 開啟本機資料夾 - - - - Open %1 in Browser - 在瀏覽器中開啟 %1 - - OCC::PollJob @@ -3197,6 +3275,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::ProcessDirectoryJob + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists on the server. + 檔案名稱尾端包含空格,且無法重新命名,因為伺服器上已有相同名稱的檔案存在。 + + + + File contains trailing spaces and could not be renamed, because a file with the same name already exists locally. + 檔案名稱尾端包含空格,且無法重新命名,因為本機已有相同名稱的檔案存在。 + Symbolic links are not supported in syncing. @@ -3214,12 +3302,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss - File names containing the character "%1" are not supported on this file system. + File names containing the character '%1' are not supported on this file system. 此檔案系統不支援包含「%1」字元的檔案名稱。 - - File names containing the character '%1' are not supported on this file system. + + File names containing the character "%1" are not supported on this file system. 此檔案系統不支援包含「%1」字元的檔案名稱。 @@ -3348,7 +3436,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss 伺服器在讀取目錄「%1」回覆錯誤:%2 - + Server replied with an error while reading directory "%1" : %2 伺服器在讀取目錄「%1」回覆錯誤:%2 @@ -3963,11 +4051,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Allow Editing 允許編輯 - - - Allow editing - 允許編輯 - Read only @@ -3988,6 +4071,16 @@ This is a new, experimental mode. If you decide to use it, please report any iss Password Protect 密碼保護 + + + Allow editing + 允許編輯 + + + + View only + 僅檢視 + Allow upload and editing @@ -4003,16 +4096,21 @@ This is a new, experimental mode. If you decide to use it, please report any iss File drop (upload only) 檔案投放(僅上傳) - - - Note to recipient - 給收件者的訊息 - Unshare 取消分享 + + + Link name + 連結名稱 + + + + Note to recipient + 給收件者的訊息 + Password protect @@ -4024,15 +4122,20 @@ This is a new, experimental mode. If you decide to use it, please report any iss 設定到期日 - - Delete share link - 刪除分享連結 + + Delete link + 刪除連結 Add another link 新增其他連結 + + + Delete share link + 刪除分享連結 + Confirm Link Share Deletion @@ -4082,7 +4185,7 @@ This is a new, experimental mode. If you decide to use it, please report any iss 「%1」沒有結果 - + No results for "%1" 「%1」沒有結果 @@ -4186,12 +4289,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss OCC::SocketApi - - - Share with %1 - parameter is Nextcloud - 與 %1 分享 - Context menu share @@ -4218,6 +4315,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Share via %1 透過 %1 分享 + + + + Activity + 事件 + Copy private link to clipboard @@ -4289,6 +4392,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss Delete 刪除 + + + Share with %1 + parameter is Nextcloud + 與 %1 分享 + OCC::SslButton @@ -4434,6 +4543,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Cannot connect securely to <i>%1</i>: 無法安全地連線到 <i>%1</i>: + + + Additional errors: + 其他錯誤: + with Certificate %1 @@ -4608,6 +4722,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Placeholders are postfixed with file sizes using Utility::octetsToString() 目前僅有 %1 可以使用,至少需要 %2 才能開始 + + + Aborted + 已中止 + @@ -4760,27 +4879,88 @@ This is a new, experimental mode. If you decide to use it, please report any iss Invalid characters, please rename "%1" 無效的字元,請重新命名為「%1」 + + + Synchronization will resume shortly. + 同步會很快恢復 + File name contains at least one invalid character 檔案名稱包含至少一個無效的字元 - - Aborted - 已中止 - - - + Disk space is low: Downloads that would reduce free space below %1 were skipped. 剩餘空間不足:下載後將使剩餘空間降至低於 %1 的檔案一律跳過。 - + There is insufficient space available on the server for some uploads. 伺服器上的剩餘空間不足以容納某些要上傳的檔案。 + + OCC::SyncStatusSummary + + + + Offline + 離線 + + + + + + All synced! + 全部都已同步! + + + + Some files couldn't be synced! + 部份檔案無法同步! + + + + See below for errors + 請參閱以下錯誤 + + + + Syncing + 正在同步 + + + + Sync paused + 同步已暫停 + + + + Some files could not be synced! + 部份檔案無法同步! + + + + See below for warnings + 請參閱以下的警告 + + + + %1 of %2 · %3 left + %2 中的 %1 · 還剩 %3 + + + + %1 of %2 + %2 中的 %1 + + + + Syncing file %1 of %2 + 正在同步檔案 %2 中的 %1 + + OCC::Systray @@ -4856,6 +5036,29 @@ This is a new, experimental mode. If you decide to use it, please report any iss <p>此版本由 %1 提供</p> + + OCC::UnifiedSearchResultsListModel + + + Failed to fetch providers. + 擷取提供者失敗。 + + + + Failed to fetch search providers for '%1'. Error: %2 + 擷取「%1」的搜尋提供者失敗。錯誤:%2 + + + + Search has failed for '%2'. + 搜尋「%2」失敗。 + + + + Search has failed for '%1'. Error: %2 + 搜尋「%1」失敗。錯誤:%2 + + OCC::User @@ -4913,24 +5116,108 @@ This is a new, experimental mode. If you decide to use it, please report any iss - OCC::Vfs + OCC::UserStatusSelectorModel - - The Virtual filesystem feature requires a NTFS file system, %1 is using %2 - 虛擬檔案系統功能需要 NTFS 檔案系統,%1 正在使用 %2 + + Could not fetch predefined statuses. Make sure you are connected to the server. + 無法擷取預定義的狀態。請確定您已連線至伺服器。 - - - OCC::VfsCfApi - - Download of end-to-end encrypted file failed - 下載端到端加密的檔案失敗 + + Could not fetch user status. Make sure you are connected to the server. + 無法擷取使用者狀態。請確定您已連線至伺服器。 - - It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". - 您似乎正在嘗試下載透過端到端加密的虛擬檔案。目前並不支援下載此類檔案。變通方法則是到設定中並將加密的資料夾標記為「一律可在本機使用」。 + + User status feature is not supported. You will not be able to set your user status. + 不支援使用者狀態功能。您將無法設定您的使用者狀態。 + + + + Emojis feature is not supported. Some user status functionality may not work. + 不支援表情符號功能。部份使用者狀態功能可能無法運作。 + + + + Could not set user status. Make sure you are connected to the server. + 無法設定使用者狀態。請確定您已連線至伺服器。 + + + + Could not clear user status message. Make sure you are connected to the server. + 無法清除使用者狀態訊息。請確保您已連線至伺服器。 + + + + + Don't clear + 不要清除 + + + + 30 minutes + 30分鐘 + + + + + 1 hour + 1小時 + + + + 4 hours + 4小時 + + + + + Today + 今天 + + + + + This week + 本週 + + + + Less than a minute + 不到一分鐘 + + + + 1 minute + 1分鐘 + + + + %1 minutes + %1分鐘 + + + + %1 hours + %1小時 + + + + 1 day + 1天 + + + + %1 days + %1天 + + + + OCC::Vfs + + + The Virtual filesystem feature requires a NTFS file system, %1 is using %2 + 虛擬檔案系統功能需要 NTFS 檔案系統,%1 正在使用 %2 @@ -5447,14 +5734,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss 登入到您的 %1 - - OwncloudWizardResultPage - - - Your entire account is synced to the local folder - 您整個帳號已同步到本機資料夾 - - QObject @@ -5547,6 +5826,38 @@ This is a new, experimental mode. If you decide to use it, please report any iss 連結資料庫失敗。 + + UnifiedSearchInputContainer + + + Search files, messages, events … + 搜尋檔案、訊息、事件…… + + + + UnifiedSearchResultFetchMoreTrigger + + + Load more results + 載入更多結果 + + + + UnifiedSearchResultItemSkeleton + + + Search result skeleton. + 搜尋結果骨架。 + + + + UnifiedSearchResultListItem + + + Load more results + 載入更多結果 + + UserLine @@ -5561,29 +5872,39 @@ This is a new, experimental mode. If you decide to use it, please report any iss - Current user status is online - 目前的使用者狀態為在線上 + Account connected + 帳號已連結 - Current user status is do not disturb - 目前的使用者狀態為請勿打擾 + Account not connected + 未連線帳號 - Account connected - 帳號已連結 + Current user status is online + 目前的使用者狀態為在線上 - Account not connected - 未連線帳號 + Current user status is do not disturb + 目前的使用者狀態為請勿打擾 Account actions 帳號動作 + + + Remove Account + 移除帳號 + + + + Set status + 設定狀態 + @@ -5596,17 +5917,65 @@ This is a new, experimental mode. If you decide to use it, please report any iss Log in 登入 - - - Remove Account - 移除帳號 - Remove account 移除帳號 + + UserStatusSelector + + + Online status + 線上狀態 + + + + Online + 線上 + + + + Away + 離開 + + + + Do not disturb + 請勿打擾 + + + + Invisible + 隱藏 + + + + Status message + 狀態訊息 + + + + What is your status? + 您目前的狀態是什麼呢? + + + + Clear status message after + 在這個時間後清除狀態訊息 + + + + Clear status message + 清除狀態訊息 + + + + Set status message + 設定狀態訊息 + + Utility @@ -5668,12 +6037,12 @@ This is a new, experimental mode. If you decide to use it, please report any iss ValidateChecksumHeader - + The checksum header is malformed. 檢查碼標頭異常。 - + The checksum header contained an unknown checksum type '%1' 檢查碼標頭包含了未知的檢查碼類型「%1」 @@ -5683,17 +6052,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 已下載的檔案與檢查碼不相符,其將會被還原。 - + The downloaded file does not match the checksum, it will be resumed. '%1' != '%2' 已下載的檔案與檢查碼不相符,其將會被還原。「%1」!=「%2」 - + The checksum header contained an unknown checksum type "%1" 檢查碼標頭包含了未知的檢查碼類型「%1」 - + The downloaded file does not match the checksum, it will be resumed. "%1" != "%2" 已下載的檔案與檢查碼不相符,其將會被還原。「%1」!=「%2」 @@ -5722,6 +6091,11 @@ This is a new, experimental mode. If you decide to use it, please report any iss Pause sync for all 暫停所有同步 + + + Set user status + 設定使用者狀態 + Add account @@ -5757,12 +6131,6 @@ This is a new, experimental mode. If you decide to use it, please report any iss Current user status is do not disturb 目前的使用者狀態為請勿打擾 - - - - Show more actions - 顯示更多動作 - Share %1 @@ -5823,6 +6191,22 @@ This is a new, experimental mode. If you decide to use it, please report any iss Open share dialog 開啟分享對話框 + + + Unified search results list + 統一搜尋結果清單 + + + + + Show more actions + 顯示更多動作 + + + + %1 - File activity + %1 - 檔案事件 + main.cpp @@ -6122,6 +6506,24 @@ This is a new, experimental mode. If you decide to use it, please report any iss 請在瀏覽器上登入 (Login Flow v2) + + OCC::OwncloudWizardResultPage + + + Everything set up! + 一切都準備就緒! + + + + Open Local Folder + 開啟本機資料夾 + + + + Open %1 in Browser + 在瀏覽器中開啟 %1 + + OCC::ShibbolethCredentials @@ -6174,6 +6576,14 @@ This is a new, experimental mode. If you decide to use it, please report any iss 登入 + + OwncloudWizardResultPage + + + Your entire account is synced to the local folder + 您整個帳號已同步到本機資料夾 + + OCC::UserStatus @@ -6197,4 +6607,17 @@ This is a new, experimental mode. If you decide to use it, please report any iss 線上 + + OCC::VfsCfApi + + + Download of end-to-end encrypted file failed + 下載端到端加密的檔案失敗 + + + + It seems that you are trying to download a virtual file that is end-to-end encrypted. Implicitly downloading such files is not supported at the moment. To workaround this issue, go to the settings and mark the encrypted folder with "Make always available locally". + 您似乎正在嘗試下載透過端到端加密的虛擬檔案。目前並不支援下載此類檔案。變通方法則是到設定中並將加密的資料夾標記為「一律可在本機使用」。 + + \ No newline at end of file