+Become our Gold Sponsor and showcase your brand to a targeted audience! Please contact us if you are interested.
### Silver Sponsors
-
+
@@ -38,9 +32,9 @@ Cryptomator is provided free of charge as an open-source project despite the hig
### Special Shoutout
-Continuous integration hosting for ARM64 builds is provided by [MacStadium](https://www.macstadium.com/opensource).
+Continuous integration hosting for ARM64 builds is provided by [MacStadium](https://www.macstadium.com/company/opensource).
-
+
---
@@ -60,7 +54,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
- File names get encrypted
- Folder structure gets obfuscated
- Use as many vaults in your Dropbox as you want, each having individual passwords
-- Four thousand commits for the security of your data!! :tada:
+- More than Five thousand commits for the security of your data!! :tada:
### Privacy
@@ -84,7 +78,7 @@ For more information on the security details visit [cryptomator.org](https://doc
### Dependencies
-* JDK 22 (e.g. temurin, zulu)
+* JDK 23 (e.g. temurin, zulu)
* Maven 3
### Run Maven
diff --git a/dist/linux/appimage/build.sh b/dist/linux/appimage/build.sh
index e815fd5b7..63cdc09f9 100755
--- a/dist/linux/appimage/build.sh
+++ b/dist/linux/appimage/build.sh
@@ -25,10 +25,10 @@ cp ../../../target/cryptomator-*.jar ../../../target/mods
JAVAFX_VERSION=22.0.2
JAVAFX_ARCH="x64"
-JAVAFX_JMODS_SHA256='d44bff3b94d5668fdee18a938d7b1269026d663d44765f02d29a9bdfd3fa1eb0'
+JAVAFX_JMODS_SHA256='2164bca470bf70a5e2764645e2078ba7f787b274e5be3d7df30d87c5bb62bba6'
if [ "${CPU_ARCH}" = "aarch64" ]; then
JAVAFX_ARCH="aarch64"
- JAVAFX_JMODS_SHA256='3d5457136690c4f5bb9522d38b45218e045bdac13c24aa4c808c7c8d17d039c7'
+ JAVAFX_JMODS_SHA256='09c92fa9fa0b82adefd88640a14ebb2a49e5f3f733a57d1542f5590d060ffe1b'
fi
# download javaFX jmods
@@ -76,7 +76,7 @@ ${JAVA_HOME}/bin/jpackage \
--vendor "Skymatic GmbH" \
--java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
- --copyright "(C) 2016 - 2024 Skymatic GmbH" \
+ --copyright "(C) 2016 - 2025 Skymatic GmbH" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
--app-version "${VERSION}.${REVISION_NO}" \
@@ -91,6 +91,7 @@ ${JAVA_HOME}/bin/jpackage \
--java-options "-Dcryptomator.showTrayIcon=true" \
--java-options "-Dcryptomator.integrationsLinux.trayIconsDir=\"@{appdir}/usr/share/icons/hicolor/symbolic/apps\"" \
--java-options "-Dcryptomator.buildNumber=\"appimage-${REVISION_NO}\"" \
+ --java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\"" \
--resource-dir ../resources
# transform AppDir
@@ -108,13 +109,13 @@ cp ../common/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/usr/share/ap
cp ../common/org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.metainfo.xml
cp ../common/application-vnd.cryptomator.vault.xml Cryptomator.AppDir/usr/share/mime/packages/application-vnd.cryptomator.vault.xml
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/org.cryptomator.Cryptomator.svg
-ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/Cryptomator.svg
ln -s usr/share/icons/hicolor/scalable/apps/org.cryptomator.Cryptomator.svg Cryptomator.AppDir/.DirIcon
-ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/Cryptomator.desktop
+ln -s usr/share/applications/org.cryptomator.Cryptomator.desktop Cryptomator.AppDir/org.cryptomator.Cryptomator.desktop
+ln -s org.cryptomator.Cryptomator.metainfo.xml Cryptomator.AppDir/usr/share/metainfo/org.cryptomator.Cryptomator.appdata.xml
ln -s bin/cryptomator.sh Cryptomator.AppDir/AppRun
# load AppImageTool
-curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-${CPU_ARCH}.AppImage -o /tmp/appimagetool.AppImage
+curl -L https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${CPU_ARCH}.AppImage -o /tmp/appimagetool.AppImage
chmod +x /tmp/appimagetool.AppImage
# create AppImage
diff --git a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml
index b15ba0356..eb01b6d1e 100644
--- a/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml
+++ b/dist/linux/common/org.cryptomator.Cryptomator.metainfo.xml
@@ -74,6 +74,9 @@
+
+ https://github.com/cryptomator/cryptomator/releases/1.15.0
+ https://github.com/cryptomator/cryptomator/releases/1.14.2
diff --git a/dist/linux/debian/control b/dist/linux/debian/control
index 2a9bbae69..96d29acd4 100644
--- a/dist/linux/debian/control
+++ b/dist/linux/debian/control
@@ -2,7 +2,7 @@ Source: cryptomator
Maintainer: Cryptobot
Section: utils
Priority: optional
-Build-Depends: debhelper (>=10), coffeelibs-jdk-22 (>= 22.0.1+8-0ppa1), libgtk-3-0, libxxf86vm1, libgl1
+Build-Depends: debhelper (>=10), coffeelibs-jdk-23 (>= 23.0.1+11-0ppa1), libgtk-3-0, libxxf86vm1, libgl1
Standards-Version: 4.5.0
Homepage: https://cryptomator.org
Vcs-Git: https://github.com/cryptomator/cryptomator.git
diff --git a/dist/linux/debian/copyright b/dist/linux/debian/copyright
index 322e549d0..f4155bf5a 100644
--- a/dist/linux/debian/copyright
+++ b/dist/linux/debian/copyright
@@ -4,11 +4,11 @@ Upstream-Contact: Cryptomator
Source: https://cryptomator.org
Files: *
-Copyright: 2016-2024 Skymatic GmbH
+Copyright: 2016-2025 Skymatic GmbH
License: GPL-3+
Files: debian/org.cryptomator.Cryptomator.appdata.xml
-Copyright: 2016-2024 Skymatic GmbH
+Copyright: 2016-2025 Skymatic GmbH
License: FSFAP
License: GPL-3+
diff --git a/dist/linux/debian/rules b/dist/linux/debian/rules
index 81d14f66a..a899dba68 100755
--- a/dist/linux/debian/rules
+++ b/dist/linux/debian/rules
@@ -4,7 +4,7 @@
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
-JAVA_HOME = /usr/lib/jvm/java-22-coffeelibs
+JAVA_HOME = /usr/lib/jvm/java-23-coffeelibs
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
ifeq ($(DEB_BUILD_ARCH),amd64)
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
@@ -45,7 +45,7 @@ override_dh_auto_build:
--vendor "Skymatic GmbH" \
--java-options "--enable-preview" \
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
- --copyright "(C) 2016 - 2024 Skymatic GmbH" \
+ --copyright "(C) 2016 - 2025 Skymatic GmbH" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
--java-options "-Dfile.encoding=\"utf-8\"" \
@@ -62,6 +62,7 @@ override_dh_auto_build:
--java-options "-Dcryptomator.appVersion=\"${SEMVER_STR}\"" \
--java-options "-Dcryptomator.disableUpdateCheck=\"${DISABLE_UPDATE_CHECK}\"" \
--java-options "-Dcryptomator.integrationsLinux.autoStartCmd=\"cryptomator\"" \
+ --java-options "-Dcryptomator.networking.truststore.p12Path=\"/etc/cryptomator/certs.p12\"" \
--app-version "${VERSION_NUM}.${REVISION_NUM}" \
--resource-dir resources \
--verbose
diff --git a/dist/mac/dmg/build.sh b/dist/mac/dmg/build.sh
index bceabbc3f..dbbd818d9 100755
--- a/dist/mac/dmg/build.sh
+++ b/dist/mac/dmg/build.sh
@@ -24,7 +24,7 @@ rm -rf runtime dmg *.app *.dmg
# set variables
APP_NAME="Cryptomator"
VENDOR="Skymatic GmbH"
-COPYRIGHT_YEARS="2016 - 2024"
+COPYRIGHT_YEARS="2016 - 2025"
PACKAGE_IDENTIFIER="org.cryptomator"
MAIN_JAR_GLOB="cryptomator-*.jar"
MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
@@ -32,15 +32,15 @@ REVISION_NO=`git rev-list --count HEAD`
VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'`
FUSE_LIB="FUSE-T"
-JAVAFX_VERSION=22.0.2
+JAVAFX_VERSION=23.0.1
JAVAFX_ARCH="undefined"
JAVAFX_JMODS_SHA256="undefined"
if [ "$(machine)" = "arm64e" ]; then
JAVAFX_ARCH="aarch64"
- JAVAFX_JMODS_SHA256="813c6748f7c99cb7a579d48b48a087b4682b1fad1fc1a4fe5f9b21cf872b15a7"
+ JAVAFX_JMODS_SHA256="a800724a1f3e6757ecfa0bd5bf7ed64d2e6a7a3f5b3522650a70b8cfc7782fb6"
else
JAVAFX_ARCH="x64"
- JAVAFX_JMODS_SHA256="115cb08bb59d880cfff6e51e0bf0dcc45785ed9d456b8b8425597b04da6ab3d4"
+ JAVAFX_JMODS_SHA256="8857965975c464a0e5d57709292ce357d0ebb39f6168c41d5ca38301e42c3c8e"
fi
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
diff --git a/dist/mac/dmg/resources/licenseTemplate.ftl b/dist/mac/dmg/resources/licenseTemplate.ftl
index 45a523f51..606c1f9b9 100644
--- a/dist/mac/dmg/resources/licenseTemplate.ftl
+++ b/dist/mac/dmg/resources/licenseTemplate.ftl
@@ -17,7 +17,7 @@
\f1\b0 \
\
-\f0\b \'a9 2016 \'96 2024 Skymatic GmbH
+\f0\b \'a9 2016 \'96 2025 Skymatic GmbH
\f1\b0 \
\
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 3 of the License, or (at your option) any later version.\
diff --git a/dist/win/build.bat b/dist/win/build.bat
index 6dcb344c0..3532a69fd 100644
--- a/dist/win/build.bat
+++ b/dist/win/build.bat
@@ -11,7 +11,7 @@ SET HELP_URL="https://cryptomator.org/contact/"
SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
SET LOOPBACK_ALIAS="cryptomator-vault"
-powershell -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
+pwsh -NoLogo -NoProfile -ExecutionPolicy Unrestricted -Command .\build.ps1^
-AppName %APPNAME%^
-MainJarGlob "%MAIN_JAR_GLOB%"^
-ModuleAndMainClass "%MODULE_AND_MAIN_CLASS%"^
diff --git a/dist/win/build.ps1 b/dist/win/build.ps1
index 61da2106e..a733f4557 100644
--- a/dist/win/build.ps1
+++ b/dist/win/build.ps1
@@ -51,23 +51,23 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
}
## download jfx jmods
-$javaFxVersion='22.0.2'
+$javaFxVersion='23.0.1'
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
-$javaFxJmodsSHA256 = 'f9376d200f5c5b85327d575c1ec1482e6455f19916577f7e2fc9be2f48bb29b6'
+$javaFxJmodsSHA256 = 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
$javaFxJmods = '.\resources\jfxJmods.zip'
if( !(Test-Path -Path $javaFxJmods) ) {
Write-Output "Downloading ${javaFxJmodsUrl}..."
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
}
-$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash
+$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
, actual: $jmodsChecksumActual"
exit 1;
}
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
-Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods"
+Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
## create custom runtime
@@ -75,7 +75,7 @@ Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\ja
--verbose `
--output runtime `
--module-path "$Env:JAVA_HOME/jmods;$buildDir/resources/javafx-jmods" `
- --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
+ --add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,jdk.crypto.mscapi,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
--strip-native-commands `
--no-header-files `
--no-man-pages `
diff --git a/dist/win/bundle/resources/licenseTemplate.ftl b/dist/win/bundle/resources/licenseTemplate.ftl
index 6940f9fe6..f0232dc73 100644
--- a/dist/win/bundle/resources/licenseTemplate.ftl
+++ b/dist/win/bundle/resources/licenseTemplate.ftl
@@ -10,7 +10,7 @@
\vieww12000\viewh15840\viewkind0
\pard\tx283\tx567\tx850\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\b\fs16\lang7 Cryptomator is distributed under the GPLv3 License, found below. Please see the bottom of this document for any other license applicable to code used within Cryptomator.\b0\par
\par
-\b\'a9 2016 \'96 2024 Skymatic GmbH \b0\par
+\b\'a9 2016 \'96 2025 Skymatic GmbH \b0\par
\par
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 3 of the License, or (at your option) any later version.\par
\par
diff --git a/dist/win/contrib/dokan1.dll b/dist/win/contrib/dokan1.dll
deleted file mode 100755
index 194945aed..000000000
Binary files a/dist/win/contrib/dokan1.dll and /dev/null differ
diff --git a/dist/win/resources/licenseTemplate.ftl b/dist/win/resources/licenseTemplate.ftl
index 011fda3cb..de5590ba1 100644
--- a/dist/win/resources/licenseTemplate.ftl
+++ b/dist/win/resources/licenseTemplate.ftl
@@ -10,7 +10,7 @@
\vieww12000\viewh15840\viewkind0
\pard\tx283\tx567\tx850\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\b\fs16\lang7 Cryptomator is distributed under the GPLv3 License, found below. Please see the bottom of this document for any other license applicable to code used within Cryptomator.\b0\par
\par
-\b\'a9 2016 \'96 2024 Skymatic GmbH \b0\par
+\b\'a9 2016 \'96 2025 Skymatic GmbH \b0\par
\par
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 3 of the License, or (at your option) any later version.\par
\par
diff --git a/pom.xml b/pom.xml
index 91e7e79d9..bb9bce0bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0org.cryptomatorcryptomator
- 1.14.2
+ 1.15.0Cryptomator Desktop App
@@ -26,51 +26,53 @@
UTF-8
- 22
+ 23org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents
- 2.7.1
- 1.4.0
+ 2.8.0
+ 1.5.01.3.01.2.4
- 1.5.1
+ 1.5.25.0.22.0.7
- 3.16.0
- 2.51.1
+ 3.17.0
+ 2.552.2
- 33.3.0-jre
- 2.17.2
- 22.0.2
+ 2.18.2
+ 23.0.14.4.09.37.3
- 1.5.7
+ 1.5.162.0.160.8.01.9.0
- 5.11.0
- 5.12.0
+ 5.11.4
+ 5.15.23.0
- 24.1.0
- 10.0.3
+ 26.0.1
+ 12.0.10.8.12
- 2.4.0
- 1.3.0
+ 2.5.0
+ 1.4.03.13.03.3.1
- 3.7.1
- 3.4.0
+ 3.8.1
+ 3.5.23.4.2
+
+
+
@@ -191,40 +193,23 @@
-
- com.google.guava
- guava
- ${guava.version}
-
-
-
- com.google.guava
- listenablefuture
-
-
- com.google.code.findbugs
- jsr305
-
-
- org.checkerframework
- checker-qual
-
-
- com.google.errorprone
- error_prone_annotations
-
-
- com.google.j2objc
- j2objc-annotations
-
-
- com.google.daggerdagger${dagger.version}
+
+ jakarta.inject
+ jakarta.inject-api
+ 2.0.1
+
+
+
+ com.github.ben-manes.caffeine
+ caffeine
+ 3.2.0
+ org.junit.jupiter
@@ -326,7 +311,6 @@
-Adagger.fastInit=enabled-Adagger.formatGeneratedSource=enabled
- --enable-preview
@@ -353,11 +337,11 @@
- --enable-previewplaintrue
+ @{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar}
@@ -367,6 +351,13 @@
org.apache.maven.pluginsmaven-dependency-plugin
+
+ jar-paths-to-properties
+ validate
+
+ properties
+
+ copy-mods
@@ -439,6 +430,9 @@
prepare-agent
+
+ surefire.jacoco.args
+ report
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 3d4194bb3..4dd4242b3 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -1,8 +1,10 @@
import ch.qos.logback.classic.spi.Configurator;
+import org.cryptomator.networking.SSLContextWithPKCS12TrustStore;
import org.cryptomator.common.locationpresets.DropboxLinuxLocationPresetsProvider;
import org.cryptomator.common.locationpresets.DropboxMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.DropboxWindowsLocationPresetsProvider;
-import org.cryptomator.common.locationpresets.GoogleDriveLocationPresetsProvider;
+import org.cryptomator.common.locationpresets.GoogleDriveMacLocationPresetsProvider;
+import org.cryptomator.common.locationpresets.GoogleDriveWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.ICloudWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.LeitzcloudLocationPresetsProvider;
@@ -12,6 +14,9 @@ import org.cryptomator.common.locationpresets.OneDriveLinuxLocationPresetsProvid
import org.cryptomator.common.locationpresets.OneDriveMacLocationPresetsProvider;
import org.cryptomator.common.locationpresets.OneDriveWindowsLocationPresetsProvider;
import org.cryptomator.common.locationpresets.PCloudLocationPresetsProvider;
+import org.cryptomator.networking.SSLContextWithMacKeychain;
+import org.cryptomator.networking.SSLContextProvider;
+import org.cryptomator.networking.SSLContextWithWindowsCertStore;
import org.cryptomator.integrations.tray.TrayMenuController;
import org.cryptomator.logging.LogbackConfiguratorFactory;
import org.cryptomator.ui.traymenu.AwtTrayMenuController;
@@ -42,21 +47,25 @@ open module org.cryptomator.desktop {
requires com.nulabinc.zxcvbn;
requires com.tobiasdiez.easybind;
requires dagger;
- requires java.compiler;
requires io.github.coffeelibs.tinyoauth2client;
requires org.slf4j;
requires org.apache.commons.lang3;
- /* TODO: filename-based modules: */
- requires static javax.inject; /* ugly dagger/guava crap */
+ /* dagger bs */
+ requires jakarta.inject;
+ requires static javax.inject;
+ requires java.compiler;
+ requires com.github.benmanes.caffeine;
uses org.cryptomator.common.locationpresets.LocationPresetsProvider;
+ uses SSLContextProvider;
provides TrayMenuController with AwtTrayMenuController;
provides Configurator with LogbackConfiguratorFactory;
+ provides SSLContextProvider with SSLContextWithWindowsCertStore, SSLContextWithMacKeychain, SSLContextWithPKCS12TrustStore;
provides LocationPresetsProvider with //
DropboxWindowsLocationPresetsProvider, DropboxMacLocationPresetsProvider, DropboxLinuxLocationPresetsProvider, //
- GoogleDriveLocationPresetsProvider, //
+ GoogleDriveMacLocationPresetsProvider, GoogleDriveWindowsLocationPresetsProvider, //
ICloudWindowsLocationPresetsProvider, ICloudMacLocationPresetsProvider, //
LeitzcloudLocationPresetsProvider, //
MegaLocationPresetsProvider, //
diff --git a/src/main/java/org/cryptomator/common/keychain/KeychainManager.java b/src/main/java/org/cryptomator/common/keychain/KeychainManager.java
index b2af2725f..ac03e5ed6 100644
--- a/src/main/java/org/cryptomator/common/keychain/KeychainManager.java
+++ b/src/main/java/org/cryptomator/common/keychain/KeychainManager.java
@@ -1,8 +1,7 @@
package org.cryptomator.common.keychain;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.LoadingCache;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
@@ -24,9 +23,9 @@ public class KeychainManager implements KeychainAccessProvider {
@Inject
KeychainManager(ObjectExpression selectedKeychain) {
this.keychain = selectedKeychain;
- this.passphraseStoredProperties = CacheBuilder.newBuilder() //
+ this.passphraseStoredProperties = Caffeine.newBuilder() //
.weakValues() //
- .build(CacheLoader.from(this::createStoredPassphraseProperty));
+ .build(this::createStoredPassphraseProperty);
keychain.addListener(ignored -> passphraseStoredProperties.invalidateAll());
}
@@ -124,7 +123,7 @@ public class KeychainManager implements KeychainAccessProvider {
* @see #isPassphraseStored(String)
*/
public ReadOnlyBooleanProperty getPassphraseStoredProperty(String key) {
- return passphraseStoredProperties.getUnchecked(key);
+ return passphraseStoredProperties.get(key);
}
private BooleanProperty createStoredPassphraseProperty(String key) {
diff --git a/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveMacLocationPresetsProvider.java b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveMacLocationPresetsProvider.java
new file mode 100644
index 000000000..a1d4d0c0e
--- /dev/null
+++ b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveMacLocationPresetsProvider.java
@@ -0,0 +1,144 @@
+package org.cryptomator.common.locationpresets;
+
+import org.cryptomator.integrations.common.CheckAvailability;
+import org.cryptomator.integrations.common.OperatingSystem;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
+
+@OperatingSystem(MAC)
+@CheckAvailability
+public final class GoogleDriveMacLocationPresetsProvider implements LocationPresetsProvider {
+
+ private static final Path ROOT_LOCATION = LocationPresetsProvider.resolveLocation("~/Library/CloudStorage/").toAbsolutePath();
+ private static final Predicate PATTERN = Pattern.compile("^GoogleDrive-[^/]+$").asMatchPredicate();
+
+ private static final List FALLBACK_LOCATIONS = List.of( //
+ LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
+ LocationPresetsProvider.resolveLocation("~/Google Drive/My Drive"), //
+ LocationPresetsProvider.resolveLocation("~/GoogleDrive"), //
+ LocationPresetsProvider.resolveLocation("~/Google Drive") //
+ );
+
+ @Override
+ public Stream getLocations() {
+ List cloudStorageDirLocations = getCloudStorageDirLocations();
+ return cloudStorageDirLocations.isEmpty() ? getFallbackLocation().stream() : cloudStorageDirLocations.stream();
+
+ }
+
+ @CheckAvailability
+ public static boolean isPresent() {
+ return isRootLocationPresent() || FALLBACK_LOCATIONS.stream().anyMatch(Files::isDirectory);
+ }
+
+ /**
+ * Checks if a root location directory is present that matches the specified pattern.
+ *
+ * This method scans the {@code ROOT_LOCATION} directory for subdirectories and tests each one against a pre-defined pattern ({@code PATTERN}).
+ *
+ * @return {@code true} if a matching root location is present, otherwise {@code false}.
+ */
+ public static boolean isRootLocationPresent() {
+ try (var dirStream = Files.list(ROOT_LOCATION)) {
+ return dirStream.anyMatch(path -> Files.isDirectory(path) && PATTERN.test(path.getFileName().toString()));
+ } catch (IOException | UncheckedIOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns Google Drive preset String.
+ *
+ * @param accountPath The path to the Google Drive account directory (e.g. {@code ~/Library/CloudStorage/GoogleDrive-username})
+ * @return {@code String}. For example: "Google Drive - username"
+ */
+ private String getDriveLocationString(Path accountPath) {
+ String accountName = accountPath.getFileName().toString().replace("GoogleDrive-", "");
+ return "Google Drive - " + accountName;
+ }
+
+ /**
+ * Retrieves a list of cloud storage directory locations based on the {@code ROOT_LOCATION}.
+ *
+ * This method lists all directories in the {@code ROOT_LOCATION}, filters them based on whether their names match
+ * a predefined pattern ({@code PATTERN}), and then extracts presets using {@code getPresetsFromAccountPath(Path)}.
+ *
+ *
+ * @return a list of {@code LocationPreset} objects representing valid cloud storage directory locations.
+ */
+ private List getCloudStorageDirLocations() {
+ try (var dirStream = Files.list(ROOT_LOCATION)) {
+ return dirStream.filter(path -> Files.isDirectory(path) && PATTERN.test(path.getFileName().toString()))
+ .flatMap(this::getPresetsFromAccountPath)
+ .toList();
+ } catch (IOException | UncheckedIOException e) {
+ return List.of();
+ }
+ }
+
+ /**
+ * Retrieves a stream of {@code LocationPreset} objects from a given Google Drive account path.
+ *
+ * This method lists all directories within the provided {@code accountPath} and filters them
+ * to identify folders whose names match any of the translations defined in {@code MY_DRIVE_TRANSLATIONS}.
+ *
+ * @param accountPath the root path of the Google Drive account to scan.
+ * @return a stream of {@code LocationPreset} objects representing matching directories.
+ */
+ private Stream getPresetsFromAccountPath(Path accountPath) {
+ try (var driveStream = Files.list(accountPath)) {
+ return driveStream
+ .filter(preset -> MY_DRIVE_TRANSLATIONS
+ .contains(preset.getFileName().toString()))
+ .map(drivePath -> new LocationPreset(
+ getDriveLocationString(accountPath),
+ drivePath
+ )).toList().stream();
+ } catch (IOException e) {
+ return Stream.empty();
+ }
+ }
+
+ /**
+ * Returns a list containing a fallback location preset for Google Drive.
+ *
+ * This method iterates through the predefined fallback locations, checks if any of them is a directory,
+ * and creates a {@code LocationPreset} object for the first matching directory found.
+ *
+ * @return a list containing a single fallback location preset if a valid directory is found, otherwise an empty list.
+ * @deprecated This method is intended for legacy support and may be removed in future releases.
+ */
+ @Deprecated
+ private List getFallbackLocation() {
+ return FALLBACK_LOCATIONS.stream()
+ .filter(Files::isDirectory)
+ .map(location -> new LocationPreset("Google Drive", location))
+ .findFirst()
+ .stream()
+ .toList();
+ }
+
+ /**
+ * Set of translations for "My Drive" in various languages.
+ *
+ * This constant is used to identify different language-specific labels for "My Drive" in Google Drive.
+ *
+ * The translations were originally extracted from the Chromium project’s Chrome OS translation files.
+ *
+ * Source: `ui/chromeos/translations` directory in the Chromium repository.
+ */
+ private static final Set MY_DRIVE_TRANSLATIONS = Set.of("My Drive", "የእኔ Drive", "ملفاتي", "মোৰ ড্ৰাইভ", "Diskim", "Мой Дыск", "Моят диск", "আমার ড্রাইভ", "Moj disk", "La meva unitat", "Můj disk", "Mit drev", "Meine Ablage", "Το Drive μου", "Mi unidad", "Minu ketas", "Nire unitatea", "Aking Drive", "Oma Drive", "Mon disque", "Mon Drive", "A miña unidade", "મારી ડ્રાઇવ", "मेरी ड्राइव", "Saját meghajtó", "Իմ դրայվը", "Drive Saya", "Drifið mitt", "I miei file", "האחסון שלי", "マイドライブ", "ჩემი Drive", "Менің Drive дискім", "ដ្រាយរបស់ខ្ញុំ", "ನನ್ನ ಡ್ರೈವ್", "내 드라이브", "Менин Drive'ым", "Mano Diskas", "Mans disks", "Мојот Drive", "എന്റെ ഡ്രൈവ്", "Миний Драйв", "माझा ड्राइव्ह", "मेरो ड्राइभ", "Mijn Drive", "Min disk", "ମୋ ଡ୍ରାଇଭ୍", "Mój dysk", "Meu Drive", "O meu disco", "Contul meu Drive", "Мой диск", "මගේ Drive", "Môj disk", "Disku im", "Мој диск", "Min enhet", "Hifadhi Yangu", "எனது இயக்ககம்", "నా డ్రైవ్", "ไดรฟ์ของฉัน", "Drive'ım", "Мій диск", "میری ڈرائیو", "Drive của tôi", "我的云端硬盘", "我的雲端硬碟", "IDrayivu yami");
+}
diff --git a/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveLocationPresetsProvider.java b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveWindowsLocationPresetsProvider.java
similarity index 85%
rename from src/main/java/org/cryptomator/common/locationpresets/GoogleDriveLocationPresetsProvider.java
rename to src/main/java/org/cryptomator/common/locationpresets/GoogleDriveWindowsLocationPresetsProvider.java
index 970bea042..fea1632c4 100644
--- a/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveLocationPresetsProvider.java
+++ b/src/main/java/org/cryptomator/common/locationpresets/GoogleDriveWindowsLocationPresetsProvider.java
@@ -9,13 +9,11 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
-import static org.cryptomator.integrations.common.OperatingSystem.Value.MAC;
import static org.cryptomator.integrations.common.OperatingSystem.Value.WINDOWS;
@OperatingSystem(WINDOWS)
-@OperatingSystem(MAC)
@CheckAvailability
-public final class GoogleDriveLocationPresetsProvider implements LocationPresetsProvider {
+public final class GoogleDriveWindowsLocationPresetsProvider implements LocationPresetsProvider {
private static final List LOCATIONS = Arrays.asList( //
LocationPresetsProvider.resolveLocation("~/GoogleDrive/My Drive"), //
@@ -37,5 +35,4 @@ public final class GoogleDriveLocationPresetsProvider implements LocationPresets
.findFirst() //
.stream();
}
-
}
diff --git a/src/main/java/org/cryptomator/common/mount/Mounter.java b/src/main/java/org/cryptomator/common/mount/Mounter.java
index 6ca067305..89f8fb782 100644
--- a/src/main/java/org/cryptomator/common/mount/Mounter.java
+++ b/src/main/java/org/cryptomator/common/mount/Mounter.java
@@ -160,7 +160,7 @@ public class Mounter {
var mountService = mountProviders.stream().filter(s -> s.getClass().getName().equals(vaultSettings.mountService.getValue())).findFirst().orElse(defaultMountService.getValue());
if (isConflictingMountService(mountService)) {
- var msg = STR."\{mountService.getClass()} unavailable due to conflict with either of \{CONFLICTING_MOUNT_SERVICES.get(mountService.getClass().getName())}";
+ var msg = mountService.getClass() + " unavailable due to conflict with either of " + CONFLICTING_MOUNT_SERVICES.get(mountService.getClass().getName());
throw new ConflictingMountServiceException(msg);
}
diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java
index 24dbed679..907d99885 100644
--- a/src/main/java/org/cryptomator/common/settings/Settings.java
+++ b/src/main/java/org/cryptomator/common/settings/Settings.java
@@ -32,7 +32,6 @@ public class Settings {
private static final Logger LOG = LoggerFactory.getLogger(Settings.class);
- static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
static final boolean DEFAULT_CHECK_FOR_UPDATES = false;
static final boolean DEFAULT_START_HIDDEN = false;
static final boolean DEFAULT_AUTO_CLOSE_VAULTS = false;
@@ -50,11 +49,9 @@ public class Settings {
SystemUtils.IS_OS_LINUX ? "org.cryptomator.linux.quickaccess.NautilusBookmarks" : null;
static final String DEFAULT_USER_INTERFACE_ORIENTATION = NodeOrientation.LEFT_TO_RIGHT.name();
- static final boolean DEFAULT_SHOW_MINIMIZE_BUTTON = false;
public static final Instant DEFAULT_TIMESTAMP = Instant.parse("2000-01-01T00:00:00Z");
+
public final ObservableList directories;
- public final BooleanProperty askedForUpdateCheck;
- public final BooleanProperty checkForUpdates;
public final BooleanProperty startHidden;
public final BooleanProperty autoCloseVaults;
public final BooleanProperty useKeychain;
@@ -67,14 +64,16 @@ public class Settings {
public final StringProperty quickAccessService;
public final ObjectProperty userInterfaceOrientation;
public final StringProperty licenseKey;
- public final BooleanProperty showMinimizeButton;
public final BooleanProperty showTrayIcon;
+ public final BooleanProperty compactMode;
public final IntegerProperty windowXPosition;
public final IntegerProperty windowYPosition;
public final IntegerProperty windowWidth;
public final IntegerProperty windowHeight;
public final StringProperty language;
public final StringProperty mountService;
+ public final BooleanProperty checkForUpdates;
+ public final ObjectProperty lastUpdateCheckReminder;
public final ObjectProperty lastSuccessfulUpdateCheck;
private Consumer saveCmd;
@@ -92,8 +91,6 @@ public class Settings {
*/
Settings(SettingsJson json) {
this.directories = FXCollections.observableArrayList(VaultSettings::observables);
- this.askedForUpdateCheck = new SimpleBooleanProperty(this, "askedForUpdateCheck", json.askedForUpdateCheck);
- this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
this.startHidden = new SimpleBooleanProperty(this, "startHidden", json.startHidden);
this.autoCloseVaults = new SimpleBooleanProperty(this, "autoCloseVaults", json.autoCloseVaults);
this.useKeychain = new SimpleBooleanProperty(this, "useKeychain", json.useKeychain);
@@ -105,8 +102,8 @@ public class Settings {
this.keychainProvider = new SimpleStringProperty(this, "keychainProvider", json.keychainProvider);
this.userInterfaceOrientation = new SimpleObjectProperty<>(this, "userInterfaceOrientation", parseEnum(json.uiOrientation, NodeOrientation.class, NodeOrientation.LEFT_TO_RIGHT));
this.licenseKey = new SimpleStringProperty(this, "licenseKey", json.licenseKey);
- this.showMinimizeButton = new SimpleBooleanProperty(this, "showMinimizeButton", json.showMinimizeButton);
this.showTrayIcon = new SimpleBooleanProperty(this, "showTrayIcon", json.showTrayIcon);
+ this.compactMode = new SimpleBooleanProperty(this, "compactMode", json.compactMode);
this.windowXPosition = new SimpleIntegerProperty(this, "windowXPosition", json.windowXPosition);
this.windowYPosition = new SimpleIntegerProperty(this, "windowYPosition", json.windowYPosition);
this.windowWidth = new SimpleIntegerProperty(this, "windowWidth", json.windowWidth);
@@ -114,6 +111,8 @@ public class Settings {
this.language = new SimpleStringProperty(this, "language", json.language);
this.mountService = new SimpleStringProperty(this, "mountService", json.mountService);
this.quickAccessService = new SimpleStringProperty(this, "quickAccessService", json.quickAccessService);
+ this.checkForUpdates = new SimpleBooleanProperty(this, "checkForUpdates", json.checkForUpdatesEnabled);
+ this.lastUpdateCheckReminder = new SimpleObjectProperty<>(this, "lastUpdateCheckReminder", json.lastReminderForUpdateCheck);
this.lastSuccessfulUpdateCheck = new SimpleObjectProperty<>(this, "lastSuccessfulUpdateCheck", json.lastSuccessfulUpdateCheck);
this.directories.addAll(json.directories.stream().map(VaultSettings::new).toList());
@@ -121,8 +120,6 @@ public class Settings {
migrateLegacySettings(json);
directories.addListener(this::somethingChanged);
- askedForUpdateCheck.addListener(this::somethingChanged);
- checkForUpdates.addListener(this::somethingChanged);
startHidden.addListener(this::somethingChanged);
autoCloseVaults.addListener(this::somethingChanged);
useKeychain.addListener(this::somethingChanged);
@@ -134,8 +131,8 @@ public class Settings {
keychainProvider.addListener(this::somethingChanged);
userInterfaceOrientation.addListener(this::somethingChanged);
licenseKey.addListener(this::somethingChanged);
- showMinimizeButton.addListener(this::somethingChanged);
showTrayIcon.addListener(this::somethingChanged);
+ compactMode.addListener(this::somethingChanged);
windowXPosition.addListener(this::somethingChanged);
windowYPosition.addListener(this::somethingChanged);
windowWidth.addListener(this::somethingChanged);
@@ -143,6 +140,8 @@ public class Settings {
language.addListener(this::somethingChanged);
mountService.addListener(this::somethingChanged);
quickAccessService.addListener(this::somethingChanged);
+ checkForUpdates.addListener(this::somethingChanged);
+ lastUpdateCheckReminder.addListener(this::somethingChanged);
lastSuccessfulUpdateCheck.addListener(this::somethingChanged);
}
@@ -177,8 +176,6 @@ public class Settings {
SettingsJson serialized() {
var json = new SettingsJson();
json.directories = directories.stream().map(VaultSettings::serialized).toList();
- json.askedForUpdateCheck = askedForUpdateCheck.get();
- json.checkForUpdatesEnabled = checkForUpdates.get();
json.startHidden = startHidden.get();
json.autoCloseVaults = autoCloseVaults.get();
json.useKeychain = useKeychain.get();
@@ -190,8 +187,8 @@ public class Settings {
json.keychainProvider = keychainProvider.get();
json.uiOrientation = userInterfaceOrientation.get().name();
json.licenseKey = licenseKey.get();
- json.showMinimizeButton = showMinimizeButton.get();
json.showTrayIcon = showTrayIcon.get();
+ json.compactMode = compactMode.get();
json.windowXPosition = windowXPosition.get();
json.windowYPosition = windowYPosition.get();
json.windowWidth = windowWidth.get();
@@ -199,6 +196,8 @@ public class Settings {
json.language = language.get();
json.mountService = mountService.get();
json.quickAccessService = quickAccessService.get();
+ json.checkForUpdatesEnabled = checkForUpdates.get();
+ json.lastReminderForUpdateCheck = lastUpdateCheckReminder.get();
json.lastSuccessfulUpdateCheck = lastSuccessfulUpdateCheck.get();
return json;
}
diff --git a/src/main/java/org/cryptomator/common/settings/SettingsJson.java b/src/main/java/org/cryptomator/common/settings/SettingsJson.java
index 7996dcb39..15f5f2790 100644
--- a/src/main/java/org/cryptomator/common/settings/SettingsJson.java
+++ b/src/main/java/org/cryptomator/common/settings/SettingsJson.java
@@ -18,15 +18,9 @@ class SettingsJson {
@JsonProperty("writtenByVersion")
String writtenByVersion;
- @JsonProperty("askedForUpdateCheck")
- boolean askedForUpdateCheck = Settings.DEFAULT_ASKED_FOR_UPDATE_CHECK;
-
@JsonProperty("autoCloseVaults")
boolean autoCloseVaults = Settings.DEFAULT_AUTO_CLOSE_VAULTS;
- @JsonProperty("checkForUpdatesEnabled")
- boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES;
-
@JsonProperty("debugMode")
boolean debugMode = Settings.DEFAULT_DEBUG_MODE;
@@ -51,12 +45,12 @@ class SettingsJson {
@JsonProperty("port")
int port = Settings.DEFAULT_PORT;
- @JsonProperty("showMinimizeButton")
- boolean showMinimizeButton = Settings.DEFAULT_SHOW_MINIMIZE_BUTTON;
-
@JsonProperty("showTrayIcon")
boolean showTrayIcon;
+ @JsonProperty("compactMode")
+ boolean compactMode;
+
@JsonProperty("startHidden")
boolean startHidden = Settings.DEFAULT_START_HIDDEN;
@@ -82,6 +76,13 @@ class SettingsJson {
@JsonProperty(value = "preferredVolumeImpl", access = JsonProperty.Access.WRITE_ONLY) // WRITE_ONLY means value is "written" into the java object during deserialization. Upvote this: https://github.com/FasterXML/jackson-annotations/issues/233
String preferredVolumeImpl;
+ @JsonProperty("checkForUpdatesEnabled")
+ boolean checkForUpdatesEnabled = Settings.DEFAULT_CHECK_FOR_UPDATES;
+
+ @JsonProperty("lastReminderForUpdateCheck")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
+ Instant lastReminderForUpdateCheck = Settings.DEFAULT_TIMESTAMP;
+
@JsonProperty("lastSuccessfulUpdateCheck")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
Instant lastSuccessfulUpdateCheck = Settings.DEFAULT_TIMESTAMP;
diff --git a/src/main/java/org/cryptomator/common/vaults/Vault.java b/src/main/java/org/cryptomator/common/vaults/Vault.java
index e65734e68..f857d6ba1 100644
--- a/src/main/java/org/cryptomator/common/vaults/Vault.java
+++ b/src/main/java/org/cryptomator/common/vaults/Vault.java
@@ -44,6 +44,7 @@ import javafx.beans.property.SimpleBooleanProperty;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.ReadOnlyFileSystemException;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
@@ -111,15 +112,22 @@ public class Vault {
private CryptoFileSystem createCryptoFileSystem(MasterkeyLoader keyLoader) throws IOException, MasterkeyLoadingFailedException {
Set flags = EnumSet.noneOf(FileSystemFlags.class);
- if (vaultSettings.usesReadOnlyMode.get()) {
+ var createReadOnly = vaultSettings.usesReadOnlyMode.get();
+ try {
+ FileSystemCapabilityChecker.assertWriteAccess(getPath());
+ } catch (FileSystemCapabilityChecker.MissingCapabilityException e) {
+ if (!createReadOnly) {
+ throw new ReadOnlyFileSystemException();
+ }
+ }
+ if (createReadOnly) {
flags.add(FileSystemFlags.READONLY);
} else if (vaultSettings.maxCleartextFilenameLength.get() == -1) {
LOG.debug("Determining cleartext filename length limitations...");
- var checker = new FileSystemCapabilityChecker();
int shorteningThreshold = configCache.get().allegedShorteningThreshold();
- int ciphertextLimit = checker.determineSupportedCiphertextFileNameLength(getPath());
+ int ciphertextLimit = FileSystemCapabilityChecker.determineSupportedCiphertextFileNameLength(getPath());
if (ciphertextLimit < shorteningThreshold) {
- int cleartextLimit = checker.determineSupportedCleartextFileNameLength(getPath());
+ int cleartextLimit = FileSystemCapabilityChecker.determineSupportedCleartextFileNameLength(getPath());
vaultSettings.maxCleartextFilenameLength.set(cleartextLimit);
} else {
vaultSettings.maxCleartextFilenameLength.setValue(UNLIMITED_FILENAME_LENGTH);
diff --git a/src/main/java/org/cryptomator/launcher/Cryptomator.java b/src/main/java/org/cryptomator/launcher/Cryptomator.java
index a8d38c312..3e0a613ca 100644
--- a/src/main/java/org/cryptomator/launcher/Cryptomator.java
+++ b/src/main/java/org/cryptomator/launcher/Cryptomator.java
@@ -9,8 +9,9 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
import dagger.Lazy;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
-import org.cryptomator.common.SubstitutingProperties;
import org.cryptomator.common.ShutdownHook;
+import org.cryptomator.common.SubstitutingProperties;
+import org.cryptomator.networking.SSLContextProvider;
import org.cryptomator.ipc.IpcCommunicator;
import org.cryptomator.logging.DebugMode;
import org.cryptomator.ui.fxapp.FxApplicationComponent;
@@ -19,8 +20,10 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
+import javax.net.ssl.SSLContext;
import javafx.application.Application;
import javafx.stage.Stage;
+import java.security.SecureRandom;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@@ -48,14 +51,16 @@ public class Cryptomator {
private final Environment env;
private final Lazy ipcMessageHandler;
private final ShutdownHook shutdownHook;
+ private final SecureRandom csprng;
@Inject
- Cryptomator(DebugMode debugMode, SupportedLanguages supportedLanguages, Environment env, Lazy ipcMessageHandler, ShutdownHook shutdownHook) {
+ Cryptomator(DebugMode debugMode, SupportedLanguages supportedLanguages, Environment env, Lazy ipcMessageHandler, ShutdownHook shutdownHook, SecureRandom csprng) {
this.debugMode = debugMode;
this.supportedLanguages = supportedLanguages;
this.env = env;
this.ipcMessageHandler = ipcMessageHandler;
this.shutdownHook = shutdownHook;
+ this.csprng = csprng;
}
public static void main(String[] args) {
@@ -89,7 +94,7 @@ public class Cryptomator {
LOG.info("Starting Cryptomator {} on {} {} ({})", env.getAppVersion(), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
debugMode.initialize();
supportedLanguages.applyPreferred();
-
+ changeDefaultSSLContext();
/*
* Attempts to create an IPC connection to a running Cryptomator instance and sends it the given args.
* If no external process could be reached, the args will be handled by the loopback IPC endpoint.
@@ -115,6 +120,17 @@ public class Cryptomator {
}
}
+ private void changeDefaultSSLContext() {
+ SSLContextProvider.loadAll().findFirst().ifPresent(p -> {
+ try {
+ var context = p.getContext(csprng);
+ SSLContext.setDefault(context);
+ } catch (SSLContextProvider.SSLContextBuildException e) {
+ LOG.warn("Failed to change default SSL context with provider {}", p.getClass().getName(), e);
+ }
+ });
+ }
+
/**
* Launches the JavaFX application, blocking the main thread until shuts down.
*
diff --git a/src/main/java/org/cryptomator/launcher/SupportedLanguages.java b/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
index 99477177b..53136e59b 100644
--- a/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
+++ b/src/main/java/org/cryptomator/launcher/SupportedLanguages.java
@@ -20,7 +20,7 @@ public class SupportedLanguages {
// "en" is not part of this list - it is always inserted at the top.
public static final List LANGUAGE_TAGS = List.of("ar", "be", "bn", "bs", "ca", "cs", "da", "de", "el", "es", "fr", "gl", "he", //
"hi", "hr", "hu", "id", "it", "ja", "ko", "lv", "nb", "nl", "nn", "pa", "pl", "pt", "pt-BR", "ro", "ru", "sk", "sr", "sr-Latn", "sv", "sw", //
- "ta", "th", "tr", "uk", "vi", "zh", "zh-HK", "zh-TW");
+ "ta", "th", "tr", "ug", "uk", "vi", "zh", "zh-HK", "zh-TW");
public static final String ENGLISH = "en";
private final List sortedLanguageTags;
diff --git a/src/main/java/org/cryptomator/networking/SSLContextDifferentTrustStoreBase.java b/src/main/java/org/cryptomator/networking/SSLContextDifferentTrustStoreBase.java
new file mode 100644
index 000000000..87e1b82ef
--- /dev/null
+++ b/src/main/java/org/cryptomator/networking/SSLContextDifferentTrustStoreBase.java
@@ -0,0 +1,33 @@
+package org.cryptomator.networking;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.IOException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+
+abstract class SSLContextDifferentTrustStoreBase implements SSLContextProvider {
+
+ abstract KeyStore getTruststore() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException;
+
+ @Override
+ public SSLContext getContext(SecureRandom csprng) throws SSLContextBuildException {
+ try {
+ KeyStore truststore = getTruststore();
+ truststore.load(null, null);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(truststore);
+
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, tmf.getTrustManagers(), csprng);
+ return context;
+ } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | KeyManagementException | IOException e) {
+ throw new SSLContextBuildException(e);
+ }
+ }
+}
diff --git a/src/main/java/org/cryptomator/networking/SSLContextProvider.java b/src/main/java/org/cryptomator/networking/SSLContextProvider.java
new file mode 100644
index 000000000..3563c546c
--- /dev/null
+++ b/src/main/java/org/cryptomator/networking/SSLContextProvider.java
@@ -0,0 +1,24 @@
+package org.cryptomator.networking;
+
+import org.cryptomator.integrations.common.IntegrationsLoader;
+
+import javax.net.ssl.SSLContext;
+import java.security.SecureRandom;
+import java.util.ServiceLoader;
+import java.util.stream.Stream;
+
+public interface SSLContextProvider {
+
+ SSLContext getContext(SecureRandom csprng) throws SSLContextBuildException;
+
+ class SSLContextBuildException extends Exception {
+
+ SSLContextBuildException(Throwable t) {
+ super(t);
+ }
+ }
+
+ static Stream loadAll() {
+ return IntegrationsLoader.loadAll(ServiceLoader.load(SSLContextProvider.class), SSLContextProvider.class);
+ }
+}
diff --git a/src/main/java/org/cryptomator/networking/SSLContextWithMacKeychain.java b/src/main/java/org/cryptomator/networking/SSLContextWithMacKeychain.java
new file mode 100644
index 000000000..0078fdfd3
--- /dev/null
+++ b/src/main/java/org/cryptomator/networking/SSLContextWithMacKeychain.java
@@ -0,0 +1,21 @@
+package org.cryptomator.networking;
+
+import org.cryptomator.integrations.common.OperatingSystem;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+
+/**
+ * SSLContextProvider for macOS using the macOS Keychain as truststore
+ */
+@OperatingSystem(OperatingSystem.Value.MAC)
+public class SSLContextWithMacKeychain extends SSLContextDifferentTrustStoreBase implements SSLContextProvider {
+
+ @Override
+ KeyStore getTruststore() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
+ return KeyStore.getInstance("KeychainStore-ROOT");
+ }
+}
diff --git a/src/main/java/org/cryptomator/networking/SSLContextWithPKCS12TrustStore.java b/src/main/java/org/cryptomator/networking/SSLContextWithPKCS12TrustStore.java
new file mode 100644
index 000000000..f530435f8
--- /dev/null
+++ b/src/main/java/org/cryptomator/networking/SSLContextWithPKCS12TrustStore.java
@@ -0,0 +1,42 @@
+package org.cryptomator.networking;
+
+import org.cryptomator.integrations.common.CheckAvailability;
+import org.cryptomator.integrations.common.OperatingSystem;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Optional;
+
+/**
+ * SSLContextProvider for Linux using a PKCS#12 file as trust store
+ */
+@OperatingSystem(OperatingSystem.Value.LINUX)
+@CheckAvailability
+public class SSLContextWithPKCS12TrustStore extends SSLContextDifferentTrustStoreBase implements SSLContextProvider {
+
+ private static final String CERT_FILE_LOCATION_PROPERTY = "cryptomator.networking.truststore.p12Path";
+
+ @Override
+ KeyStore getTruststore() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
+ var pkcs12FilePath = Path.of(System.getProperty(CERT_FILE_LOCATION_PROPERTY));
+ try {
+ return KeyStore.getInstance(pkcs12FilePath.toFile(), new char[]{});
+ } catch (IllegalArgumentException e) {
+ throw new NoSuchFileException(pkcs12FilePath.toString());
+ }
+ }
+
+ @CheckAvailability
+ public static boolean isSupported() {
+ var pkcs12Path = System.getProperty(CERT_FILE_LOCATION_PROPERTY);
+ return Optional.ofNullable(pkcs12Path) //
+ .map(Path::of) //
+ .map(Files::exists).orElse(false);
+ }
+}
diff --git a/src/main/java/org/cryptomator/networking/SSLContextWithWindowsCertStore.java b/src/main/java/org/cryptomator/networking/SSLContextWithWindowsCertStore.java
new file mode 100644
index 000000000..0f1ea04b5
--- /dev/null
+++ b/src/main/java/org/cryptomator/networking/SSLContextWithWindowsCertStore.java
@@ -0,0 +1,21 @@
+package org.cryptomator.networking;
+
+import org.cryptomator.integrations.common.OperatingSystem;
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+
+/**
+ * SSLContextProvider for Windows using the Windows certificate store as trust store
+ *
+ * In order to work, the jdk.crypto.mscapi jmod is needed
+ */
+@OperatingSystem(OperatingSystem.Value.WINDOWS)
+public class SSLContextWithWindowsCertStore extends SSLContextDifferentTrustStoreBase implements SSLContextProvider {
+
+ @Override
+ KeyStore getTruststore() throws KeyStoreException {
+ return KeyStore.getInstance("WINDOWS-ROOT");
+ }
+
+}
diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java
index f222d92c4..c8b7bee22 100644
--- a/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java
+++ b/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultLocationController.java
@@ -40,7 +40,6 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
@@ -50,7 +49,7 @@ public class CreateNewVaultLocationController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(CreateNewVaultLocationController.class);
private static final Path DEFAULT_CUSTOM_VAULT_PATH = Paths.get(System.getProperty("user.home"));
- private static final String TEMP_FILE_FORMAT = ".locationTest.cryptomator.tmp";
+ private static final String TEMP_FILE_PREFIX = ".locationTest.cryptomator";
private final Stage window;
private final Lazy chooseNameScene;
@@ -126,16 +125,19 @@ public class CreateNewVaultLocationController implements FxController {
private boolean isActuallyWritable(Path p) {
- Path tmpFile = p.resolve(TEMP_FILE_FORMAT);
- try (var chan = Files.newByteChannel(tmpFile, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE, StandardOpenOption.DELETE_ON_CLOSE)) {
+ Path tmpDir = null;
+ try {
+ tmpDir = Files.createTempDirectory(p, TEMP_FILE_PREFIX );
return true;
} catch (IOException e) {
return false;
} finally {
- try {
- Files.deleteIfExists(tmpFile);
- } catch (IOException e) {
- LOG.warn("Unable to delete temporary file {}. Needs to be deleted manually.", tmpFile);
+ if (tmpDir != null) {
+ try {
+ Files.deleteIfExists(tmpDir);
+ } catch (IOException e) {
+ LOG.warn("Unable to delete temporary directory {}. Needs to be deleted manually.", tmpDir);
+ }
}
}
}
diff --git a/src/main/java/org/cryptomator/ui/common/FxmlFile.java b/src/main/java/org/cryptomator/ui/common/FxmlFile.java
index 938f93687..6bf8ac7db 100644
--- a/src/main/java/org/cryptomator/ui/common/FxmlFile.java
+++ b/src/main/java/org/cryptomator/ui/common/FxmlFile.java
@@ -12,7 +12,6 @@ public enum FxmlFile {
CONVERTVAULT_HUBTOPASSWORD_START("/fxml/convertvault_hubtopassword_start.fxml"), //
CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), //
CONVERTVAULT_HUBTOPASSWORD_SUCCESS("/fxml/convertvault_hubtopassword_success.fxml"), //
- DOKANY_SUPPORT_END("/fxml/dokany_support_end.fxml"), //
ERROR("/fxml/error.fxml"), //
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
HEALTH_START("/fxml/health_start.fxml"), //
@@ -45,8 +44,8 @@ public enum FxmlFile {
RECOVERYKEY_RESET_PASSWORD("/fxml/recoverykey_reset_password.fxml"), //
RECOVERYKEY_RESET_PASSWORD_SUCCESS("/fxml/recoverykey_reset_password_success.fxml"), //
RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), //
- REMOVE_VAULT("/fxml/remove_vault.fxml"), //
SHARE_VAULT("/fxml/share_vault.fxml"), //
+ SIMPLE_DIALOG("/fxml/simple_dialog.fxml"), //
UPDATE_REMINDER("/fxml/update_reminder.fxml"), //
UNLOCK_ENTER_PASSWORD("/fxml/unlock_enter_password.fxml"),
UNLOCK_REQUIRES_RESTART("/fxml/unlock_requires_restart.fxml"), //
diff --git a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java
index e454835cf..485e89304 100644
--- a/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java
+++ b/src/main/java/org/cryptomator/ui/controls/FontAwesome5Icon.java
@@ -17,6 +17,7 @@ public enum FontAwesome5Icon {
COGS("\uF085"), //
COPY("\uF0C5"), //
CROWN("\uF521"), //
+ DONATE("\uF4B9"), //
EDIT("\uF044"), //
EXCHANGE_ALT("\uF362"), //
EXCLAMATION("\uF12A"), //
@@ -49,6 +50,7 @@ public enum FontAwesome5Icon {
SEARCH("\uF002"), //
SHARE("\uF064"), //
SPINNER("\uF110"), //
+ SPONSORS("\uF2B5"), //
STETHOSCOPE("\uF0f1"), //
SYNC("\uF021"), //
TIMES("\uF00D"), //
diff --git a/src/main/java/org/cryptomator/ui/controls/NotificationBar.java b/src/main/java/org/cryptomator/ui/controls/NotificationBar.java
new file mode 100644
index 000000000..64a08f220
--- /dev/null
+++ b/src/main/java/org/cryptomator/ui/controls/NotificationBar.java
@@ -0,0 +1,96 @@
+package org.cryptomator.ui.controls;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.fxml.FXML;
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+
+public class NotificationBar extends HBox {
+
+ @FXML
+ private Label notificationLabel;
+
+ private final BooleanProperty dismissable = new SimpleBooleanProperty();
+ private final BooleanProperty notify = new SimpleBooleanProperty();
+
+
+ public NotificationBar() {
+ setAlignment(Pos.CENTER);
+ setStyle("-fx-alignment: center;");
+
+ Region spacer = new Region();
+ spacer.setMinWidth(40);
+
+ Region leftRegion = new Region();
+ HBox.setHgrow(leftRegion, javafx.scene.layout.Priority.ALWAYS);
+
+ Region rightRegion = new Region();
+ HBox.setHgrow(rightRegion, javafx.scene.layout.Priority.ALWAYS);
+
+ VBox vbox = new VBox();
+ vbox.setAlignment(Pos.CENTER);
+ HBox.setHgrow(vbox, javafx.scene.layout.Priority.ALWAYS);
+
+ notificationLabel = new Label();
+ notificationLabel.getStyleClass().add("notification-label");
+ notificationLabel.setStyle("-fx-alignment: center;");
+ vbox.getChildren().add(notificationLabel);
+
+ Button closeButton = new Button("X");
+ closeButton.setMinWidth(40);
+ closeButton.setStyle("-fx-background-color: transparent; -fx-text-fill: white; -fx-font-weight: bold;");
+ closeButton.visibleProperty().bind(dismissable);
+
+ closeButton.setOnAction(_ -> {
+ visibleProperty().unbind();
+ managedProperty().unbind();
+ visibleProperty().set(false);
+ managedProperty().set(false);
+ });
+ closeButton.visibleProperty().bind(dismissable);
+
+ getChildren().addAll(spacer, leftRegion, vbox, rightRegion, closeButton);
+
+ visibleProperty().bind(notifyProperty());
+ managedProperty().bind(notifyProperty());
+ }
+
+ public String getText() {
+ return notificationLabel.getText();
+ }
+
+ public void setText(String text) {
+ notificationLabel.setText(text);
+ }
+
+ public void setStyleClass(String styleClass) {
+ getStyleClass().clear();
+ getStyleClass().add(styleClass);
+ }
+
+ public boolean isDismissable() {
+ return dismissable.get();
+ }
+
+ public void setDismissable(boolean value) {
+ dismissable.set(value);
+ }
+
+ public boolean getNotify() {
+ return notify.get();
+ }
+
+ public void setNotify(boolean value) {
+ notify.set(value);
+ }
+
+ public BooleanProperty notifyProperty() {
+ return notify;
+ }
+
+}
diff --git a/src/main/java/org/cryptomator/ui/dialogs/Dialogs.java b/src/main/java/org/cryptomator/ui/dialogs/Dialogs.java
new file mode 100644
index 000000000..5107fe740
--- /dev/null
+++ b/src/main/java/org/cryptomator/ui/dialogs/Dialogs.java
@@ -0,0 +1,90 @@
+package org.cryptomator.ui.dialogs;
+
+import org.cryptomator.common.settings.Settings;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.ui.common.StageFactory;
+import org.cryptomator.ui.controls.FontAwesome5Icon;
+import org.cryptomator.ui.fxapp.FxApplicationScoped;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javafx.collections.ObservableList;
+import javafx.stage.Stage;
+import java.util.ResourceBundle;
+import java.util.function.Consumer;
+
+@FxApplicationScoped
+public class Dialogs {
+
+ private final ResourceBundle resourceBundle;
+ private final StageFactory stageFactory;
+
+ @Inject
+ public Dialogs(ResourceBundle resourceBundle, StageFactory stageFactory) {
+ this.resourceBundle = resourceBundle;
+ this.stageFactory = stageFactory;
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(Dialogs.class);
+
+ private SimpleDialog.Builder createDialogBuilder() {
+ return new SimpleDialog.Builder(resourceBundle, stageFactory);
+ }
+
+ public SimpleDialog.Builder prepareRemoveVaultDialog(Stage window, Vault vault, ObservableList vaults) {
+ return createDialogBuilder().setOwner(window) //
+ .setTitleKey("removeVault.title", vault.getDisplayName()) //
+ .setMessageKey("removeVault.message") //
+ .setDescriptionKey("removeVault.description") //
+ .setIcon(FontAwesome5Icon.QUESTION) //
+ .setOkButtonKey("removeVault.confirmBtn") //
+ .setCancelButtonKey("generic.button.cancel") //
+ .setOkAction(stage -> {
+ LOG.debug("Removing vault {}.", vault.getDisplayName());
+ vaults.remove(vault);
+ stage.close();
+ });
+ }
+
+ public SimpleDialog.Builder prepareRemoveCertDialog(Stage window, Settings settings) {
+ return createDialogBuilder() //
+ .setOwner(window) //
+ .setTitleKey("removeCert.title") //
+ .setMessageKey("removeCert.message") //
+ .setDescriptionKey("removeCert.description") //
+ .setIcon(FontAwesome5Icon.QUESTION) //
+ .setOkButtonKey("removeCert.confirmBtn") //
+ .setCancelButtonKey("generic.button.cancel") //
+ .setOkAction(stage -> {
+ settings.licenseKey.set(null);
+ stage.close();
+ });
+ }
+
+ public SimpleDialog.Builder prepareDokanySupportEndDialog(Stage window, Consumer cancelAction) {
+ return createDialogBuilder() //
+ .setOwner(window) //
+ .setTitleKey("dokanySupportEnd.title") //
+ .setMessageKey("dokanySupportEnd.message") //
+ .setDescriptionKey("dokanySupportEnd.description") //
+ .setIcon(FontAwesome5Icon.EXCLAMATION) //
+ .setOkButtonKey("generic.button.close") //
+ .setCancelButtonKey("dokanySupportEnd.preferencesBtn") //
+ .setOkAction(Stage::close) //
+ .setCancelAction(cancelAction);
+ }
+
+ public SimpleDialog.Builder prepareRetryIfReadonlyDialog(Stage window, Consumer okAction) {
+ return createDialogBuilder() //
+ .setOwner(window) //
+ .setTitleKey("retryIfReadonly.title") //
+ .setMessageKey("retryIfReadonly.message") //
+ .setDescriptionKey("retryIfReadonly.description") //
+ .setIcon(FontAwesome5Icon.EXCLAMATION) //
+ .setOkButtonKey("retryIfReadonly.retry") //
+ .setCancelButtonKey("generic.button.close") //
+ .setOkAction(okAction) //
+ .setCancelAction(Stage::close);
+ }
+}
diff --git a/src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java b/src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java
new file mode 100644
index 000000000..84d9e4f75
--- /dev/null
+++ b/src/main/java/org/cryptomator/ui/dialogs/SimpleDialog.java
@@ -0,0 +1,140 @@
+package org.cryptomator.ui.dialogs;
+
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlLoaderFactory;
+import org.cryptomator.ui.common.StageFactory;
+import org.cryptomator.ui.controls.FontAwesome5Icon;
+
+import javafx.scene.Scene;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.IllegalFormatException;
+import java.util.Objects;
+import java.util.ResourceBundle;
+import java.util.function.Consumer;
+
+public class SimpleDialog {
+
+ private final ResourceBundle resourceBundle;
+ private final Stage dialogStage;
+
+ SimpleDialog(Builder builder) throws IOException {
+ this.resourceBundle = builder.resourceBundle;
+ dialogStage = builder.stageFactory.create();
+ dialogStage.initOwner(builder.owner);
+ dialogStage.initModality(Modality.WINDOW_MODAL);
+ dialogStage.setTitle(resolveText(builder.titleKey, builder.titleArgs));
+ dialogStage.setResizable(false);
+
+ FxmlLoaderFactory loaderFactory = FxmlLoaderFactory.forController( //
+ new SimpleDialogController(resolveText(builder.messageKey, null), //
+ resolveText(builder.descriptionKey, null), //
+ builder.icon, resolveText(builder.okButtonKey, null), //
+ resolveText(builder.cancelButtonKey, null), //
+ () -> builder.okAction.accept(dialogStage), //
+ () -> builder.cancelAction.accept(dialogStage)), //
+ Scene::new, builder.resourceBundle);
+
+ dialogStage.setScene(new Scene(loaderFactory.load(FxmlFile.SIMPLE_DIALOG.getRessourcePathString()).getRoot()));
+ }
+
+ public void showAndWait() {
+ dialogStage.showAndWait();
+ }
+
+ private String resolveText(String key, String[] args) {
+ if (key == null || key.isEmpty() || !resourceBundle.containsKey(key)) {
+ throw new IllegalArgumentException(String.format("Invalid key: '%s'. Key not found in ResourceBundle.", key));
+ }
+ String text = resourceBundle.getString(key);
+ try {
+ return args != null && args.length > 0 ? String.format(text, (Object[]) args) : text;
+ } catch (IllegalFormatException e) {
+ throw new IllegalArgumentException("Formatting error: Check if arguments match placeholders in the text.", e);
+ }
+ }
+
+ public static class Builder {
+
+ private Stage owner;
+ private final ResourceBundle resourceBundle;
+ private final StageFactory stageFactory;
+ private String titleKey;
+ private String[] titleArgs;
+ private String messageKey;
+ private String descriptionKey;
+ private String okButtonKey;
+ private String cancelButtonKey;
+
+ private FontAwesome5Icon icon;
+ private Consumer okAction = Stage::close;
+ private Consumer cancelAction = Stage::close;
+
+ public Builder(ResourceBundle resourceBundle, StageFactory stageFactory) {
+ this.resourceBundle = resourceBundle;
+ this.stageFactory = stageFactory;
+ }
+
+ public Builder setOwner(Stage owner) {
+ this.owner = owner;
+ return this;
+ }
+
+ public Builder setTitleKey(String titleKey, String... args) {
+ this.titleKey = titleKey;
+ this.titleArgs = args;
+ return this;
+ }
+
+ public Builder setMessageKey(String messageKey) {
+ this.messageKey = messageKey;
+ return this;
+ }
+
+ public Builder setDescriptionKey(String descriptionKey) {
+ this.descriptionKey = descriptionKey;
+ return this;
+ }
+
+ public Builder setIcon(FontAwesome5Icon icon) {
+ this.icon = icon;
+ return this;
+ }
+
+ public Builder setOkButtonKey(String okButtonKey) {
+ this.okButtonKey = okButtonKey;
+ return this;
+ }
+
+ public Builder setCancelButtonKey(String cancelButtonKey) {
+ this.cancelButtonKey = cancelButtonKey;
+ return this;
+ }
+
+ public Builder setOkAction(Consumer okAction) {
+ this.okAction = okAction;
+ return this;
+ }
+
+ public Builder setCancelAction(Consumer cancelAction) {
+ this.cancelAction = cancelAction;
+ return this;
+ }
+
+ public SimpleDialog build() {
+ Objects.requireNonNull(titleKey, "SimpleDialog titleKey must be set.");
+ Objects.requireNonNull(messageKey, "SimpleDialog messageKey must be set.");
+ Objects.requireNonNull(descriptionKey, "SimpleDialog descriptionKey must be set.");
+ Objects.requireNonNull(okButtonKey, "SimpleDialog okButtonKey must be set.");
+ Objects.requireNonNull(cancelButtonKey, "SimpleDialog cancelButtonKey must be set.");
+
+ try {
+ return new SimpleDialog(this);
+ } catch (IOException e) {
+ throw new UncheckedIOException("Failed to create SimpleDialog.", e);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/ui/dialogs/SimpleDialogController.java b/src/main/java/org/cryptomator/ui/dialogs/SimpleDialogController.java
new file mode 100644
index 000000000..0eee1b308
--- /dev/null
+++ b/src/main/java/org/cryptomator/ui/dialogs/SimpleDialogController.java
@@ -0,0 +1,61 @@
+package org.cryptomator.ui.dialogs;
+
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.controls.FontAwesome5Icon;
+
+import javafx.fxml.FXML;
+
+public class SimpleDialogController implements FxController {
+
+ private final String message;
+ private final String description;
+ private final FontAwesome5Icon icon;
+ private final String okButtonText;
+ private final String cancelButtonText;
+ private final Runnable okAction;
+ private final Runnable cancelAction;
+
+ public SimpleDialogController(String message, String description, FontAwesome5Icon icon, String okButtonText, String cancelButtonText, Runnable okAction, Runnable cancelAction) {
+ this.message = message;
+ this.description = description;
+ this.icon = icon;
+ this.okButtonText = okButtonText;
+ this.cancelButtonText = cancelButtonText;
+ this.okAction = okAction;
+ this.cancelAction = cancelAction;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public FontAwesome5Icon getIcon() {
+ return icon;
+ }
+
+ public String getOkButtonText() {
+ return okButtonText;
+ }
+
+ public String getCancelButtonText() {
+ return cancelButtonText;
+ }
+
+ @FXML
+ private void handleOk() {
+ if (okAction != null) {
+ okAction.run();
+ }
+ }
+
+ @FXML
+ private void handleCancel() {
+ if (cancelAction != null) {
+ cancelAction.run();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndComponent.java b/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndComponent.java
deleted file mode 100644
index 48a5ab36c..000000000
--- a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndComponent.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import dagger.Lazy;
-import dagger.Subcomponent;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-@DokanySupportEndScoped
-@Subcomponent(modules = {DokanySupportEndModule.class})
-public interface DokanySupportEndComponent {
-
- @DokanySupportEndWindow
- Stage window();
-
- @FxmlScene(FxmlFile.DOKANY_SUPPORT_END)
- Lazy dokanySupportEndScene();
-
-
- default void showDokanySupportEndWindow() {
- Stage stage = window();
- stage.setScene(dokanySupportEndScene().get());
- stage.sizeToScene();
- stage.show();
- }
-
- @Subcomponent.Factory
- interface Factory {
-
- DokanySupportEndComponent create();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndController.java b/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndController.java
deleted file mode 100644
index a1d626402..000000000
--- a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndController.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.preferences.SelectedPreferencesTab;
-
-import javax.inject.Inject;
-import javafx.fxml.FXML;
-import javafx.stage.Stage;
-
-
-@DokanySupportEndScoped
-public class DokanySupportEndController implements FxController {
-
- private final Stage window;
- private final FxApplicationWindows applicationWindows;
-
- @Inject
- DokanySupportEndController(@DokanySupportEndWindow Stage window, FxApplicationWindows applicationWindows) {
- this.window = window;
- this.applicationWindows = applicationWindows;
- }
-
- @FXML
- public void close() {
- window.close();
- }
-
- public void openVolumePreferences() {
- applicationWindows.showPreferencesWindow(SelectedPreferencesTab.VOLUME);
- window.close();
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndModule.java b/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndModule.java
deleted file mode 100644
index 64689eb26..000000000
--- a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndModule.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import org.cryptomator.ui.common.DefaultSceneFactory;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxControllerKey;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlLoaderFactory;
-import org.cryptomator.ui.common.FxmlScene;
-import org.cryptomator.ui.common.StageFactory;
-
-import javax.inject.Provider;
-import javafx.scene.Scene;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-@Module
-abstract class DokanySupportEndModule {
-
- @Provides
- @DokanySupportEndWindow
- @DokanySupportEndScoped
- static FxmlLoaderFactory provideFxmlLoaderFactory(Map, Provider> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
- return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
- }
-
- @Provides
- @DokanySupportEndWindow
- @DokanySupportEndScoped
- static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle) {
- Stage stage = factory.create();
- stage.setTitle(resourceBundle.getString("dokanySupportEnd.title"));
- stage.setMinWidth(500);
- stage.setMinHeight(100);
- stage.initModality(Modality.APPLICATION_MODAL);
- return stage;
- }
-
- @Provides
- @FxmlScene(FxmlFile.DOKANY_SUPPORT_END)
- @DokanySupportEndScoped
- static Scene provideDokanySupportEndScene(@DokanySupportEndWindow FxmlLoaderFactory fxmlLoaders) {
- return fxmlLoaders.createScene(FxmlFile.DOKANY_SUPPORT_END);
- }
-
-
- @Binds
- @IntoMap
- @FxControllerKey(DokanySupportEndController.class)
- abstract FxController bindDokanySupportEndController(DokanySupportEndController controller);
-
-}
diff --git a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndScoped.java b/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndScoped.java
deleted file mode 100644
index 967e6f86f..000000000
--- a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndScoped.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import javax.inject.Scope;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Scope
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@interface DokanySupportEndScoped {
-
-}
diff --git a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndWindow.java b/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndWindow.java
deleted file mode 100644
index bb9b1617c..000000000
--- a/src/main/java/org/cryptomator/ui/dokanysupportend/DokanySupportEndWindow.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.cryptomator.ui.dokanysupportend;
-
-import javax.inject.Qualifier;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-@interface DokanySupportEndWindow {
-
-}
diff --git a/src/main/java/org/cryptomator/ui/error/ErrorComponent.java b/src/main/java/org/cryptomator/ui/error/ErrorComponent.java
index 554aa65f1..47798c920 100644
--- a/src/main/java/org/cryptomator/ui/error/ErrorComponent.java
+++ b/src/main/java/org/cryptomator/ui/error/ErrorComponent.java
@@ -20,6 +20,8 @@ public interface ErrorComponent {
default Stage show() {
Stage stage = window();
stage.setScene(scene());
+ stage.setMinWidth(420);
+ stage.setMinHeight(300);
stage.show();
return stage;
}
diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java
index 30e40ea8c..fd480033c 100644
--- a/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java
+++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java
@@ -11,6 +11,8 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javafx.application.Platform;
+import java.time.Duration;
+import java.time.Instant;
import java.util.concurrent.TimeUnit;
@FxApplicationScoped
@@ -72,8 +74,12 @@ public class FxApplication {
return null;
});
- if (!environment.disableUpdateCheck()) {
- appWindows.checkAndShowUpdateReminderWindow();
+ var time14DaysAgo = Instant.now().minus(Duration.ofDays(14));
+ if (!environment.disableUpdateCheck() //
+ && !settings.checkForUpdates.getValue() //
+ && settings.lastSuccessfulUpdateCheck.get().isBefore(time14DaysAgo) //
+ && settings.lastUpdateCheckReminder.get().isBefore(time14DaysAgo)) {
+ appWindows.showUpdateReminderWindow();
}
migrateAndInformDokanyRemoval();
diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java
index 0b8b6c70f..af98e284c 100644
--- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java
+++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationModule.java
@@ -7,7 +7,6 @@ package org.cryptomator.ui.fxapp;
import dagger.Module;
import dagger.Provides;
-import org.cryptomator.ui.dokanysupportend.DokanySupportEndComponent;
import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.health.HealthCheckComponent;
import org.cryptomator.ui.lock.LockComponent;
@@ -34,7 +33,6 @@ import java.io.InputStream;
ErrorComponent.class, //
HealthCheckComponent.class, //
UpdateReminderComponent.class, //
- DokanySupportEndComponent.class, //
ShareVaultComponent.class})
abstract class FxApplicationModule {
diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java
index 33d8491a7..54acf62a3 100644
--- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java
+++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationWindows.java
@@ -5,7 +5,7 @@ import dagger.Lazy;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.integrations.tray.TrayIntegrationProvider;
-import org.cryptomator.ui.dokanysupportend.DokanySupportEndComponent;
+import org.cryptomator.ui.dialogs.Dialogs;
import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.lock.LockComponent;
import org.cryptomator.ui.mainwindow.MainWindowComponent;
@@ -48,14 +48,14 @@ public class FxApplicationWindows {
private final Lazy preferencesWindow;
private final QuitComponent.Builder quitWindowBuilder;
private final UnlockComponent.Factory unlockWorkflowFactory;
- private final UpdateReminderComponent.Factory updateReminderWindowBuilder;
- private final DokanySupportEndComponent.Factory dokanySupportEndWindowBuilder;
+ private final UpdateReminderComponent.Factory updateReminderWindowFactory;
private final LockComponent.Factory lockWorkflowFactory;
private final ErrorComponent.Factory errorWindowFactory;
private final ExecutorService executor;
private final VaultOptionsComponent.Factory vaultOptionsWindow;
private final ShareVaultComponent.Factory shareVaultWindow;
private final FilteredList visibleWindows;
+ private final Dialogs dialogs;
@Inject
public FxApplicationWindows(@PrimaryStage Stage primaryStage, //
@@ -64,27 +64,27 @@ public class FxApplicationWindows {
Lazy preferencesWindow, //
QuitComponent.Builder quitWindowBuilder, //
UnlockComponent.Factory unlockWorkflowFactory, //
- UpdateReminderComponent.Factory updateReminderWindowBuilder, //
- DokanySupportEndComponent.Factory dokanySupportEndWindowBuilder, //
+ UpdateReminderComponent.Factory updateReminderWindowFactory, //
LockComponent.Factory lockWorkflowFactory, //
ErrorComponent.Factory errorWindowFactory, //
VaultOptionsComponent.Factory vaultOptionsWindow, //
ShareVaultComponent.Factory shareVaultWindow, //
- ExecutorService executor) {
+ ExecutorService executor, //
+ Dialogs dialogs) {
this.primaryStage = primaryStage;
this.trayIntegration = trayIntegration;
this.mainWindow = mainWindow;
this.preferencesWindow = preferencesWindow;
this.quitWindowBuilder = quitWindowBuilder;
this.unlockWorkflowFactory = unlockWorkflowFactory;
- this.updateReminderWindowBuilder = updateReminderWindowBuilder;
- this.dokanySupportEndWindowBuilder = dokanySupportEndWindowBuilder;
+ this.updateReminderWindowFactory = updateReminderWindowFactory;
this.lockWorkflowFactory = lockWorkflowFactory;
this.errorWindowFactory = errorWindowFactory;
this.executor = executor;
this.vaultOptionsWindow = vaultOptionsWindow;
this.shareVaultWindow = shareVaultWindow;
this.visibleWindows = Window.getWindows().filtered(Window::isShowing);
+ this.dialogs = dialogs;
}
public void initialize() {
@@ -142,15 +142,20 @@ public class FxApplicationWindows {
CompletableFuture.runAsync(() -> quitWindowBuilder.build().showQuitWindow(response,forced), Platform::runLater);
}
- public void checkAndShowUpdateReminderWindow() {
- CompletableFuture.runAsync(() -> updateReminderWindowBuilder.create().checkAndShowUpdateReminderWindow(), Platform::runLater);
+ public void showUpdateReminderWindow() {
+ CompletableFuture.runAsync(() -> updateReminderWindowFactory.create().showUpdateReminderWindow(), Platform::runLater);
}
public void showDokanySupportEndWindow() {
- CompletableFuture.runAsync(() -> dokanySupportEndWindowBuilder.create().showDokanySupportEndWindow(), Platform::runLater);
+ CompletableFuture.runAsync(() -> dialogs.prepareDokanySupportEndDialog(
+ mainWindow.get().window(),
+ stage -> {
+ showPreferencesWindow(SelectedPreferencesTab.VOLUME);
+ stage.close();
+ }
+ ).build().showAndWait(), Platform::runLater);
}
-
public CompletionStage startUnlockWorkflow(Vault vault, @Nullable Stage owner) {
return CompletableFuture.supplyAsync(() -> {
Preconditions.checkState(vault.stateProperty().transition(VaultState.Value.LOCKED, VaultState.Value.PROCESSING), "Vault not locked.");
diff --git a/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java b/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java
index aa69e0828..3903734c9 100644
--- a/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java
+++ b/src/main/java/org/cryptomator/ui/health/HealthCheckComponent.java
@@ -25,6 +25,8 @@ public interface HealthCheckComponent {
default Stage showHealthCheckWindow() {
Stage stage = window();
stage.setScene(startScene().get());
+ stage.setMinWidth(420);
+ stage.setMinHeight(300);
stage.show();
return stage;
}
diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java b/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java
index eefad55a2..4697864f7 100644
--- a/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java
+++ b/src/main/java/org/cryptomator/ui/keyloading/hub/HubConfig.java
@@ -20,7 +20,7 @@ public class HubConfig {
public String devicesResourceUrl;
/**
- * A collection of String template processors to construct URIs related to this Hub instance.
+ * A collection of functions to construct URIs related to this Hub instance.
*/
@JsonIgnore
public final URIProcessors URIs = new URIProcessors();
@@ -49,14 +49,20 @@ public class HubConfig {
public class URIProcessors {
+ public final URIProcessor API = this::fromApiEndpoint;
+
/**
* Resolves paths relative to the /api/ endpoint of this Hub instance.
*/
- public final StringTemplate.Processor API = template -> {
- var path = template.interpolate();
+ public URI fromApiEndpoint(String path) {
var relPath = path.startsWith("/") ? path.substring(1) : path;
return getApiBaseUrl().resolve(relPath);
- };
+ }
+ }
+ @FunctionalInterface
+ public interface URIProcessor {
+
+ URI resolve(String path);
}
}
diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java
index 3bfb4ec8e..aa56a22e7 100644
--- a/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java
+++ b/src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java
@@ -88,7 +88,7 @@ public class ReceiveKeyController implements FxController {
* STEP 0 (Request): GET /api/config
*/
private void requestApiConfig() {
- var configUri = hubConfig.URIs.API."config";
+ var configUri = hubConfig.URIs.API.resolve("config");
var request = HttpRequest.newBuilder(configUri) //
.GET() //
.timeout(REQ_TIMEOUT) //
@@ -122,7 +122,7 @@ public class ReceiveKeyController implements FxController {
* STEP 1 (Request): GET user key for this device
*/
private void requestDeviceData() {
- var deviceUri = hubConfig.URIs.API."devices/\{deviceId}";
+ var deviceUri = hubConfig.URIs.API.resolve("devices/" + deviceId);
var request = HttpRequest.newBuilder(deviceUri) //
.header("Authorization", "Bearer " + bearerToken) //
.GET() //
@@ -162,7 +162,7 @@ public class ReceiveKeyController implements FxController {
* STEP 2 (Request): GET vault key for this user
*/
private void requestVaultMasterkey(String encryptedUserKey) {
- var vaultKeyUri = hubConfig.URIs.API."vaults/\{vaultId}/access-token";
+ var vaultKeyUri = hubConfig.URIs.API.resolve("vaults/" + vaultId + "/access-token");
var request = HttpRequest.newBuilder(vaultKeyUri) //
.header("Authorization", "Bearer " + bearerToken) //
.GET() //
@@ -205,7 +205,7 @@ public class ReceiveKeyController implements FxController {
*/
@Deprecated
private void requestLegacyAccessToken() {
- var legacyAccessTokenUri = hubConfig.URIs.API."vaults/\{vaultId}/keys/\{deviceId}";
+ var legacyAccessTokenUri = hubConfig.URIs.API.resolve("vaults/" + vaultId + "/keys/" + deviceId);
var request = HttpRequest.newBuilder(legacyAccessTokenUri) //
.header("Authorization", "Bearer " + bearerToken) //
.GET() //
diff --git a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java
index b00d49874..186d06208 100644
--- a/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java
+++ b/src/main/java/org/cryptomator/ui/keyloading/hub/RegisterDeviceController.java
@@ -115,7 +115,7 @@ public class RegisterDeviceController implements FxController {
workInProgress.set(true);
- var userReq = HttpRequest.newBuilder(hubConfig.URIs.API."users/me") //
+ var userReq = HttpRequest.newBuilder(hubConfig.URIs.API.resolve("users/me")) //
.GET() //
.timeout(REQ_TIMEOUT) //
.header("Authorization", "Bearer " + bearerToken) //
@@ -143,7 +143,7 @@ public class RegisterDeviceController implements FxController {
var now = Instant.now().toString();
var dto = new CreateDeviceDto(deviceId, deviceNameField.getText(), BaseEncoding.base64().encode(deviceKeyPair.getPublic().getEncoded()), "DESKTOP", jwe.serialize(), now);
var json = toJson(dto);
- var deviceUri = hubConfig.URIs.API."devices/\{deviceId}";
+ var deviceUri = hubConfig.URIs.fromApiEndpoint("devices/" + deviceId);
var putDeviceReq = HttpRequest.newBuilder(deviceUri) //
.PUT(HttpRequest.BodyPublishers.ofString(json, StandardCharsets.UTF_8)) //
.timeout(REQ_TIMEOUT) //
@@ -164,7 +164,7 @@ public class RegisterDeviceController implements FxController {
private void migrateLegacyDevices(ECPublicKey userPublicKey) {
try {
// GET legacy access tokens
- var getUri = hubConfig.URIs.API."devices/\{deviceId}/legacy-access-tokens";
+ var getUri = hubConfig.URIs.API.resolve("devices/" + deviceId + "/legacy-access-tokens");
var getReq = HttpRequest.newBuilder(getUri).GET().timeout(REQ_TIMEOUT).header("Authorization", "Bearer " + bearerToken).build();
var getRes = httpClient.send(getReq, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
if (getRes.statusCode() != 200) {
@@ -185,12 +185,12 @@ public class RegisterDeviceController implements FxController {
LOG.warn("Failed to decrypt legacy access token for vault {}. Skipping migration.", entry.getKey());
}
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
- var postUri = hubConfig.URIs.API."users/me/access-tokens";
+ var postUri = hubConfig.URIs.fromApiEndpoint("users/me/access-tokens");
var postBody = JSON.writer().writeValueAsString(newAccessTokens);
var postReq = HttpRequest.newBuilder(postUri).POST(HttpRequest.BodyPublishers.ofString(postBody)).timeout(REQ_TIMEOUT).header("Authorization", "Bearer " + bearerToken).build();
var postRes = httpClient.send(postReq, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
if (postRes.statusCode() != 200) {
- throw new IOException(STR."Unexpected response from POST \{postUri}: \{postRes.statusCode()}");
+ throw new IOException("Unexpected response from POST " + postUri + ": " + postRes.statusCode());
}
} catch (IOException e) {
// log and ignore: this is merely a best-effort attempt of migrating legacy devices. Failure is uncritical as this is merely a convenience feature.
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java
index b2c912834..999ff7882 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java
@@ -1,19 +1,26 @@
package org.cryptomator.ui.mainwindow;
-import org.apache.commons.lang3.SystemUtils;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.common.vaults.VaultListManager;
-import org.cryptomator.ui.common.FxController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
import javafx.beans.Observable;
+import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
+import org.apache.commons.lang3.SystemUtils;
+import org.cryptomator.common.LicenseHolder;
+import org.cryptomator.common.settings.Settings;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.common.vaults.VaultListManager;
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.fxapp.FxApplicationWindows;
+import org.cryptomator.ui.fxapp.UpdateChecker;
+import org.cryptomator.ui.preferences.SelectedPreferencesTab;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
@MainWindowScoped
public class MainWindowController implements FxController {
@@ -22,22 +29,61 @@ public class MainWindowController implements FxController {
private final Stage window;
private final ReadOnlyObjectProperty selectedVault;
+ private final Settings settings;
+ private final FxApplicationWindows appWindows;
+ private final BooleanBinding updateAvailable;
+ private final LicenseHolder licenseHolder;
- public StackPane root;
+ @FXML
+ private StackPane root;
@Inject
- public MainWindowController(@MainWindow Stage window, ObjectProperty selectedVault) {
+ public MainWindowController(@MainWindow Stage window, //
+ ObjectProperty selectedVault, //
+ Settings settings, //
+ FxApplicationWindows appWindows, //
+ UpdateChecker updateChecker, //
+ LicenseHolder licenseHolder) {
this.window = window;
this.selectedVault = selectedVault;
+ this.settings = settings;
+ this.appWindows = appWindows;
+ this.updateAvailable = updateChecker.updateAvailableProperty();
+ this.licenseHolder = licenseHolder;
+ updateChecker.automaticallyCheckForUpdatesIfEnabled();
+
}
@FXML
public void initialize() {
LOG.trace("init MainWindowController");
+
if (SystemUtils.IS_OS_WINDOWS) {
root.getStyleClass().add("os-windows");
}
window.focusedProperty().addListener(this::mainWindowFocusChanged);
+
+ if (!neverTouched()) {
+ window.setHeight(settings.windowHeight.get() > window.getMinHeight() ? settings.windowHeight.get() : window.getMinHeight());
+ window.setWidth(settings.windowWidth.get() > window.getMinWidth() ? settings.windowWidth.get() : window.getMinWidth());
+ window.setX(settings.windowXPosition.get());
+ window.setY(settings.windowYPosition.get());
+ }
+ window.widthProperty().addListener((_, _, _) -> savePositionalSettings());
+ window.heightProperty().addListener((_, _, _) -> savePositionalSettings());
+ window.xProperty().addListener((_, _, _) -> savePositionalSettings());
+ window.yProperty().addListener((_, _, _) -> savePositionalSettings());
+ }
+
+ private boolean neverTouched() {
+ return (settings.windowHeight.get() == 0) && (settings.windowWidth.get() == 0) && (settings.windowXPosition.get() == 0) && (settings.windowYPosition.get() == 0);
+ }
+
+ public void savePositionalSettings() {
+ settings.windowWidth.setValue(window.getWidth());
+ settings.windowHeight.setValue(window.getHeight());
+ settings.windowXPosition.setValue(window.getX());
+ settings.windowYPosition.setValue(window.getY());
}
private void mainWindowFocusChanged(Observable observable) {
@@ -47,4 +93,43 @@ public class MainWindowController implements FxController {
}
}
+ @FXML
+ public void showGeneralPreferences() {
+ appWindows.showPreferencesWindow(SelectedPreferencesTab.GENERAL);
+ }
+
+ @FXML
+ public void showContributePreferences() {
+ appWindows.showPreferencesWindow(SelectedPreferencesTab.CONTRIBUTE);
+ }
+
+ @FXML
+ public void showUpdatePreferences() {
+ appWindows.showPreferencesWindow(SelectedPreferencesTab.UPDATES);
+ }
+
+ public ReadOnlyBooleanProperty debugModeEnabledProperty() {
+ return settings.debugMode;
+ }
+
+ public boolean getDebugModeEnabled() {
+ return debugModeEnabledProperty().get();
+ }
+
+ public BooleanBinding updateAvailableProperty() {
+ return updateAvailable;
+ }
+
+ public boolean getUpdateAvailable() {
+ return updateAvailable.get();
+ }
+
+ public BooleanBinding licenseValidProperty(){
+ return licenseHolder.validLicenseProperty();
+ }
+
+ public boolean getLicenseValid() {
+ return licenseHolder.isValidLicense();
+ }
+
}
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java
index 0b403bb47..b80804f2e 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java
@@ -6,7 +6,6 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
-import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -14,10 +13,9 @@ import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.common.StageInitializer;
+import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.fxapp.PrimaryStage;
-import org.cryptomator.ui.health.HealthCheckComponent;
import org.cryptomator.ui.migration.MigrationComponent;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
import org.cryptomator.ui.stats.VaultStatisticsComponent;
import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
@@ -28,11 +26,10 @@ import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
-import javafx.stage.StageStyle;
import java.util.Map;
import java.util.ResourceBundle;
-@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, RemoveVaultComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class})
+@Module(subcomponents = {AddVaultWizardComponent.class, MigrationComponent.class, VaultStatisticsComponent.class, WrongFileAlertComponent.class, ErrorComponent.class})
abstract class MainWindowModule {
@Provides
@@ -41,9 +38,8 @@ abstract class MainWindowModule {
static Stage provideMainWindow(@PrimaryStage Stage stage, StageInitializer initializer) {
initializer.accept(stage);
stage.setTitle("Cryptomator");
- stage.initStyle(StageStyle.UNDECORATED);
stage.setMinWidth(650);
- stage.setMinHeight(440);
+ stage.setMinHeight(498);
return stage;
}
@@ -85,16 +81,6 @@ abstract class MainWindowModule {
@FxControllerKey(MainWindowController.class)
abstract FxController bindMainWindowController(MainWindowController controller);
- @Binds
- @IntoMap
- @FxControllerKey(MainWindowTitleController.class)
- abstract FxController bindMainWindowTitleController(MainWindowTitleController controller);
-
- @Binds
- @IntoMap
- @FxControllerKey(ResizeController.class)
- abstract FxController bindResizeController(ResizeController controller);
-
@Binds
@IntoMap
@FxControllerKey(VaultListController.class)
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java
index d78192186..fbc96513b 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java
@@ -18,22 +18,20 @@ public class MainWindowSceneFactory extends DefaultSceneFactory {
protected static final KeyCodeCombination SHORTCUT_N = new KeyCodeCombination(KeyCode.N, KeyCombination.SHORTCUT_DOWN);
protected static final KeyCodeCombination SHORTCUT_O = new KeyCodeCombination(KeyCode.O, KeyCombination.SHORTCUT_DOWN);
- private final Lazy mainWindowTitleController;
+ private final Stage window;
private final Lazy vaultListController;
@Inject
- public MainWindowSceneFactory(Settings settings, Lazy mainWindowTitleController, Lazy vaultListController) {
+ public MainWindowSceneFactory(Settings settings, @MainWindow Stage window, Lazy vaultListController) {
super(settings);
- this.mainWindowTitleController = mainWindowTitleController;
+ this.window = window;
this.vaultListController = vaultListController;
}
@Override
protected void setupDefaultAccelerators(Scene scene, Stage stage) {
- if (SystemUtils.IS_OS_WINDOWS) {
- scene.getAccelerators().put(ALT_F4, mainWindowTitleController.get()::close);
- } else {
- scene.getAccelerators().put(SHORTCUT_W, mainWindowTitleController.get()::close);
+ if (!SystemUtils.IS_OS_WINDOWS) {
+ scene.getAccelerators().put(SHORTCUT_W, window::close);
}
scene.getAccelerators().put(SHORTCUT_N, vaultListController.get()::didClickAddNewVault);
scene.getAccelerators().put(SHORTCUT_O, vaultListController.get()::didClickAddExistingVault);
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowTitleController.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowTitleController.java
deleted file mode 100644
index f3c92790d..000000000
--- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowTitleController.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.cryptomator.ui.mainwindow;
-
-import org.cryptomator.common.LicenseHolder;
-import org.cryptomator.common.settings.Settings;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.fxapp.FxApplicationTerminator;
-import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.fxapp.UpdateChecker;
-import org.cryptomator.ui.preferences.SelectedPreferencesTab;
-import org.cryptomator.ui.traymenu.TrayMenuComponent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javafx.beans.binding.Bindings;
-import javafx.beans.binding.BooleanBinding;
-import javafx.beans.property.ReadOnlyBooleanProperty;
-import javafx.fxml.FXML;
-import javafx.scene.input.MouseButton;
-import javafx.scene.layout.HBox;
-import javafx.stage.Stage;
-
-@MainWindowScoped
-public class MainWindowTitleController implements FxController {
-
- private static final Logger LOG = LoggerFactory.getLogger(MainWindowTitleController.class);
-
- private final Stage window;
- private final FxApplicationTerminator terminator;
- private final FxApplicationWindows appWindows;
- private final boolean trayMenuInitialized;
- private final UpdateChecker updateChecker;
- private final BooleanBinding updateAvailable;
- private final LicenseHolder licenseHolder;
- private final Settings settings;
- private final BooleanBinding showMinimizeButton;
-
- public HBox titleBar;
- private double xOffset;
- private double yOffset;
-
- @Inject
- MainWindowTitleController(@MainWindow Stage window, FxApplicationTerminator terminator, FxApplicationWindows appWindows, TrayMenuComponent trayMenu, UpdateChecker updateChecker, LicenseHolder licenseHolder, Settings settings) {
- this.window = window;
- this.terminator = terminator;
- this.appWindows = appWindows;
- this.trayMenuInitialized = trayMenu.isInitialized();
- this.updateChecker = updateChecker;
- this.updateAvailable = updateChecker.updateAvailableProperty();
- this.licenseHolder = licenseHolder;
- this.settings = settings;
- this.showMinimizeButton = Bindings.createBooleanBinding(this::isShowMinimizeButton, settings.showMinimizeButton, settings.showTrayIcon);
- }
-
- @FXML
- public void initialize() {
- LOG.trace("init MainWindowTitleController");
- updateChecker.automaticallyCheckForUpdatesIfEnabled();
- titleBar.setOnMousePressed(event -> {
- xOffset = event.getSceneX();
- yOffset = event.getSceneY();
-
- });
- titleBar.setOnMouseClicked(event -> {
- if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
- window.setFullScreen(!window.isFullScreen());
- }
- });
- titleBar.setOnMouseDragged(event -> {
- if (window.isFullScreen()) return;
- window.setX(event.getScreenX() - xOffset);
- window.setY(event.getScreenY() - yOffset);
- });
- titleBar.setOnDragDetected(mouseDragEvent -> {
- titleBar.startFullDrag();
- });
- titleBar.setOnMouseDragReleased(mouseDragEvent -> {
- saveWindowSettings();
- });
-
- window.setOnCloseRequest(event -> {
- close();
- event.consume();
- });
- }
-
- private void saveWindowSettings() {
- settings.windowXPosition.setValue(window.getX());
- settings.windowYPosition.setValue(window.getY());
- settings.windowWidth.setValue(window.getWidth());
- settings.windowHeight.setValue(window.getHeight());
- }
-
- @FXML
- public void close() {
- if (trayMenuInitialized) {
- window.close();
- } else {
- terminator.terminate();
- }
- }
-
- @FXML
- public void minimize() {
- window.setIconified(true);
- }
-
- @FXML
- public void showPreferences() {
- appWindows.showPreferencesWindow(SelectedPreferencesTab.ANY);
- }
-
- @FXML
- public void showGeneralPreferences() {
- appWindows.showPreferencesWindow(SelectedPreferencesTab.GENERAL);
- }
-
- @FXML
- public void showContributePreferences() {
- appWindows.showPreferencesWindow(SelectedPreferencesTab.CONTRIBUTE);
- }
-
- /* Getter/Setter */
-
- public LicenseHolder getLicenseHolder() {
- return licenseHolder;
- }
-
- public BooleanBinding updateAvailableProperty() {
- return updateAvailable;
- }
-
- public boolean isUpdateAvailable() {
- return updateAvailable.get();
- }
-
- public boolean isTrayIconPresent() {
- return trayMenuInitialized;
- }
-
- public ReadOnlyBooleanProperty debugModeEnabledProperty() {
- return settings.debugMode;
- }
-
- public boolean isDebugModeEnabled() {
- return debugModeEnabledProperty().get();
- }
-
- public BooleanBinding showMinimizeButtonProperty() {
- return showMinimizeButton;
- }
-
- public boolean isShowMinimizeButton() {
- // always show the minimize button if no tray icon is present OR it is explicitly enabled
- return !trayMenuInitialized || settings.showMinimizeButton.get();
- }
-}
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java b/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java
deleted file mode 100644
index 2c3838ea0..000000000
--- a/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java
+++ /dev/null
@@ -1,194 +0,0 @@
-package org.cryptomator.ui.mainwindow;
-
-import org.cryptomator.common.settings.Settings;
-import org.cryptomator.ui.common.FxController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javafx.beans.binding.BooleanBinding;
-import javafx.fxml.FXML;
-import javafx.geometry.Rectangle2D;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.Region;
-import javafx.stage.Screen;
-import javafx.stage.Stage;
-import javafx.stage.WindowEvent;
-
-@MainWindow
-public class ResizeController implements FxController {
-
- private static final Logger LOG = LoggerFactory.getLogger(ResizeController.class);
-
- private final Stage window;
-
- public Region tlResizer;
- public Region trResizer;
- public Region blResizer;
- public Region brResizer;
- public Region tResizer;
- public Region rResizer;
- public Region bResizer;
- public Region lResizer;
- public Region lDefaultRegion;
- public Region tDefaultRegion;
- public Region rDefaultRegion;
- public Region bDefaultRegion;
-
- private double origX, origY, origW, origH;
-
- private final Settings settings;
-
- private final BooleanBinding showResizingArrows;
-
- @Inject
- ResizeController(@MainWindow Stage window, Settings settings) {
- this.window = window;
- this.settings = settings;
- this.showResizingArrows = window.fullScreenProperty().not();
- }
-
- @FXML
- public void initialize() {
- LOG.trace("init ResizeController");
-
- if (!neverTouched()) {
- window.setHeight(settings.windowHeight.get() > window.getMinHeight() ? settings.windowHeight.get() : window.getMinHeight());
- window.setWidth(settings.windowWidth.get() > window.getMinWidth() ? settings.windowWidth.get() : window.getMinWidth());
- window.setX(settings.windowXPosition.get());
- window.setY(settings.windowYPosition.get());
- }
-
- window.setOnShowing(this::checkDisplayBounds);
- }
-
- private boolean neverTouched() {
- return (settings.windowHeight.get() == 0) && (settings.windowWidth.get() == 0) && (settings.windowXPosition.get() == 0) && (settings.windowYPosition.get() == 0);
- }
-
- private void checkDisplayBounds(WindowEvent evt) {
- // Minimizing a window in Windows and closing it could result in an out of bounds position at (x, y) = (-32000, -32000)
- // See https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37453
- // If the position is (-32000, -32000), restore to the last saved position
- if (window.getX() == -32000 && window.getY() == -32000) {
- window.setX(settings.windowXPosition.get());
- window.setY(settings.windowYPosition.get());
- window.setWidth(settings.windowWidth.get());
- window.setHeight(settings.windowHeight.get());
- }
-
- if (isOutOfDisplayBounds()) {
- // If the position is illegal, then the window appears on the main screen in the middle of the window.
- LOG.debug("Resetting window position due to insufficient screen overlap");
- Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds();
- window.setX((primaryScreenBounds.getWidth() - window.getMinWidth()) / 2);
- window.setY((primaryScreenBounds.getHeight() - window.getMinHeight()) / 2);
- window.setWidth(window.getMinWidth());
- window.setHeight(window.getMinHeight());
- savePositionalSettings();
- }
- }
-
- private boolean isOutOfDisplayBounds() {
- // define a rect which is inset on all sides from the window's rect:
- final double x = window.getX() + 20; // 20px left
- final double y = window.getY() + 5; // 5px top
- final double w = window.getWidth() - 40; // 20px left + 20px right
- final double h = window.getHeight() - 25; // 5px top + 20px bottom
- return isRectangleOutOfScreen(x, y, 0, h) // Left pixel column
- || isRectangleOutOfScreen(x + w, y, 0, h) // Right pixel column
- || isRectangleOutOfScreen(x, y, w, 0) // Top pixel row
- || isRectangleOutOfScreen(x, y + h, w, 0); // Bottom pixel row
- }
-
- private boolean isRectangleOutOfScreen(double x, double y, double width, double height) {
- return Screen.getScreensForRectangle(x, y, width, height).isEmpty();
- }
-
- private void startResize(MouseEvent evt) {
- origX = window.getX();
- origY = window.getY();
- origW = window.getWidth();
- origH = window.getHeight();
- }
-
- @FXML
- private void resizeTopLeft(MouseEvent evt) {
- resizeTop(evt);
- resizeLeft(evt);
- }
-
- @FXML
- private void resizeTopRight(MouseEvent evt) {
- resizeTop(evt);
- resizeRight(evt);
- }
-
- @FXML
- private void resizeBottomLeft(MouseEvent evt) {
- resizeBottom(evt);
- resizeLeft(evt);
- }
-
- @FXML
- private void resizeBottomRight(MouseEvent evt) {
- resizeBottom(evt);
- resizeRight(evt);
- }
-
- @FXML
- private void resizeTop(MouseEvent evt) {
- startResize(evt);
- double newY = evt.getScreenY();
- double dy = newY - origY;
- double newH = origH - dy;
- if (newH < window.getMaxHeight() && newH > window.getMinHeight()) {
- window.setY(newY);
- window.setHeight(newH);
- }
- }
-
- @FXML
- private void resizeLeft(MouseEvent evt) {
- startResize(evt);
- double newX = evt.getScreenX();
- double dx = newX - origX;
- double newW = origW - dx;
- if (newW < window.getMaxWidth() && newW > window.getMinWidth()) {
- window.setX(newX);
- window.setWidth(newW);
- }
- }
-
- @FXML
- private void resizeBottom(MouseEvent evt) {
- double newH = evt.getSceneY();
- if (newH < window.getMaxHeight() && newH > window.getMinHeight()) {
- window.setHeight(newH);
- }
- }
-
- @FXML
- private void resizeRight(MouseEvent evt) {
- double newW = evt.getSceneX();
- if (newW < window.getMaxWidth() && newW > window.getMinWidth()) {
- window.setWidth(newW);
- }
- }
-
- @FXML
- public void savePositionalSettings() {
- settings.windowWidth.setValue(window.getWidth());
- settings.windowHeight.setValue(window.getHeight());
- settings.windowXPosition.setValue(window.getX());
- settings.windowYPosition.setValue(window.getY());
- }
-
- public BooleanBinding showResizingArrowsProperty() {
- return showResizingArrows;
- }
-
- public boolean isShowResizingArrows() {
- return showResizingArrows.get();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java
index 372d29040..6f57a0d17 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailMissingVaultController.java
@@ -3,10 +3,11 @@ package org.cryptomator.ui.mainwindow;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
+import org.cryptomator.ui.dialogs.Dialogs;
import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
+import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
@@ -19,17 +20,22 @@ import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
public class VaultDetailMissingVaultController implements FxController {
private final ObjectProperty vault;
- private final RemoveVaultComponent.Builder removeVault;
+ private final ObservableList vaults;
private final ResourceBundle resourceBundle;
private final Stage window;
-
+ private final Dialogs dialogs;
@Inject
- public VaultDetailMissingVaultController(ObjectProperty vault, RemoveVaultComponent.Builder removeVault, ResourceBundle resourceBundle, @MainWindow Stage window) {
+ public VaultDetailMissingVaultController(ObjectProperty vault, //
+ ObservableList vaults, //
+ ResourceBundle resourceBundle, //
+ @MainWindow Stage window, //
+ Dialogs dialogs) {
this.vault = vault;
- this.removeVault = removeVault;
+ this.vaults = vaults;
this.resourceBundle = resourceBundle;
this.window = window;
+ this.dialogs = dialogs;
}
@FXML
@@ -39,7 +45,7 @@ public class VaultDetailMissingVaultController implements FxController {
@FXML
void didClickRemoveVault() {
- removeVault.vault(vault.get()).build().showRemoveVault();
+ dialogs.prepareRemoveVaultDialog(window, vault.get(), vaults).build().showAndWait();
}
@FXML
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java
index 6e40d54b3..503e50ffd 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnknownErrorController.java
@@ -3,12 +3,13 @@ package org.cryptomator.ui.mainwindow;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.dialogs.Dialogs;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
import javax.inject.Inject;
import javax.inject.Named;
import javafx.beans.property.ObjectProperty;
+import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.stage.Stage;
@@ -18,14 +19,23 @@ public class VaultDetailUnknownErrorController implements FxController {
private final ObjectProperty vault;
private final FxApplicationWindows appWindows;
private final Stage errorWindow;
- private final RemoveVaultComponent.Builder removeVault;
+ private final ObservableList vaults;
+ private final Stage mainWindow;
+ private final Dialogs dialogs;
@Inject
- public VaultDetailUnknownErrorController(ObjectProperty vault, FxApplicationWindows appWindows, @Named("errorWindow") Stage errorWindow, RemoveVaultComponent.Builder removeVault) {
+ public VaultDetailUnknownErrorController(@MainWindow Stage mainWindow, //
+ ObjectProperty vault, //
+ ObservableList vaults, //
+ FxApplicationWindows appWindows, //
+ @Named("errorWindow") Stage errorWindow, //
+ Dialogs dialogs) {
+ this.mainWindow = mainWindow;
this.vault = vault;
+ this.vaults = vaults;
this.appWindows = appWindows;
this.errorWindow = errorWindow;
- this.removeVault = removeVault;
+ this.dialogs = dialogs;
}
@FXML
@@ -40,6 +50,6 @@ public class VaultDetailUnknownErrorController implements FxController {
@FXML
void didClickRemoveVault() {
- removeVault.vault(vault.get()).build().showRemoveVault();
+ dialogs.prepareRemoveVaultDialog(mainWindow, vault.get(), vaults).build().showAndWait();
}
}
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListCellController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListCellController.java
index 6374d7ae3..75ce21dfe 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListCellController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListCellController.java
@@ -1,5 +1,6 @@
package org.cryptomator.ui.mainwindow;
+import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.ui.common.Animations;
@@ -12,21 +13,31 @@ import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
+import javafx.fxml.FXML;
+import javafx.geometry.Insets;
+import javafx.scene.layout.HBox;
// unscoped because each cell needs its own controller
public class VaultListCellController implements FxController {
+ private static final Insets COMPACT_INSETS = new Insets(6, 12, 6, 12);
+ private static final Insets DEFAULT_INSETS = new Insets(12);
+
private final ObjectProperty vault = new SimpleObjectProperty<>();
private final ObservableValue glyph;
+ private final ObservableValue compactMode;
private AutoAnimator spinAnimation;
/* FXML */
public FontAwesome5IconView vaultStateView;
+ @FXML
+ public HBox vaultListCell;
@Inject
- VaultListCellController() {
+ VaultListCellController(Settings settings) {
this.glyph = vault.flatMap(Vault::stateProperty).map(this::getGlyphForVaultState);
+ this.compactMode = settings.compactMode;
}
public void initialize() {
@@ -34,6 +45,7 @@ public class VaultListCellController implements FxController {
.onCondition(vault.flatMap(Vault::stateProperty).map(VaultState.Value.PROCESSING::equals).orElse(false)) //
.afterStop(() -> vaultStateView.setRotate(0)) //
.build();
+ this.vaultListCell.paddingProperty().bind(compactMode.map(c -> c ? COMPACT_INSETS : DEFAULT_INSETS));
}
// TODO deduplicate w/ VaultDetailController
@@ -68,6 +80,14 @@ public class VaultListCellController implements FxController {
return vault.get();
}
+ public ObservableValue compactModeProperty() {
+ return compactMode;
+ }
+
+ public boolean getCompactMode() {
+ return compactMode.getValue();
+ }
+
public void setVault(Vault value) {
vault.set(value);
}
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java
index a6baa0baf..97c03194f 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListContextMenuController.java
@@ -5,8 +5,8 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.VaultService;
+import org.cryptomator.ui.dialogs.Dialogs;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
import org.cryptomator.ui.vaultoptions.SelectedVaultOptionsTab;
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
@@ -14,6 +14,7 @@ import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.value.ObservableValue;
+import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.stage.Stage;
import java.util.EnumSet;
@@ -33,23 +34,32 @@ public class VaultListContextMenuController implements FxController {
private final FxApplicationWindows appWindows;
private final VaultService vaultService;
private final KeychainManager keychain;
- private final RemoveVaultComponent.Builder removeVault;
private final VaultOptionsComponent.Factory vaultOptionsWindow;
private final ObservableValue selectedVaultState;
private final ObservableValue selectedVaultPassphraseStored;
private final ObservableValue selectedVaultRemovable;
private final ObservableValue selectedVaultUnlockable;
private final ObservableValue selectedVaultLockable;
+ private final ObservableList vaults;
+ private final Dialogs dialogs;
@Inject
- VaultListContextMenuController(ObjectProperty selectedVault, @MainWindow Stage mainWindow, FxApplicationWindows appWindows, VaultService vaultService, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Factory vaultOptionsWindow) {
+ VaultListContextMenuController(ObjectProperty selectedVault, //
+ ObservableList vaults, //
+ @MainWindow Stage mainWindow, //
+ FxApplicationWindows appWindows, //
+ VaultService vaultService, //
+ KeychainManager keychain, //
+ VaultOptionsComponent.Factory vaultOptionsWindow, //
+ Dialogs dialogs) {
this.selectedVault = selectedVault;
+ this.vaults = vaults;
this.mainWindow = mainWindow;
this.appWindows = appWindows;
this.vaultService = vaultService;
this.keychain = keychain;
- this.removeVault = removeVault;
this.vaultOptionsWindow = vaultOptionsWindow;
+ this.dialogs = dialogs;
this.selectedVaultState = selectedVault.flatMap(Vault::stateProperty).orElse(null);
this.selectedVaultPassphraseStored = selectedVault.map(this::isPasswordStored).orElse(false);
@@ -65,7 +75,7 @@ public class VaultListContextMenuController implements FxController {
@FXML
public void didClickRemoveVault() {
var vault = Objects.requireNonNull(selectedVault.get());
- removeVault.vault(vault).build().showRemoveVault();
+ dialogs.prepareRemoveVaultDialog(mainWindow, vault, vaults).build().showAndWait();
}
@FXML
diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java
index e8ea21fe4..e353fe8ed 100644
--- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java
+++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java
@@ -1,6 +1,7 @@
package org.cryptomator.ui.mainwindow;
import org.apache.commons.lang3.SystemUtils;
+import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
@@ -8,8 +9,9 @@ import org.cryptomator.cryptofs.DirStructure;
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.VaultService;
+import org.cryptomator.ui.dialogs.Dialogs;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
-import org.cryptomator.ui.removevault.RemoveVaultComponent;
+import org.cryptomator.ui.preferences.SelectedPreferencesTab;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,7 +26,6 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.geometry.Side;
-import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListView;
import javafx.scene.input.ContextMenuEvent;
@@ -33,6 +34,7 @@ import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
+import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.io.File;
@@ -64,15 +66,17 @@ public class VaultListController implements FxController {
private final VaultListCellFactory cellFactory;
private final AddVaultWizardComponent.Builder addVaultWizard;
private final BooleanBinding emptyVaultList;
- private final RemoveVaultComponent.Builder removeVaultDialogue;
private final VaultListManager vaultListManager;
private final BooleanProperty draggingVaultOver = new SimpleBooleanProperty();
private final ResourceBundle resourceBundle;
private final FxApplicationWindows appWindows;
+ private final ObservableValue cellSize;
+ private final Dialogs dialogs;
public ListView vaultList;
public StackPane root;
- public Button addVaultBtn;
+ @FXML
+ private HBox addVaultButton;
@FXML
private ContextMenu addVaultContextMenu;
@@ -83,29 +87,36 @@ public class VaultListController implements FxController {
VaultListCellFactory cellFactory, //
VaultService vaultService, //
AddVaultWizardComponent.Builder addVaultWizard, //
- RemoveVaultComponent.Builder removeVaultDialogue, //
VaultListManager vaultListManager, //
ResourceBundle resourceBundle, //
- FxApplicationWindows appWindows) {
+ FxApplicationWindows appWindows, //
+ Settings settings, //
+ Dialogs dialogs) {
this.mainWindow = mainWindow;
this.vaults = vaults;
this.selectedVault = selectedVault;
this.cellFactory = cellFactory;
this.vaultService = vaultService;
this.addVaultWizard = addVaultWizard;
- this.removeVaultDialogue = removeVaultDialogue;
this.vaultListManager = vaultListManager;
this.resourceBundle = resourceBundle;
this.appWindows = appWindows;
+ this.dialogs = dialogs;
this.emptyVaultList = Bindings.isEmpty(vaults);
selectedVault.addListener(this::selectedVaultDidChange);
+ cellSize = settings.compactMode.map(compact -> compact ? 30.0 : 60.0);
}
public void initialize() {
vaultList.setItems(vaults);
vaultList.setCellFactory(cellFactory);
+
+ vaultList.prefHeightProperty().bind(
+ vaultList.fixedCellSizeProperty().multiply(Bindings.size(vaultList.getItems()))
+ );
+
selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty());
vaults.addListener((ListChangeListener.Change extends Vault> c) -> {
while (c.next()) {
@@ -171,7 +182,7 @@ public class VaultListController implements FxController {
if (addVaultContextMenu.isShowing()) {
addVaultContextMenu.hide();
} else {
- addVaultContextMenu.show(addVaultBtn, Side.BOTTOM, 0.0, 0.0);
+ addVaultContextMenu.show(addVaultButton, Side.BOTTOM, 0.0, 0.0);
}
}
@@ -202,7 +213,7 @@ public class VaultListController implements FxController {
private void pressedShortcutToRemoveVault() {
final var vault = selectedVault.get();
if (vault != null && EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION).contains(vault.getState())) {
- removeVaultDialogue.vault(vault).build().showRemoveVault();
+ dialogs.prepareRemoveVaultDialog(mainWindow, vault, vaults).build().showAndWait();
}
}
@@ -247,6 +258,11 @@ public class VaultListController implements FxController {
}
}
+ @FXML
+ public void showPreferences() {
+ appWindows.showPreferencesWindow(SelectedPreferencesTab.ANY);
+ }
+
// Getter and Setter
public BooleanBinding emptyVaultListProperty() {
@@ -265,5 +281,12 @@ public class VaultListController implements FxController {
return draggingVaultOver.get();
}
+ public ObservableValue cellSizeProperty() {
+ return cellSize;
+ }
+
+ public Double getCellSize() {
+ return cellSize.getValue();
+ }
}
diff --git a/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java
index 40983c3f0..573bfc394 100644
--- a/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java
+++ b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java
@@ -36,8 +36,8 @@ public class InterfacePreferencesController implements FxController {
private final ResourceBundle resourceBundle;
private final SupportedLanguages supportedLanguages;
public ChoiceBox themeChoiceBox;
- public CheckBox showMinimizeButtonCheckbox;
public CheckBox showTrayIconCheckbox;
+ public CheckBox compactModeCheckbox;
public ChoiceBox preferredLanguageChoiceBox;
public ToggleGroup nodeOrientation;
public RadioButton nodeOrientationLtr;
@@ -63,9 +63,8 @@ public class InterfacePreferencesController implements FxController {
themeChoiceBox.valueProperty().bindBidirectional(settings.theme);
themeChoiceBox.setConverter(new UiThemeConverter(resourceBundle));
- showMinimizeButtonCheckbox.selectedProperty().bindBidirectional(settings.showMinimizeButton);
-
showTrayIconCheckbox.selectedProperty().bindBidirectional(settings.showTrayIcon);
+ compactModeCheckbox.selectedProperty().bindBidirectional(settings.compactMode);
preferredLanguageChoiceBox.getItems().addAll(supportedLanguages.getLanguageTags());
preferredLanguageChoiceBox.valueProperty().bindBidirectional(settings.language);
diff --git a/src/main/java/org/cryptomator/ui/preferences/PreferencesComponent.java b/src/main/java/org/cryptomator/ui/preferences/PreferencesComponent.java
index 2d569970d..136479bc0 100644
--- a/src/main/java/org/cryptomator/ui/preferences/PreferencesComponent.java
+++ b/src/main/java/org/cryptomator/ui/preferences/PreferencesComponent.java
@@ -31,7 +31,7 @@ public interface PreferencesComponent {
Stage stage = window();
stage.setScene(scene().get());
stage.setMinWidth(420);
- stage.setMinHeight(300);
+ stage.setMinHeight(400);
stage.show();
stage.requestFocus();
return stage;
diff --git a/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java b/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java
index bff56bc3c..b36d7454e 100644
--- a/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java
+++ b/src/main/java/org/cryptomator/ui/preferences/SupporterCertificateController.java
@@ -5,6 +5,7 @@ import org.cryptomator.common.LicenseHolder;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.UiTheme;
import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.dialogs.Dialogs;
import javax.inject.Inject;
import javafx.application.Application;
@@ -12,22 +13,36 @@ import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextFormatter;
+import javafx.stage.Stage;
+
@PreferencesScoped
public class SupporterCertificateController implements FxController {
+ private static final String DONATE_URI = "https://cryptomator.org/donate";
+ private static final String SPONSORS_URI = "https://cryptomator.org/sponsors";
private static final String SUPPORTER_URI = "https://store.cryptomator.org/desktop";
private final Application application;
+ private final Stage window;
private final LicenseHolder licenseHolder;
private final Settings settings;
- public TextArea supporterCertificateField;
+ private final Dialogs dialogs;
+
+ @FXML
+ private TextArea supporterCertificateField;
@Inject
- SupporterCertificateController(Application application, LicenseHolder licenseHolder, Settings settings) {
+ SupporterCertificateController(Application application, //
+ @PreferencesWindow Stage window, //
+ LicenseHolder licenseHolder, //
+ Settings settings, //
+ Dialogs dialogs) {
this.application = application;
+ this.window = window;
this.licenseHolder = licenseHolder;
this.settings = settings;
+ this.dialogs = dialogs;
}
@FXML
@@ -35,6 +50,11 @@ public class SupporterCertificateController implements FxController {
supporterCertificateField.setText(licenseHolder.getLicenseKey().orElse(null));
supporterCertificateField.textProperty().addListener(this::registrationKeyChanged);
supporterCertificateField.setTextFormatter(new TextFormatter<>(this::removeWhitespaces));
+ settings.licenseKey.addListener((_, _, newValue) -> {
+ if (newValue == null) {
+ supporterCertificateField.setText(null);
+ }
+ });
}
private TextFormatter.Change removeWhitespaces(TextFormatter.Change change) {
@@ -57,7 +77,23 @@ public class SupporterCertificateController implements FxController {
application.getHostServices().showDocument(SUPPORTER_URI);
}
+ @FXML
+ public void showDonate() {
+ application.getHostServices().showDocument(DONATE_URI);
+ }
+
+ @FXML
+ public void showSponsors() {
+ application.getHostServices().showDocument(SPONSORS_URI);
+ }
+
+ @FXML
+ void didClickRemoveCert() {
+ dialogs.prepareRemoveCertDialog(window, settings).build().showAndWait();
+ }
+
public LicenseHolder getLicenseHolder() {
return licenseHolder;
}
+
}
diff --git a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultComponent.java b/src/main/java/org/cryptomator/ui/removevault/RemoveVaultComponent.java
deleted file mode 100644
index c8b3fd574..000000000
--- a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultComponent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import dagger.BindsInstance;
-import dagger.Lazy;
-import dagger.Subcomponent;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-
-@RemoveVaultScoped
-@Subcomponent(modules = {RemoveVaultModule.class})
-public interface RemoveVaultComponent {
-
- @RemoveVaultWindow
- Stage window();
-
- @FxmlScene(FxmlFile.REMOVE_VAULT)
- Lazy scene();
-
- default void showRemoveVault() {
- Stage stage = window();
- stage.setScene(scene().get());
- stage.sizeToScene();
- stage.show();
- }
-
- @Subcomponent.Builder
- interface Builder {
-
- @BindsInstance
- Builder vault(@RemoveVaultWindow Vault vault);
-
- RemoveVaultComponent build();
- }
-
-}
diff --git a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultController.java b/src/main/java/org/cryptomator/ui/removevault/RemoveVaultController.java
deleted file mode 100644
index e486d65f0..000000000
--- a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.FxController;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import javafx.collections.ObservableList;
-import javafx.fxml.FXML;
-import javafx.stage.Stage;
-
-@RemoveVaultScoped
-public class RemoveVaultController implements FxController {
-
- private static final Logger LOG = LoggerFactory.getLogger(RemoveVaultController.class);
-
- private final Stage window;
- private final Vault vault;
- private final ObservableList vaults;
-
- @Inject
- public RemoveVaultController(@RemoveVaultWindow Stage window, @RemoveVaultWindow Vault vault, ObservableList vaults) {
- this.window = window;
- this.vault = vault;
- this.vaults = vaults;
- }
-
- @FXML
- public void close() {
- window.close();
- }
-
- @FXML
- public void finish() {
- vaults.remove(vault);
- LOG.debug("Removing vault {}.", vault.getDisplayName());
- window.close();
- }
-}
diff --git a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultModule.java b/src/main/java/org/cryptomator/ui/removevault/RemoveVaultModule.java
deleted file mode 100644
index 2fcac4add..000000000
--- a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultModule.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.DefaultSceneFactory;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxControllerKey;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlLoaderFactory;
-import org.cryptomator.ui.common.FxmlScene;
-import org.cryptomator.ui.common.StageFactory;
-import org.cryptomator.ui.fxapp.PrimaryStage;
-
-import javax.inject.Provider;
-import javafx.scene.Scene;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-@Module
-abstract class RemoveVaultModule {
-
- @Provides
- @RemoveVaultWindow
- @RemoveVaultScoped
- static FxmlLoaderFactory provideFxmlLoaderFactory(Map, Provider> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
- return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
- }
-
- @Provides
- @RemoveVaultWindow
- @RemoveVaultScoped
- static Stage provideStage(StageFactory factory, @PrimaryStage Stage primaryStage, @RemoveVaultWindow Vault vault, ResourceBundle resourceBundle) {
- Stage stage = factory.create();
- stage.setTitle(String.format(resourceBundle.getString("removeVault.title"), vault.getDisplayName()));
- stage.setResizable(false);
- stage.initModality(Modality.WINDOW_MODAL);
- stage.initOwner(primaryStage);
- return stage;
- }
-
- @Provides
- @FxmlScene(FxmlFile.REMOVE_VAULT)
- @RemoveVaultScoped
- static Scene provideRemoveVaultScene(@RemoveVaultWindow FxmlLoaderFactory fxmlLoaders) {
- return fxmlLoaders.createScene(FxmlFile.REMOVE_VAULT);
- }
-
- // ------------------
-
- @Binds
- @IntoMap
- @FxControllerKey(RemoveVaultController.class)
- abstract FxController bindRemoveVaultController(RemoveVaultController controller);
-}
diff --git a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultScoped.java b/src/main/java/org/cryptomator/ui/removevault/RemoveVaultScoped.java
deleted file mode 100644
index aa2281541..000000000
--- a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultScoped.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import javax.inject.Scope;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Scope
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RemoveVaultScoped {
-
-}
diff --git a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultWindow.java b/src/main/java/org/cryptomator/ui/removevault/RemoveVaultWindow.java
deleted file mode 100644
index 7348e213b..000000000
--- a/src/main/java/org/cryptomator/ui/removevault/RemoveVaultWindow.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.cryptomator.ui.removevault;
-
-import javax.inject.Qualifier;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-@interface RemoveVaultWindow {
-
-}
diff --git a/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java b/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java
index 804f4cd67..4b78bf693 100644
--- a/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java
+++ b/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java
@@ -10,6 +10,7 @@ import org.cryptomator.integrations.mount.MountFailedException;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.VaultService;
+import org.cryptomator.ui.dialogs.Dialogs;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
import org.cryptomator.ui.fxapp.PrimaryStage;
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
@@ -25,6 +26,8 @@ import javafx.scene.Scene;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
+import java.nio.file.ReadOnlyFileSystemException;
+import java.util.concurrent.TimeUnit;
/**
* A multi-step task that consists of background activities as well as user interaction.
@@ -46,6 +49,7 @@ public class UnlockWorkflow extends Task {
private final FxApplicationWindows appWindows;
private final KeyLoadingStrategy keyLoadingStrategy;
private final ObjectProperty illegalMountPointException;
+ private final Dialogs dialogs;
@Inject
UnlockWorkflow(@PrimaryStage Stage mainWindow, //
@@ -57,7 +61,8 @@ public class UnlockWorkflow extends Task {
@FxmlScene(FxmlFile.UNLOCK_REQUIRES_RESTART) Lazy restartRequiredScene, //
FxApplicationWindows appWindows, //
@UnlockWindow KeyLoadingStrategy keyLoadingStrategy, //
- @UnlockWindow ObjectProperty illegalMountPointException) {
+ @UnlockWindow ObjectProperty illegalMountPointException, //
+ Dialogs dialogs) {
this.mainWindow = mainWindow;
this.window = window;
this.vault = vault;
@@ -68,6 +73,7 @@ public class UnlockWorkflow extends Task {
this.appWindows = appWindows;
this.keyLoadingStrategy = keyLoadingStrategy;
this.illegalMountPointException = illegalMountPointException;
+ this.dialogs = dialogs;
}
@Override
@@ -144,11 +150,36 @@ public class UnlockWorkflow extends Task {
switch (throwable) {
case IllegalMountPointException e -> handleIllegalMountPointError(e);
case ConflictingMountServiceException _ -> handleConflictingMountServiceException();
+ case ReadOnlyFileSystemException _ -> handleReadOnlyFileSystem();
default -> handleGenericError(throwable);
}
vault.stateProperty().transition(VaultState.Value.PROCESSING, VaultState.Value.LOCKED);
}
+ private void handleReadOnlyFileSystem() {
+ var readOnlyDialog = dialogs.prepareRetryIfReadonlyDialog(mainWindow, stage -> {
+ stage.close();
+ this.retry();
+ }).build();
+
+ Platform.runLater(readOnlyDialog::showAndWait);
+ }
+
+ private void retry() {
+ try {
+ vault.getVaultSettings().usesReadOnlyMode.set(true);
+ var isLocked = vault.stateProperty().awaitState(VaultState.Value.LOCKED, 5, TimeUnit.SECONDS);
+ if (!isLocked) {
+ LOG.error("Vault did not changed to LOCKED state within 5 seconds. Aborting unlock retry.");
+ } else {
+ appWindows.startUnlockWorkflow(vault, mainWindow);
+ }
+ } catch (InterruptedException e) {
+ LOG.error("Waiting for LOCKED vault state was interrupted. Aborting unlock retry.", e);
+ Thread.currentThread().interrupt();
+ }
+ }
+
@Override
protected void cancelled() {
LOG.debug("Unlock of '{}' canceled.", vault.getDisplayName());
diff --git a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java
index d2c10f8fd..c27c98382 100644
--- a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java
+++ b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderComponent.java
@@ -2,14 +2,11 @@ package org.cryptomator.ui.updatereminder;
import dagger.Lazy;
import dagger.Subcomponent;
-import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javafx.scene.Scene;
import javafx.stage.Stage;
-import java.time.Duration;
-import java.time.Instant;
@UpdateReminderScoped
@Subcomponent(modules = {UpdateReminderModule.class})
@@ -21,16 +18,11 @@ public interface UpdateReminderComponent {
@FxmlScene(FxmlFile.UPDATE_REMINDER)
Lazy updateReminderScene();
- Settings settings();
-
- default void checkAndShowUpdateReminderWindow() {
- var now = Instant.now();
- if (!settings().checkForUpdates.getValue() && settings().lastSuccessfulUpdateCheck.get().isBefore(now.minus(Duration.ofDays(14)))) {
- Stage stage = window();
- stage.setScene(updateReminderScene().get());
- stage.sizeToScene();
- stage.show();
- }
+ default void showUpdateReminderWindow() {
+ Stage stage = window();
+ stage.setScene(updateReminderScene().get());
+ stage.sizeToScene();
+ stage.show();
}
@Subcomponent.Factory
diff --git a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java
index 183298c44..a6fce0b79 100644
--- a/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java
+++ b/src/main/java/org/cryptomator/ui/updatereminder/UpdateReminderController.java
@@ -7,6 +7,7 @@ import org.cryptomator.ui.fxapp.UpdateChecker;
import javax.inject.Inject;
import javafx.fxml.FXML;
import javafx.stage.Stage;
+import java.time.Instant;
@UpdateReminderScoped
public class UpdateReminderController implements FxController {
@@ -23,6 +24,11 @@ public class UpdateReminderController implements FxController {
this.updateChecker = updateChecker;
}
+ @FXML
+ public void initialize() {
+ settings.lastUpdateCheckReminder.set(Instant.now());
+ }
+
@FXML
public void cancel() {
window.close();
diff --git a/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java b/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java
index 59a52adf2..5fe6746d7 100644
--- a/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java
+++ b/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java
@@ -57,9 +57,14 @@ public class GeneralVaultOptionsController implements FxController {
}
private void trimVaultNameOnFocusLoss(Observable observable, Boolean wasFocussed, Boolean isFocussed) {
+ var displayNameSetting = vault.getVaultSettings().displayName;
if (!isFocussed) {
var trimmed = vaultName.getText().trim();
- vault.getVaultSettings().displayName.set(trimmed);
+ if (!trimmed.isEmpty()) {
+ displayNameSetting.set(trimmed); //persist changes
+ } else {
+ vaultName.setText(displayNameSetting.get()); //revert changes
+ }
}
}
diff --git a/src/main/java/org/cryptomator/ui/vaultoptions/MountOptionsController.java b/src/main/java/org/cryptomator/ui/vaultoptions/MountOptionsController.java
index 106623985..a9a2042a3 100644
--- a/src/main/java/org/cryptomator/ui/vaultoptions/MountOptionsController.java
+++ b/src/main/java/org/cryptomator/ui/vaultoptions/MountOptionsController.java
@@ -17,6 +17,8 @@ import org.cryptomator.ui.preferences.VolumePreferencesController;
import javax.inject.Inject;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
+import javafx.beans.binding.BooleanBinding;
+import javafx.beans.value.ObservableBooleanValue;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
@@ -50,7 +52,6 @@ public class MountOptionsController implements FxController {
private final ObservableValue defaultMountFlags;
private final ObservableValue mountpointDirSupported;
private final ObservableValue mountpointDriveLetterSupported;
- private final ObservableValue readOnlySupported;
private final ObservableValue mountFlagsSupported;
private final ObservableValue defaultMountServiceSelected;
private final ObservableValue directoryPath;
@@ -60,6 +61,7 @@ public class MountOptionsController implements FxController {
private final ObservableValue selectedMountService;
private final ObservableValue selectedMountServiceRequiresRestart;
private final ObservableValue loopbackPortChangeable;
+ private final ObservableBooleanValue readOnlyOptionAllowed;
//-- FXML objects --
@@ -108,10 +110,10 @@ public class MountOptionsController implements FxController {
});
this.mountFlagsSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_FLAGS));
this.defaultMountServiceSelected = ObservableUtil.mapWithDefault(vaultSettings.mountService, _ -> false, true);
- this.readOnlySupported = selectedMountService.map(s -> s.hasCapability(MountCapability.READ_ONLY));
this.mountpointDirSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_TO_EXISTING_DIR) || s.hasCapability(MountCapability.MOUNT_WITHIN_EXISTING_PARENT));
this.mountpointDriveLetterSupported = selectedMountService.map(s -> s.hasCapability(MountCapability.MOUNT_AS_DRIVE_LETTER));
this.loopbackPortChangeable = selectedMountService.map(s -> s.hasCapability(MountCapability.LOOPBACK_PORT) && vaultSettings.mountService.getValue() != null);
+ this.readOnlyOptionAllowed = BooleanBinding.booleanExpression(selectedMountService.map(s -> s.hasCapability(MountCapability.READ_ONLY))).or(vaultSettings.usesReadOnlyMode);
}
private MountService reselectMountService() {
@@ -345,12 +347,12 @@ public class MountOptionsController implements FxController {
return mountpointDriveLetterSupported.getValue();
}
- public ObservableValue readOnlySupportedProperty() {
- return readOnlySupported;
+ public ObservableValue readOnlyOptionAllowedProperty() {
+ return readOnlyOptionAllowed;
}
- public boolean isReadOnlySupported() {
- return readOnlySupported.getValue();
+ public boolean isReadOnlyOptionAllowed() {
+ return readOnlyOptionAllowed.getValue();
}
public ObservableValue directoryPathProperty() {
diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css
index 86d9aaa71..dae0d1898 100644
--- a/src/main/resources/css/dark_theme.css
+++ b/src/main/resources/css/dark_theme.css
@@ -100,6 +100,7 @@
.label-extra-large {
-fx-font-family: 'Open Sans SemiBold';
+ -fx-fill: TEXT_FILL;
-fx-font-size: 1.5em;
}
@@ -181,31 +182,20 @@
-fx-border-width: 1px;
}
-.main-window .title {
- -fx-background-color: CONTROL_BORDER_NORMAL, TITLE_BG;
- -fx-background-insets: 0, 0 0 1px 0;
+.main-window .button-bar {
+ -fx-background-color: MAIN_BG;
+ -fx-border-color: CONTROL_BORDER_NORMAL transparent transparent transparent;
+ -fx-border-width: 1px 0 0 0;
}
-.main-window .title .button {
- -fx-pref-height: 30px;
- -fx-pref-width: 30px;
- -fx-background-color: none;
- -fx-padding: 0;
+.main-window .button-left {
+ -fx-border-color: CONTROL_BORDER_NORMAL;
+ -fx-border-width: 0 1px 0 0;
}
-.main-window .title .button .glyph-icon {
- -fx-fill: white;
-}
-
-.main-window .title .button:armed .glyph-icon {
- -fx-fill: GRAY_8;
-}
-
-.main-window .update-indicator {
- -fx-background-color: white, RED_5;
- -fx-background-insets: 1px, 2px;
- -fx-background-radius: 6px, 5px;
- -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.8), 2, 0, 0, 0);
+.main-window .button-right {
+ -fx-border-color: CONTROL_BORDER_NORMAL;
+ -fx-border-width: 0 0 0 1px;
}
/*******************************************************************************
@@ -322,23 +312,33 @@
-fx-fill: transparent;
}
-.button.toolbar-button {
- -fx-min-height: 40px;
- -fx-background-color: transparent;
- -fx-background-insets: 0;
- -fx-background-radius: 0;
- -fx-border-color: CONTROL_BORDER_NORMAL transparent transparent transparent;
- -fx-border-width: 1px 0 0 0;
- -fx-padding: 0;
+/*******************************************************************************
+ * *
+ * NotificationBar *
+ * *
+ ******************************************************************************/
+
+.notification-label {
+ -fx-text-fill: white;
+ -fx-font-weight: bold;
}
-.button.toolbar-button:focused {
- -fx-background-color: CONTROL_BORDER_FOCUSED, MAIN_BG;
- -fx-background-insets: 0, 2px 1px 1px 1px;
+.notification-debug {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: RED_5;
}
-.button.toolbar-button:armed {
- -fx-background-color: CONTROL_BG_ARMED;
+.notification-update {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: YELLOW_5;
+}
+
+.notification-support {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: PRIMARY;
}
/*******************************************************************************
@@ -394,16 +394,6 @@
-fx-background-color: MUTED_BG;
}
-/* Note: These values below are kinda random such that it looks ok. I'm pretty sure there is room for improvement. Additionally, fx-text-fill does not work*/
-.badge-debug {
- -fx-font-family: 'Open Sans Bold';
- -fx-font-size: 1.0em;
- -fx-background-radius: 8px;
- -fx-padding: 0.3em 0.55em 0.3em 0.55em;
- -fx-background-color: RED_5;
- -fx-background-radius: 2em;
-}
-
/*******************************************************************************
* *
* Password Strength Indicator *
diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css
index 88cf6d970..84df05b10 100644
--- a/src/main/resources/css/light_theme.css
+++ b/src/main/resources/css/light_theme.css
@@ -177,34 +177,24 @@
/* windows needs an explicit border: */
.main-window.os-windows {
- -fx-border-color: TITLE_BG;
- -fx-border-width: 1px;
+ -fx-border-color: CONTROL_BORDER_NORMAL;
+ -fx-border-width: 1px 0 0 0;
}
-.main-window .title {
- -fx-background-color: TITLE_BG;
+.main-window .button-bar {
+ -fx-background-color: MAIN_BG;
+ -fx-border-color: CONTROL_BORDER_NORMAL transparent transparent transparent;
+ -fx-border-width: 1px 0 0 0;
}
-.main-window .title .button {
- -fx-pref-height: 30px;
- -fx-pref-width: 30px;
- -fx-background-color: none;
- -fx-padding: 0;
+.main-window .button-bar .button-left {
+ -fx-border-color: CONTROL_BORDER_NORMAL;
+ -fx-border-width: 0 1px 0 0;
}
-.main-window .title .button .glyph-icon {
- -fx-fill: white;
-}
-
-.main-window .title .button:armed .glyph-icon {
- -fx-fill: GRAY_8;
-}
-
-.main-window .update-indicator {
- -fx-background-color: white, RED_5;
- -fx-background-insets: 1px, 2px;
- -fx-background-radius: 6px, 5px;
- -fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.8), 2, 0, 0, 0);
+.main-window .button-bar .button-right {
+ -fx-border-color: CONTROL_BORDER_NORMAL;
+ -fx-border-width: 0 0 0 1px;
}
/*******************************************************************************
@@ -321,23 +311,33 @@
-fx-fill: transparent;
}
-.button.toolbar-button {
- -fx-min-height: 40px;
- -fx-background-color: transparent;
- -fx-background-insets: 0;
- -fx-background-radius: 0;
- -fx-border-color: CONTROL_BORDER_NORMAL transparent transparent transparent;
- -fx-border-width: 1px 0 0 0;
- -fx-padding: 0;
+/*******************************************************************************
+ * *
+ * NotificationBar *
+ * *
+ ******************************************************************************/
+
+.notification-label {
+ -fx-text-fill: white;
+ -fx-font-weight: bold;
}
-.button.toolbar-button:focused {
- -fx-background-color: CONTROL_BORDER_FOCUSED, MAIN_BG;
- -fx-background-insets: 0, 2px 1px 1px 1px;
+.notification-debug {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: RED_5;
}
-.button.toolbar-button:armed {
- -fx-background-color: CONTROL_BG_ARMED;
+.notification-update {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: YELLOW_5;
+}
+
+.notification-support {
+ -fx-min-height:24px;
+ -fx-max-height:24px;
+ -fx-background-color: PRIMARY;
}
/*******************************************************************************
@@ -393,16 +393,6 @@
-fx-background-color: MUTED_BG;
}
-/* Note: These values below are kinda random such that it looks ok. I'm pretty sure there is room for improvement. Additionally, fx-text-fill does not work*/
-.badge-debug {
- -fx-font-family: 'Open Sans Bold';
- -fx-font-size: 1.0em;
- -fx-background-radius: 8px;
- -fx-padding: 0.3em 0.55em 0.3em 0.55em;
- -fx-background-color: RED_5;
- -fx-background-radius: 2em;
-}
-
/*******************************************************************************
* *
* Password Strength Indicator *
diff --git a/src/main/resources/fxml/dokany_support_end.fxml b/src/main/resources/fxml/dokany_support_end.fxml
deleted file mode 100644
index 423a54c72..000000000
--- a/src/main/resources/fxml/dokany_support_end.fxml
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/fxml/health_start.fxml b/src/main/resources/fxml/health_start.fxml
index cc65aaaaa..56c38f740 100644
--- a/src/main/resources/fxml/health_start.fxml
+++ b/src/main/resources/fxml/health_start.fxml
@@ -25,8 +25,8 @@
-
-
+
+
diff --git a/src/main/resources/fxml/main_window.fxml b/src/main/resources/fxml/main_window.fxml
index 2796455d3..327e2c470 100644
--- a/src/main/resources/fxml/main_window.fxml
+++ b/src/main/resources/fxml/main_window.fxml
@@ -3,17 +3,31 @@
+
+
-
-
+
+
+
+
-
diff --git a/src/main/resources/fxml/main_window_resize.fxml b/src/main/resources/fxml/main_window_resize.fxml
deleted file mode 100644
index 7d5fb9437..000000000
--- a/src/main/resources/fxml/main_window_resize.fxml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/fxml/main_window_title.fxml b/src/main/resources/fxml/main_window_title.fxml
deleted file mode 100644
index bd60aa25d..000000000
--- a/src/main/resources/fxml/main_window_title.fxml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/fxml/preferences_about.fxml b/src/main/resources/fxml/preferences_about.fxml
index 1555de504..52c620f21 100644
--- a/src/main/resources/fxml/preferences_about.fxml
+++ b/src/main/resources/fxml/preferences_about.fxml
@@ -17,12 +17,12 @@
-
-
+
+
-
+
diff --git a/src/main/resources/fxml/preferences_contribute.fxml b/src/main/resources/fxml/preferences_contribute.fxml
index 55d40b495..a6a52bf4e 100644
--- a/src/main/resources/fxml/preferences_contribute.fxml
+++ b/src/main/resources/fxml/preferences_contribute.fxml
@@ -3,13 +3,18 @@
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
diff --git a/src/main/resources/fxml/preferences_interface.fxml b/src/main/resources/fxml/preferences_interface.fxml
index 6cb9b7d73..36f58ebb3 100644
--- a/src/main/resources/fxml/preferences_interface.fxml
+++ b/src/main/resources/fxml/preferences_interface.fxml
@@ -37,9 +37,7 @@
-
-
-
+
diff --git a/src/main/resources/fxml/remove_vault.fxml b/src/main/resources/fxml/simple_dialog.fxml
similarity index 64%
rename from src/main/resources/fxml/remove_vault.fxml
rename to src/main/resources/fxml/simple_dialog.fxml
index 57a36576e..32ad63abf 100644
--- a/src/main/resources/fxml/remove_vault.fxml
+++ b/src/main/resources/fxml/simple_dialog.fxml
@@ -1,24 +1,23 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ spacing="12">
@@ -29,24 +28,23 @@
-
+
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/fxml/vault_detail_missing.fxml b/src/main/resources/fxml/vault_detail_missing.fxml
index 6f78b8064..8721496f5 100644
--- a/src/main/resources/fxml/vault_detail_missing.fxml
+++ b/src/main/resources/fxml/vault_detail_missing.fxml
@@ -9,7 +9,7 @@
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.mainwindow.VaultDetailMissingVaultController"
alignment="TOP_CENTER"
- spacing="24">
+ spacing="9">
diff --git a/src/main/resources/fxml/vault_detail_welcome.fxml b/src/main/resources/fxml/vault_detail_welcome.fxml
index 8fdcf85eb..132ec33fc 100644
--- a/src/main/resources/fxml/vault_detail_welcome.fxml
+++ b/src/main/resources/fxml/vault_detail_welcome.fxml
@@ -8,10 +8,10 @@
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.mainwindow.WelcomeController"
alignment="CENTER"
- spacing="24">
+ spacing="9">
-
-
+
+
diff --git a/src/main/resources/fxml/vault_list.fxml b/src/main/resources/fxml/vault_list.fxml
index f9cb29258..267148d3e 100644
--- a/src/main/resources/fxml/vault_list.fxml
+++ b/src/main/resources/fxml/vault_list.fxml
@@ -1,15 +1,16 @@
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/fxml/vault_list_cell.fxml b/src/main/resources/fxml/vault_list_cell.fxml
index aedb18b06..20df9b924 100644
--- a/src/main/resources/fxml/vault_list_cell.fxml
+++ b/src/main/resources/fxml/vault_list_cell.fxml
@@ -1,29 +1,26 @@
-
-
-
-
-
+
diff --git a/src/main/resources/fxml/vault_options_mount.fxml b/src/main/resources/fxml/vault_options_mount.fxml
index d5df2534f..4f6295af8 100644
--- a/src/main/resources/fxml/vault_options_mount.fxml
+++ b/src/main/resources/fxml/vault_options_mount.fxml
@@ -54,7 +54,7 @@
-
+
diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties
index b310e9c46..a4829138a 100644
--- a/src/main/resources/i18n/strings.properties
+++ b/src/main/resources/i18n/strings.properties
@@ -14,6 +14,7 @@ generic.button.copied=Copied!
generic.button.done=Done
generic.button.next=Next
generic.button.print=Print
+generic.button.remove=Remove
# Error
error.message=An error occurred
@@ -106,7 +107,6 @@ addvaultwizard.success.unlockNow=Unlock Now
removeVault.title=Remove "%s"
removeVault.message=Remove vault?
removeVault.description=This will only make Cryptomator forget about this vault. You can add it again. No encrypted files will be deleted from your hard drive.
-removeVault.confirmBtn=Remove Vault
# Change Password
changepassword.title=Change Password
@@ -177,7 +177,7 @@ hub.registerFailed.description.generic=An error was thrown in the registration p
hub.registerFailed.description.deviceAlreadyExists=This device is already registered for a different user. Try to change the user account or use a different device.
### Unauthorized
hub.unauthorized.message=Access denied
-hub.unauthorized.description=Your device has not yet been authorized to access this vault. Ask the vault owner to authorize it.
+hub.unauthorized.description=You are not authorized to open this vault. Contact the vault's owner to request access.
### Requires Account Initialization
hub.requireAccountInit.message=Action required
hub.requireAccountInit.description.0=To proceed, please complete the steps required in your
@@ -301,8 +301,8 @@ preferences.interface.language.auto=System Default
preferences.interface.interfaceOrientation=Interface Orientation
preferences.interface.interfaceOrientation.ltr=Left to Right
preferences.interface.interfaceOrientation.rtl=Right to Left
-preferences.interface.showMinimizeButton=Show minimize button
preferences.interface.showTrayIcon=Show tray icon (requires restart)
+preferences.interface.compactMode=Enable compact vault list
## Volume
preferences.volume=Virtual Drive
preferences.volume.type=Default Volume Type
@@ -336,6 +336,14 @@ preferences.contribute.registeredFor=Supporter certificate registered for %s
preferences.contribute.noCertificate=Support Cryptomator and receive a supporter certificate. It's like a license key but for awesome people using free software. ;-)
preferences.contribute.getCertificate=Don't have one already? Learn how you can obtain it.
preferences.contribute.promptText=Paste supporter certificate code here
+preferences.contribute.thankYou=Thank you for supporting Cryptomator's open-source development!
+preferences.contribute.donate=Donate
+preferences.contribute.sponsor=Sponsor
+
+### Remove License Key Dialog
+removeCert.title=Remove Certificate
+removeCert.message=Remove supporter certificate?
+removeCert.description=Cryptomator's core features are not affected by this. Neither access to your vaults is restricted nor the level of security is lowered.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -377,11 +385,6 @@ stats.access.total=Total accesses: %d
# Main Window
-main.closeBtn.tooltip=Close
-main.minimizeBtn.tooltip=Minimize
-main.preferencesBtn.tooltip=Preferences
-main.debugModeEnabled.tooltip=Debug mode is enabled
-main.supporterCertificateMissing.tooltip=Please consider donating
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Click here to add a vault
main.vaultlist.contextMenu.remove=Remove…
@@ -390,9 +393,11 @@ main.vaultlist.contextMenu.unlock=Unlock…
main.vaultlist.contextMenu.unlockNow=Unlock Now
main.vaultlist.contextMenu.vaultoptions=Show Vault Options
main.vaultlist.contextMenu.reveal=Reveal Drive
-main.vaultlist.addVaultBtn=Add
-main.vaultlist.addVaultBtn.menuItemNew=New Vault...
-main.vaultlist.addVaultBtn.menuItemExisting=Existing Vault...
+main.vaultlist.addVaultBtn.menuItemNew=Create New Vault...
+main.vaultlist.addVaultBtn.menuItemExisting=Open Existing Vault...
+##Notificaition
+main.notification.updateAvailable=Update is available.
+main.notification.support=Support Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Thanks for choosing Cryptomator to protect your files. If you need any assistance, check out our getting started guides:
@@ -548,6 +553,12 @@ dokanySupportEnd.message=Support end for Dokany
dokanySupportEnd.description=The volume type Dokany is no longer supported by Cryptomator. Your settings are adjusted to use the default volume type now. You can view the default type in the preferences.
dokanySupportEnd.preferencesBtn=Open Preferences
+#Retry If Readonly
+retryIfReadonly.title=Restricted Vault Access
+retryIfReadonly.message=No write access to vault directory
+retryIfReadonly.description=Cryptomator cannot write to the vault directory. You can change the vault to be read-only and try again. This option can be disabled in the vault options.
+retryIfReadonly.retry=Change and Retry
+
# Share Vault
shareVault.title=Share Vault
shareVault.message=Would you like to share your vault with others?
diff --git a/src/main/resources/i18n/strings_af.properties b/src/main/resources/i18n/strings_af.properties
index 125593fee..16d2016cd 100644
--- a/src/main/resources/i18n/strings_af.properties
+++ b/src/main/resources/i18n/strings_af.properties
@@ -118,4 +118,6 @@
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_ar.properties b/src/main/resources/i18n/strings_ar.properties
index c7ca09254..1739b866d 100644
--- a/src/main/resources/i18n/strings_ar.properties
+++ b/src/main/resources/i18n/strings_ar.properties
@@ -13,6 +13,7 @@ generic.button.copied=تم النسخ!
generic.button.done=تم
generic.button.next=التالي
generic.button.print=طباعة
+generic.button.remove=حذف
# Error
error.message=حدث خطأ ما
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=افتح الان
removeVault.title=احذف الحافظة
removeVault.message=حذف المخزن؟
removeVault.description=سيؤدي هذا إلى نسيان Cryptomator لهذا المخزن فقط. يمكنك إضافته مرة أخرى لاحقاً. لن يتم حذف أي من الملفات المشفرة من القرص الصلب الخاص بك.
-removeVault.confirmBtn=احذف الحافظة
# Change Password
changepassword.title=تغيير كلمة المرور
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=حدث خطأ في عملية تسجيل
hub.registerFailed.description.deviceAlreadyExists=هذا الجهاز مسجل لمستخدم مختلف بالفعل. حاول تغيير حساب المستخدم أو استخدام جهاز مختلف.
### Unauthorized
hub.unauthorized.message=تم رفض الوصول
-hub.unauthorized.description=لم يتم بعد منح الإذن لجهازك بالوصول إلى هذا المخزن. اطلب من مالك المخزن أن يأذن بذلك.
### Requires Account Initialization
hub.requireAccountInit.message=مطلوب اتخاذ إجراء
hub.requireAccountInit.description.0=للمتابعة، يرجى إكمال الخطوات المطلوبة في
@@ -287,6 +286,7 @@ preferences.general.debugLogging=تمكين سجلات التصحيح
preferences.general.debugDirectory=عرض ملفات السجل
preferences.general.autoStart=تشغيل Cryptomator عند بدء تشغيل النظام
preferences.general.keychainBackend=تخزين كلمات المرور مع
+preferences.general.quickAccessService=إضافة الخزانات المفتوحة إلى منطقة الوصول السريع
## Interface
preferences.interface=الواجهة
preferences.interface.theme=الشكل والمظهر
@@ -300,6 +300,7 @@ preferences.interface.interfaceOrientation=اتجاه الواجهة
preferences.interface.interfaceOrientation.ltr=من اليسار إلى اليمين
preferences.interface.interfaceOrientation.rtl=من اليمين إلى اليسار
preferences.interface.showTrayIcon=إظهار أيقونة اللوحة (يتطلب إعادة تشغيل)
+preferences.interface.compactMode=تمكين قائمة الخزنة المدمجة
## Volume
preferences.volume=القرص الإفتراضي
preferences.volume.type=نوع القرص الافتراضي
@@ -333,12 +334,14 @@ preferences.contribute.registeredFor=شهادة الداعم مسجلة لـ %s
preferences.contribute.noCertificate=ادعم Cryptomator واحصل على شهادة الداعم. إنها مثل مفتاح الترخيص لكن للأشخاص الرائعين الذين يستخدمون البرامج المجانية ؛-)
preferences.contribute.getCertificate=ليس لديك واحدة بعد؟ تعلم كيف يمكنك الحصول عليها.
preferences.contribute.promptText=قم بلصق رمز شهادة الداعم هنا
+preferences.contribute.thankYou=نشكرك على دعمك لتطوير Cryptomator مفتوح المصدر!
preferences.contribute.donate=تبرع
+preferences.contribute.sponsor=الراعي
### Remove License Key Dialog
removeCert.title=إزالة الشهادة
removeCert.message=إزالة شهادة الداعم؟
-removeCert.confirmBtn=حذف
+removeCert.description=الميزات الأساسية لـ Cryptomator غير متأثرة بهذا. لا يتم تقييد الوصول إلى خزاناتك ولا يتم تخفيض مستوى الأمان.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -388,7 +391,11 @@ main.vaultlist.contextMenu.unlock=فتح…
main.vaultlist.contextMenu.unlockNow=افتح الان
main.vaultlist.contextMenu.vaultoptions=إظهار خيارات المخزن
main.vaultlist.contextMenu.reveal=اظهار القرص
+main.vaultlist.addVaultBtn.menuItemNew=إنشاء مخزن جديد...
+main.vaultlist.addVaultBtn.menuItemExisting=افتح مخزن موجود...
##Notificaition
+main.notification.updateAvailable=هناك تحديث متاح.
+main.notification.support=دعم Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=شكرا لاختيار Cryptomator لحماية ملفاتك. إذا كنت بحاجة إلى أية مساعدة، تحقق من دليل وتعليمات الإستخدام:
@@ -544,6 +551,8 @@ dokanySupportEnd.message=انتهاء الدعم لـDokany
dokanySupportEnd.description=نوع وحدة التخزين Dokany لم يعد مدعوماً من قبل Cryptomator. تم تعديل إعداداتك لاستخدام نوع وحدة التخزين الافتراضي الآن. يمكنك عرض النوع الافتراضي في التفضيلات.
dokanySupportEnd.preferencesBtn=فتح التفضيلات
+#Retry If Readonly
+
# Share Vault
shareVault.title=مشاركة الخزانة
shareVault.message=هل ترغب في مشاركة خزانتك مع الآخرين؟
diff --git a/src/main/resources/i18n/strings_ba.properties b/src/main/resources/i18n/strings_ba.properties
index 660c529b4..f71aa0917 100644
--- a/src/main/resources/i18n/strings_ba.properties
+++ b/src/main/resources/i18n/strings_ba.properties
@@ -13,6 +13,7 @@ generic.button.copied=Күсермә алынды!
generic.button.done=Тамам
generic.button.next=Киләһе
generic.button.print=Баҫтыр
+generic.button.remove=Алып ташлау
# Error
error.message=Хата килеп сыҡты
@@ -104,7 +105,6 @@ addvaultwizard.success.unlockNow=Хәҙер бикте ас
removeVault.title="%s" һаҡлағысын алып ташла
removeVault.message=Һаҡлағысты алып ташларғамы?
removeVault.description=Cryptomator был һаҡлағысты ғына онотасаҡ. Һеҙ уны яңынан өҫтәй алаһығыҙ. Ҡаты дисктан шифрланған файлдар юйылмаясаҡ.
-removeVault.confirmBtn=Һаҡлағысты алып ташла
# Change Password
changepassword.title=Серһүҙҙе үҙгәртеү
@@ -164,7 +164,6 @@ hub.registerSuccess.unlockBtn=Биген ас
### Registration Failed
### Unauthorized
hub.unauthorized.message=Инеү кире ҡағылды
-hub.unauthorized.description=Һеҙҙең йыһаз әлегә был һаҡлағысҡа инеү хоҡуғына эйә түгел. Һаҡлағыс хужаһынан рөхсәт һорағыҙ.
### Requires Account Initialization
hub.requireAccountInit.message=Эш-хәрәкәт кәрәкле
hub.requireAccountInit.description.0=Дауам итер өсөн, кәрәкле аҙымдар тамамланырға тейеш урын:
@@ -316,7 +315,6 @@ preferences.contribute.getCertificate=Юҡ мы әллә? Уны нисек ал
preferences.contribute.promptText=Ярҙамсы сертификатын бында йәбештерегеҙ
### Remove License Key Dialog
-removeCert.confirmBtn=Алып ташлау
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -517,4 +515,6 @@ updateReminder.yesAutomatically=Эйе, автоматик рәүештә
#Dokany Support End
dokanySupportEnd.preferencesBtn=Көйләүҙәрҙе ас
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_be.properties b/src/main/resources/i18n/strings_be.properties
index 2a14e0970..87de4f257 100644
--- a/src/main/resources/i18n/strings_be.properties
+++ b/src/main/resources/i18n/strings_be.properties
@@ -13,6 +13,7 @@ generic.button.copied=Скапіявана!
generic.button.done=Файна
generic.button.next=Далей
generic.button.print=Друкаваць
+generic.button.remove=Выдаліць
# Error
error.message=Адбылася памылка
@@ -104,7 +105,6 @@ addvaultwizard.success.unlockNow=Разамкнуць зараз
removeVault.title=Выдаліць "%s"
removeVault.message=Ці выдаліць скарбніцу?
removeVault.description=Гэта прывядзе толькі да таго, што Cryptomator забудзецца на гэтую скрынку. Ты зможаш дадаць яе пазней ізноў. Аніякія зашыфраваныя файлы з тайго жорсткага дыску не выдаляцьмуцца.
-removeVault.confirmBtn=Выдаліць скарбніцу
# Change Password
changepassword.title=Змяніць пароль
@@ -157,7 +157,6 @@ hub.registerSuccess.unlockBtn=Адамкнуць
### Registration Failed
### Unauthorized
hub.unauthorized.message=Адмова ў доступе
-hub.unauthorized.description=Тваёй прыладзе ў дадзены момант не дазволена мець доступ да гэтай скрабніцы. Запытайся ўладальніка скрабніцы за дазволам.
### Requires Account Initialization
### License Exceeded
hub.invalidLicense.message=Несапраўдная ліцэнзія Hub
@@ -303,7 +302,6 @@ preferences.contribute.getCertificate=Яшчэ ня маеш такога? Да
preferences.contribute.promptText=Устаў код сэртыфікату ахвяравальніка сюды
### Remove License Key Dialog
-removeCert.confirmBtn=Выдаліць
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -497,4 +495,6 @@ updateReminder.yesAutomatically=Так, аўтаматычна
#Dokany Support End
dokanySupportEnd.preferencesBtn=Адчыніць налады
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_bg.properties b/src/main/resources/i18n/strings_bg.properties
index d6e02a243..2817fb65d 100644
--- a/src/main/resources/i18n/strings_bg.properties
+++ b/src/main/resources/i18n/strings_bg.properties
@@ -13,6 +13,7 @@ generic.button.copied=Копирано!
generic.button.done=Готово
generic.button.next=Напред
generic.button.print=Отпечатване
+generic.button.remove=Премахване
# Error
error.message=Възникна грешка
@@ -104,7 +105,6 @@ addvaultwizard.success.unlockNow=Отключване сега
removeVault.title=Премахване на „%s“
removeVault.message=Премахване на хранилище?
removeVault.description=По този начин Криптоматор ще забрави за това хранилище. Можете да го добавите отново. Шифрованите файлове няма да бъдат премахнати от твърдия диск.
-removeVault.confirmBtn=Премахване
# Change Password
changepassword.title=Промяна на парола
@@ -164,7 +164,6 @@ hub.registerSuccess.unlockBtn=Отключване
### Registration Failed
### Unauthorized
hub.unauthorized.message=Отказан достъп
-hub.unauthorized.description=Устройството не е упълномощено за достъп до това хранилище. Поискайте достъп от собственика.
### Requires Account Initialization
hub.requireAccountInit.message=Необходимо е действие
hub.requireAccountInit.description.0=За да продължите завършете необходимите стъпки в
@@ -316,7 +315,6 @@ preferences.contribute.getCertificate=Все още нямате? Научете
preferences.contribute.promptText=Поставете тук кода на сертификата за дарение
### Remove License Key Dialog
-removeCert.confirmBtn=Премахване
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -517,4 +515,6 @@ updateReminder.yesAutomatically=Да, автоматично
#Dokany Support End
dokanySupportEnd.preferencesBtn=Към настройките
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_bn.properties b/src/main/resources/i18n/strings_bn.properties
index f1c77f782..7fb8a46df 100644
--- a/src/main/resources/i18n/strings_bn.properties
+++ b/src/main/resources/i18n/strings_bn.properties
@@ -13,6 +13,7 @@ generic.button.copied=কপি হয়েছে!
generic.button.done=সম্পন্ন হয়েছে
generic.button.next=পরবর্তী
generic.button.print=প্রিন্ট
+generic.button.remove=বাতিল
# Error
error.message=ত্রুটি %s
@@ -127,7 +128,6 @@ lock.forced.retryBtn=পুনরায় চেষ্টা করুন
## Contribution
### Remove License Key Dialog
-removeCert.confirmBtn=বাতিল
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -182,4 +182,6 @@ vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন ক
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_bs.properties b/src/main/resources/i18n/strings_bs.properties
index 88679218f..9955f00a7 100644
--- a/src/main/resources/i18n/strings_bs.properties
+++ b/src/main/resources/i18n/strings_bs.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopirano!
generic.button.done=Gotovo
generic.button.next=Sljedeće
generic.button.print=Ispis
+generic.button.remove=Ukloni
# Error
error.message=Došlo je do greške
@@ -78,7 +79,6 @@ addvaultwizard.success.unlockNow=Otključaj sada
# Remove Vault
removeVault.title=Ukloni Sef
removeVault.description=Ovo će samo natjerati Cryptomator da zaboravi na ovaj sef. Možete ga dodati ponovo kasnije. Nijedna enkriptovana datoteka neće se izbrisati s vašeg diska.
-removeVault.confirmBtn=Ukloni Sef
# Change Password
changepassword.title=Promjeni lozinku
@@ -175,7 +175,6 @@ preferences.updates.updateAvailable=Dostupno ažuriranje na verziju %s.
## Contribution
### Remove License Key Dialog
-removeCert.confirmBtn=Ukloni
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -319,4 +318,6 @@ quit.lockAndQuitBtn=Zaključaj i zatvori
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_ca.properties b/src/main/resources/i18n/strings_ca.properties
index 6b089b121..61471bff8 100644
--- a/src/main/resources/i18n/strings_ca.properties
+++ b/src/main/resources/i18n/strings_ca.properties
@@ -13,6 +13,7 @@ generic.button.copied=Copiat!
generic.button.done=Fet
generic.button.next=Següent
generic.button.print=Imprimeix
+generic.button.remove=Elimina
# Error
error.message=S'ha produït un error
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Desbloqueja ara
removeVault.title=Elimina la caixa forta
removeVault.message=Voleu eliminar la caixa forta?
removeVault.description=Cryptomator simplement deixarà de mostrar la caixa forta. Podeu tornar a afegir-la més endavant. Cap fitxer xifrat serà eliminat del disc dur.
-removeVault.confirmBtn=Elimina la caixa forta
# Change Password
changepassword.title=Canvia la contrasenya
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=S'ha produït un error en el procés de r
hub.registerFailed.description.deviceAlreadyExists=El dispositiu ja ha estat registrat per un altre usuari. Mireu de canviar el compte d'usuari o feu servir un dispositiu diferent.
### Unauthorized
hub.unauthorized.message=Accés denegat
-hub.unauthorized.description=El vostre dispositiu no ha estat encara autoritzat a accedir a aquesta caixa forta. Demaneu autorització al propietari.
### Requires Account Initialization
hub.requireAccountInit.message=Acció necessària
hub.requireAccountInit.description.0=Per a continuar, si us plau, seguiu els passos necessaris en el vostre
@@ -287,6 +286,7 @@ preferences.general.debugLogging=Habilita el registre de depuració
preferences.general.debugDirectory=Mostra els fitxers de registres
preferences.general.autoStart=Executa Cryptomator en engegar el sistema
preferences.general.keychainBackend=Desar contrasenyes amb
+preferences.general.quickAccessService=Afegeix caixes fortes desblocades a l'àrea d'accés directe
## Interface
preferences.interface=Interfície
preferences.interface.theme=Aparença
@@ -300,6 +300,7 @@ preferences.interface.interfaceOrientation=Orientació de la interfície
preferences.interface.interfaceOrientation.ltr=Esquerra a dreta
preferences.interface.interfaceOrientation.rtl=Dreta a esquerra
preferences.interface.showTrayIcon=Mostra la icona en la barra (cal reiniciar)
+preferences.interface.compactMode=Activa la llista compacta de caixes fortes
## Volume
preferences.volume=Unitat virtual
preferences.volume.type=Tipus de volum per defecte
@@ -319,6 +320,13 @@ preferences.updates.currentVersion=Versió actual: %s
preferences.updates.autoUpdateCheck=Comprova automàticament si hi ha actualitzacions
preferences.updates.checkNowBtn=Comprova-ho ara
preferences.updates.updateAvailable=L'actualització a la versió %s es troba disponible.
+preferences.updates.lastUpdateCheck=Darrera comprovació: %s
+preferences.updates.lastUpdateCheck.never=mai
+preferences.updates.lastUpdateCheck.recently=recentment
+preferences.updates.lastUpdateCheck.daysAgo=Fa %s dies
+preferences.updates.lastUpdateCheck.hoursAgo=fa %s hores
+preferences.updates.checkFailed=Ha fallat la cerca d'actualitzacions. Si us plau, comproveu la connexió a Internet o torneu a provar-ho més tard.
+preferences.updates.upToDate=Cryptomator està actualitzat.
## Contribution
preferences.contribute=Doneu-nos suport
@@ -326,9 +334,13 @@ preferences.contribute.registeredFor=Certificat de col·laborador registrat per
preferences.contribute.noCertificate=Doneu suport a Cryptomator i rebeu un certificat de col·laborador. És com una clau de llicència però per a gent meravellosa que fa servir programari lliure. ;-)
preferences.contribute.getCertificate=Encara no en teniu cap? Sapigueu com aconseguir-ne un.
preferences.contribute.promptText=Enganxeu aquí el certificat de col·laborador
+preferences.contribute.thankYou=Gràcies pel vostre suport al desenvolupament open-source de Cryptomator!
+preferences.contribute.donate=Feu un donatiu
+preferences.contribute.sponsor=Patrocinador
### Remove License Key Dialog
-removeCert.confirmBtn=Elimina
+removeCert.title=Suprimeix certificat
+removeCert.description=Les característiques principals de Cryptomator no es veuen afectades per això. Ni l'accés a les vostres caixes fortes s'ha restringit ni el nivell de seguretat ha estat rebaixat.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -378,7 +390,11 @@ main.vaultlist.contextMenu.unlock=Desbloca…
main.vaultlist.contextMenu.unlockNow=Desbloqueja ara
main.vaultlist.contextMenu.vaultoptions=Opcions de la caixa forta
main.vaultlist.contextMenu.reveal=Mostra la unitat
+main.vaultlist.addVaultBtn.menuItemNew=Crea una nova caixa forta…
+main.vaultlist.addVaultBtn.menuItemExisting=Obri una caixa forta existent...
##Notificaition
+main.notification.updateAvailable=Hi ha una actualització disponible.
+main.notification.support=Doneu suport a Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Gràcies per escollir Cryptomator per protegir els vostres fitxers. Si vos cal ajuda, llegiu les nostres guies per donar els Primers passos:
@@ -531,6 +547,8 @@ updateReminder.yesAutomatically=Sí, automàticament
#Dokany Support End
dokanySupportEnd.preferencesBtn=Obrir les Preferències
+#Retry If Readonly
+
# Share Vault
shareVault.title=Comparteix la caixa forta
shareVault.message=Voleu compartir la vostra caixa forta amb altres persones?
diff --git a/src/main/resources/i18n/strings_cs.properties b/src/main/resources/i18n/strings_cs.properties
index 7372220f4..a5d210dec 100644
--- a/src/main/resources/i18n/strings_cs.properties
+++ b/src/main/resources/i18n/strings_cs.properties
@@ -13,6 +13,7 @@ generic.button.copied=Zkopírováno!
generic.button.done=Hotovo
generic.button.next=Další
generic.button.print=Tisk
+generic.button.remove=Odstranit
# Error
error.message=Chyba %s
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Odemknout nyní
removeVault.title=Odstranit trezor
removeVault.message=Odstranit trezor?
removeVault.description=Toto jen umožní Cryptomatoru zapomenout tento trezor. Později jej můžete opět přidat. Žádné šifrované soubory nebudou z vašeho disku smazány.
-removeVault.confirmBtn=Odstranit trezor
# Change Password
changepassword.title=Změnit heslo
@@ -137,6 +137,7 @@ unlock.success.revealBtn=Zobrazit jednotku
unlock.error.customPath.message=Nelze připojit trezor k vlastní cestě
unlock.error.customPath.description.notSupported=Pokud chcete pokračovat v používání vlastní cesty, přejděte do nastavení a vyberte typ hlasitosti, který ji podporuje. V opačném případě přejděte do možností trezoru a vyberte podporovaný přípojný bod.
unlock.error.customPath.description.notExists=Cesta k připojení neexistuje. Buď ji vytvořte ve vašem lokálním souborovém systému, nebo ji změňte v možnostech trezoru.
+unlock.error.customPath.description.inUse=Označení úložiště nebo vlastní cesta "%s" se již používá.
unlock.error.restartRequired.message=Nelze odemknout trezor
unlock.error.restartRequired.description=Změňte typ svazku v možnostech trezoru nebo restartujte Cryptomator.
unlock.error.title=Odemknutí "%s" selhalo
@@ -171,7 +172,6 @@ hub.registerFailed.description.generic=Došlo k chybě v registračním procesu.
hub.registerFailed.description.deviceAlreadyExists=Toto zařízení je již registrováno pro jiného uživatele. Zkuste změnit uživatelský účet nebo použijte jiné zařízení.
### Unauthorized
hub.unauthorized.message=Přístup odepřen
-hub.unauthorized.description=Vaše zařízení dosud nebylo oprávněno k přístupu k tomuto trezoru. Požádejte vlastníka trezoru, aby jej autorizoval.
### Requires Account Initialization
hub.requireAccountInit.message=Požadována akce
hub.requireAccountInit.description.0=Chcete-li pokračovat, vyplňte prosím požadované kroky ve vašem
@@ -315,7 +315,6 @@ preferences.contribute.getCertificate=Ještě žádný nemáte? Naučte se, jak
preferences.contribute.promptText=Sem vložte kód certifikátu podporovatele
### Remove License Key Dialog
-removeCert.confirmBtn=Odstranit
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -516,6 +515,8 @@ dokanySupportEnd.title=Oznámení o zastaralosti
dokanySupportEnd.message=Konec podpory pro Dokany
dokanySupportEnd.preferencesBtn=Otevřít předvolby
+#Retry If Readonly
+
# Share Vault
shareVault.title=Sdílet trezor
shareVault.message=Chcete sdílet svůj trezor s ostatními?
diff --git a/src/main/resources/i18n/strings_da.properties b/src/main/resources/i18n/strings_da.properties
index 41096768a..0399e5c95 100644
--- a/src/main/resources/i18n/strings_da.properties
+++ b/src/main/resources/i18n/strings_da.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopieret!
generic.button.done=Færdig
generic.button.next=Næste
generic.button.print=Print
+generic.button.remove=Fjern
# Error
error.message=Der opstod en fejl
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Lås op nu
removeVault.title=Fjern "%s"
removeVault.message=Fjern boks?
removeVault.description=Dette får blot Cryptomator til at glemme boksen. Du kan tilføje den igen senere. Ingen krypterede filer bliver slettet fra harddisken.
-removeVault.confirmBtn=Fjern boks
# Change Password
changepassword.title=Skift adgangskode
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Der opstod en fejl i registreringsprocess
hub.registerFailed.description.deviceAlreadyExists=Denne enhed er allerede registreret af en anden bruger. Prøv at ændre brugerkontoen eller brug en anden enhed.
### Unauthorized
hub.unauthorized.message=Adgang nægtet
-hub.unauthorized.description=Din enhed er endnu ikke blevet godkendt til at få adgang til denne boks. Spørg boks-ejeren om godkendelse.
+hub.unauthorized.description=Du har ikke tilladelse til at åbne denne boks. Kontant ejeren af boksen for at anmode om adgang.
### Requires Account Initialization
hub.requireAccountInit.message=Handling påkrævet
hub.requireAccountInit.description.0=For at fortsætte, skal du fuldføre de nødvendige trin i din
@@ -287,6 +287,7 @@ preferences.general.debugLogging=Aktivér fejllogning
preferences.general.debugDirectory=Vis logfiler
preferences.general.autoStart=Start Cryptomator automatisk ved opstart
preferences.general.keychainBackend=Gem adgangskoder med
+preferences.general.quickAccessService=Tilføj oplåste bokse til området hurtig adgang
## Interface
preferences.interface=Brugerflade
preferences.interface.theme=Udseende
@@ -319,6 +320,7 @@ preferences.updates.currentVersion=Nuværende version: %s
preferences.updates.autoUpdateCheck=Søg automatisk efter opdateringer
preferences.updates.checkNowBtn=Kontrollér nu
preferences.updates.updateAvailable=Opdatering til version %s er tilgængelig.
+preferences.updates.checkFailed=Søgning efter opdateringer fejlede. Tjek din internetforbindelse eller forsøg igen senere.
## Contribution
preferences.contribute=Støt os
@@ -328,7 +330,6 @@ preferences.contribute.getCertificate=Har du ikke et allerede? Se her hvordan du
preferences.contribute.promptText=Indsæt koden for supporter-certifikatet her
### Remove License Key Dialog
-removeCert.confirmBtn=Fjern
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -379,6 +380,8 @@ main.vaultlist.contextMenu.unlockNow=Lås op nu
main.vaultlist.contextMenu.vaultoptions=Vis boksindstillinger
main.vaultlist.contextMenu.reveal=Vis drev
##Notificaition
+main.notification.updateAvailable=Opdatering er tilgængelig.
+main.notification.support=Støt Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Tak fordi du valgte Cryptomator til at beskytte dine filer. Hvis du har brug for hjælp, så tjek vores guider for at komme i gang:
@@ -531,6 +534,8 @@ updateReminder.yesAutomatically=Ja, automatisk
#Dokany Support End
dokanySupportEnd.preferencesBtn=Åbn Indstillinger
+#Retry If Readonly
+
# Share Vault
shareVault.title=Del Boks
shareVault.message=Vil du dele din boks med andre?
diff --git a/src/main/resources/i18n/strings_de.properties b/src/main/resources/i18n/strings_de.properties
index 0b67adc82..bd328c0a1 100644
--- a/src/main/resources/i18n/strings_de.properties
+++ b/src/main/resources/i18n/strings_de.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopiert!
generic.button.done=Fertig
generic.button.next=Weiter
generic.button.print=Drucken
+generic.button.remove=Entfernen
# Error
error.message=Ein Fehler ist aufgetreten
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Jetzt entsperren
removeVault.title=„%s“ entfernen
removeVault.message=Tresor entfernen?
removeVault.description=Dieser Tresor wird nur aus der Tresorliste entfernt; du kannst ihn später jederzeit wieder hinzufügen. Es werden keine verschlüsselten Daten gelöscht.
-removeVault.confirmBtn=Tresor entfernen
# Change Password
changepassword.title=Passwort ändern
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=Im Registrierungsprozess ist ein Fehler a
hub.registerFailed.description.deviceAlreadyExists=Dieses Gerät ist bereits für einen anderen Benutzer registriert. Ändere das Benutzerkonto oder verwende ein anderes Gerät.
### Unauthorized
hub.unauthorized.message=Zugriff verweigert
-hub.unauthorized.description=Dein Gerät wurde noch nicht für den Zugriff auf diesen Tresor autorisiert. Bitte den Tresorbesitzer, dein Gerät zu autorisieren.
### Requires Account Initialization
hub.requireAccountInit.message=Aktion erforderlich
hub.requireAccountInit.description.0=Um fortzufahren, führe bitte die erforderlichen Schritte in deinem
@@ -245,7 +244,7 @@ health.checkList.selectAllButton=Alle Prüfungen auswählen
health.checkList.deselectAllButton=Alle Prüfungen abwählen
health.check.runBatchBtn=Ausgewählte Prüfungen ausführen
## Detail view
-health.check.detail.noSelectedCheck=Wähle für die Ergebnisse eine abgeschlossene Intregritätsprüfung in der Liste links aus.
+health.check.detail.noSelectedCheck=Wähle für die Ergebnisse eine abgeschlossene Integritätsprüfung in der Liste links aus.
health.check.detail.checkScheduled=Die Prüfung ist geplant.
health.check.detail.checkRunning=Die Prüfung läuft derzeit …
health.check.detail.checkSkipped=Die Prüfung wurde nicht zur Ausführung ausgewählt.
@@ -287,7 +286,7 @@ preferences.general.debugLogging=Diagnoseprotokoll aktivieren
preferences.general.debugDirectory=Protokolldateien anzeigen
preferences.general.autoStart=Cryptomator beim Systemstart starten
preferences.general.keychainBackend=Passwörter speichern mit
-preferences.general.quickAccessService=Die entsperrten Tresore zum Schnellzugriff hinzufügen
+preferences.general.quickAccessService=Entsperrte Tresore zum Schnellzugriff hinzufügen
## Interface
preferences.interface=Benutzeroberfläche
preferences.interface.theme=Erscheinungsbild
@@ -301,7 +300,7 @@ preferences.interface.interfaceOrientation=Oberflächenausrichtung
preferences.interface.interfaceOrientation.ltr=Von links nach rechts
preferences.interface.interfaceOrientation.rtl=Von rechts nach links
preferences.interface.showTrayIcon=Symbol im Infobereich anzeigen (Neustart erforderlich)
-preferences.interface.compactMode=Kompakte Tresoransicht einschalten
+preferences.interface.compactMode=Kompakte Tresorliste
## Volume
preferences.volume=Virtuelles Laufwerk
preferences.volume.type=Standard-Laufwerkstyp
@@ -343,7 +342,6 @@ preferences.contribute.sponsor=Sponsern
removeCert.title=Zertifikat entfernen
removeCert.message=Supporter-Zertifikat entfernen?
removeCert.description=Die Kernfunktionen von Cryptomator sind davon nicht betroffen. Weder der Zugriff auf deine Tresore ist eingeschränkt, noch wird das Sicherheitsniveau verringert.
-removeCert.confirmBtn=Entfernen
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -548,11 +546,13 @@ updateReminder.yesOnce=Ja, einmalig
updateReminder.yesAutomatically=Ja, automatisch
#Dokany Support End
-dokanySupportEnd.title=Hinweis: nicht mehr verwendet
-dokanySupportEnd.message=Ende der Unterstützung für Dokany
+dokanySupportEnd.title=Hinweis zur Ausmusterung
+dokanySupportEnd.message=Supportende für Dokany
dokanySupportEnd.description=Der Laufwerkstyp Dokany wird von Cryptomator nicht weiter unterstützt. Deine Einstellungen wurden angepasst, dass der Standard-Laufwerkstyp verwendet wird. Du kannst den Standardtyp in den Einstellungen anzeigen lassen.
dokanySupportEnd.preferencesBtn=Einstellungen öffnen
+#Retry If Readonly
+
# Share Vault
shareVault.title=Tresor teilen
shareVault.message=Möchtest du deinen Tresor mit anderen teilen?
diff --git a/src/main/resources/i18n/strings_el.properties b/src/main/resources/i18n/strings_el.properties
index 354e30c63..dedb4e6ef 100644
--- a/src/main/resources/i18n/strings_el.properties
+++ b/src/main/resources/i18n/strings_el.properties
@@ -13,6 +13,7 @@ generic.button.copied=Αντιγράφηκε!
generic.button.done=Κλείσιμο
generic.button.next=Επόμενο
generic.button.print=Εκτύπωση
+generic.button.remove=Αφαίρεση
# Error
error.message=Παρουσιάστηκε σφάλμα
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Ξεκλείδωμα τώρα
removeVault.title=Διαγραφή "%s"
removeVault.message=Διαγραφή κρύπτης;
removeVault.description=Αυτό θα κάνει το Cryptomator να ξεχάσει αυτή την κρύπτη. Μπορείτε να την προσθέσετε ξανά. Κανένα κρυπτογραφημένο αρχείο δε θα διαγραφεί από τον σκληρό σας δίσκο.
-removeVault.confirmBtn=Διαγραφή Κρύπτης
# Change Password
changepassword.title=Αλλαγή κωδικού πρόσβασης
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Παρουσιάστηκε σφάλμα
hub.registerFailed.description.deviceAlreadyExists=Αυτή η συσκευή είναι ήδη εγγεγραμμένη για διαφορετικό χρήστη. Προσπαθήστε να αλλάξετε τον λογαριασμό χρήστη ή να χρησιμοποιήσετε διαφορετική συσκευή.
### Unauthorized
hub.unauthorized.message=Δεν επιτρέπεται η πρόσβαση
-hub.unauthorized.description=Η συσκευή σας δεν έχει ακόμη εξουσιοδοτηθεί να έχει πρόσβαση σε αυτή την κρύπτη. Ζητήστε από τον κάτοχο της κρύπτης να την εξουσιοδοτήσει.
+hub.unauthorized.description=Δεν είστε εξουσιοδοτημένοι να ανοίξετε αυτή την κρύπτη. Επικοινωνήστε με τον ιδιοκτήτη τς κρύπτης για να ζητήσετε πρόσβαση.
### Requires Account Initialization
hub.requireAccountInit.message=Απαιτείται ενέργεια
hub.requireAccountInit.description.0=Για να συνεχίσετε, παρακαλούμε ολοκληρώστε τα βήματα που απαιτούνται στο δικό σας
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Χορηγός
removeCert.title=Αφαίρεση Πιστοποιητικού
removeCert.message=Αφαίρεση πιστοποιητικού υποστηρικτή;
removeCert.description=Οι βασικές λειτουργίες του Cryptomator δεν επηρεάζονται από αυτό. Ούτε η πρόσβαση στις κρύπτες σας είναι περιορισμένη ούτε το επίπεδο ασφάλειας μειώνεται.
-removeCert.confirmBtn=Αφαίρεση
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Τέλος υποστήριξης για Dokany
dokanySupportEnd.description=Ο τύπος τόμου Dokany δεν υποστηρίζεται πλέον από το Cryptomator. Οι ρυθμίσεις σας έχουν προσαρμοστεί για να χρησιμοποιούν τον προεπιλεγμένο τύπο τόμου. Μπορείτε να δείτε τον προεπιλεγμένο τύπο στις προτιμήσεις.
dokanySupportEnd.preferencesBtn=Άνοιγμα Προτιμήσεων
+#Retry If Readonly
+retryIfReadonly.title=Περιορισμένη Πρόσβαση Κρύπτης
+retryIfReadonly.message=Δεν υπάρχει πρόσβαση εγγραφής στον κατάλογο κρύπτης
+retryIfReadonly.description=Το Cryptomator δεν μπορεί να γράψει στον κατάλογο κρύπτης. Μπορείτε να αλλάξετε την κρύπτη ώστε να είναι μόνο για ανάγνωση και να προσπαθήσετε ξανά. Αυτή η επιλογή μπορεί να απενεργοποιηθεί στις επιλογές κρύπτης.
+retryIfReadonly.retry=Αλλαγή και Επανάληψη
+
# Share Vault
shareVault.title=Κοινή χρήση Κρύπτης
shareVault.message=Θα θέλατε να μοιραστείτε την κρύπτη σας με άλλους;
diff --git a/src/main/resources/i18n/strings_es.properties b/src/main/resources/i18n/strings_es.properties
index faa8b876c..6359cc8a2 100644
--- a/src/main/resources/i18n/strings_es.properties
+++ b/src/main/resources/i18n/strings_es.properties
@@ -13,6 +13,7 @@ generic.button.copied=¡Copiado!
generic.button.done=Hecho
generic.button.next=Siguiente
generic.button.print=Imprimir
+generic.button.remove=Eliminar
# Error
error.message=Ocurrió un error
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Desbloquear ahora
removeVault.title=Eliminar "%s"
removeVault.message=¿Eliminar bóveda?
removeVault.description=Esto sólo hará que Cryptomator olvide la bóveda. Se la puede añadir de nuevo más tarde. Los archivos cifrados no se eliminarán del disco duro.
-removeVault.confirmBtn=Eliminar bóveda
# Change Password
changepassword.title=Cambiar contraseña
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Ha ocurrido un error al intentar registra
hub.registerFailed.description.deviceAlreadyExists=Este dispositivo ya se ha registrado para otro usuario. Intente cambiar la cuenta de usuario o utilice un dispositivo diferente.
### Unauthorized
hub.unauthorized.message=Acceso denegado
-hub.unauthorized.description=Su dispositivo aún no ha sido autorizado para acceder a esta bóveda. Pídale al propietario de la bóveda que lo autorice.
+hub.unauthorized.description=No tiene autorización para abrir esta bóveda. Contacta al propietario de la bóveda para solicitar acceso.
### Requires Account Initialization
hub.requireAccountInit.message=Acción requerida
hub.requireAccountInit.description.0=Para continuar, por favor complete los pasos necesarios en su
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Patrocinador
removeCert.title=Eliminar Certificado
removeCert.message=¿Eliminar certificado de soporte?
removeCert.description=Las características principales de Cryptomator no se ven afectadas por esto. No se restringe el acceso a sus bóvedas ni se reduce el nivel de seguridad.
-removeCert.confirmBtn=Eliminar
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Fin de soporte para Dokany
dokanySupportEnd.description=El tipo de volumen Dokany ya no está soportado por Cryptomator. Su configuración se ajusta para utilizar el tipo de volumen predeterminado ahora. Puede ver el tipo predeterminado en las preferencias.
dokanySupportEnd.preferencesBtn=Abrir preferencias
+#Retry If Readonly
+retryIfReadonly.title=Acceso restringido a la Bóveda
+retryIfReadonly.message=No tiene acceso de escritura al directorio de bóveda
+retryIfReadonly.description=Cryptomator no puede escribir en el directorio de la bóveda. Puede cambiar la bóveda para que sea de solo lectura e inténtelo de nuevo. Esta opción puede desactivarse en las opciones de bóveda.
+retryIfReadonly.retry=Cambiar y reintentar
+
# Share Vault
shareVault.title=Compartir bóveda
shareVault.message=¿Le gustaría compartir su bóveda con alguien más?
diff --git a/src/main/resources/i18n/strings_fa.properties b/src/main/resources/i18n/strings_fa.properties
index 0d96b1fa9..6f8df4fed 100644
--- a/src/main/resources/i18n/strings_fa.properties
+++ b/src/main/resources/i18n/strings_fa.properties
@@ -13,6 +13,7 @@ generic.button.copied=کپی شد!
generic.button.done=انجام شده
generic.button.next=بعدی
generic.button.print=چاپ
+generic.button.remove=حذف
# Error
error.message=خطایی رخ داده است
@@ -155,7 +156,6 @@ preferences.updates.upToDate=Cryptomator به روز می باشد.
## Contribution
### Remove License Key Dialog
-removeCert.confirmBtn=حذف
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -210,4 +210,6 @@ vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_fi.properties b/src/main/resources/i18n/strings_fi.properties
index 3e76a1f8c..47d17499f 100644
--- a/src/main/resources/i18n/strings_fi.properties
+++ b/src/main/resources/i18n/strings_fi.properties
@@ -2,10 +2,10 @@
# Generics
## Button
-generic.button.apply=Vahvista
+generic.button.apply=Käytä
generic.button.back=Takaisin
generic.button.cancel=Peruuta
-generic.button.change=Muuta
+generic.button.change=Vaihda
generic.button.choose=Valitse…
generic.button.close=Sulje
generic.button.copy=Kopioi
@@ -13,6 +13,7 @@ generic.button.copied=Kopioitu!
generic.button.done=Valmis
generic.button.next=Seuraava
generic.button.print=Tulosta
+generic.button.remove=Poista
# Error
error.message=Tapahtui virhe
@@ -22,27 +23,32 @@ error.hyperlink.report=Ilmoita ongelmasta
error.technicalDetails=Tiedot:
error.existingSolutionDescription=Cryptomator ei odottanut tämän tapahtuvan. Mutta löysimme olemassa olevan ratkaisun tähän virheeseen. Ole hyvä ja katso seuraavaa linkkiä.
error.hyperlink.solution=Etsi ratkaisu
+error.lookupPermissionMessage=Cryptomator voi etsiä ratkaisun tähän ongelmaan verkosta. Tämä lähettää pyynnön ongelmatietokannallemme IP-osoitteestasi.
+error.dismiss=Ohita
+error.lookUpSolution=Etsi ratkaisu
# Defaults
-defaults.vault.vaultName=Vault
+defaults.vault.vaultName=Holvi
# Tray Menu
traymenu.showMainWindow=Näytä
traymenu.showPreferencesWindow=Asetukset
-traymenu.lockAllVaults=Lukitse Kaikki
+traymenu.lockAllVaults=Lukitse kaikki
traymenu.quitApplication=Sulje
traymenu.vault.unlock=Avaa
traymenu.vault.lock=Lukitse
traymenu.vault.reveal=Paljasta
# Add Vault Wizard
-addvaultwizard.title=Lisää Vault
+addvaultwizard.title=Lisää holvi
## New
+addvaultwizard.new.title=Lisää uusi holvi
### Name
-addvaultwizard.new.nameInstruction=Anna uusi nimi Vaultille
-addvaultwizard.new.namePrompt=Vault Nimi
+addvaultwizard.new.nameInstruction=Valitse holvin nimi
+addvaultwizard.new.namePrompt=Holvin nimi
### Location
-addvaultwizard.new.locationInstruction=Missä pitäisi Cryptomator tallentaa salattuja tiedostoja Vault?
+addvaultwizard.new.locationInstruction=Missä Cryptomatorin tulisi säilyttää holvisi salattuja tiedostoja?
+addvaultwizard.new.locationLoading=Etsitään paikallisesta tiedostojärjestelmästä pilvikansioita…
addvaultwizard.new.locationLabel=Tallennustilan sijainti
addvaultwizard.new.locationPrompt=…
addvaultwizard.new.directoryPickerLabel=Oma sijainti
@@ -59,6 +65,11 @@ addvaultwizard.new.validCharacters.chars=Sanamerkit (e.g. a, ж or 수)
addvaultwizard.new.validCharacters.numbers=Numerot
addvaultwizard.new.validCharacters.dashes=Hyphen (%s) tai alaviiva (%s)
### Expert Settings
+addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox=Ota lisäasetukset käyttöön
+addvaultwizard.new.expertSettings.shorteningThreshold.invalid=Syötä arvo väliltä 36 ja 220 (oletus 220)
+addvaultwizard.new.expertSettings.shorteningThreshold.tooltip=Avaa dokumentaatio lisätietoja varten.
+addvaultwizard.new.expertSettings.shorteningThreshold.title=Salattujen tiedostonimien enimmäispituus
+addvaultwizard.new.expertSettings.shorteningThreshold.valid=Kelvollinen
### Password
addvaultwizard.new.createVaultBtn=Luo Uusi Vault
addvaultwizard.new.generateRecoveryKeyChoice=Et voi käyttää tietojasi ilman salasanaasi. Haluatko palautusavaimen siltä varalta, että menetät salasanasi?
@@ -82,6 +93,7 @@ addvault.new.readme.accessLocation.2=Tämä on salatun holvisi tallennuskansio.
addvault.new.readme.accessLocation.3=Cryptomator salaa kaikki tänne siirtämäsi tiedostot. Voit työskennellä tässä kansiossa aivan samalla tavalla kuin muutenkin. Tämä on ainoastaan näkymä jossa salaus on purettu. Todellisuudessa kaikki tiedostot pysyvät salattuina aina.
addvault.new.readme.accessLocation.4=Voit halutessasi poistaa tämän tiedoston. Poistaminen ei vaikuta Cryptomatorin toimintaan.
## Existing
+addvaultwizard.existing.title=Lisää olemassa oleva holvi
addvaultwizard.existing.instruction=Valitse olemassa olevan Cryptomator holvin "vault.cryptomator" -tiedosto. Mikäli "vault.cryptomator" -tiedostoa ei ole, valitse "masterkey.cryptomator" -tiedosto.
addvaultwizard.existing.chooseBtn=Valitse…
addvaultwizard.existing.filePickerTitle=Valitse Holvi -tiedosto
@@ -93,32 +105,31 @@ addvaultwizard.success.unlockNow=Avaa Nyt
# Remove Vault
removeVault.title=Poista "%s"
removeVault.message=Poistetaanko holvi?
-removeVault.description=Tämä toiminto ainoastaan poistaa valitun holvin Cryptomatorin näkymästä. Salattuja tiedostoja tai holvia itsessään ei poisteta.
-removeVault.confirmBtn=Poista Holvi
+removeVault.description=Tämä toiminto ainoastaan poistaa valitun holvin Cryptomatorin näkymästä. Voit lisätä sen uudelleen. Salattuja tiedostoja ei poisteta levyltäsi.
# Change Password
changepassword.title=Vaihda salasana
-changepassword.enterOldPassword=Syötä "%s": n nykyinen salasana
+changepassword.enterOldPassword=Kirjoita holvin "%s" nykyinen salasana
changepassword.finalConfirmation=Ymmärrän, että tiedostojani ei voi palauttaa, mikäli unohdan salasanani.
# Forget Password
-forgetPassword.title=Unohda Salasana
+forgetPassword.title=Unohda salasana
forgetPassword.message=Unohda tallennetut salasanat?
forgetPassword.description=Tämä poistaa valitun holvin tallennetun salasanan järjestelmäsi avainrenkaasta.
-forgetPassword.confirmBtn=Unohda Salasana
+forgetPassword.confirmBtn=Unohda salasana
# Unlock
unlock.title=Avaa "%s"
-unlock.passwordPrompt=Syötä salasana "%s":lle
+unlock.passwordPrompt=Syötä holvin "%s" salasana:
unlock.savePassword=Muista salasana
unlock.unlockBtn=Avaa
## Select
-unlock.chooseMasterkey.message=Masterkey -tiedostoa ei löydy
-unlock.chooseMasterkey.description=Cryptomator ei paikantanut masterkey -tiedostoa holville "%s". Ole hyvä ja valitse tiedosto manuaalisesti.
-unlock.chooseMasterkey.filePickerTitle=Valitse Masterkey -tiedosto
-unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator Masterkey
+unlock.chooseMasterkey.message=Masterkey-tiedostoa ei löydy
+unlock.chooseMasterkey.description=Cryptomator ei paikantanut masterkey-tiedostoa holville "%s". Ole hyvä ja valitse tiedosto manuaalisesti.
+unlock.chooseMasterkey.filePickerTitle=Valitse masterkey-tiedosto
+unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator masterkey
## Success
-unlock.success.message=Lukituksen purku onnistui
+unlock.success.message=Avaus onnistui
unlock.success.description="%s" holvin sisältö on nyt saatavilla sen hallinnointikohteessa.
unlock.success.rememberChoice=Muista valintani. Älä kysy uudelleen.
unlock.success.revealBtn=Paljasta Asema
@@ -126,6 +137,14 @@ unlock.success.revealBtn=Paljasta Asema
unlock.error.customPath.message=Holvia ei pystytty yhdistämään valittuun polkuun
unlock.error.customPath.description.notSupported=Mikäli haluat jatkaa mukautetun polun käyttöä, ole hyvä ja mene Asetuksiin ja valitse volyymityyppi mikä tukee sitä. Muussa tapauksessa avaa holvin asetukset ja valitse tuettu mukautettu polku.
unlock.error.customPath.description.notExists=Valitsemaasi mukautettua polkua ei ole olemassa. Voit joko luoda uuden polun tai muuttaa polkua holvisi asetuksissa.
+unlock.error.customPath.description.inUse=Aseman kirjain tai mukautettu liitospolku "%s" on jo käytössä.
+unlock.error.customPath.description.hideawayNotDir=Avaukseen käytettävää väliaikaista piilotettua tiedostoa "%3$s" ei voitu poistaa. Tarkista tiedosto ja poista se manuaalisesti.
+unlock.error.customPath.description.couldNotBeCleaned=Holviasi ei voilu liittää polkuun "%s". Yritä uudelleen tai valitse toinen polku.
+unlock.error.customPath.description.notEmptyDir=Mukautettu liitospolku "%s" ei ole tyhtjä kansio. Valitse tyhjä kansio ja yritä uudelleen.
+unlock.error.customPath.description.generic=Olet valinnut mukautetun liitospolun holvillesi, mutta sen kanssa ilmeni ongelma: %2$s
+unlock.error.restartRequired.message=Holvin avaus epäonnistui
+unlock.error.restartRequired.description=Vaihda aseman tyyppiä holvin asetuksissa tai käynnistä Cryptomator uudelleen.
+unlock.error.title="%s" avaaminen epäonnistui
## Hub
hub.noKeychain.message=Laitteen avainta ei löytynyt
hub.noKeychain.description=Hub-holvien purkamiseksi tarvitaan laiteavain joka on suojattu avainrenkaalla. Jatkaaksesi, kytke “%s” päälle ja valitse avainrengas asetuksista.
@@ -138,15 +157,30 @@ hub.auth.loginLink=Uudelleenohjaus epäonnistui? Avaa tästä manuaalisesti.
hub.receive.message=Odotetaan vastausta…
hub.receive.description=Cryptomator yhdistää Hub:iin. Ole hyvä ja odota.
### Register Device
+hub.register.message=Uusi laite
+hub.register.description=Tämä on ensimmäinen Hub-yhteys tästä laitteesta. Rekisteröi se käyttäen Account Keytäsi.
hub.register.nameLabel=Laitteen Nimi
+hub.register.invalidAccountKeyLabel=Virheellinen Account Key
+hub.register.registerBtn=Rekisteröidy
### Register Device Legacy
+hub.register.legacy.occupiedMsg=Nimi on jo käytössä
+hub.register.legacy.description=Tämä on ensimmäinen Hub-yhteys tästä laitteesta. Ole hyvä ja rekisteröi se.
### Registration Success
+hub.registerSuccess.message=Laite rekisteröity
+hub.registerSuccess.description=Laitteesi on rekisteröity onnistuneesti. Voit nyt avata holvin.
hub.registerSuccess.unlockBtn=Avaa
+hub.registerSuccess.legacy.description=Käyttääksesi holvia, holvin omistajan on valtuutettava laitteesi.
### Registration Failed
+hub.registerFailed.message=Laitteen rekisteröinti epäonnistui
+hub.registerFailed.description.generic=Rekisteröinnissä tapahtui virhe. Löydät lisätietoja lokitiedostoista.
+hub.registerFailed.description.deviceAlreadyExists=Tämä laite on jo rekisteröity toiselle käyttäjälle. Yritä vaihtaa käyttäjätiliä tai käytää toista laitetta.
### Unauthorized
hub.unauthorized.message=Pääsy estetty
-hub.unauthorized.description=Laitteellasi ei ole pääsyvaltuutusta tähän holviin. Pyydä holvin omistajaa lisäämän valtuutus laitteellesi.
### Requires Account Initialization
+hub.requireAccountInit.message=Toimia vaaditaan
+hub.requireAccountInit.description.0=Jatkaaksesi, ole hyvä ja suorita tarvittavat toimenpiteet
+hub.requireAccountInit.description.1=Hub käyttäjäprofiili
+hub.requireAccountInit.description.2=.
### License Exceeded
hub.invalidLicense.message=Hub-lisenssi ei ole voimassa
hub.invalidLicense.description=Cryptomator Hub:illasi ei ole voimassa olevaa lisenssiä. Ole hyvä ja ilmoita Hubin järjestelmänvalvojalle lisenssin päivittämiseksi tai sen uusimiseksi.
@@ -194,82 +228,335 @@ migration.impossible.moreInfo=Varasto voidaan edelleen avata vanhemmalla versiol
## Start
health.title="%s" kuntotarkastus
health.intro.header=Kuntotarkastus
+health.intro.text=Kuntotarkistus on kokoelma testejä, joilla havaitaan ja korjataan ongelmia holvissasi. Ole hyvä ja pidä mielessäsi:
+health.intro.remarkSync=Varmista että kaikki laitteet ovat täysin synkronoitu, tämä ratkaisee useimmat ongelmat.
+health.intro.remarkFix=Kaikkia ongelmia ei voida ratkaista.
+health.intro.remarkBackup=Jos tiedot ovat korruptoituneita, vain varmuuskopiosta on apua.
+health.intro.affirmation=Olen lukenut ja ymmärtänyt yllä mainitut huomiot
## Start Failure
+health.fail.header=Virhe ladattaessa holvin asetuksia
+health.fail.ioError=Asetustiedostoa lukiessa tapahtui virhe.
+health.fail.parseError=Holvin asetuksia jäsentäessä tapahtui virhe.
+health.fail.moreInfo=Lisätietoja
## Check Selection
+health.checkList.description=Valitse testit vasemmalta luettelosta tai käytä alla olevia painikkeita.
+health.checkList.selectAllButton=Valitse kaikki testit
+health.checkList.deselectAllButton=Poista testivalinnat
+health.check.runBatchBtn=Suorita valitut testit
## Detail view
+health.check.detail.noSelectedCheck=Katsoaksesi tulokset, valitse suoritettu kuntotarkistus vasemmalta luettelosta.
+health.check.detail.checkScheduled=Testi on ajoitettu.
+health.check.detail.checkRunning=Testi on käynnissä…
+health.check.detail.checkSkipped=Testiä ei valittu suoritettavaksi.
+health.check.detail.checkFinished=Testi suoritettiin onnistuneesti.
+health.check.detail.checkFinishedAndFound=Testi suorietttiin loppuun. Ole hyvä ja katso tulokset.
+health.check.detail.checkFailed=Testi päättyi virheen vuoksi.
+health.check.detail.checkCancelled=Testi peruutettiin.
+health.check.detail.listFilters.label=Suodata
+health.check.detail.fixAllSpecificBtn=Korjaa kaikki tyyppiä
+health.check.exportBtn=Vie raportti
## Result view
+health.result.severityFilter.all=Vakavuus - Kaikki
+health.result.severityFilter.good=Hyvä
+health.result.severityFilter.info=Huomio
+health.result.severityFilter.warn=Varoitus
+health.result.severityFilter.crit=Kriittinen
+health.result.severityTip.good=Vakavuus: Hyvä\nNormaali holvirakenne.
+health.result.severityTip.info=Vakavuus: Huomio\nHolvin rakenne ehjä. Ehdotetaan korjausta.
+health.result.severityTip.warn=Vakavuus: Varoitus\nHolvin rakenne korruptoitunut. Korjaus erittäin suositeltavaa.
+health.result.severityTip.crit=Vakavuus: Kriittinen\nHolvin rakenne korruptoitunut. Tietoja menetetty.
+health.result.fixStateFilter.all=Korjauksen tila - Kaikki
+health.result.fixStateFilter.fixable=Korjattavissa
+health.result.fixStateFilter.notFixable=Ei korjattavissa
+health.result.fixStateFilter.fixing=Korjataan…
+health.result.fixStateFilter.fixed=Korjattu
+health.result.fixStateFilter.fixFailed=Korjaus epäonnistui
## Fix Application
+health.fix.fixBtn=Korjaa
+health.fix.successTip=Korjaus onnistui
+health.fix.failTip=Korjaus epäonnistui, katso lisätietoja lokista
# Preferences
preferences.title=Asetukset
## General
+preferences.general=Yleiset
+preferences.general.startHidden=Piilota ikkuna kun Cryptomator käynnistyy
+preferences.general.autoCloseVaults=Lukitse avoimet holvit automaattisesti kun ohjelma sammutetaan
+preferences.general.debugLogging=Ota virheloki käyttöön
+preferences.general.debugDirectory=Näytä lokitiedostot
+preferences.general.autoStart=Käynnistä Cryptomator järjestelmän käynnistyessä
+preferences.general.keychainBackend=Tallenna salasanat käyttäen
+preferences.general.quickAccessService=Lisää avatut holvit pikavalikkoon
## Interface
+preferences.interface=Käyttöliittymä
+preferences.interface.theme=Ulkonäkö
+preferences.interface.theme.automatic=Automaattinen
+preferences.interface.theme.dark=Tumma
+preferences.interface.theme.light=Vaalea
+preferences.interface.unlockThemes=Hanki tumma tila
+preferences.interface.language=Kieli (vaatii uudelleenkäynnistyksen)
+preferences.interface.language.auto=Järjestelmän oletus
+preferences.interface.interfaceOrientation=Käyttöliittymän kätisyys
+preferences.interface.interfaceOrientation.ltr=Vasemmalta oikealle
+preferences.interface.interfaceOrientation.rtl=Oikealta vasemmalle
+preferences.interface.showTrayIcon=Näytä ilmoitusalueen kuvake (vaatii uudelleenkäynnistyksen)
+preferences.interface.compactMode=Käytä kompaktia holviluetteloa
## Volume
+preferences.volume=Virtuaaliasema
+preferences.volume.type=Aseman oletustyyppi
+preferences.volume.type.automatic=Automaattinen
+preferences.volume.docsTooltip=Lue lisää asematyypeistä dokumentaatiosta.
+preferences.volume.fuseRestartRequired=Jotta muutokset tulevat voimaan, Cryptomator täytyy käynnistää uudelleen.
+preferences.volume.tcp.port=Oletus TCP-portti
+preferences.volume.supportedFeatures=Valittu asematyyppi tukee seuraavia ominaisuuksia:
+preferences.volume.feature.mountAuto=Automaattinen liitospolun valinta
+preferences.volume.feature.mountToDir=Mukautettu kansio litospolkuna
+preferences.volume.feature.mountToDriveLetter=Aseman kirjain liitospolkuna
+preferences.volume.feature.mountFlags=Mukautetut liitosasetukset
+preferences.volume.feature.readOnly=Liitos vain lukuoikeuksilla
## Updates
+preferences.updates=Päivitykset
+preferences.updates.currentVersion=Nykyinen versio: %s
+preferences.updates.autoUpdateCheck=Tarkista päivitykset automaattisesti
+preferences.updates.checkNowBtn=Tarkista nyt
+preferences.updates.updateAvailable=Päivitys versioon %s saatavilla.
+preferences.updates.lastUpdateCheck=Edellinen tarkistus: %s
+preferences.updates.lastUpdateCheck.never=ei koskaan
+preferences.updates.lastUpdateCheck.recently=viimeaikoina
+preferences.updates.lastUpdateCheck.daysAgo=%s päivää sitten
+preferences.updates.lastUpdateCheck.hoursAgo=%s tuntia sitten
+preferences.updates.checkFailed=Päivitysten etsiminen epäonnistui. Tarkista internetyhteys tai yritä myöhemmin uudelleen.
+preferences.updates.upToDate=Cryptomator on ajan tasalla.
## Contribution
+preferences.contribute=Tue meitä
+preferences.contribute.noCertificate=Tue Cryptomatoria ja saa tukijasertifikaatti. Se on kuin lisenssiavain, mutta mahtaville ihmisille, jotka käyttävät vapaata ohjelmistoa. ;-)
+preferences.contribute.getCertificate=Eikö sinulla ole sellaista? Lue lisää miten voit hankkia sellaisen.
+preferences.contribute.promptText=Liitä tukijasertifikaatin koodi tähän
+preferences.contribute.thankYou=Kiitos tuestasi Cryptomatorin avoimeen kehittämiseen!
+preferences.contribute.donate=Lahjoita
+preferences.contribute.sponsor=Sponsori
### Remove License Key Dialog
+removeCert.title=Poista sertifikaatti
+removeCert.message=Poista tukijasertifikaatti?
+removeCert.description=Tämä ei vaikuta Cryptomatorin ydintoimintoihin. Holveihin pääsyä ei rajoiteta eikä turvallisuutta heikennetä.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
+preferences.about=Tietoja
# Vault Statistics
+stats.title=%s tilastot
## Read
+stats.read.throughput.idle=Luku: toimeton
+stats.read.throughput.kibs=Luku: %.2f KiB/s
+stats.read.throughput.mibs=Luku: %.2f MiB/s
+stats.read.total.data.none=Dataa luettu: -
+stats.read.total.data.kib=Dataa luettu: %.1f KiB
+stats.read.total.data.mib=Dataa luettu: %.1f MiB
+stats.read.total.data.gib=Dataa luettu: %.1f GiB
+stats.decr.total.data.none=Dataa purettu: -
+stats.decr.total.data.kib=Dataa purettu: %.1f KiB
+stats.decr.total.data.mib=Dataa purettu: %.1f MiB
+stats.decr.total.data.gib=Dataa purettu: %.1f GiB
+stats.read.accessCount=Lukuja yhteensä: %d
## Write
+stats.write.throughput.idle=Kirjoitus: toimeton
+stats.write.throughput.kibs=Kirjoitus: %.2f KiB/s
+stats.write.throughput.mibs=Kirjoitus: %.2f MiB/s
+stats.write.total.data.none=Dataa kirjoitettu: -
+stats.write.total.data.kib=Dataa kirjoitettu: %.1f KiB
+stats.write.total.data.mib=Dataa kirjoitettu: %.1f MiB
+stats.write.total.data.gib=Dataa kirjoitettu: %.1f GiB
+stats.encr.total.data.none=Dataa salattu: -
+stats.encr.total.data.kib=Dataa salattu: %.1f KiB
+stats.encr.total.data.mib=Dataa salattu: %.1f MiB
+stats.encr.total.data.gib=Dataa salattu: %.1f GiB
+stats.write.accessCount=Kirjoituksia yhteensä: %d
## Accesses
+stats.access.current=Tiedostoja avattuna: %d
+stats.access.total=Avauksia yhteensä: %d
# Main Window
## Vault List
+main.vaultlist.emptyList.onboardingInstruction=Klikkaa tästä lisätäksesi holvin
+main.vaultlist.contextMenu.remove=Poista…
main.vaultlist.contextMenu.lock=Lukitse
+main.vaultlist.contextMenu.unlock=Avaa…
main.vaultlist.contextMenu.unlockNow=Avaa Nyt
+main.vaultlist.contextMenu.vaultoptions=Näytä holvin asetukset
main.vaultlist.contextMenu.reveal=Paljasta Asema
+main.vaultlist.addVaultBtn.menuItemNew=Luo uusi holvi...
+main.vaultlist.addVaultBtn.menuItemExisting=Avaa olemassa oleva holvi...
##Notificaition
+main.notification.updateAvailable=Päivitys on saatavilla.
+main.notification.support=Tue Cryptomatoria.
## Vault Detail
### Welcome
+main.vaultDetail.welcomeOnboarding=Kiitos kun valitsit Cryptomatorin tiedostojesi suojaamiseen. Mikäli tarvitset apua, tutustu aloitusoppaaseemme:
### Locked
+main.vaultDetail.lockedStatus=LUKITTU
+main.vaultDetail.unlockBtn=Avaa…
main.vaultDetail.unlockNowBtn=Avaa Nyt
+main.vaultDetail.optionsBtn=Holvin asetukset
+main.vaultDetail.passwordSavedInKeychain=Salasana on tallennettu
+main.vaultDetail.share=Jaa…
### Unlocked
+main.vaultDetail.unlockedStatus=AVATTU
+main.vaultDetail.accessLocation=Holvisi sisältö on saatavilla täältä:
main.vaultDetail.revealBtn=Paljasta Asema
+main.vaultDetail.copyUri=Kopioi URI
main.vaultDetail.lockBtn=Lukitse
+main.vaultDetail.bytesPerSecondRead=Luku:
+main.vaultDetail.bytesPerSecondWritten=Kirjoitus:
+main.vaultDetail.throughput.idle=toimeton
+main.vaultDetail.throughput.kbps=%.1f KiB/s
+main.vaultDetail.throughput.mbps=%.1f MiB/s
+main.vaultDetail.stats=Holvin tilastot
+main.vaultDetail.locateEncryptedFileBtn=Etsi salattu tiedosto
+main.vaultDetail.locateEncryptedFileBtn.tooltip=Valitse tiedosto holvistasi löytääksesi sen salatun vastineen
+main.vaultDetail.encryptedPathsCopied=Polut kopioitu leikepöydälle!
+main.vaultDetail.filePickerTitle=Valitse tiedosto holvin sisältä
### Missing
+main.vaultDetail.missing.info=Cryptomator ei löytänyt täältä holvia.
+main.vaultDetail.missing.recheck=Tarkista uudelleen
+main.vaultDetail.missing.remove=Poista holvilistalta…
+main.vaultDetail.missing.changeLocation=Vaihda holvin sijaintia…
### Needs Migration
main.vaultDetail.migrateButton=Päivitä Holvi
+main.vaultDetail.migratePrompt=Holvisi täytyy muuntaa uuteen muotoon ennen kuin voit avata sen
### Error
+main.vaultDetail.error.info=Tapahtui virhe ladatessa holvia levyltä.
+main.vaultDetail.error.reload=Päivitä
+main.vaultDetail.error.windowTitle=Virhe ladatessa holvia
# Wrong File Alert
+wrongFileAlert.title=Kuinka tiedostoja salataan
+wrongFileAlert.message=Yritkö salata nämä tiedostot?
+wrongFileAlert.instruction.0=Salaa tiedostot seuraavasti:
+wrongFileAlert.instruction.1=1. Avaa holvisi.
+wrongFileAlert.instruction.2=2. Klikkaa "Paljasta" avataksesi aseman tiedostoselaimessasi.
+wrongFileAlert.instruction.3=3. Siirrä tiedostosi asemalle.
+wrongFileAlert.link=Lisäapua varten katso
# Vault Options
## General
-vaultOptions.general.vaultName=Vault Nimi
+vaultOptions.general=Yleiset
+vaultOptions.general.vaultName=Holvin nimi
+vaultOptions.general.autoLock.lockAfterTimePart1=Lukitse kun ollut käyttämättä
+vaultOptions.general.autoLock.lockAfterTimePart2=minuuttia
+vaultOptions.general.unlockAfterStartup=Avaa holvi kun Cryptomator käynnistyy
+vaultOptions.general.actionAfterUnlock=Avauksen jälkeen
+vaultOptions.general.actionAfterUnlock.ignore=Älä tee mitään
vaultOptions.general.actionAfterUnlock.reveal=Paljasta Asema
+vaultOptions.general.actionAfterUnlock.ask=Kysy
+vaultOptions.general.startHealthCheckBtn=Aloita kuntotarkastus
## Mount
+vaultOptions.mount=Liittäminen
+vaultOptions.mount.info=Avaa virtuaaliaseman asetukset muuttaaksesi oletuksia.
+vaultOptions.mount.readonly=Vain luku
+vaultOptions.mount.customMountFlags=Mukautetut liitosasetukset
+vaultOptions.mount.winDriveLetterOccupied=käytössä
+vaultOptions.mount.mountPoint=Liitoskohta
+vaultOptions.mount.mountPoint.auto=Valitse sopiva sijainti automaattisesti
+vaultOptions.mount.mountPoint.driveLetter=Käytä määritettyä asemakirjainta
+vaultOptions.mount.mountPoint.custom=Käytä valittua kansiota
vaultOptions.mount.mountPoint.directoryPickerButton=Valitse…
+vaultOptions.mount.mountPoint.directoryPickerTitle=Valitse kansio
+vaultOptions.mount.volumeType.default=Oletus (%s)
+vaultOptions.mount.volumeType.restartRequired=Jotta tätä asematyyppiä voidaan käyttää, Cryptomator täytyy käynnistää uudelleen.
+vaultOptions.mount.volume.tcp.port=TCP-portti
+vaultOptions.mount.volume.type=Aseman tyyppi
## Master Key
+vaultOptions.masterkey=Salasana
vaultOptions.masterkey.changePasswordBtn=Vaihda salasana
+vaultOptions.masterkey.forgetSavedPasswordBtn=Unohda tallennettu salasana
+vaultOptions.masterkey.recoveryKeyExplanation=Palautusavain on ainoa tapa päästä käsiksi holviin jos unohdat salasanasi.
+vaultOptions.masterkey.showRecoveryKeyBtn=Näytä Palautusavain
+vaultOptions.masterkey.recoverPasswordBtn=Palauta salasana
## Hub
+vaultOptions.hub=Palautus
+vaultOptions.hub.convertInfo=Voit käyttää palautusavainta muuttaaksesi tämä Hub-holvin salasanapohjaiseksi holviksi hätätapauksessa.
+vaultOptions.hub.convertBtn=Muunna salasanapohjaiseksi holviksi
# Recovery Key
## Display Recovery Key
+recoveryKey.display.title=Näytä palautusavain
+recoveryKey.create.message=Salasana vaaditaan
+recoveryKey.create.description=Syötä salasana holville "%s" näyttääksesi sen palautusavaimen.
+recoveryKey.display.description=Tällä palautusavaimella voidaan palauttaa pääsy holviin "%s":
+recoveryKey.display.StorageHints=Pidä se hyvin tallessa, esimerkiksi\n • Säilytä se salasananhallintaohjelmassa\n • Tallenna se USB-asemalle\n • Tulosta se paperille
## Reset Password
### Enter Recovery Key
+recoveryKey.recover.title=Palauta salasana
+recoveryKey.recover.prompt=Syötä palautusavain holville "%s":
+recoveryKey.recover.correctKey=Tämä palautusavain on oikea
+recoveryKey.recover.wrongKey=Tämä palautusavain kuuluu jollekin toiselle holville
+recoveryKey.recover.invalidKey=Tämä palautusavain ei ole kelvollinen
+recoveryKey.printout.heading=Cryptomator palautusavain\n"%s"\n
### Reset Password
+recoveryKey.recover.resetBtn=Palauta
### Recovery Key Password Reset Success
+recoveryKey.recover.resetSuccess.message=Salasanan palautus onnistui
+recoveryKey.recover.resetSuccess.description=Voit avata holvin uudella salasanalla.
# Convert Vault
+convertVault.title=Muunna holvi
+convertVault.convert.convertBtn.before=Muunna
+convertVault.convert.convertBtn.processing=Muunnetaan…
+convertVault.success.message=Muuntaminen onnistui
+convertVault.hubToPassword.success.description=Voit nyt avata holvin valitulla salasanalla ilman Hub-yhteyttä.
# New Password
+newPassword.promptText=Syötä uusi salasana
+newPassword.reenterPassword=Vahvista uusi salasana
+newPassword.passwordsMatch=Salasanat täsmäävät!
+newPassword.passwordsDoNotMatch=Salasanat eivät täsmää
+passwordStrength.messageLabel.tooShort=Käytä ainakin %d merkkiä
+passwordStrength.messageLabel.0=Erittäin heikko
+passwordStrength.messageLabel.1=Heikko
+passwordStrength.messageLabel.2=Kohtalainen
+passwordStrength.messageLabel.3=Vahva
+passwordStrength.messageLabel.4=Erittäin vahva
# Quit
+quit.title=Lopeta ohjelma
+quit.message=Holveja on auki
+quit.description=Vahvista että haluat lopettaa. Cryptomator lukitsee kaikki avatut holvit datan menetyksen ehkäisemiseksi.
+quit.lockAndQuitBtn=Lukitse ja lopeta
# Forced Quit
+quit.forced.message=Joitain holveja ei voitu lukita
+quit.forced.description=Holvien lukiseminen estyi odottavien tehtävien tai avattujen tiedostojen vuoksi. Voit pakottaa lukituksen, mutta datasiirron keskeyttäminen voi johtaa datan menetykseen.
+quit.forced.forceAndQuitBtn=Pakota ja lopeta
# Update Reminder
+updateReminder.title=Päivitysten tarkistus
+updateReminder.message=Tarkistetaanko päivitykset?
+updateReminder.description=Pysy ajan tasalla uusista ominaisuuksista, korjauksista ja turvallisuusparannuksista. Suosittelemme tarkistamaan päivitykset automaattisesti.
+updateReminder.notNow=Ei nyt
+updateReminder.yesOnce=Kyllä, vain tämän kerran
+updateReminder.yesAutomatically=Kyllä, automaattisesti
#Dokany Support End
dokanySupportEnd.preferencesBtn=Avaa asetukset
+#Retry If Readonly
+
# Share Vault
+shareVault.title=Jaa holvi
+shareVault.message=Haluatko jakaa holvisi muiden kanssa?
+shareVault.description=Ole aina varuillasi jakaessasi holvia muiden kanssa. Noudata näitä ohjeita:
+shareVault.instruction.1=1. Jaa käyttöoikeus salattuun holvikansioon pilvipalvelun kautta.
+shareVault.instruction.2=2. Jaa holvin salasana turvallisella tavalla.
+shareVault.remarkBestPractices=Lisätietoja varten tutustu hyvien käytäntöjen suosituksiin dokumentaatiossamme.
+shareVault.docsTooltip=Avaa dokumentaatio lukeaksesi lisää holvein jakamisesta.
+shareVault.visitHub=Käy Cryptomator Hubissa
+
+shareVault.hub.message=Kuinka jakaa Hub -holvi
+shareVault.hub.instruction.1=1. Jaa käyttöoikeus salattuun holvikansioon pilvipalvelun kautta.
+shareVault.hub.openHub=Avaa Cryptomator Hub
\ No newline at end of file
diff --git a/src/main/resources/i18n/strings_fil.properties b/src/main/resources/i18n/strings_fil.properties
index 120e04625..82cc3353a 100644
--- a/src/main/resources/i18n/strings_fil.properties
+++ b/src/main/resources/i18n/strings_fil.properties
@@ -13,6 +13,7 @@ generic.button.copied=Nakopya na!
generic.button.done=Tapos na
generic.button.next=Sunod
generic.button.print=I-print
+generic.button.remove=Tanggalin
# Error
error.message=Error %s
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=I-unlock Ngayon
removeVault.title=Tanggalin %s
removeVault.message=Itangal ang vault?
removeVault.description=Makakalimutan lang nito ang Cryptomator tungkol sa vault na ito. Maaari mo itong idagdag muli. Walang matatanggal na mga naka-encrypt na file mula sa iyong hard drive.
-removeVault.confirmBtn=Itangal ang vault
# Change Password
changepassword.title=Palitan ANG password
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=Nagkaroon ng error sa proseso ng pag regi
hub.registerFailed.description.deviceAlreadyExists=Ang device na ito ay registrado na sa ibang user. Subukang palitan ang user account o gumamit ng ibang device.
### Unauthorized
hub.unauthorized.message=Walang pahintulot
-hub.unauthorized.description=Hindi pa pinahihintulutan ang iyong device na i-access ang vault na ito. Hilingin sa may-ari ng vault na pahintulutan ito.
### Requires Account Initialization
hub.requireAccountInit.message=Kinakailangan ang pagkilos
hub.requireAccountInit.description.0=Upang magpatuloy, mangyaring kumpletuhin ang mga hakbang na kinakailangan sa iyong
@@ -336,7 +335,6 @@ preferences.contribute.getCertificate=Wala ka na ba? Alamin kung paano mo ito ma
preferences.contribute.promptText=I-paste ang code ng certificate ng tagasuporta dito
### Remove License Key Dialog
-removeCert.confirmBtn=Tanggalin
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -542,6 +540,8 @@ dokanySupportEnd.message=Pagtatapos ng suporta para sa Dokany
dokanySupportEnd.description=Ang uri ng volume na Dokany ay hindi na sinusuportahan ng Cryptomator. Isinasaayos ang iyong mga setting upang magamit ang default na uri ng volume ngayon. Maaari mong tingnan ang default na uri sa mga kagustuhan.
dokanySupportEnd.preferencesBtn=Buksan ang Mga Kagustuhan
+#Retry If Readonly
+
# Share Vault
shareVault.title=Ibahagi ang Vault
shareVault.message=Gusto mo bang ibahagi ang iyong vault sa iba?
diff --git a/src/main/resources/i18n/strings_fr.properties b/src/main/resources/i18n/strings_fr.properties
index 9422955aa..5bdaa268a 100644
--- a/src/main/resources/i18n/strings_fr.properties
+++ b/src/main/resources/i18n/strings_fr.properties
@@ -13,6 +13,7 @@ generic.button.copied=Copié !
generic.button.done=OK
generic.button.next=Suivant
generic.button.print=Imprimer
+generic.button.remove=Supprimer
# Error
error.message=Une erreur s'est produite
@@ -22,9 +23,9 @@ error.hyperlink.report=Signaler cette erreur
error.technicalDetails=Détails :
error.existingSolutionDescription=Cryptomator ne s'attendait pas à ce que cela se produise. Mais nous avons trouvé une solution existante pour cette erreur. Veuillez consulter le lien suivant.
error.hyperlink.solution=Rechercher la solution
-error.lookupPermissionMessage=Cryptomator peut trouver une solution à ce problème en ligne. Cela enverra une requête à notre base de données de problèmes à partir de votre adresse IP.
+error.lookupPermissionMessage=Cryptomator peut chercher une solution à ce problème en ligne. Une requête sera envoyée à notre base de données de problèmes à partir de votre adresse IP.
error.dismiss=Ignorer
-error.lookUpSolution=Rechercher la solution
+error.lookUpSolution=Chercher une solution
# Defaults
defaults.vault.vaultName=Coffre
@@ -65,7 +66,7 @@ addvaultwizard.new.validCharacters.numbers=Nombres
addvaultwizard.new.validCharacters.dashes=Tiret (%s) ou tiret du bas (%s)
### Expert Settings
addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox=Activer les paramètres experts
-addvaultwizard.new.expertSettings.shorteningThreshold.invalid=Entrez une valeur entre 36 et 220 (par défaut 220)
+addvaultwizard.new.expertSettings.shorteningThreshold.invalid=Entrez une valeur comprise entre 36 et 220 (par défaut 220)
addvaultwizard.new.expertSettings.shorteningThreshold.tooltip=Ouvrez la documentation pour en savoir plus.
addvaultwizard.new.expertSettings.shorteningThreshold.title=Longueur maximale des noms de fichiers chiffrés
addvaultwizard.new.expertSettings.shorteningThreshold.valid=Valide
@@ -94,7 +95,7 @@ addvault.new.readme.accessLocation.4=Vous pouvez supprimer ce fichier.
## Existing
addvaultwizard.existing.title=Ajouter un coffre existant
addvaultwizard.existing.instruction=Choisissez le fichier « vault.cryptomator » de votre volume existant. Si seul le fichier « masterkey.cryptomator » est présent, sélectionnez celui-là.
-addvaultwizard.existing.chooseBtn=Choisir...
+addvaultwizard.existing.chooseBtn=Choisir…
addvaultwizard.existing.filePickerTitle=Sélectionnez le fichier correspondant au volume chiffré
addvaultwizard.existing.filePickerMimeDesc=Coffre-fort Cryptomator
## Success
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Déverrouiller
removeVault.title=Supprimer "%s"
removeVault.message=Supprimer le coffre ?
removeVault.description=Ceci ne fera que retirer ce coffre de Cryptomator. Vous pourrez l’ajouter à nouveau plus tard. Aucun fichier chiffré ne sera supprimé de votre disque dur.
-removeVault.confirmBtn=Supprimer le coffre
# Change Password
changepassword.title=Modifier le mot de passe
@@ -127,7 +127,7 @@ unlock.unlockBtn=Déverrouiller
unlock.chooseMasterkey.message=Fichier Masterkey introuvable
unlock.chooseMasterkey.description=Impossible de trouver le fichier clef à l'adresse attendue pour l'espace chiffré "%s". Veuillez sélectionner le fichier clef manuellement.
unlock.chooseMasterkey.filePickerTitle=Sélectionner le fichier clef
-unlock.chooseMasterkey.filePickerMimeDesc=\ clé principale Cryptomator
+unlock.chooseMasterkey.filePickerMimeDesc=Clé principale Cryptomator
## Success
unlock.success.message=Déverrouillage réussi
unlock.success.description=“%s” déverrouillé ! Le contenu de votre espace chiffré est maintenant accessible par son lecteur virtuel.
@@ -142,7 +142,7 @@ unlock.error.customPath.description.hideawayNotDir=Le fichier temporaire et cach
unlock.error.customPath.description.couldNotBeCleaned=Votre coffre n'a pas pu être monté au point "%s". Veuillez réessayer ou choisissez un autre point.
unlock.error.customPath.description.notEmptyDir=Le chemin de montage personnalisé "%s" n'est pas un dossier vide. Veuillez choisir un dossier vide et réessayez.
unlock.error.customPath.description.generic=Vous avez sélectionné un point de montage personnalisé pour ce coffre, mais son utilisation a échoué avec le message : %2$s
-unlock.error.restartRequired.message=Impossible de déverrouiller le volume
+unlock.error.restartRequired.message=Impossible de déverrouiller le coffre
unlock.error.restartRequired.description=Modifiez le type de volume dans les options du coffre ou redémarrez Cryptomator.
unlock.error.title=Échec du déverrouillage de "%s"
## Hub
@@ -152,7 +152,7 @@ hub.noKeychain.openBtn=Ouvrir les préférences
### Waiting
hub.auth.message=Authentification en cours…
hub.auth.description=Vous devriez automatiquement être redirigé vers la page de connexion.
-hub.auth.loginLink=Vous n'avez pas été redirigé(e) ? Cliquez ici pour l'ouvrir.
+hub.auth.loginLink=Vous n'êtes pas redirigé·e ? Cliquez ici pour l'ouvrir.
### Receive Key
hub.receive.message=Traitement de la réponse…
hub.receive.description=Cryptomator est en train de recevoir et de traiter la réponse de Hub. Veuillez patienter.
@@ -171,12 +171,12 @@ hub.registerSuccess.description=Votre appareil est enregistré avec succès. Vou
hub.registerSuccess.unlockBtn=Déverrouiller
hub.registerSuccess.legacy.description=Pour accéder au coffre, votre appareil doit être autorisé par le propriétaire du coffre.
### Registration Failed
-hub.registerFailed.message=Echec de l'enregistrement de l'appareil
+hub.registerFailed.message=Échec de l'enregistrement de l'appareil
hub.registerFailed.description.generic=Le processus de nommage a retourné une erreur. Pour plus de détails, regardez dans le journal de l'application.
hub.registerFailed.description.deviceAlreadyExists=Cet appareil est déjà enregistré pour un autre utilisateur. Essayez de changer de compte ou utilisez un autre appareil.
### Unauthorized
hub.unauthorized.message=Accès refusé
-hub.unauthorized.description=Votre appareil n'a pas encore été autorisé à accéder à ce coffre. Demandez au propriétaire du coffre de l'autoriser.
+hub.unauthorized.description=Vous n'êtes pas autorisé à ouvrir ce coffre. Contactez le propriétaire du coffre pour en demander l'accès.
### Requires Account Initialization
hub.requireAccountInit.message=Action requise
hub.requireAccountInit.description.0=Pour continuer, veuillez compléter les étapes requises
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Parrain
removeCert.title=Supprimer le certificat
removeCert.message=Supprimer le certificat de soutien ?
removeCert.description=
-removeCert.confirmBtn=Retirer
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Fin de la prise en charge de Dokany
dokanySupportEnd.description=Le type de volume Dokany n'est plus pris en charge par Cryptomator. Vos paramètres sont à présent ajustés pour utiliser le type de volume par défaut. Vous pouvez voir le type par défaut dans les préférences.
dokanySupportEnd.preferencesBtn=Ouvrir les préférences
+#Retry If Readonly
+retryIfReadonly.title=Accès restreint au coffre
+retryIfReadonly.message=Pas d'accès en écriture au dossier du coffre
+retryIfReadonly.description=Cryptomator ne peut pas écrire dans le dossier du coffre. Vous pouvez passer le coffre en mode lecture seule et réessayer. Cette option peut être désactivée dans les options du coffre.
+retryIfReadonly.retry=Changer et réessayer
+
# Share Vault
shareVault.title=Partager le coffre
shareVault.message=Vous aimeriez partager votre coffre avec d'autres personnes ?
diff --git a/src/main/resources/i18n/strings_gl.properties b/src/main/resources/i18n/strings_gl.properties
index 13ea3debe..3cb526fc7 100644
--- a/src/main/resources/i18n/strings_gl.properties
+++ b/src/main/resources/i18n/strings_gl.properties
@@ -13,6 +13,7 @@ generic.button.copied=Copiado!
generic.button.done=Feito
generic.button.next=Seguinte
generic.button.print=Imprimir
+generic.button.remove=Eliminar
# Error
error.message=Produciuse un erro
@@ -81,7 +82,6 @@ lock.forced.retryBtn=Tentar de novo
## Contribution
### Remove License Key Dialog
-removeCert.confirmBtn=Eliminar
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -132,4 +132,6 @@ removeCert.confirmBtn=Eliminar
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_he.properties b/src/main/resources/i18n/strings_he.properties
index 30024035c..66e488750 100644
--- a/src/main/resources/i18n/strings_he.properties
+++ b/src/main/resources/i18n/strings_he.properties
@@ -13,6 +13,7 @@ generic.button.copied=הועתק!
generic.button.done=סיום
generic.button.next=הבא
generic.button.print=הדפס
+generic.button.remove=הסר
# Error
error.message=אירעה שגיאה
@@ -104,7 +105,6 @@ addvaultwizard.success.unlockNow=בטל נעילה כעת
removeVault.title=הסר כספת
removeVault.message=להסיר את ה vault?
removeVault.description=זה יגרום ל-Cryptomator לשכוח מהכספת הזו. תוכל/י להוסיף אותה שוב מאוחר יותר. קבצים מוצפנים לא ימחקו מהכונן שלך.
-removeVault.confirmBtn=הסר כספת
# Change Password
changepassword.title=שנה סיסמה
@@ -159,7 +159,6 @@ hub.registerSuccess.unlockBtn=בטל נעילה
### Registration Failed
### Unauthorized
hub.unauthorized.message=הגישה נדחתה
-hub.unauthorized.description=המכשיר שלך טרם אושר לגשת לכספת הזאת. יש לבקש אישור גישה מבעל הכספת.
### Requires Account Initialization
### License Exceeded
hub.invalidLicense.message=רישיון האב לא תקף
@@ -305,7 +304,6 @@ preferences.contribute.getCertificate=עדיין אין לכם אחד? לימד
preferences.contribute.promptText=הדבק את קוד תעודת התומך כאן
### Remove License Key Dialog
-removeCert.confirmBtn=הסר
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -493,4 +491,6 @@ updateReminder.notNow=לא עכשיו
#Dokany Support End
dokanySupportEnd.preferencesBtn=פתח העדפות
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_hi.properties b/src/main/resources/i18n/strings_hi.properties
index 75bf20107..1a90e5572 100644
--- a/src/main/resources/i18n/strings_hi.properties
+++ b/src/main/resources/i18n/strings_hi.properties
@@ -13,6 +13,7 @@ generic.button.copied=कॉपी हुआ!
generic.button.done=हो गया
generic.button.next=अगला
generic.button.print=प्रिंट करें
+generic.button.remove=हटाएँ
# Error
error.message=एक त्रुटि पाई गई
@@ -100,7 +101,6 @@ addvaultwizard.success.unlockNow=अब अनलॉक करें
removeVault.title=वॉल्ट हटाए
removeVault.message=वॉल्ट हटाए?
removeVault.description=यह करने से सिर्फ क्रिप्टोमेटर इस वॉल्ट के बारे में भूल जाएगा। आप इस वॉल्ट को वापस ऐड कर पाएंगे। कोई भी एन्क्रिप्टेड फाइल आपकी हार्ड डिस्क से नहीं डिलीट होगी।
-removeVault.confirmBtn=वॉल्ट हटाए
# Change Password
changepassword.title=पासवर्ड बदलें
@@ -221,7 +221,6 @@ preferences.updates.updateAvailable=संस्करण %s की तरफ
preferences.contribute=हमें सपोर्ट करें
### Remove License Key Dialog
-removeCert.confirmBtn=हटाएँ
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -315,4 +314,6 @@ quit.forced.message=कुछ वॉल्ट्स लॉक नहीं ह
#Dokany Support End
dokanySupportEnd.preferencesBtn=प्राथमिकताएँ खोलें
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_hr.properties b/src/main/resources/i18n/strings_hr.properties
index 2ef01dcd5..108f8ff7a 100644
--- a/src/main/resources/i18n/strings_hr.properties
+++ b/src/main/resources/i18n/strings_hr.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopirano!
generic.button.done=Gotovo
generic.button.next=Sljedeći
generic.button.print=Ispiši
+generic.button.remove=Ukloni
# Error
error.message=Greška: %s
@@ -85,7 +86,6 @@ addvaultwizard.success.unlockNow=Otključaj sada
# Remove Vault
removeVault.title=Ukloni trezor
removeVault.description=Ovo će jedino učiniti da Cryptomator zaboravi trezor. Možete ga kasnije ponovno dodati. Niti jedna šifrirana datoteka neće biti uklonjena s Vašeg tvrdog diska.
-removeVault.confirmBtn=Ukloni trezor
# Change Password
changepassword.title=Promijeni lozinku
@@ -232,7 +232,6 @@ preferences.contribute.getCertificate=Još ga nemate? Naučite kako ga dobiti.
preferences.contribute.promptText=Zalijepi certifikat podržavatelja ovdje
### Remove License Key Dialog
-removeCert.confirmBtn=Ukloni
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -382,4 +381,6 @@ quit.lockAndQuitBtn=Zaključaj i napusti
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_hu.properties b/src/main/resources/i18n/strings_hu.properties
index 6fbe147e3..f67d6f53e 100644
--- a/src/main/resources/i18n/strings_hu.properties
+++ b/src/main/resources/i18n/strings_hu.properties
@@ -13,6 +13,7 @@ generic.button.copied=Másolva!
generic.button.done=Kész
generic.button.next=Következő
generic.button.print=Nyomtatás
+generic.button.remove=Eltávolítás
# Error
error.message=Hiba: %s
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Azonnali feloldás
removeVault.title=Széf eltávolitása
removeVault.message=Vault eltávolitása?
removeVault.description=Ez kizárolag a Cryptomator-ból távolitja el ezt a széfet. Később hozzáadhatja újra. A titkosított fájlokat nem törli a merevlemezről.
-removeVault.confirmBtn=Széf eltávolitása
# Change Password
changepassword.title=Jelszó megváltoztatása
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=Hiba történt a regisztrációs folyamat
hub.registerFailed.description.deviceAlreadyExists=Ez az eszköz már egy másik felhasználóhoz van regisztrálva. Próbáljon meg felhasználói fiókot váltani, vagy használjon egy másik eszközt.
### Unauthorized
hub.unauthorized.message=Hozzáférés megtagadva
-hub.unauthorized.description=Eszköze még nem kapott engedélyt ehhez a széfhez. Kérje a széf tulajdonosát, hogy engedélyezze a hozzáférést.
### Requires Account Initialization
hub.requireAccountInit.message=Beavatkozás szükséges
hub.requireAccountInit.description.0=A folytatáshoz kérlek töltsd ki a szükséges lépéseket a te
@@ -343,7 +342,6 @@ preferences.contribute.sponsor=Szponzor
removeCert.title=Tanúsítvány eltávolítása
removeCert.message=Eltávolítja a támogatói tanúsítványt?
removeCert.description=A Cryptomator alapvető funkcióit ez nem érinti. Sem a széfekhez való hozzáférés nem korlátozott, sem a biztonsági szint nem csökken.
-removeCert.confirmBtn=Eltávolítás
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +551,8 @@ dokanySupportEnd.message=Vége a Dokany támogatásának
dokanySupportEnd.description=A Cryptomator nem támogatja tovább a Dokany kötettípust. A beállítások az alapértelmezett kötettípus használatára lettek állítva. Az alapértelmezett típust a beállítások közt tekintheted meg.
dokanySupportEnd.preferencesBtn=Beállítások megnyitása
+#Retry If Readonly
+
# Share Vault
shareVault.title=Széf megosztása
shareVault.message=Szeretné megosztani a széfét másokkal?
diff --git a/src/main/resources/i18n/strings_id.properties b/src/main/resources/i18n/strings_id.properties
index 16b7c6246..86f70acfb 100644
--- a/src/main/resources/i18n/strings_id.properties
+++ b/src/main/resources/i18n/strings_id.properties
@@ -13,6 +13,7 @@ generic.button.copied=Tersalin!
generic.button.done=Selesai
generic.button.next=Lanjut
generic.button.print=Cetak
+generic.button.remove=Hapus
# Error
error.message=Terjadi kesalahan %s
@@ -27,7 +28,7 @@ error.dismiss=Tutup
error.lookUpSolution=Cari tahu solusinya
# Defaults
-defaults.vault.vaultName=Vault
+defaults.vault.vaultName=Brangkas
# Tray Menu
traymenu.showMainWindow=Tampilkan
@@ -41,7 +42,7 @@ traymenu.vault.reveal=Perlihatkan
# Add Vault Wizard
addvaultwizard.title=Tambah Brankas
## New
-addvaultwizard.new.title=Tambah Vault baru
+addvaultwizard.new.title=Tambah Brankas Baru
### Name
addvaultwizard.new.nameInstruction=Buat sebuah nama untuk brankas
addvaultwizard.new.namePrompt=Nama Brankas
@@ -57,8 +58,8 @@ addvaultwizard.new.fileAlreadyExists=Sudah ada file atau direktori dengan nama v
addvaultwizard.new.locationDoesNotExist=Direktori pada path yang dipilih tidak tersedia atau tidak dapat diakses
addvaultwizard.new.locationIsNotWritable=Anda tidak memiliki hak akses untuk menulis pada path yang dipilih
addvaultwizard.new.locationIsOk=Lokasi yang sesuai dengan vault Anda
-addvaultwizard.new.invalidName=Nama Vault tidak valid
-addvaultwizard.new.validName=Nama vault yang valid
+addvaultwizard.new.invalidName=Nama brangkas tidak valid
+addvaultwizard.new.validName=Nama brangkas yang valid
addvaultwizard.new.validCharacters.message=Nama vault mungkin berisi karakter berikut:
addvaultwizard.new.validCharacters.chars=Karakter kata (mis. a, ж or 수)
addvaultwizard.new.validCharacters.numbers=Angka
@@ -70,7 +71,7 @@ addvaultwizard.new.expertSettings.shorteningThreshold.tooltip=Buka dokumentasi u
addvaultwizard.new.expertSettings.shorteningThreshold.title=Panjang maksimum nama file terenkripsi
addvaultwizard.new.expertSettings.shorteningThreshold.valid=Valid
### Password
-addvaultwizard.new.createVaultBtn=Buat Vault
+addvaultwizard.new.createVaultBtn=Buat Brangkas
addvaultwizard.new.generateRecoveryKeyChoice=Anda tidak dapat mengakses data tanpa kata sandi yang Anda miliki. Apa Anda ingin sebuah kunci pemulihan untuk berjaga-jaga jika seandainya Anda kehilangan kata sandi?
addvaultwizard.new.generateRecoveryKeyChoice.yes=Ya tolong, Lebih baik aman daripada menyesal
addvaultwizard.new.generateRecoveryKeyChoice.no=Tidak terima kasih, Saya tidak akan kehilangan kata sandi saya
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Buka Kunci Sekarang
removeVault.title=Hapus Vault
removeVault.message=Hapus vault?
removeVault.description=Tindakan ini hanya akan membuat Cryptomator melupakan vault ini. Anda dapat menambahkan vault ini lagi nanti. File yang telah dienkripsi tidak akan dihapus dari hard drive Anda.
-removeVault.confirmBtn=Hapus Vault
# Change Password
changepassword.title=Ubah Kata Sandi
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=Kesalahan terjadi dalam proses pendaftara
hub.registerFailed.description.deviceAlreadyExists=Perangkat ini sudah terdaftar untuk pengguna lain. Cobalah menggunakan akun pengguna atau perangkat yang berbeda.
### Unauthorized
hub.unauthorized.message=Akses ditolak
-hub.unauthorized.description=Perangkat Anda belum diizinkan mengakses vault ini. Mintalah pemilik vault untuk mengizinkannya.
### Requires Account Initialization
hub.requireAccountInit.message=Tindakan diperlukan
hub.requireAccountInit.description.0=Untuk melanjutkan, silakan lengkapi langkah-langkah yang diperlukan
@@ -287,6 +286,7 @@ preferences.general.debugLogging=Aktifkan pencatatan debug
preferences.general.debugDirectory=Perlihatkan file log
preferences.general.autoStart=Jalankan Cryptomator saat sistem dimulai
preferences.general.keychainBackend=Simpan kata sandi dengan
+preferences.general.quickAccessService=Tambahkan brankas terbuka ke area akses cepat
## Interface
preferences.interface=Tampilan
preferences.interface.theme=Tampilan & Suasana
@@ -300,6 +300,7 @@ preferences.interface.interfaceOrientation=Orientasi Antarmuka
preferences.interface.interfaceOrientation.ltr=Kiri ke Kanan
preferences.interface.interfaceOrientation.rtl=Kanan ke Kiri
preferences.interface.showTrayIcon=Tampilkan ikon tray (aplikasi perlu dimuat ulang)
+preferences.interface.compactMode=Aktifkan daftar brankas kompak
## Volume
preferences.volume=Drive Virtual
preferences.volume.type=Jenis Default Volume
@@ -319,6 +320,13 @@ preferences.updates.currentVersion=Versi Saat Ini: %s
preferences.updates.autoUpdateCheck=Otomatis periksa update
preferences.updates.checkNowBtn=Periksa Sekarang
preferences.updates.updateAvailable=Pembaharuan ke versi %s tersedia.
+preferences.updates.lastUpdateCheck=Terakhir Diperiksa: %s
+preferences.updates.lastUpdateCheck.never=jangan pernah
+preferences.updates.lastUpdateCheck.recently=baru-baru ini
+preferences.updates.lastUpdateCheck.daysAgo=%s hari yang lalu
+preferences.updates.lastUpdateCheck.hoursAgo=%s jam yang lalu
+preferences.updates.checkFailed=Gagal mencari pembaruan. Harap periksa koneksi internet Anda atau coba lagi nanti.
+preferences.updates.upToDate=Cryptomator versi terkini.
## Contribution
preferences.contribute=Dukung Kami
@@ -326,9 +334,14 @@ preferences.contribute.registeredFor=Sertifikat supporter terdaftar atas nama %s
preferences.contribute.noCertificate=Dukung Cryptomator dan terima sebuah sertifikat supporter. Sertifikat ini layaknya kunci lisensi, tetapi hanya untuk orang-orang hebat yang menggunakan aplikasi versi gratis. ;-)
preferences.contribute.getCertificate=Belum punya? Pelajari bagaimana Anda bisa mendapatkannya.
preferences.contribute.promptText=Tempel kode sertifikat supporter di sini
+preferences.contribute.thankYou=Terima kasih telah mendukung pengembangan open-source Cryptomator!
+preferences.contribute.donate=Donasi
+preferences.contribute.sponsor=Sponsor
### Remove License Key Dialog
-removeCert.confirmBtn=Hapus
+removeCert.title=Hapus Sertifikat
+removeCert.message=Hapus sertifikat dukungan?
+removeCert.description=Fitur inti Cryptomator tidak terpengaruh oleh hal ini. Akses ke brankas Anda tidak dibatasi dan tingkat keamanannya tidak diturunkan.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -378,7 +391,11 @@ main.vaultlist.contextMenu.unlock=Buka Kunci…
main.vaultlist.contextMenu.unlockNow=Buka Kunci Sekarang
main.vaultlist.contextMenu.vaultoptions=Tampilkan Opsi Vault
main.vaultlist.contextMenu.reveal=Buka Drive
+main.vaultlist.addVaultBtn.menuItemNew=Buat Vault Baru...
+main.vaultlist.addVaultBtn.menuItemExisting=Buka Vault yang Tersedia...
##Notificaition
+main.notification.updateAvailable=Pembaruan tersedia.
+main.notification.support=Dukung Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Terima kasih telah memilih Cryptomator untuk melindungi file Anda. Jika Anda memerlukan bantuan, lihat panduan awal kami:
@@ -529,8 +546,13 @@ updateReminder.yesOnce=Ya, Sekali
updateReminder.yesAutomatically=Ya, Secara Otomatis
#Dokany Support End
+dokanySupportEnd.title=Pemberitahuan penghentian
+dokanySupportEnd.message=Dukungan untuk Dokany telah berakhir
+dokanySupportEnd.description=Volume berjenis Dokany sudah tidak didukung oleh Cryptomator. Konfigurasi Anda telah disesuai kan dengan tipe volume yang saat ini. Anda dapat melihat tipe baku dipreferensi.
dokanySupportEnd.preferencesBtn=Buka Preferensi
+#Retry If Readonly
+
# Share Vault
shareVault.title=Bagikan Vault
shareVault.message=Apakah Anda ingin berbagi vault dengan orang lain?
diff --git a/src/main/resources/i18n/strings_it.properties b/src/main/resources/i18n/strings_it.properties
index 4c3b201b4..f04c40d35 100644
--- a/src/main/resources/i18n/strings_it.properties
+++ b/src/main/resources/i18n/strings_it.properties
@@ -13,6 +13,7 @@ generic.button.copied=Copiato!
generic.button.done=Fatto
generic.button.next=Avanti
generic.button.print=Stampa
+generic.button.remove=Rimuovi
# Error
error.message=Si è verificato un errore
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Sblocca Ora
removeVault.title=Rimuovi Cassaforte
removeVault.message=Rimuovere cassaforte?
removeVault.description=Questo farà solo dimenticare questa cassaforte a Cryptomator. Puoi aggiungerla nuovamente in seguito. Nessun file crittografato sarà eliminato dal tuo disco rigido.
-removeVault.confirmBtn=Rimuovi Cassaforte
# Change Password
changepassword.title=Modifica la Password
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Si è verificato un errore nel processo d
hub.registerFailed.description.deviceAlreadyExists=Questo dispositivo è già registrato per un utente diverso. Prova a cambiare l'account utente o usa un altro dispositivo.
### Unauthorized
hub.unauthorized.message=Accesso negato
-hub.unauthorized.description=Il tuo dispositivo non è ancora stato autorizzato ad accedere a questa cassaforte. Chiedi al proprietario della cassaforte di autorizzarlo.
+hub.unauthorized.description=Non sei autorizzato ad aprire questa cassaforte. Chiedi l'accesso al proprietario.
### Requires Account Initialization
hub.requireAccountInit.message=Azione richiesta
hub.requireAccountInit.description.0=Per procedere, completa i passaggi richiesti nel tuo
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Sponsor
removeCert.title=Rimuovi Certificato
removeCert.message=Rimuovere il certificato supporter?
removeCert.description=Questo non incide sulle funzionalità principali di Cryptomator. Non ti viene negato l'accesso alle tue casseforti e non viene abbassato il livello di sicurezza.
-removeCert.confirmBtn=Rimuovi
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Supporto terminato per Dokany
dokanySupportEnd.description=Il tipo di volume Dokany non è più supportato da Cryptomator. Le impostazioni sono state aggiornate per utilizzare il tipo di volume ora predefinito. È possibile visualizzare il tipo predefinito nelle preferenze.
dokanySupportEnd.preferencesBtn=Apri Preferenze
+#Retry If Readonly
+retryIfReadonly.title=Accesso Limitato Cassaforte
+retryIfReadonly.message=Accesso negato in scrittura alla cartella della cassaforte
+retryIfReadonly.description=Cryptomator non può scrivere nella cartella della cassaforte. Puoi cambiare l'impostazione "sola lettura" della cassaforte e riprovare. Questa opzione può essere impostata nelle opzioni della cassaforte.
+retryIfReadonly.retry=Modifica e riprova
+
# Share Vault
shareVault.title=Condividi cassaforte
shareVault.message=Vuoi condividere la tua cassaforte con altri?
diff --git a/src/main/resources/i18n/strings_ja.properties b/src/main/resources/i18n/strings_ja.properties
index e6559172d..1122eeb8c 100644
--- a/src/main/resources/i18n/strings_ja.properties
+++ b/src/main/resources/i18n/strings_ja.properties
@@ -13,6 +13,7 @@ generic.button.copied=コピー完了!
generic.button.done=完了
generic.button.next=次へ
generic.button.print=印刷
+generic.button.remove=削除
# Error
error.message=エラー %s
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=今すぐ解錠
removeVault.title=金庫を削除
removeVault.message=金庫を削除しますか?
removeVault.description=この操作で Cryptomator がこの金庫を認識しなくなります。あとで再度追加することが可能です。暗号化されたファイルがドライブから削除されることはありません。
-removeVault.confirmBtn=金庫を削除
# Change Password
changepassword.title=パスワードの変更
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=登録中にエラーが発生しまし
hub.registerFailed.description.deviceAlreadyExists=このデバイスは既に別のユーザーに登録されています。ユーザーアカウントを変更するか、別のデバイスを使用してください。
### Unauthorized
hub.unauthorized.message=アクセスが拒否されました
-hub.unauthorized.description=お使いのデバイスはまだこの金庫にアクセスする権限がありません。金庫のオーナーに権限を与えてもらってください。
### Requires Account Initialization
hub.requireAccountInit.message=アクションが必要です
hub.requireAccountInit.description.0=続行するには以下のサイトで必要な手順を完了してください
@@ -336,7 +335,6 @@ preferences.contribute.getCertificate=まだ証明書を手に入れていませ
preferences.contribute.promptText=サポーター証明書をここに張り付けてください
### Remove License Key Dialog
-removeCert.confirmBtn=削除
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -542,6 +540,8 @@ dokanySupportEnd.message=Dokany のサポート終了
dokanySupportEnd.description=ボリュームタイプ
dokanySupportEnd.preferencesBtn=環境設定を開く
+#Retry If Readonly
+
# Share Vault
shareVault.title=保管庫を共有する
shareVault.message=保管庫を他の人と共有しますか?
diff --git a/src/main/resources/i18n/strings_ko.properties b/src/main/resources/i18n/strings_ko.properties
index ba11dab0c..02fa06758 100644
--- a/src/main/resources/i18n/strings_ko.properties
+++ b/src/main/resources/i18n/strings_ko.properties
@@ -13,6 +13,7 @@ generic.button.copied=복사됨!
generic.button.done=완료
generic.button.next=다음
generic.button.print=인쇄
+generic.button.remove=제거
# Error
error.message=오류가 발생했습니다
@@ -20,7 +21,11 @@ error.description=예상치 못한 에러가 발생했습니다. 온라인에
error.hyperlink.lookup=에러 검색하기
error.hyperlink.report=에러 보고하기
error.technicalDetails=상세 정보:
+error.existingSolutionDescription=Cryptomator에 알수 없는 문제가 발생했습니다. 하지만 이 오류에 대한 기존 해결책이 있습니다. 다음 링크를 살펴보시기 바랍니다.
+error.hyperlink.solution=솔루션 찾기
+error.lookupPermissionMessage=Cryptomator는 온라인에서 이 문제에 대한 해결책을 찾아볼 수 있습니다. 그러면 귀하의 IP 주소가 문제 데이터베이스로 전송됩니다.
error.dismiss=무시
+error.lookUpSolution=솔루션 찾기
# Defaults
defaults.vault.vaultName=Vault
@@ -39,10 +44,11 @@ addvaultwizard.title=Vault 추가
## New
addvaultwizard.new.title=새로운 금고 추가
### Name
-addvaultwizard.new.nameInstruction=새 Vault의 이름을 입력하십시요
+addvaultwizard.new.nameInstruction=새 Vault의 이름을 입력하십시오
addvaultwizard.new.namePrompt=Vault 이름
### Location
-addvaultwizard.new.locationInstruction=Cryptomator Vault의 암호화 파일을 어디에 저장하시겠습니까?
+addvaultwizard.new.locationInstruction=Cryptomator Vault의 암호화된 파일을 어디에 저장하시겠습니까?
+addvaultwizard.new.locationLoading=기본 클라우드 저장소 디렉터리에 대한 로컬 파일 시스템을 확인하는 중…
addvaultwizard.new.locationLabel=저장 위치
addvaultwizard.new.locationPrompt=…
addvaultwizard.new.directoryPickerLabel=사용자 지정 위치
@@ -100,7 +106,6 @@ addvaultwizard.success.unlockNow=지금 잠금해제
removeVault.title=Vault 제거
removeVault.message=Vault를 삭제하시겠습니까?
removeVault.description=이 행위는 단지 Cryptomator에서 이 Vault를 잊게합니다. 나중에 다시 추가 할 수 있습니다. 암호화된 파일은 하드디스크에서 삭제되지 않을 것입니다.
-removeVault.confirmBtn=Vault 제거
# Change Password
changepassword.title=비밀번호 변경
@@ -125,33 +130,58 @@ unlock.chooseMasterkey.filePickerTitle=마스터키 파일 선택
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator 마스터키
## Success
unlock.success.message=잠금 해제 성공
-unlock.success.description="%s"이(가) 성공적으로 잠금해제되었습니다. 이제 이 Vault를 가상드라이브로 접근할 수 있습니다.
+unlock.success.description="%s"이(가) 성공적으로 잠금 해제되었습니다. 이제 이 Vault를 마운트 지점으로 접근할 수 있습니다.
unlock.success.rememberChoice=선택 기억함, 다시 묻지 않음
unlock.success.revealBtn=드라이브 표시
## Failure
+unlock.error.customPath.message=Vault을 사용자 정의 경로에 마운트할 수 없습니다.
+unlock.error.customPath.description.notSupported=사용자 지정 경로를 계속 사용하려면 기본 설정으로 이동하여 이를 지원하는 볼륨 유형을 선택하세요. 그렇지 않으면 볼트 옵션으로 이동하여 지원되는 마운트 지점을 선택하십시오.
+unlock.error.customPath.description.notExists=사용자 정의 마운트 경로가 존재하지 않습니다. 로컬 파일 시스템에서 생성하거나 볼트 옵션에서 변경하세요.
+unlock.error.customPath.description.inUse=드라이브 문자 또는 사용자 정의 마운트 경로 "%s"가 이미 사용 중입니다.
+unlock.error.customPath.description.hideawayNotDir=잠금 해제에 사용된 임시 숨김 파일 "%3$s"을 제거할 수 없습니다. 파일을 확인한 후 수동으로 삭제해 주세요.
+unlock.error.customPath.description.couldNotBeCleaned=Vault를 "%s" 경로에 마운트할 수 없습니다. 다시 시도하거나 다른 경로를 선택하세요.
+unlock.error.customPath.description.notEmptyDir=사용자 정의 마운트 경로 "%s"은 빈 폴더가 아닙니다. 빈 폴더를 선택하고 다시 시도하세요.
+unlock.error.customPath.description.generic=이 볼트에 대한 사용자 정의 마운트 경로를 선택했지만 다음 메시지와 함께 해당 경로를 사용하지 못했습니다: %2$s
+unlock.error.restartRequired.message=Vault을 잠금 해제할 수 없습니다.
+unlock.error.restartRequired.description=볼트 옵션에서 볼륨 유형을 변경하거나 Cryptomator를 다시 시작하세요.
+unlock.error.title="%s" 잠금 해제 실패
## Hub
+hub.noKeychain.message=장치 키에 액세스할 수 없습니다
+hub.noKeychain.description=허브 저장소를 잠금 해제하려면 키체인을 사용하여 보호되는 장치 키가 필요합니다. 계속하려면 "%s"을 활성화하고 기본 설정에서 키체인을 선택하세요.
hub.noKeychain.openBtn=설정 열기
### Waiting
hub.auth.message=인증 대기중…
+hub.auth.description=자동으로 로그인 페이지로 리다이렉트 될 것입니다.
+hub.auth.loginLink=수동으로 열려면 클릭하십시오.
### Receive Key
+hub.receive.message=응답 처리중…
+hub.receive.description=Hub로부터 응답을 처리하고 있습니다. 잠시만 기다려 주십시오.
### Register Device
hub.register.message=새 기기
+hub.register.description=이 기기로부터 첫번째 Hub 접근입니다. Account Key로 등록하십시오.
hub.register.nameLabel=기기 이름
hub.register.invalidAccountKeyLabel=유효하지 않은 계정 키
hub.register.registerBtn=등록
### Register Device Legacy
hub.register.legacy.occupiedMsg=이미 사용 중인 이름
+hub.register.legacy.description=이 기기로부터 첫번째 Hub 접근입니다. 등록하십시오.
### Registration Success
hub.registerSuccess.message=기기 등록됨
-hub.registerSuccess.unlockBtn=잠금해제
+hub.registerSuccess.description=등록에 성공하였습니다. Vault를 잠금 해제할 수 있습니다.
+hub.registerSuccess.unlockBtn=잠금 해제
+hub.registerSuccess.legacy.description=Vault에 접근하기 위해서는 이 기기를 Vault 소유주가 추가적으로 허가해야 합니다.
### Registration Failed
hub.registerFailed.message=기기 등록 실패
hub.registerFailed.description.generic=등록 중에 에러가 발생했습니다. 앱 로그에서 자세한 정보를 확인할 수 있습니다.
+hub.registerFailed.description.deviceAlreadyExists=이 기기는 이미 다른 사용자에 등록되어 있습니다. 다른 사용자 계정이나 다른 기기를 사용해보세요.
### Unauthorized
-hub.unauthorized.message=액세스 거부
-hub.unauthorized.description=귀하의 기기는 아직 이 저장소에 액세스할 수 있는 권한이 없습니다. Vault 소유자에게 승인을 요청하세요.
+hub.unauthorized.message=액세스 거부됨
+hub.unauthorized.description=해당 Vault에 접근하도록 허가되지 않았습니다. Vault의 소유자에게 권한을 요청하세요.
### Requires Account Initialization
hub.requireAccountInit.message=조치가 필요함
+hub.requireAccountInit.description.0=진행하려면 필요한 조치를 완료하십시오:
+hub.requireAccountInit.description.1=Hub 사용자 프로필
+hub.requireAccountInit.description.2=.
### License Exceeded
hub.invalidLicense.message=Hub 라이선스가 잘못되었습니다.
hub.invalidLicense.description=Cryptomator Hub 인스턴스에 잘못된 라이선스가 있습니다. 라이센스를 업그레이드하거나 갱신하려면 허브 관리자에게 알리십시오.
@@ -200,9 +230,10 @@ migration.impossible.moreInfo=Vault를 이전 버전으로 계속 열수 있습
health.title="%s"의 상태 검사
health.intro.header=상태 검사
health.intro.text=상태 검사는 Vault의 내부 구조의 문제점을 점검하고 해결할 수 있는 기능입니다. 다음 사항을 유의하시기 바랍니다:
+health.intro.remarkSync=모든 장치가 완전히 동기화됐는지 확인하십시오. 대부분의 문제를 해결합니다.
health.intro.remarkFix=모든 문제를 해결할 수 있는 것은 아닙니다.
health.intro.remarkBackup=데이터가 손상된 경우 백업만이 유일한 해결책입니다.
-health.intro.affirmation=나는 위 정보를 읽고 정말 이해했습니다.
+health.intro.affirmation=나는 위 정보를 읽었으며, 이해했습니다.
## Start Failure
health.fail.header=Vault 설정을 불러오는 중 에러 발생
health.fail.ioError=설정 파일에 접근하는 중 에러가 발생했습니다.
@@ -223,13 +254,17 @@ health.check.detail.checkFinishedAndFound=검사가 완료되었습니다. 검
health.check.detail.checkFailed=오류로 인해 검사가 종료되었습니다.
health.check.detail.checkCancelled=검사가 취소되었습니다
health.check.detail.listFilters.label=필터
+health.check.detail.fixAllSpecificBtn=모든 문제 형식 고치기
health.check.exportBtn=보고서 내보내기
## Result view
health.result.severityFilter.all=모든 상태 표시
health.result.severityFilter.good=양호
+health.result.severityFilter.info=정보
health.result.severityFilter.warn=경고
health.result.severityFilter.crit=심각
health.result.severityTip.good=상태: 양호\n정상적인 vault 구조를 가지고 있습니다.
+health.result.severityTip.info=상태: 정보\nVault 구조 온전함, 문제 해결 권장됨.
+health.result.severityTip.warn=상태: 경고\nVault 구조 손상됨, 문제 해결 요구됨.
health.result.severityTip.crit=상태: 심각\nVault 구조가 손상되었습니다. 데이터 손실이 발생했습니다.
health.result.fixStateFilter.all=모든 문제 해결 상태
health.result.fixStateFilter.fixable=문제 해결 가능
@@ -247,10 +282,12 @@ preferences.title=환경설정
## General
preferences.general=일반
preferences.general.startHidden=Cryptomator를 시작할 때 창 숨김
-preferences.general.debugLogging=디버그 로그기록을 사용하도록 설정
-preferences.general.debugDirectory=Log 파일 표시
+preferences.general.autoCloseVaults=애플리케이션을 닫을 때 자동으로 열린 Vault를 잠그기.
+preferences.general.debugLogging=디버그 로깅 활성화
+preferences.general.debugDirectory=로그 파일 표시
preferences.general.autoStart=시스템 시작 시 Cryptomator 실행
preferences.general.keychainBackend=다음 경로에 비밀번호 저장
+preferences.general.quickAccessService=열린 Vault를 빠른 접근 위치에 추가하기
## Interface
preferences.interface=인터페이스
preferences.interface.theme=테마설정
@@ -264,11 +301,16 @@ preferences.interface.interfaceOrientation=인터페이스 방향
preferences.interface.interfaceOrientation.ltr=왼쪽에서 오른쪽으로
preferences.interface.interfaceOrientation.rtl=오른쪽에서 왼쪽으로
preferences.interface.showTrayIcon=트레이 아이콘 보기 (재시작 필요)
+preferences.interface.compactMode=간소화 Vault 리스트 활성화
## Volume
preferences.volume=가상 드라이브
+preferences.volume.type=기본 볼륨 타입
preferences.volume.type.automatic=자동
+preferences.volume.docsTooltip=다른 볼륨 타입에 대해서는 문서를 참조하십시오.
+preferences.volume.fuseRestartRequired=변경 사항을 적용하기 위해, Cryptomator의 재시작이 필요합니다.
preferences.volume.tcp.port=기본 TCP 포트
preferences.volume.supportedFeatures=현재 선택한 볼륨 타입은 다음과 같은 기능들을 지원합니다:
+preferences.volume.feature.mountAuto=마운트 지점 자동 지정
preferences.volume.feature.mountToDir=마운트할 폴더 지정
preferences.volume.feature.mountToDriveLetter=마운트할 드라이브 문자
preferences.volume.feature.mountFlags=사용자 정의 마운트 설정
@@ -293,9 +335,14 @@ preferences.contribute.registeredFor=%s (으)로 후원자 인증 등록됨
preferences.contribute.noCertificate=Cryptomator를 후원하시고 후원자 인증을 받으십시요. 라이선스 키와 비슷하지만 무료 소프트웨어를 사용하는 멋진 사람들을 위한 것입니다. ;-)
preferences.contribute.getCertificate=아직 후원자 인증이 없으신가요? 어떻게 얻는지 배울 수 있습니다.
preferences.contribute.promptText=후원자 인증코드를 여기에 붙여넣기
+preferences.contribute.thankYou=Cryptomator의 오픈 소스 개발을 지원해 주셔서 감사합니다!
+preferences.contribute.donate=후원하기
+preferences.contribute.sponsor=스폰서
### Remove License Key Dialog
-removeCert.confirmBtn=제거
+removeCert.title=인증서 제거
+removeCert.message=서포터 인증서를 제거하시겠습니까?
+removeCert.description=Cryptomator의 핵심 기능은 영향을 받지 않습니다. Vault에 대한 접근이 제한되거나 보안이 약화되지 않습니다.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -333,30 +380,35 @@ stats.write.accessCount=총 쓰기 횟수: %d
## Accesses
stats.access.current=접근: %d
+stats.access.total=총 접근: %d
# Main Window
## Vault List
-main.vaultlist.emptyList.onboardingInstruction=Vault를 추가하기 위해 이곳을 클릭합니다.
+main.vaultlist.emptyList.onboardingInstruction=여기를 클릭하여 Vault를 추가하세요
main.vaultlist.contextMenu.remove=제거...
main.vaultlist.contextMenu.lock=잠금
-main.vaultlist.contextMenu.unlock=잠금해제...
-main.vaultlist.contextMenu.unlockNow=지금 잠금해제
+main.vaultlist.contextMenu.unlock=잠금 해제...
+main.vaultlist.contextMenu.unlockNow=지금 잠금 해제
main.vaultlist.contextMenu.vaultoptions=Vault 옵션 보기
main.vaultlist.contextMenu.reveal=드라이브 표시
+main.vaultlist.addVaultBtn.menuItemNew=새 Vault 생성...
+main.vaultlist.addVaultBtn.menuItemExisting=기존 Vault 열기...
##Notificaition
+main.notification.updateAvailable=업데이트가 있습니다.
+main.notification.support=Cryptomator 지원하기.
## Vault Detail
### Welcome
-main.vaultDetail.welcomeOnboarding=파일을 보호하기 위해 Cryptomator를 선택해주셔서 감사합니다. 만약 다른 도움이 필요하시면, 시작안내서를 참조하시기 바랍니다.
+main.vaultDetail.welcomeOnboarding=파일을 보호하기 위해 Cryptomator를 선택해주셔서 감사합니다. 만약 다른 도움이 필요하시면, 시작 안내서를 참조하시기 바랍니다.
### Locked
main.vaultDetail.lockedStatus=잠김
-main.vaultDetail.unlockBtn=잠금해제...
-main.vaultDetail.unlockNowBtn=지금 잠금해제
+main.vaultDetail.unlockBtn=잠금 해제...
+main.vaultDetail.unlockNowBtn=지금 잠금 해제
main.vaultDetail.optionsBtn=Vault 옵션
main.vaultDetail.passwordSavedInKeychain=비밀번호 저장됨
main.vaultDetail.share=공유하기
### Unlocked
-main.vaultDetail.unlockedStatus=잠금해제됨
+main.vaultDetail.unlockedStatus=잠금 해제됨
main.vaultDetail.accessLocation=이 Vault의 내용은 다음의 경로에서 접근할 수 있습니다:
main.vaultDetail.revealBtn=드라이브 표시
main.vaultDetail.copyUri=URI 복사
@@ -368,6 +420,9 @@ main.vaultDetail.throughput.kbps=%.1f KiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Vault 통계
main.vaultDetail.locateEncryptedFileBtn=암호화된 파일 위치
+main.vaultDetail.locateEncryptedFileBtn.tooltip=암호화된 파일을 보기 위해 Vault에서 파일을 선택하십시오.
+main.vaultDetail.encryptedPathsCopied=클립보드에 복사됨!
+main.vaultDetail.filePickerTitle=Vault 내부에서 파일 선택
### Missing
main.vaultDetail.missing.info=Cryptomator가 이 경로에 있는 Vault를 찾지 못했습니다.
main.vaultDetail.missing.recheck=다시 시도
@@ -375,20 +430,21 @@ main.vaultDetail.missing.remove=Vault 목록에서 제거...
main.vaultDetail.missing.changeLocation=Vault 위치 변경
### Needs Migration
main.vaultDetail.migrateButton=Vault 업그레이드
-main.vaultDetail.migratePrompt=Vault에 접근하기 전, 새로운 포멧으로 업그레이드가 필요합니다.
+main.vaultDetail.migratePrompt=Vault에 접근하기 전, 새로운 포맷으로 업그레이드가 필요합니다.
### Error
+main.vaultDetail.error.info=디스크에서 Vault를 로드 중 에러 발생
main.vaultDetail.error.reload=새로고침
-main.vaultDetail.error.windowTitle=Vault 로딩중 에러 발생
+main.vaultDetail.error.windowTitle=Vault 로드중 에러 발생
# Wrong File Alert
wrongFileAlert.title=파일 암호화 방법
wrongFileAlert.message=이 파일들을 암호화하려고 하십니까?
wrongFileAlert.description=이 목적을 위해, Cryptomator는 파일 관리자에 볼륨을 제공합니다.
-wrongFileAlert.instruction.0=파일을 암호화 하려면, 다음의 3단계를 따르십시요:
-wrongFileAlert.instruction.1=1. Vault의 잠금해제
-wrongFileAlert.instruction.2=2. 파일 관리자에서 열람된 볼륨의 "표시" 버튼 클릭
-wrongFileAlert.instruction.3=3. 이 볼륨에 파일 추가
-wrongFileAlert.link=추후 지원을 위해, 다음을 방문하십시요
+wrongFileAlert.instruction.0=파일을 암호화 하려면, 다음의 3단계를 따르십시오:
+wrongFileAlert.instruction.1=1. Vault를 잠금 해제하십시오.
+wrongFileAlert.instruction.2=2. "표시" 버튼을 클릭해 파일 탐색기에서 볼륨을 여십시오.
+wrongFileAlert.instruction.3=3. 이 볼륨에 파일을 추가하십시오.
+wrongFileAlert.link=더 많은 지원을 위해, 다음을 방문하십시오
# Vault Options
## General
@@ -405,6 +461,7 @@ vaultOptions.general.startHealthCheckBtn=상태 검사 시작
## Mount
vaultOptions.mount=드라이브 구성
+vaultOptions.mount.info=기본 설정을 바꾸기 위해 가상 드라이브 설정을 여십시오.
vaultOptions.mount.readonly=읽기 전용
vaultOptions.mount.customMountFlags=사용자 정의 매개변수 사용
vaultOptions.mount.winDriveLetterOccupied=사용됨
@@ -414,7 +471,10 @@ vaultOptions.mount.mountPoint.driveLetter=드라이브 문자를 지정하여
vaultOptions.mount.mountPoint.custom=선택한 디렉토리 사용
vaultOptions.mount.mountPoint.directoryPickerButton=선택
vaultOptions.mount.mountPoint.directoryPickerTitle=디렉토리 선택
+vaultOptions.mount.volumeType.default=기본 (%s)
+vaultOptions.mount.volumeType.restartRequired=이 볼륨 타입을 사용하기 위해, Cryptomator의 재시작이 필요합니다.
vaultOptions.mount.volume.tcp.port=TCP 포트
+vaultOptions.mount.volume.type=볼륨 타입
## Master Key
vaultOptions.masterkey=비밀번호
vaultOptions.masterkey.changePasswordBtn=비밀번호 변경
@@ -424,6 +484,8 @@ vaultOptions.masterkey.showRecoveryKeyBtn=복구 키 표시
vaultOptions.masterkey.recoverPasswordBtn=비밀번호 재설정
## Hub
vaultOptions.hub=복구
+vaultOptions.hub.convertInfo=비상상황에 이 Hub Vault를 비밀번호 기반 Vault로 변환하기 위해 복구 키를 사용할 수 있습니다.
+vaultOptions.hub.convertBtn=비밀번호 기반 Vault로 변환하기
# Recovery Key
## Display Recovery Key
@@ -431,7 +493,7 @@ recoveryKey.display.title=복구 키 보기
recoveryKey.create.message=비밀번호가 필요합니다
recoveryKey.create.description="%s"의 복구 키를 표시하려면 비밀번호를 입력해 주세요.
recoveryKey.display.description="%s" 데이터 접근을 복원하는데 사용 할 수 있는 복구 키 입니다:
-recoveryKey.display.StorageHints=매우 안전한곳에 보관하십시요. 예시:\n • 비밀번호 관리자를 사용하여 저장\n • USB 플래시 드라이브에 저장\n • 종이에 출력
+recoveryKey.display.StorageHints=매우 안전한곳에 보관하십시오. 예시:\n • 비밀번호 관리자를 사용하여 저장\n • USB 플래시 드라이브에 저장\n • 종이로 출력
## Reset Password
### Enter Recovery Key
recoveryKey.recover.title=비밀번호 바꾸기
@@ -447,9 +509,11 @@ recoveryKey.recover.resetSuccess.message=비밀번호 재설정 성공
recoveryKey.recover.resetSuccess.description=이제 해당 vault를 새 비밀번호로 잠금 해제할 수 있습니다.
# Convert Vault
+convertVault.title=Vault 변환
convertVault.convert.convertBtn.before=변환
convertVault.convert.convertBtn.processing=변환중…
convertVault.success.message=변환 완료
+convertVault.hubToPassword.success.description=이제 Hub 접근 없이 지정된 비밀번호로 Vault를 잠금해제할 수 있습니다.
# New Password
newPassword.promptText=새 비밀번호를 입력하세요
@@ -466,16 +530,46 @@ passwordStrength.messageLabel.4=매우 강함
# Quit
quit.title=앱 종료
quit.message=잠금 해제된 vault들이 존재합니다
+quit.description=정말로 나가시겠습니까? Cryptomator는 데이터 손실을 막기 위해 열린 Vault를 잠글 것입니다.
quit.lockAndQuitBtn=Vault 잠금 후 종료하기
# Forced Quit
+quit.forced.message=일부 Vault를 잠글 수 없습니다.
+quit.forced.description=대기 중인 작동이나 파일이 열려있어 Vault를 잠그는데 실패하였습니다. 남은 Vault를 강제로 잠글 수 있으나, 입/출력의 중단은 저장되지 않은 데이터의 유실을 초래할 수 있습니다.
quit.forced.forceAndQuitBtn=Vault 강제 잠금 후 종료하기
# Update Reminder
updateReminder.title=업데이트 확인
+updateReminder.message=업데이트 확인
+updateReminder.description=새로운 기능, 버그 수정, 보안 향상을 위해 업데이트하십시오. 업데이트 자동 확인을 권장합니다.
updateReminder.notNow=나중에
+updateReminder.yesOnce=예, 한번만
+updateReminder.yesAutomatically=예, 자동으로
#Dokany Support End
+dokanySupportEnd.title=지원 중단 경고
+dokanySupportEnd.message=Dokany에 대한 지원 중단
+dokanySupportEnd.description=Cryptomator에서 Dokany 볼륨 형식은 더이상 지원되지 않습니다. 기본 볼륨 형식을 사용하도록 설정이 조정되었으며, 설정에서 기본 형식을 확인할 수 있습니다.
dokanySupportEnd.preferencesBtn=설정 열기
+#Retry If Readonly
+
# Share Vault
+shareVault.title=Vault 공유
+shareVault.message=Vault를 다른 사람과 공유하려 하십니까?
+shareVault.description=Vault를 타인과 공유할 때에는 항상 주의하십시오. 간단히 이 단계들을 따르세요.
+shareVault.instruction.1=1. 암호화된 Vault 폴더를 클라우드 스토리지를 통해 공유하십시오.
+shareVault.instruction.2=2. Vault의 비밀번호를 안전한 방식으로 전달하십시오.
+shareVault.remarkBestPractices=문서에 있는 권장사항을 통해 더 많은 정보를 확인하십시오.
+shareVault.docsTooltip=Vault의 공유에 대해서는 문서를 참조하십시오.
+shareVault.hubAd.description=팀에서 작업하는 안전한 방법
+shareVault.hubAd.keyManagement=• 사전지식 없는 키 관리
+shareVault.hubAd.authentication=• 강력한 인증
+shareVault.hubAd.encryption=• 종단간 암호화
+shareVault.visitHub=Cryptomator Hub 방문하기
+
+shareVault.hub.message=Hub Vault를 공유하는법
+shareVault.hub.description=다른 팀 구성원과 Vault를 공유하기 위해서는 다음 단계를 따르십시오:
+shareVault.hub.instruction.1=1. 암호화된 Vault 폴더를 클라우드 스토리지를 통해 공유하십시오.
+shareVault.hub.instruction.2=2. Cryptomator Hub에서 팀 구성원에 접근을 허가하기
+shareVault.hub.openHub=Cryptomator Hub 열기
\ No newline at end of file
diff --git a/src/main/resources/i18n/strings_lv.properties b/src/main/resources/i18n/strings_lv.properties
index c343c8121..e2b976468 100644
--- a/src/main/resources/i18n/strings_lv.properties
+++ b/src/main/resources/i18n/strings_lv.properties
@@ -85,7 +85,6 @@ addvaultwizard.success.unlockNow=Atslēgt tagad
# Remove Vault
removeVault.title=Noņemt glabātuvi
removeVault.description=Šis tikai liks Cryptomator aizmirst šo glabātuvi. Jūs to variet pievienot vēlāk atkārtoti. Nekādi šifrētie dati no diska netiks dzēsti.
-removeVault.confirmBtn=Noņemt glabātuvi
# Change Password
changepassword.title=Mainīt paroli
@@ -281,4 +280,6 @@ quit.lockAndQuitBtn=Aizslēgt un aizvērt
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_mk.properties b/src/main/resources/i18n/strings_mk.properties
index bf16368b7..7ec6aa5f2 100644
--- a/src/main/resources/i18n/strings_mk.properties
+++ b/src/main/resources/i18n/strings_mk.properties
@@ -164,4 +164,6 @@ vaultOptions.mount.mountPoint.directoryPickerButton=Избор…
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_mr.properties b/src/main/resources/i18n/strings_mr.properties
index 125593fee..16d2016cd 100644
--- a/src/main/resources/i18n/strings_mr.properties
+++ b/src/main/resources/i18n/strings_mr.properties
@@ -118,4 +118,6 @@
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_nb.properties b/src/main/resources/i18n/strings_nb.properties
index 88dfa246d..d80a58618 100644
--- a/src/main/resources/i18n/strings_nb.properties
+++ b/src/main/resources/i18n/strings_nb.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopiert!
generic.button.done=Ferdig
generic.button.next=Neste
generic.button.print=Skriv ut
+generic.button.remove=Fjern
# Error
error.message=Feilkode %s
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Lås opp nå
removeVault.title=Fjern hvelvet
removeVault.message=Fjerne hvelv?
removeVault.description=Dette vil kun få Cryptomator til å glemme dette hvelvet. Du kan legge til hvelvet senere igjen. Ingen krypterte filer blir slettet fra harddisken.
-removeVault.confirmBtn=Fjern hvelvet
# Change Password
changepassword.title=Endre passord
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=En feil ble gjort under registreringspros
hub.registerFailed.description.deviceAlreadyExists=Denne enheten er allerede registrert for en annen bruker. Prøv å endre brukerkontoen eller bruk en annen enhet.
### Unauthorized
hub.unauthorized.message=Ingen tilgang
-hub.unauthorized.description=Enheten din har ikke blitt autorisert til å få tilgang til dette hvelvet ennå. Spør hvelveieren om å tillate det.
### Requires Account Initialization
hub.requireAccountInit.message=Påkrevd handling
hub.requireAccountInit.description.0=For å fortsette, fullfør trinnene som kreves i din
@@ -333,9 +332,11 @@ preferences.contribute.registeredFor=Supporter sertifikat registrert for %s
preferences.contribute.noCertificate=Støtt Cryptomator og motta et supporter-sertifikat. Det er som en lisensnøkkel, men for fantastiske mennesker som bruker fri programvare. ;-)
preferences.contribute.getCertificate=Har du ikke en allerede? Lær hvordan du kan skaffe den.
preferences.contribute.promptText=Lim inn supporter sertifikatkoden her
+preferences.contribute.donate=Donér
+preferences.contribute.sponsor=Sponsor
### Remove License Key Dialog
-removeCert.confirmBtn=Fjern
+removeCert.title=Fjern sertifikat
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -386,6 +387,7 @@ main.vaultlist.contextMenu.unlockNow=Lås opp nå
main.vaultlist.contextMenu.vaultoptions=Alternativer for hvelvet
main.vaultlist.contextMenu.reveal=Vis enheten
##Notificaition
+main.notification.support=Støtt Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Takk for at du valgte Cryptomator for å beskytte filene dine. Hvis du trenger hjelp, sjekk ut våre guider for å komme i gang:
@@ -541,6 +543,8 @@ dokanySupportEnd.message=Støtte for Dokany er avsluttet
dokanySupportEnd.description=Volumtypen Dokany støttes ikke lenger av Cryptomator. Innstillingene dine er justert for å bruke standard volumtype nå. Du kan se standardtypen i innstillingene.
dokanySupportEnd.preferencesBtn=Åpne innstillinger
+#Retry If Readonly
+
# Share Vault
shareVault.title=Del hvelv
shareVault.message=Vil du dele hvelvet ditt med andre?
diff --git a/src/main/resources/i18n/strings_nl.properties b/src/main/resources/i18n/strings_nl.properties
index a825e5c35..5a544e7d8 100644
--- a/src/main/resources/i18n/strings_nl.properties
+++ b/src/main/resources/i18n/strings_nl.properties
@@ -13,6 +13,7 @@ generic.button.copied=Gekopieerd!
generic.button.done=Klaar
generic.button.next=Volgende
generic.button.print=Afdrukken
+generic.button.remove=Verwijderen
# Error
error.message=Er deed zich een fout voor
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Nu Ontgrendelen
removeVault.title=Verwijder Kluis
removeVault.message=Kluis verwijderen?
removeVault.description=Dit laat Cryptomator enkel deze kluis vergeten. U kunt deze later opnieuw toevoegen. Er worden geen versleutelde bestanden van uw harde schijf verwijderd.
-removeVault.confirmBtn=Verwijder Kluis
# Change Password
changepassword.title=Wijzig wachtwoord
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Er is een fout gemaakt in het registratie
hub.registerFailed.description.deviceAlreadyExists=Dit apparaat is al geregistreerd voor een andere gebruiker. Probeer de account te wijzigen of gebruik een ander apparaat.
### Unauthorized
hub.unauthorized.message=Toegang geweigerd
-hub.unauthorized.description=Uw apparaat is nog niet gemachtigd om toegang te krijgen tot deze kluis. Vraag de eigenaar van de kluis om toestemming te geven.
+hub.unauthorized.description=U bent niet geautoriseerd om deze kluis te openen. Neem contact op met de eigenaar van de kluis om toegang aan te vragen.
### Requires Account Initialization
hub.requireAccountInit.message=Actie vereist
hub.requireAccountInit.description.0=Om verder te gaan, gelieve de stappen te voltooien in uw
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Sponsor
removeCert.title=Verwijder Certificaat
removeCert.message=Certificaat verwijderen?
removeCert.description=De kernfuncties van Cryptomator worden hierdoor niet beïnvloed. Toegang tot uw kluizen wordt niet beperkt, noch wordt het beveiligingsniveau verlaagd.
-removeCert.confirmBtn=Verwijderen
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Ondersteuning beëindigd voor Dokany
dokanySupportEnd.description=Het volumetype Dokany wordt niet langer ondersteund door Cryptomator. Uw instellingen zijn aangepast om nu het standaard volumetype te gebruiken. U kunt het standaardtype bekijken in de voorkeuren.
dokanySupportEnd.preferencesBtn=Open Voorkeuren
+#Retry If Readonly
+retryIfReadonly.title=Beperkte toegang tot kluis
+retryIfReadonly.message=Geen schrijftoegang tot de kluis map
+retryIfReadonly.description=Cryptomator kan niet naar de kluis map schrijven. U kunt de kluis veranderen om alleen-lezen te zijn en het opnieuw proberen. Deze optie kan worden uitgeschakeld in de kluis opties.
+retryIfReadonly.retry=Wijzig en probeer opnieuw
+
# Share Vault
shareVault.title=Kluis delen
shareVault.message=Wilt u uw kluis met anderen delen?
@@ -569,6 +574,6 @@ shareVault.visitHub=Bezoek Cryptomator Hub
shareVault.hub.message=Hoe een Hub kluis delen
shareVault.hub.description=Om de inhoud van de kluis te delen met een ander teamlid, moet u twee stappen uitvoeren:
-shareVault.hub.instruction.1=1. Deel toegang van de versleutelde kluismap via de cloud opslag.
+shareVault.hub.instruction.1=1. Deel toegang van de versleutelde kluis map via de cloud opslag.
shareVault.hub.instruction.2=2. Geef teamlid toegang in Cryptomator Hub.
shareVault.hub.openHub=Open Cryptomator Hub
\ No newline at end of file
diff --git a/src/main/resources/i18n/strings_nn.properties b/src/main/resources/i18n/strings_nn.properties
index 6aeb6daf7..f159b5ae8 100644
--- a/src/main/resources/i18n/strings_nn.properties
+++ b/src/main/resources/i18n/strings_nn.properties
@@ -72,7 +72,6 @@ addvaultwizard.success.unlockNow=Lås opp no
# Remove Vault
removeVault.title=Fjern kvelv
removeVault.description=Dette vil berre få Cryptomator til å gløyma denne kvelven. Du kan legga til kvelven seinare igjen. Ingen krypterte filer blir sletta frå harddisken.
-removeVault.confirmBtn=Fjern kvelv
# Change Password
changepassword.title=Byt passord
@@ -279,4 +278,6 @@ quit.lockAndQuitBtn=Lås og avslutt
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_no.properties b/src/main/resources/i18n/strings_no.properties
index 125593fee..16d2016cd 100644
--- a/src/main/resources/i18n/strings_no.properties
+++ b/src/main/resources/i18n/strings_no.properties
@@ -118,4 +118,6 @@
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_pa.properties b/src/main/resources/i18n/strings_pa.properties
index 459d17621..9bb50b838 100644
--- a/src/main/resources/i18n/strings_pa.properties
+++ b/src/main/resources/i18n/strings_pa.properties
@@ -13,6 +13,7 @@ generic.button.copied=ਕਾਪੀ ਕੀਤਾ!
generic.button.done=ਮੁਕੰਮਲ
generic.button.next=ਅੱਗੇ
generic.button.print=ਪਰਿੰਟ ਕਰੋ
+generic.button.remove=ਹਟਾਓ
# Error
error.message=ਇੱਕ ਤਰੁੱਟੀ ਆਈ ਹੈ
@@ -51,6 +52,7 @@ addvaultwizard.new.directoryPickerLabel=ਪਸੰਦੀਦਾ ਟਿਕਾਣਾ
addvaultwizard.new.directoryPickerButton=…ਚੁਣੋ
addvaultwizard.new.directoryPickerTitle=ਡਾਇਰੈਕਟਰੀ ਚੁਣੋ
addvaultwizard.new.fileAlreadyExists=ਵਾਲਟ ਨਾਂ ਨਾਲ ਫਾਇਲ ਜਾਂ ਡਾਇਰੈਕਟਰੀ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ
+addvaultwizard.new.locationIsOk=ਤੁਹਾਡੇ ਵਾਲਟ ਲਈ ਢੁੱਕਵਾਂ ਟਿਕਾਣਾ
addvaultwizard.new.invalidName=ਗਲਤ ਵਾਲਟ ਨਾਂ
addvaultwizard.new.validName=ਵਾਜਬ ਵਾਲਟ ਨਾਂ
addvaultwizard.new.validCharacters.message=ਵਾਲਟ ਨਾਂ ਵਿੱਚ ਅੱਗੇ ਦਿੱਤੇ ਅੱਖਰ ਹੋ ਸਕਦੇ ਹਨ:
@@ -59,6 +61,8 @@ addvaultwizard.new.validCharacters.numbers=ਅੰਕ
addvaultwizard.new.validCharacters.dashes=ਹਾਈਫਨ (%s) ਜਾਂ ਹੇਠਾਂ ਲਾਈਨ (%s)
### Expert Settings
addvaultwizard.new.expertSettings.enableExpertSettingsCheckbox=ਮਾਹਰ ਸੈਟਿੰਗਾਂ ਨੂੰ ਸਮਰੱਥ ਕਰੋ
+addvaultwizard.new.expertSettings.shorteningThreshold.invalid=ਮੁੱਲ 36 ਤੋਂ 220 ਵਿਚਾਲੇ ਚਾਹੀਦਾ ਹੈ (ਮੂਲ 220 ਹੈ)
+addvaultwizard.new.expertSettings.shorteningThreshold.tooltip=ਹੋਰ ਸਿੱਖਣ ਲਈ ਦਸਤਾਵੇਜ਼ ਨੂੰ ਖੋਲ੍ਹੋ।
addvaultwizard.new.expertSettings.shorteningThreshold.valid=ਵਾਜਬ
### Password
addvaultwizard.new.createVaultBtn=ਵਾਲਟ ਬਣਾਓ
@@ -95,7 +99,6 @@ addvaultwizard.success.unlockNow=ਹੁਣੇ ਅਣ-ਲਾਕ ਕਰੋ
removeVault.title=ਵਾਲਟ ਹਟਾਓ
removeVault.message=ਵਾਲਟ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?
removeVault.description=ਇਸ ਸਿਰਫ਼ Cryptomator ਨੂੰ ਇਹ ਵਾਲਟ ਭੁਲਾਏਗਾ। ਤੁਸੀਂ ਇਸ ਨੂੰ ਬਾਅਦ ਵਿੱਚ ਵੀ ਜੋੜ ਸਕਦੇ ਹੋ। ਕੋਈ ਵੀ ਇੰਕ੍ਰਿਪਟ ਕੀਤੀ ਫਾਇਲ ਤੁਹਾਡੀ ਹਾਰਡ ਡਰਾਇਵ ਉਤੋਂ ਹਟਾਈ ਨਹੀਂ ਜਾਵੇਗੀ।
-removeVault.confirmBtn=ਵਾਲਟ ਹਟਾਓ
# Change Password
changepassword.title=ਪਾਸਵਰਡ ਬਦਲੋ
@@ -146,8 +149,10 @@ hub.registerFailed.message=ਡਿਵਾਈਸ ਰਜਿਸਟਰ ਕਰਨਾ
hub.unauthorized.message=ਪਹੁੰਚ ਤੋਂ ਇਨਾਕਰ
### Requires Account Initialization
hub.requireAccountInit.message=ਕਾਰਵਾਈ ਦੀ ਲੋੜ ਹੈ
+hub.requireAccountInit.description.1=ਹੱਬ ਵਰਤੋਂਕਾਰ ਪਰੋਫਾਇਲ
hub.requireAccountInit.description.2=.
### License Exceeded
+hub.invalidLicense.message=ਹੱਬ ਲਸੰਸ ਗ਼ੈਰਵਾਜਬ ਹੈ
# Lock
## Force
@@ -163,6 +168,7 @@ lock.fail.description=ਵਾਲਟ "%s" ਨੂੰ ਲਾਕ ਨਹੀਂ ਕੀ
migration.title=ਵਾਲਟ ਅੱਪਗਰੇਡ ਕਰੋ
## Start
migration.start.header=ਵਾਲਟ ਅੱਪਗਰੇਡ ਕਰੋ
+migration.start.remarkUndone=ਇਸ ਅੱਪਗਰੇਡ ਨੂੰ ਵਾਪਸ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਦਾ ਹੈ।
migration.start.confirm=ਮੈਂ ਉੱਤੇ ਦਿੱਤੀ ਜਾਣਕਾਰੀ ਨੂੰ ਪੜ੍ਹੋ ਅਤੇ ਸਮਝ ਲਿਆ ਹੈ
## Run
migration.run.enterPassword="%s" ਲਈ ਪਾਸਵਰਡ ਦਿਓ
@@ -196,9 +202,15 @@ health.intro.affirmation=ਮੈਂ ਉੱਤੇ ਦਿੱਤੀ ਜਾਣਕਾ
health.fail.header=ਵਾਲਟ ਸੰਰਚਨਾ ਲੋਡ ਕਰਨ ਲਈ ਗਲਤੀ
health.fail.moreInfo=ਹੋਰ ਜਾਣਕਾਰੀ
## Check Selection
+health.checkList.selectAllButton=ਸਭ ਚੋਣਾਂ ਨੂੰ ਚੁਣੋ
+health.checkList.deselectAllButton=ਸਭ ਚੋਣਾਂ ਨੂੰ ਨਾ ਚੁਣੋ
+health.check.runBatchBtn=ਚੁਣੀਆਂ ਚੋਣਾਂ ਨੂੰ ਚਲਾਓ
## Detail view
+health.check.detail.checkScheduled=ਜਾਂਚ ਨੂੰ ਸੈਡਿਊਲ ਕੀਤਾ ਗਿਆ ਹੈ।
health.check.detail.checkRunning=ਜਾਂਚ ਇਸ ਵੇਲੇ ਚੱਲ ਰਹੀ ਹੈ…
+health.check.detail.checkCancelled=ਜਾਂਚ ਨੂੰ ਰੱਦ ਕੀਤਾ ਗਿਆ ਹੈ।
health.check.detail.listFilters.label=ਫਿਲਟਰ
+health.check.exportBtn=ਰਿਪੋਰਟ ਨੂੰ ਐਕਸਪੋਰਟ ਕਰੋ
## Result view
health.result.severityFilter.good=ਵਧੀਆ
health.result.severityFilter.info=ਜਾਣਕਾਰੀ
@@ -236,6 +248,7 @@ preferences.volume=ਵਰਚੁਅਲ ਡਰਾਇਵ
preferences.volume.type=ਮੂਲ ਵਾਲੀਅਮ ਕਿਸਮ
preferences.volume.type.automatic=ਆਟੋਮੈਟਿਕ
preferences.volume.tcp.port=ਮੂਲ TCP ਪੋਰਟ
+preferences.volume.feature.readOnly=ਸਿਰਫ਼-ਪੜ੍ਹਨ ਲਈ ਮਾਊਂਟ
## Updates
preferences.updates=ਅੱਪਡੇਟ
preferences.updates.currentVersion=ਮੌਜੂਦਾ ਵਰਜ਼ਨ: %s
@@ -247,15 +260,18 @@ preferences.updates.lastUpdateCheck.never=ਕਦੇ ਨਹੀਂ
preferences.updates.lastUpdateCheck.recently=ਸੱਜਰੇ
preferences.updates.lastUpdateCheck.daysAgo=%s ਦਿਨ ਪਹਿਲਾਂ
preferences.updates.lastUpdateCheck.hoursAgo=%s ਘੰਟੇ ਪਹਿਲਾਂ
+preferences.updates.upToDate=Cryptomator ਅੱਪ-ਟੂ-ਡੇਟ ਹੈ।
## Contribution
preferences.contribute=ਸਾਡਾ ਸਮਰਥਨ ਕਰੋ
+preferences.contribute.registeredFor=%s ਲਈ ਰਜਿਸਟਰ ਕੀਤਾ ਸਹਿਯੋਗੀ ਸਰਟੀਫਿਕੇਟ
+preferences.contribute.thankYou=Cryptomator ਦੇ ਖੁੱਲ੍ਹੇ ਸਰੋਤ ਵਿਕਾਸ ਨੂੰ ਸਹਿਯੋਗ ਦੇਣ ਲਈ ਤੁਹਾਡਾ ਧੰਨਵਾਦ ਹੈ!
preferences.contribute.donate=ਦਾਨ ਕਰੋ
preferences.contribute.sponsor=ਸਪਾਂਸਰ
### Remove License Key Dialog
removeCert.title=ਸਰਟੀਫਿਕੇਟ ਨੂੰ ਹਟਾਓ
-removeCert.confirmBtn=ਹਟਾਓ
+removeCert.message=ਸਹਿਯੋਗੀ ਸਰਟੀਫਿਕੇਟ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -333,6 +349,7 @@ main.vaultDetail.throughput.kbps=%.1f KiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=ਵਾਲਟ ਅੰਕੜੇ
main.vaultDetail.locateEncryptedFileBtn=ਇੰਕ੍ਰਿਪਟ ਕੀਤੀ ਫਾਇਲ ਨੂੰ ਲੱਭੋ
+main.vaultDetail.filePickerTitle=ਵਾਲਟ ਵਿੱਚ ਫਾਇਲ ਨੂੰ ਚੁਣੋ
### Missing
main.vaultDetail.missing.info=Cryptomator ਇਸ ਮਾਗਰ ਉੱਤੇ ਵਾਲਟ ਨਹੀਂ ਲੱਭਿਆ ਸਕੀ।
main.vaultDetail.missing.recheck=ਮੁੜ-ਜਾਂਚੋ
@@ -393,6 +410,7 @@ vaultOptions.masterkey.showRecoveryKeyBtn=ਰਿਕਰਵੀ ਕੁੰਜੀ ਦ
vaultOptions.masterkey.recoverPasswordBtn=ਪਾਸਵਰਡ ਰੀਸੈੱਟ ਕਰੋ
## Hub
vaultOptions.hub=ਰਿਕਵਰੀ
+vaultOptions.hub.convertBtn=ਪਾਸਵਰਡ ਅਧਾਰਿਤ ਵਾਲਟ ਲਈ ਬਦਲੋ
# Recovery Key
## Display Recovery Key
@@ -413,8 +431,13 @@ recoveryKey.printout.heading=Cryptomator ਰਿਕਵਰੀ ਕੁੰਜੀ\n"%s
recoveryKey.recover.resetBtn=ਰੀਸੈੱਟ ਕਰੋ
### Recovery Key Password Reset Success
recoveryKey.recover.resetSuccess.message=ਪਾਸਵਰਡ ਨੂੰ ਕਾਮਯਾਬੀ ਨਾਲ ਮੁੜ-ਸੈੱਟ ਕੀਤਾ ਗਿਆ
+recoveryKey.recover.resetSuccess.description=ਤੁਸੀਂ ਆਪਣੇ ਵਾਲਟ ਨੂੰ ਨਵੇਂ ਪਾਸਵਰਡ ਨਾਲ ਖੋਲ੍ਹ ਸਕਦੇ ਹੋ
# Convert Vault
+convertVault.title=ਵਾਲਟ ਨੂੰ ਬਦਲੋ
+convertVault.convert.convertBtn.before=ਬਦਲੋ
+convertVault.convert.convertBtn.processing=…ਬਦਲਿਆ ਜਾ ਰਿਹਾ ਹੈ
+convertVault.success.message=ਬਦਲਣਾ ਕਾਮਯਾਬ ਹੈ
# New Password
newPassword.promptText=ਨਵਾਂ ਪਾਸਵਰਡ ਦਿਓ
@@ -452,6 +475,8 @@ dokanySupportEnd.title=ਬਰਤਰਫ਼ੀ ਨੋਟਿਸ
dokanySupportEnd.message=Dokany ਲਈ ਸਹਿਯੋਗ ਖ਼ਤਮ
dokanySupportEnd.preferencesBtn=ਪਸੰਦੀਦਾ ਖੋਲ੍ਹੋ
+#Retry If Readonly
+
# Share Vault
shareVault.title=ਵਾਲਟ ਨੂੰ ਸਾਂਝਾ ਕਰੋ
shareVault.message=ਕੀ ਤੁਸੀਂ ਆਪਣੇ ਵਾਲਟ ਨੂੰ ਹੋਰਾਂ ਨਾਲ ਸਾਂਝਾ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?
diff --git a/src/main/resources/i18n/strings_pl.properties b/src/main/resources/i18n/strings_pl.properties
index dfef9d6d8..a3dc2c7b2 100644
--- a/src/main/resources/i18n/strings_pl.properties
+++ b/src/main/resources/i18n/strings_pl.properties
@@ -13,6 +13,7 @@ generic.button.copied=Skopiowano!
generic.button.done=Gotowe
generic.button.next=Dalej
generic.button.print=Drukuj
+generic.button.remove=Usuń
# Error
error.message=Wystąpił błąd
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Odblokuj teraz
removeVault.title=Usuń sejf
removeVault.message=Usunąć sejf?
removeVault.description=To tylko sprawi, że Cryptomator nie będzie widział tego sejfu. Możesz dodać go ponownie później. Żadne zaszyfrowane pliki nie zostaną usunięte z dysku twardego.
-removeVault.confirmBtn=Usuń sejf
# Change Password
changepassword.title=Zmiana Hasła
@@ -150,7 +150,7 @@ hub.noKeychain.message=Brak dostępu do klucza urządzenia
hub.noKeychain.description=Aby odblokować sejfy na Hubie, wymagany jest klucz urządzenia zabezpieczony za pomocą pęku kluczy. Aby kontynuować, włącz "%s" i wybierz Pęk kluczy w ustawieniach.
hub.noKeychain.openBtn=Otwórz ustawienia
### Waiting
-hub.auth.message=Czekanie na autoryzację…
+hub.auth.message=Oczekiwanie na autoryzację…
hub.auth.description=Przekierowanie na stronę logowania nastąpi automatycznie.
hub.auth.loginLink=Nie przekierowano? Kliknij tutaj.
### Receive Key
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=Wystąpił błąd w procesie rejestracji.
hub.registerFailed.description.deviceAlreadyExists=To urządzenie jest już zarejestrowane dla innego użytkownika. Spróbuj zmienić konto użytkownika lub użyć innego urządzenia.
### Unauthorized
hub.unauthorized.message=Brak dostępu
-hub.unauthorized.description=Twoje urządzenie nie zostało jeszcze upoważnione do dostępu do tego sejfu. Poproś właściciela sejfu o autoryzację.
### Requires Account Initialization
hub.requireAccountInit.message=Wymagane działanie
hub.requireAccountInit.description.0=Aby kontynuować, wykonaj wymagane kroki w Twoim
@@ -246,7 +245,7 @@ health.checkList.deselectAllButton=Odznacz wszystkie testy
health.check.runBatchBtn=Uruchom wybrane testy
## Detail view
health.check.detail.noSelectedCheck=Aby sprawdzić wyniki, wybierz test z listy po lewej stronie.
-health.check.detail.checkScheduled=Test będzie uruchomiony.
+health.check.detail.checkScheduled=Test został zaplanowany.
health.check.detail.checkRunning=Test jest aktualnie uruchomiony…
health.check.detail.checkSkipped=Test nie był wybrany do uruchomienia.
health.check.detail.checkFinished=Test zakończony pomyślnie.
@@ -337,12 +336,12 @@ preferences.contribute.getCertificate=Nie masz jeszcze? Dowiedz się, jak możes
preferences.contribute.promptText=Wklej tutaj kod certyfikatu darczyńcy
preferences.contribute.thankYou=Dziękujemy za wsparcie rozwoju Cryptomatora!
preferences.contribute.donate=Wspomóż
+preferences.contribute.sponsor=Sponsor
### Remove License Key Dialog
removeCert.title=Usuń Certyfikat
removeCert.message=Usunąć certyfikat wsparcia?
-removeCert.description=Nie ma to wpływu na podstawowe funkcje Cryptomatora. Dostęp do twoich sejfów nie jest ograniczony, oraz nie zmniejsza się poziom bezpieczeństwa.
-removeCert.confirmBtn=Usuń
+removeCert.description=Nie ma to wpływu na podstawowe funkcje Cryptomatora. Dostęp do twoich sejfów nie jest ograniczony oraz nie zmniejsza się poziom bezpieczeństwa.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -369,7 +368,7 @@ stats.write.throughput.idle=Zapis: bezczynny
stats.write.throughput.kibs=Zapis: %.2f KiB/s
stats.write.throughput.mibs=Zapis: %.2f MiB/s
stats.write.total.data.none=Zapisane dane: -
-stats.write.total.data.kib=Zapis danych: %.1f KiB
+stats.write.total.data.kib=Zapisane dane: %.1f KiB
stats.write.total.data.mib=Zapisane dane: %.1f MiB
stats.write.total.data.gib=Zapisane dane: %.1f GiB
stats.encr.total.data.none=Dane zaszyfrowane: -
@@ -414,7 +413,7 @@ main.vaultDetail.revealBtn=Otwórz lokalizację
main.vaultDetail.copyUri=Kopiuj URI
main.vaultDetail.lockBtn=Blokuj
main.vaultDetail.bytesPerSecondRead=Odczyt:
-main.vaultDetail.bytesPerSecondWritten=Zapisz:
+main.vaultDetail.bytesPerSecondWritten=Zapis:
main.vaultDetail.throughput.idle=bezczynny
main.vaultDetail.throughput.kbps=%.1f KiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
@@ -442,7 +441,7 @@ wrongFileAlert.message=Czy chciałeś zaszyfrować te pliki?
wrongFileAlert.description=W tym celu Cryptomator zapewnia udział dostępny w menedżerze plików.
wrongFileAlert.instruction.0=Aby zaszyfrować pliki, wykonaj następujące kroki:
wrongFileAlert.instruction.1=1. Odblokuj swój sejf.
-wrongFileAlert.instruction.2=2. Kliknij na "Otwórz lokalizację", aby otworzyć udział w menedżerze plików.
+wrongFileAlert.instruction.2=2. Kliknij "Otwórz lokalizację", aby otworzyć udział w menedżerze plików.
wrongFileAlert.instruction.3=3. Dodaj pliki do tego udziału.
wrongFileAlert.link=Aby uzyskać pomoc, wejdź na
@@ -501,7 +500,7 @@ recoveryKey.recover.prompt=Wprowadź klucz odzyskiwania dla "%s":
recoveryKey.recover.correctKey=To jest prawidłowy klucz odzyskiwania
recoveryKey.recover.wrongKey=Ten klucz należy do innego sejfu
recoveryKey.recover.invalidKey=Ten klucz jest nieprawidłowy
-recoveryKey.printout.heading=Cryptomator - Klucz odzyskiwania "%s"\n
+recoveryKey.printout.heading=Cryptomator - Klucz odzyskiwania\n"%s"\n
### Reset Password
recoveryKey.recover.resetBtn=Resetuj
### Recovery Key Password Reset Success
@@ -552,6 +551,8 @@ dokanySupportEnd.message=Koniec wsparcia dla Dokany
dokanySupportEnd.description=Typ udziału Dokany nie jest już wspierany przez Cryptomator. Twoje ustawienia zostały dostosowane do domyślnego typu udziału. Możesz sprawdzić jaki jest domyślny typ w ustawieniach.
dokanySupportEnd.preferencesBtn=Otwórz ustawienia
+#Retry If Readonly
+
# Share Vault
shareVault.title=Udostępnij sejf
shareVault.message=Czy chcesz udostępnić swój sejf innym?
diff --git a/src/main/resources/i18n/strings_pt.properties b/src/main/resources/i18n/strings_pt.properties
index 1a72f2887..bd4b5c500 100644
--- a/src/main/resources/i18n/strings_pt.properties
+++ b/src/main/resources/i18n/strings_pt.properties
@@ -13,6 +13,7 @@ generic.button.copied=Copiado!
generic.button.done=Ok
generic.button.next=Seguinte
generic.button.print=Imprimir
+generic.button.remove=Remover
# Error
error.message=Erro %s
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Desbloquear agora
removeVault.title=Remover Cofre
removeVault.message=Remover Cofre?
removeVault.description=Isto fará unicamente com que o Cryptomator esqueça este cofre. Poderá adicioná-lo novamente mais tarde. Nenhum ficheiro encriptado será apagado do seu disco rígido.
-removeVault.confirmBtn=Remover Cofre
# Change Password
changepassword.title=Alterar Palavra-passe
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Ocorreu um erro no processo de registo. P
hub.registerFailed.description.deviceAlreadyExists=Este dispositivo já está registado para um utilizador diferente. Tente alterar a conta de utilizador ou use um dispositivo diferente.
### Unauthorized
hub.unauthorized.message=Acesso negado
-hub.unauthorized.description=O seu dispositivo ainda não foi autorizado a aceder a este cofre. Peça ao proprietário do cofre para o autorizar.
+hub.unauthorized.description=Não está autorizado a abrir este cofre. Contacte o proprietário do cofre para solicitar o acesso.
### Requires Account Initialization
hub.requireAccountInit.message=Ação requerida
hub.requireAccountInit.description.0=Para continuar, conclua as etapas necessárias no seu
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Patrocinador
removeCert.title=Remover certificado
removeCert.message=Remover o certificado de apoiante?
removeCert.description=As principais caraterísticas do Cryptomator não são afectadas por isto. Nem o acesso aos seus cofres é restringido nem o nível de segurança é reduzido.
-removeCert.confirmBtn=Remover
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Suporte termina para o Dokany
dokanySupportEnd.description=O tipo de volume Dokany não é mais suportado pelo Cryptomator. As configurações serão ajustadas para usar o tipo de volume padrão por agora. Pode ver o tipo padrão nas preferências.
dokanySupportEnd.preferencesBtn=Abrir preferências
+#Retry If Readonly
+retryIfReadonly.title=Acesso ao Cofre Restrito
+retryIfReadonly.message=Sem acesso de gravação ao diretório do cofre
+retryIfReadonly.description=O Cryptomator não pode escrever no diretório do cofre. Pode alterar o cofre para ser apenas de leitura e tentar novamente. Esta opção pode ser desactivada nas opções do cofre.
+retryIfReadonly.retry=Alterar e tentar de novo
+
# Share Vault
shareVault.title=Partilhar cofre
shareVault.message=Quer partilhar o seu cofre com outros?
diff --git a/src/main/resources/i18n/strings_pt_BR.properties b/src/main/resources/i18n/strings_pt_BR.properties
index b2dd6f666..9dc86b406 100644
--- a/src/main/resources/i18n/strings_pt_BR.properties
+++ b/src/main/resources/i18n/strings_pt_BR.properties
@@ -13,16 +13,17 @@ generic.button.copied=Copiado!
generic.button.done=Concluído
generic.button.next=Próximo
generic.button.print=Imprimir
+generic.button.remove=Remover
# Error
error.message=Erro %s
-error.description=O Cryptomator encontrou um erro inesperado. Você pode procurar soluções pré-existentes na internet ou até mesmo reportar como bug.
+error.description=O Cryptomator não esperava que isso acontecesse. Você pode procurar soluções existentes para este erro. Ou, se ainda não foi relatado, sinta-se à vontade para fazê-lo.
error.hyperlink.lookup=Procure este erro
error.hyperlink.report=Reportar este erro
error.technicalDetails=Detalhes:
error.existingSolutionDescription=O Cryptomator encontrou um erro inesperado, mas há uma solução pré-existente disponível no seguinte link.
error.hyperlink.solution=Procure a solução
-error.lookupPermissionMessage=O Cryptomator pode procurar uma solução online. Isso enviará um pedido ao nosso banco de problemas a partir do seu endereço IP.
+error.lookupPermissionMessage=O Cryptomator pode procurar uma solução para este problema online. Isso enviará uma solicitação para nosso banco de dados de problemas a partir do seu endereço IP.
error.dismiss=Ignorar
error.lookUpSolution=Procurar solução
@@ -55,7 +56,7 @@ addvaultwizard.new.directoryPickerButton=Escolher…
addvaultwizard.new.directoryPickerTitle=Selecionar Diretório
addvaultwizard.new.fileAlreadyExists=Já existe um arquivo ou diretório com esse nome
addvaultwizard.new.locationDoesNotExist=Um diretório no caminho especificado não existe ou não pode ser acessado
-addvaultwizard.new.locationIsNotWritable=Não há acesso de escrita nesse caminho
+addvaultwizard.new.locationIsNotWritable=Sem acesso de gravação no caminho especificado
addvaultwizard.new.locationIsOk=Local adequado para o seu cofre
addvaultwizard.new.invalidName=Nome do cofre inválido
addvaultwizard.new.validName=Nome do cofre válido
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Desbloquear Agora
removeVault.title=Remover o cofre "%s"
removeVault.message=Remover o cofre?
removeVault.description=Isso só fará com que o Cryptomator esqueça esse cofre. Você pode adicioná-lo novamente. Nenhum arquivo criptografado será excluído do seu disco rígido.
-removeVault.confirmBtn=Remover Cofre
# Change Password
changepassword.title=Alterar Senha
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Um erro ocorreu no processo de registro.
hub.registerFailed.description.deviceAlreadyExists=Este dispositivo já está registrado para um usuário diferente. Tente alterar a conta de usuário ou use um dispositivo diferente.
### Unauthorized
hub.unauthorized.message=Acesso negado
-hub.unauthorized.description=Seu dispositivo ainda não foi autorizado a acessar este cofre. Peça ao proprietário do cofre para autorizá-lo.
+hub.unauthorized.description=Você não está autorizado a abrir este cofre. Entre em contato com o proprietário do cofre para solicitar acesso.
### Requires Account Initialization
hub.requireAccountInit.message=Ação necessária
hub.requireAccountInit.description.0=Para prosseguir, por favor, complete os passos necessários
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Patrocinador
removeCert.title=Excluir Certificado
removeCert.message=Excluir certificado de apoiador?
removeCert.description=Os principais recursos do Cryptomador não são afetados por isso. Nem o acesso aos seus cofres é restrito, nem o nível de segurança é reduzido.
-removeCert.confirmBtn=Remover
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Fim do suporte para o Dokany
dokanySupportEnd.description=O volume do tipo Dokany não é mais suportado pelo Cryptomator. Suas configurações serão ajustadas para usar o tipo de volume padrão agora. Você pode ver o tipo padrão nas preferências.
dokanySupportEnd.preferencesBtn=Abrir Preferências
+#Retry If Readonly
+retryIfReadonly.title=Acesso Restrito ao Cofre
+retryIfReadonly.message=Sem acesso de gravação ao diretório do cofre
+retryIfReadonly.description=O Cryptomator não pode escrever no diretório do cofre. Você pode alterar o cofre para somente leitura e tentar novamente. Esta opção pode ser desativada nas opções de cofre.
+retryIfReadonly.retry=Alterar e Repetir
+
# Share Vault
shareVault.title=Compartilhar Cofre
shareVault.message=Gostaria de compartilhar o seu cofre com outras pessoas?
diff --git a/src/main/resources/i18n/strings_ro.properties b/src/main/resources/i18n/strings_ro.properties
index 8abe8bcae..da93916db 100644
--- a/src/main/resources/i18n/strings_ro.properties
+++ b/src/main/resources/i18n/strings_ro.properties
@@ -13,6 +13,7 @@ generic.button.copied=Copiat!
generic.button.done=Terminat
generic.button.next=Următorul
generic.button.print=Tipărește
+generic.button.remove=Șterge
# Error
error.message=A apărut o eroare
@@ -20,7 +21,7 @@ error.description=Cryptomator nu se aștepta să se întâmple asta. Puteți că
error.hyperlink.lookup=Caută soluții pentru această eroare
error.hyperlink.report=Raportează această eroare
error.technicalDetails=Detalii:
-error.existingSolutionDescription=Cryptomator nu s-a aşteptat să se întâmple asta. Dar am găsit o soluţie pentru această eroare. Vă rugăm să cititi următorul link.
+error.existingSolutionDescription=Cryptomator nu s-a aşteptat să se întâmple asta. Dar am găsit o soluţie existenta pentru această eroare. Vă rugăm să cititi următorul link.
error.hyperlink.solution=Caută soluția
error.lookupPermissionMessage=Cryptomator poate căuta online o soluție pentru această problemă. O cerere va fi trimisa către baza noastră de date de la adresa ta IP.
error.dismiss=Renunță
@@ -47,6 +48,7 @@ addvaultwizard.new.nameInstruction=Alege un nume pentru seif
addvaultwizard.new.namePrompt=Nume seif
### Location
addvaultwizard.new.locationInstruction=Unde ar trebui ca Cryptomator să stocheze fișierele criptate din seiful dumneavoastră?
+addvaultwizard.new.locationLoading=Se verifică sistemul de fișiere locale pentru directoarele implicite de stocare în nor…
addvaultwizard.new.locationLabel=Locație stocare
addvaultwizard.new.locationPrompt=…
addvaultwizard.new.directoryPickerLabel=Locație personalizată
@@ -104,7 +106,6 @@ addvaultwizard.success.unlockNow=Deblochează acum
removeVault.title=Eliminați seiful
removeVault.message=Ștergeți seiful?
removeVault.description=Acest lucru va face Cryptomator să uite de acest seif. Îl puteţi adăuga din nou mai târziu. Nici un fişier criptat nu va fi şters din hard disk-ul dvs.
-removeVault.confirmBtn=Eliminați seiful
# Change Password
changepassword.title=Schimbați parola
@@ -159,7 +160,7 @@ hub.receive.description=In acest moment Criptomatorul primește și procesează
hub.register.message=Dispozitiv nou
hub.register.description=Acesta este primul acces la Hub de pe acest dispozitiv. Vă rugăm să îl înregistrați folosind cheia de cont.
hub.register.nameLabel=Numele dispozitivului
-hub.register.invalidAccountKeyLabel=Cheie cont nevalidă
+hub.register.invalidAccountKeyLabel=Cheie cont invalidă
hub.register.registerBtn=Înregistrare
### Register Device Legacy
hub.register.legacy.occupiedMsg=Numele este deja în uz
@@ -172,9 +173,9 @@ hub.registerSuccess.legacy.description=Pentru a accesa seiful dispozitivului tre
### Registration Failed
hub.registerFailed.message=Înregistrarea dispozitivului a eșuat
hub.registerFailed.description.generic=.
+hub.registerFailed.description.deviceAlreadyExists=Acest dispozitiv este deja înregistrat pentru un alt utilizator. Încercați să schimbați contul de utilizator sau folosiți un alt dispozitiv.
### Unauthorized
hub.unauthorized.message=Acces respins
-hub.unauthorized.description=Dispozitivul dvs. nu a fost autorizat să acceseze acest seif. Solicitați proprietarului seifului să va autorizeze accesul.
### Requires Account Initialization
hub.requireAccountInit.message=Acțiune necesară
hub.requireAccountInit.description.0=Pentru a continua, vă rugăm să finalizaţi paşii necesari în
@@ -321,7 +322,8 @@ preferences.updates.updateAvailable=Actualizare la versiunea %s disponibilă.
preferences.updates.lastUpdateCheck=Ultima verificare: %s
preferences.updates.lastUpdateCheck.never=niciodată
preferences.updates.lastUpdateCheck.recently=recent
-preferences.updates.lastUpdateCheck.daysAgo=acum %s zile
+preferences.updates.lastUpdateCheck.daysAgo=Acum %s zile
+preferences.updates.lastUpdateCheck.hoursAgo=%s ore în urmă
preferences.updates.checkFailed=Căutarea actualizărilor a eșuat. Verificați conexiunea la internet sau încercați din nou mai târziu.
preferences.updates.upToDate=Cryptomator este actualizat.
@@ -331,9 +333,13 @@ preferences.contribute.registeredFor=Certificat de suporter înregistrat pentru
preferences.contribute.noCertificate=Susțineți Cryptomator și primiți un certificat de suport. E ca o cheie de licență dar pentru persoanele minunate care folosesc software gratuit. ;-)
preferences.contribute.getCertificate=Nu aveți deja unul? Aflați cum îl puteți obține.
preferences.contribute.promptText=Lipiți codul certificatului de suporter aici
+preferences.contribute.thankYou=Va mulțumim pentru suportul dumneavoastră la dezvoltarea open-source a Cryptomatorului
+preferences.contribute.donate=Donez
+preferences.contribute.sponsor=Sponsor
### Remove License Key Dialog
-removeCert.confirmBtn=Șterge
+removeCert.title=Elimina Certificat
+removeCert.message=Elimina Certificat suporter?
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -383,7 +389,11 @@ main.vaultlist.contextMenu.unlock=Deblochează…
main.vaultlist.contextMenu.unlockNow=Deblochează acum
main.vaultlist.contextMenu.vaultoptions=Arată opțiunile seifului
main.vaultlist.contextMenu.reveal=Dezvăluie unitatea
+main.vaultlist.addVaultBtn.menuItemNew=Creare seif nou...
+main.vaultlist.addVaultBtn.menuItemExisting=Deschide un seif existent...
##Notificaition
+main.notification.updateAvailable=O nouă versiune este valabilă.
+main.notification.support=Susține Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Vă mulțumim că ați ales Cryptomator pentru a vă proteja fișierele. Dacă aveți nevoie de asistență, verificați ghidurile noastre de pornire:
@@ -393,6 +403,7 @@ main.vaultDetail.unlockBtn=Deblochează…
main.vaultDetail.unlockNowBtn=Deblochează acum
main.vaultDetail.optionsBtn=Opțiuni seif
main.vaultDetail.passwordSavedInKeychain=Parola a fost salvată
+main.vaultDetail.share=Distribuie…
### Unlocked
main.vaultDetail.unlockedStatus=DEBLOCAT
main.vaultDetail.accessLocation=Conținutul seifului tău este accesibil aici:
@@ -459,7 +470,8 @@ vaultOptions.mount.mountPoint.directoryPickerButton=Alege…
vaultOptions.mount.mountPoint.directoryPickerTitle=Alege un director
vaultOptions.mount.volumeType.default=Implicit (%s)
vaultOptions.mount.volumeType.restartRequired=Cryptomator trebuie repornit pentru ca modificările să fie aplicate.
-vaultOptions.mount.volume.tcp.port=Portul TCP
+vaultOptions.mount.volume.tcp.port=Port TCP
+vaultOptions.mount.volume.type=Tip volum
## Master Key
vaultOptions.masterkey=Parolă
vaultOptions.masterkey.changePasswordBtn=Schimbați parola
@@ -532,22 +544,28 @@ updateReminder.yesOnce=Da, o dată
updateReminder.yesAutomatically=Da, automat
#Dokany Support End
-dokanySupportEnd.description=Tipul de volum Dokany nu mai este suportat de Criptomator. Setările dvs. sunt ajustate pentru a utiliza acum tipul de volum implicit. Puteți vizualiza tipul implicit din preferințe.
+dokanySupportEnd.message=Se termină suportul pentru Dokany
+dokanySupportEnd.description=Tipul de volum Dokany nu mai este suportat de Cryptomator. Setările dumneavoastra sunt ajustate pentru a utiliza acum tipul de volum implicit. Puteți vizualiza tipul implicit din preferințe.
dokanySupportEnd.preferencesBtn=Deschideţi preferinţele
+#Retry If Readonly
+
# Share Vault
shareVault.title=Partajare seif
shareVault.message=Doriți să vă împărtășiți seiful cu ceilalți?
shareVault.description=Fiți întotdeauna precauți când împărtășiți seiful cu alte persoane. Pe scurt, urmați acești pași:
-shareVault.instruction.1=1. Partajarea accesului la folderul criptat din seif prin stocarea în cloud.
-shareVault.instruction.2=2. Partajează parola seifului într-un mod sigur.
+shareVault.instruction.1=1. Partajati accesul la folderul criptat din seif prin stocarea în cloud.
+shareVault.instruction.2=2. Partajati parola seifului într-un mod sigur.
shareVault.remarkBestPractices=Pentru mai multe informații, consultați cele mai bune practici sugerate în documentele noastre.
-shareVault.hubAd.description=Modul securizat de a lucra în echipe
-shareVault.hubAd.keyManagement=• Managementul cheie al cunoașterii spațiale
+shareVault.docsTooltip=Deschideți documentația pentru a afla mai multe despre tipurile diferite de unități de stocare.
+shareVault.hubAd.description=Modul securizat pentru a lucra în echipe
+shareVault.hubAd.keyManagement=Fara cunostinte despre managementul cheie.
shareVault.hubAd.authentication=• Autentificare puternică
shareVault.hubAd.encryption=• Criptare în ambele părți
-shareVault.visitHub=Vizitează Hub pentru Criptomator
+shareVault.visitHub=Vizitează Hub-ul Cryptomator
+shareVault.hub.message=Cum să partajezi un seif Hub
shareVault.hub.description=Pentru a partaja conținutul de seif cu un alt membru al echipei, trebuie să efectuați doi pași:
-shareVault.hub.instruction.1=1. Partajarea accesului la folderul criptat din seif prin stocarea în cloud.
-shareVault.hub.instruction.2=2. Acordă acces membrului echipei din hub-ul Cryptomator.
\ No newline at end of file
+shareVault.hub.instruction.1=1. Partajarea accesului la folderul criptat din seif prin stocarea in nor.
+shareVault.hub.instruction.2=2. Acordă acces membrului echipei din hub-ul Cryptomator.
+shareVault.hub.openHub=Deschide Cryptomator Hub
\ No newline at end of file
diff --git a/src/main/resources/i18n/strings_ru.properties b/src/main/resources/i18n/strings_ru.properties
index 7f5ab3c5d..381e5c737 100644
--- a/src/main/resources/i18n/strings_ru.properties
+++ b/src/main/resources/i18n/strings_ru.properties
@@ -13,6 +13,7 @@ generic.button.copied=Скопировано!
generic.button.done=Готово
generic.button.next=Далее
generic.button.print=Печать
+generic.button.remove=Удалить
# Error
error.message=Произошла ошибка
@@ -47,7 +48,7 @@ addvaultwizard.new.nameInstruction=Выберите имя для хранили
addvaultwizard.new.namePrompt=Имя хранилища
### Location
addvaultwizard.new.locationInstruction=Где Cryptomator должен хранить зашифрованные файлы хранилища?
-addvaultwizard.new.locationLoading=Поиск в локальной файловой системе облачных каталогов по умолчанию…
+addvaultwizard.new.locationLoading=Поиск облачных каталогов по умолчанию в локальной файловой системе…
addvaultwizard.new.locationLabel=Место хранения
addvaultwizard.new.locationPrompt=…
addvaultwizard.new.directoryPickerLabel=Другое место
@@ -60,7 +61,7 @@ addvaultwizard.new.locationIsOk=Подходящее расположение д
addvaultwizard.new.invalidName=Неверное имя хранилища
addvaultwizard.new.validName=Допустимое имя хранилища
addvaultwizard.new.validCharacters.message=Имя хранилища может содержать следующие символы:
-addvaultwizard.new.validCharacters.chars=Буквы (например, a, ж или 수)
+addvaultwizard.new.validCharacters.chars=Буквы (например: a, ж или 수)
addvaultwizard.new.validCharacters.numbers=Цифры
addvaultwizard.new.validCharacters.dashes=Дефис (%s) или подчёркивание (%s)
### Expert Settings
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Разблокировать
removeVault.title=Удалить "%s"
removeVault.message=Удалить хранилище?
removeVault.description=Cryptomator просто забудет это хранилище. Позже вы можете добавить его снова. Зашифрованные файлы не будут удалены с диска.
-removeVault.confirmBtn=Удалить хранилище
# Change Password
changepassword.title=Изменить пароль
@@ -124,8 +124,8 @@ unlock.passwordPrompt=Введите пароль для "%s"
unlock.savePassword=Запомнить пароль
unlock.unlockBtn=Разблокировать
## Select
-unlock.chooseMasterkey.message=Файл мастер-ключа не найден
-unlock.chooseMasterkey.description=Не удалось найти файл мастер-ключа для хранилища "%s". Выберите ключевой файл вручную.
+unlock.chooseMasterkey.message=Файл Masterkey не найден
+unlock.chooseMasterkey.description=Не удалось найти файл Masterkey для хранилища "%s". Выберите ключевой файл вручную.
unlock.chooseMasterkey.filePickerTitle=Выберите файл MasterKey
unlock.chooseMasterkey.filePickerMimeDesc=Мастер-ключ Cryptomator
## Success
@@ -152,7 +152,7 @@ hub.noKeychain.openBtn=Открыть настройки
### Waiting
hub.auth.message=Ожидание аутентификации…
hub.auth.description=Вы должны быть автоматически перенаправлены на страницу входа.
-hub.auth.loginLink=Не перенаправлено? Нажмите здесь, чтобы открыть её.
+hub.auth.loginLink=Перенаправления не произошло? Нажмите здесь, чтобы открыть её.
### Receive Key
hub.receive.message=Обработка ответа…
hub.receive.description=Cryptomator принимает и обрабатывает ответ от хаба. Подождите.
@@ -160,7 +160,7 @@ hub.receive.description=Cryptomator принимает и обрабатывае
hub.register.message=Новое устройство
hub.register.description=Это первый доступ к хабу с этого устройства. Авторизуйтесь, используя ваш ключ аккаунта.
hub.register.nameLabel=Имя устройства
-hub.register.invalidAccountKeyLabel=Неверный Account Key
+hub.register.invalidAccountKeyLabel=Неверный ключ учётной записи
hub.register.registerBtn=Регистрация
### Register Device Legacy
hub.register.legacy.occupiedMsg=Имя уже используется
@@ -175,8 +175,8 @@ hub.registerFailed.message=Ошибка регистрации устройст
hub.registerFailed.description.generic=Ошибка регистрации. Подробную информацию см. в журнале приложения.
hub.registerFailed.description.deviceAlreadyExists=Это устройство уже зарегистрировано другим пользователем. Попробуйте изменить учётную запись или используйте другое устройство.
### Unauthorized
-hub.unauthorized.message=Доступ запрещен
-hub.unauthorized.description=Устройство ещё не авторизовано для доступа к этому хранилищу. Попросите владельца хранилища разрешить его.
+hub.unauthorized.message=Нет доступа
+hub.unauthorized.description=Вы не авторизованы для открытия этого хранилища. Свяжитесь с владельцем хранилища, чтобы запросить доступ.
### Requires Account Initialization
hub.requireAccountInit.message=Требуется действие
hub.requireAccountInit.description.0=Для продолжения выполните необходимые шаги в
@@ -290,7 +290,7 @@ preferences.general.keychainBackend=Хранение паролей
preferences.general.quickAccessService=Добавлять открытые хранилища в область быстрого доступа
## Interface
preferences.interface=Интерфейс
-preferences.interface.theme=Отображение
+preferences.interface.theme=Тема
preferences.interface.theme.automatic=Автоматически
preferences.interface.theme.dark=Тёмная
preferences.interface.theme.light=Светлая
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Спонсировать
removeCert.title=Удалить сертификат
removeCert.message=Удалить сертификат поддержки?
removeCert.description=Ключевые функции криптоматора не затронуты этим. Ни один доступ к хранилищу не ограничен, уровень безопасности не снижен.
-removeCert.confirmBtn=Удалить
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Заканчивается поддержка для Do
dokanySupportEnd.description=Cryptomator больше не поддерживает тома Dokany. Параметры будут изменены на использование типа томов по умолчанию. Тип по умолчанию см. в настройках.
dokanySupportEnd.preferencesBtn=Открыть настройки
+#Retry If Readonly
+retryIfReadonly.title=Ограниченный доступ к хранилищу
+retryIfReadonly.message=Нет доступа на запись в каталог хранилища
+retryIfReadonly.description=Cryptomator не может выполнять запись в папку хранилища. Можно изменить у хранилища доступ только для чтения и повторить попытку. Эта опция может быть отключена в параметрах хранилища.
+retryIfReadonly.retry=Изменить и повторить
+
# Share Vault
shareVault.title=Поделиться хранилищем
shareVault.message=Хотите поделиться хранилищем с другими?
diff --git a/src/main/resources/i18n/strings_si.properties b/src/main/resources/i18n/strings_si.properties
index 06ed357c8..535e0dca0 100644
--- a/src/main/resources/i18n/strings_si.properties
+++ b/src/main/resources/i18n/strings_si.properties
@@ -135,4 +135,6 @@ hub.registerSuccess.unlockBtn=අගුළුහරින්න
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_sk.properties b/src/main/resources/i18n/strings_sk.properties
index 9d2752b2a..2dbc737d6 100644
--- a/src/main/resources/i18n/strings_sk.properties
+++ b/src/main/resources/i18n/strings_sk.properties
@@ -13,6 +13,7 @@ generic.button.copied=Skopírované!
generic.button.done=Hotovo
generic.button.next=Ďalej
generic.button.print=Tlač
+generic.button.remove=Odstrániť
# Error
error.message=Vyskytla sa chyba
@@ -104,7 +105,6 @@ addvaultwizard.success.unlockNow=Odomknúť teraz
removeVault.title=Odstrániť "%s"
removeVault.message=Odstrániť trezor?
removeVault.description=To spôsobí, že Cryptomator iba zabudne na tento trezor. Môžete ho pridať znova neskôr. Z pevného disku sa neodstránia žiadne šifrované súbory.
-removeVault.confirmBtn=Odstrániť trezor
# Change Password
changepassword.title=Zmeniť heslo
@@ -168,7 +168,6 @@ hub.registerSuccess.unlockBtn=Odomknúť
hub.registerFailed.message=Registrácia zariadenia zlyhala
### Unauthorized
hub.unauthorized.message=Prístup zamietnutý
-hub.unauthorized.description=Vaše zaradenie zatiaľ ešte nebolo autorizované pre pristúp tohto trezora. Požiadajte majiteľa trezora o autorizovanie.
### Requires Account Initialization
hub.requireAccountInit.message=Vyžadovaná akcia
hub.requireAccountInit.description.0=Pre pokračovanie vyplňte potrebné kroky vo vašom
@@ -335,7 +334,6 @@ preferences.contribute.sponsor=Sponzor
removeCert.title=Odstrániť certifikát
removeCert.message=Odstrániť certifikát podporovateľa?
removeCert.description=Funkcionality jadra Cryptomator-a nie sú týmto dotknuté. Žiadny pristúp do Vášho trezora ani úroveň zabezpečenia nie je znížená.
-removeCert.confirmBtn=Odstrániť
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -544,6 +542,8 @@ dokanySupportEnd.message=Ukončenie podpory pre Dokany
dokanySupportEnd.description=Typ média Dokany už Cryptomator viac nepodporuje. Vaše nastavenia sú nastavené používať základný typ média. Základný typ môžete vidieť v nastaveniach.
dokanySupportEnd.preferencesBtn=Otvoriť predvoľby
+#Retry If Readonly
+
# Share Vault
shareVault.title=Zdielať trezor
shareVault.hubAd.authentication=* Silná autentifikácia
diff --git a/src/main/resources/i18n/strings_sl.properties b/src/main/resources/i18n/strings_sl.properties
index af82b27e9..21f49fc5b 100644
--- a/src/main/resources/i18n/strings_sl.properties
+++ b/src/main/resources/i18n/strings_sl.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopirano!
generic.button.done=Opravljeno
generic.button.next=Naslednji
generic.button.print=Natisni
+generic.button.remove=Odstrani
# Error
error.message=Prišlo je do napake
@@ -116,7 +117,6 @@ preferences.updates.lastUpdateCheck.daysAgo=%s dni nazaj
## Contribution
### Remove License Key Dialog
-removeCert.confirmBtn=Odstrani
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -178,4 +178,6 @@ recoveryKey.recover.invalidKey=Obnovitveni ključ ni pravilen
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_sr.properties b/src/main/resources/i18n/strings_sr.properties
index 1cfdb5075..8a5c9ef99 100644
--- a/src/main/resources/i18n/strings_sr.properties
+++ b/src/main/resources/i18n/strings_sr.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopirano!
generic.button.done=Završeno
generic.button.next=Dalje
generic.button.print=Štampaj
+generic.button.remove=Уклони
# Error
@@ -77,7 +78,6 @@ addvaultwizard.success.unlockNow=Otključaj sada
# Remove Vault
removeVault.title=Ukloni sef
removeVault.description=Ovo će uraditi da Cryptomator zaboravi vaš sef. Uvek ga ponovo možete dodati kasnije. Šifrovane datoteke neće biti obrisane sa vašeg tvrdog diska.
-removeVault.confirmBtn=Ukloni sef
# Change Password
changepassword.title=Promena lozinke
@@ -179,7 +179,6 @@ preferences.contribute.getCertificate=Nemate sertifikat? Saznajte kako ga možet
preferences.contribute.promptText=Unesite vaš "Prijatelj Projekta" kod ovde
### Remove License Key Dialog
-removeCert.confirmBtn=Уклони
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -323,4 +322,6 @@ quit.lockAndQuitBtn=Zaključaj i Izađi
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_sr_Latn.properties b/src/main/resources/i18n/strings_sr_Latn.properties
index 13a7ddc6e..c05c42e36 100644
--- a/src/main/resources/i18n/strings_sr_Latn.properties
+++ b/src/main/resources/i18n/strings_sr_Latn.properties
@@ -74,7 +74,6 @@ addvaultwizard.success.nextStepsInstructions=Dodat je sef "%s".\nMorate da otklj
addvaultwizard.success.unlockNow=Otključaj sada
# Remove Vault
-removeVault.confirmBtn=Ukloni sef
# Change Password
changepassword.title=Promena lozinke
@@ -242,4 +241,6 @@ vaultOptions.masterkey.changePasswordBtn=Promena lozinke
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_sv.properties b/src/main/resources/i18n/strings_sv.properties
index 860b5f71e..79735b489 100644
--- a/src/main/resources/i18n/strings_sv.properties
+++ b/src/main/resources/i18n/strings_sv.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopierad!
generic.button.done=Klar
generic.button.next=Nästa
generic.button.print=Skriv ut
+generic.button.remove=Radera
# Error
error.message=Fel: %s
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Lås upp nu
removeVault.title=Ta bort valv
removeVault.message=Ta bort valv?
removeVault.description=Detta kommer bara ta bort valvet från Cryptomator. Du kan lägga till det igen senare. Inga krypterade filer kommer tas bort från din hårddisk.
-removeVault.confirmBtn=Ta bort valv
# Change Password
changepassword.title=Ändra lösenord
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Ett fel uppstod i registreringsprocessen.
hub.registerFailed.description.deviceAlreadyExists=Denna enhet är redan registrerad för en annan användare. Försök att ändra användarkontot eller använda en annan enhet.
### Unauthorized
hub.unauthorized.message=Åtkomst nekad
-hub.unauthorized.description=Din enhet har ännu inte behörighet att komma åt detta valv. Be valvägaren att godkänna det.
+hub.unauthorized.description=Du har inte behörighet att öppna detta valv. Kontakta valvets ägare för att begära åtkomst.
### Requires Account Initialization
hub.requireAccountInit.message=Åtgärd krävs
hub.requireAccountInit.description.0=För att fortsätta, vänligen fyll i de steg som krävs i din
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Sponsor
removeCert.title=Ta bort certifikat
removeCert.message=Ta bort supportercertifikat?
removeCert.description=Cryptomators kärnfunktioner påverkas inte av detta. Åtkomst till dina valv begränsas inte och säkerhetsnivån sänks inte.
-removeCert.confirmBtn=Ta bort
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Dokany stöds inte längre
dokanySupportEnd.description=Volymtypen Dokany stöds inte längre av Cryptomator. Dina inställningar justeras för att använda standardvolymtypen nu. Du kan visa standardtypen i inställningarna.
dokanySupportEnd.preferencesBtn=Gå till inställningarna
+#Retry If Readonly
+retryIfReadonly.title=Begränsad valvåtkomst
+retryIfReadonly.message=Ingen skrivbehörighet till valvkatalogen
+retryIfReadonly.description=Cryptomator kan inte skriva till valvkatalogen. Du kan ändra valvet till att vara skrivskyddad och försök igen. Det här alternativet kan inaktiveras i valvalternativen.
+retryIfReadonly.retry=Ändra och försök igen
+
# Share Vault
shareVault.title=Dela valv
shareVault.message=Vill du dela ditt valv med andra?
diff --git a/src/main/resources/i18n/strings_sw.properties b/src/main/resources/i18n/strings_sw.properties
index 4cdadc28a..84f640b03 100644
--- a/src/main/resources/i18n/strings_sw.properties
+++ b/src/main/resources/i18n/strings_sw.properties
@@ -13,6 +13,7 @@ generic.button.copied=Nakiliwa!
generic.button.done=Tayari
generic.button.next=Nyingine
generic.button.print=Chapisha
+generic.button.remove=Ondoa
# Error
error.message=Kosa %s
@@ -92,7 +93,6 @@ addvaultwizard.success.unlockNow=Fungua Sasa
removeVault.title=Ondoa Kuba
removeVault.message=Ungependa kuondoa kuba?
removeVault.description=Hii itafanya tu Cryptomator kusahau kuhusu kuba hii. Unaweza kuiongeza tena baadaye. Hakuna faili zilizosimbwa kwa njia fiche zitafutwa kutoka kwenye diski yako kuu.
-removeVault.confirmBtn=Ondoa Kuba
# Change Password
changepassword.title=Badilisha Neno la siri
@@ -143,7 +143,6 @@ hub.registerSuccess.unlockBtn=Fungua
### Registration Failed
### Unauthorized
hub.unauthorized.message=Ufikiaji umekataliwa
-hub.unauthorized.description=Kifaa chako bado hakijaidhinishwa kufikia kuba hii. Uliza mwenye kuba aidhinishe.
### Requires Account Initialization
### License Exceeded
hub.invalidLicense.message=Leseni ya Hub ni batili
@@ -288,7 +287,6 @@ preferences.contribute.getCertificate=Je, si kuwa na moja tayari? Jifunze jinsi
preferences.contribute.promptText=Bandika msimbo wa cheti cha msaidizi hapa
### Remove License Key Dialog
-removeCert.confirmBtn=Ondoa
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -470,4 +468,6 @@ quit.forced.forceAndQuitBtn=Lazimisha na Uache
#Dokany Support End
dokanySupportEnd.preferencesBtn=Fungua Mapendeleo
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_ta.properties b/src/main/resources/i18n/strings_ta.properties
index cf72b3f16..d8359bdb0 100644
--- a/src/main/resources/i18n/strings_ta.properties
+++ b/src/main/resources/i18n/strings_ta.properties
@@ -13,6 +13,7 @@ generic.button.copied=நகலெடுக்கப்பட்டது!
generic.button.done=முடிந்தது
generic.button.next=அடுத்து
generic.button.print=அச்சிடு
+generic.button.remove=நீக்கு
# Error
error.message=ஒரு பிழை ஏற்பட்டுள்ளது
@@ -86,7 +87,6 @@ addvaultwizard.success.unlockNow=இப்போது திறக்கவு
removeVault.title="%s" ஐ அகற்று
removeVault.message=பெட்டகத்தை அகற்றவா?
removeVault.description=இது Cryptomator -ஐ இந்தப் பெட்டகத்தை மறக்க மட்டும் செய்யும். நீங்கள் அதை மீண்டும் சேர்க்கலாம். உங்கள் ஹார்ட் டிரைவிலிருந்து குறியாக்கம் செய்யப்பட்ட கோப்புகள் எதுவும் நீக்கப்படாது.
-removeVault.confirmBtn=பெட்டகத்தை அகற்றவும்
# Change Password
changepassword.title=கடவுச்சொல்லை மாற்று
@@ -190,7 +190,6 @@ preferences.interface.theme.light=வெளிச்சம்
## Contribution
### Remove License Key Dialog
-removeCert.confirmBtn=நீக்கு
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -306,4 +305,6 @@ quit.forced.forceAndQuitBtn=கட்டாயப்படுத்தி வெ
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_te.properties b/src/main/resources/i18n/strings_te.properties
index 48bb4423d..4555a9cda 100644
--- a/src/main/resources/i18n/strings_te.properties
+++ b/src/main/resources/i18n/strings_te.properties
@@ -2,6 +2,7 @@
# Generics
## Button
+generic.button.remove=తొలగించు
# Error
@@ -71,7 +72,6 @@ preferences.interface.theme.light=కాంతి
## Contribution
### Remove License Key Dialog
-removeCert.confirmBtn=తొలగించు
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -122,4 +122,6 @@ removeCert.confirmBtn=తొలగించు
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_th.properties b/src/main/resources/i18n/strings_th.properties
index 7072367d9..2f57abf4e 100644
--- a/src/main/resources/i18n/strings_th.properties
+++ b/src/main/resources/i18n/strings_th.properties
@@ -13,6 +13,7 @@ generic.button.copied=คัดลอกแล้ว!
generic.button.done=เสร็จสิ้น
generic.button.next=ถัดไป
generic.button.print=พิมพ์
+generic.button.remove=ลบ
# Error
error.message=เกิดข้อผิดพลาด
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=ปลดล็อกตอนนี้
removeVault.title=ลบ "%s"
removeVault.message=ลบ Vault หรือไม่?
removeVault.description=นี่จะทำให้ Cryptomator ลืมเกี่ยวกับ vault นี้เท่านั้น คุณสามารถเพิ่มมันอีกครั้งได้ ไม่มีไฟล์ที่เข้ารหัสจะถูกลบจากฮาร์ดดิสก์ของคุณ
-removeVault.confirmBtn=ลบ Vault
# Change Password
changepassword.title=เปลี่ยนรหัสผ่าน
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=เกิดข้อผิดพลา
hub.registerFailed.description.deviceAlreadyExists=อุปกรณ์นี้ลงทะเบียนไว้แล้วสำหรับผู้ใชอื่น โปรดลองเปลี่ยนบัญชีผู้ใช้หรือลงทะเบียนอุปกรณ์อื่น
### Unauthorized
hub.unauthorized.message=การเข้าถึงถูกปฏิเสธ
-hub.unauthorized.description=อุปกรณ์ของคุณยังไม่ได้รับการอนุญาตให้เข้าถึง vault นี้ โปรดขอให้เจ้าของ vault อนุญาต
### Requires Account Initialization
hub.requireAccountInit.message=โปรดดำเนินการ
hub.requireAccountInit.description.0=เพื่อดำเนินการต่อ โปรดทำตามขั้นตอนที่จำเป็นใน
@@ -292,7 +291,6 @@ preferences.updates.lastUpdateCheck.hoursAgo=%s ชั่วโมงที่
preferences.contribute=สนับสนุนเรา
### Remove License Key Dialog
-removeCert.confirmBtn=ลบ
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -446,6 +444,8 @@ updateReminder.yesAutomatically=ตกลง, ตรวจสอบอัปเ
dokanySupportEnd.title=หมายเหตุการเลิกใช้งาน
dokanySupportEnd.preferencesBtn=การตั้งค่า
+#Retry If Readonly
+
# Share Vault
shareVault.title=แชร์ Vault
shareVault.hubAd.authentication=• การพิสูจน์ตัวตนที่เข้มงวด
diff --git a/src/main/resources/i18n/strings_tr.properties b/src/main/resources/i18n/strings_tr.properties
index 57b0c0f50..4f7ed1ab4 100644
--- a/src/main/resources/i18n/strings_tr.properties
+++ b/src/main/resources/i18n/strings_tr.properties
@@ -13,6 +13,7 @@ generic.button.copied=Kopyalandı!
generic.button.done=Tamam
generic.button.next=İleri
generic.button.print=Yazdır
+generic.button.remove=Kaldır
# Error
error.message=Bir hata oluştu
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=Kilidi Şimdi Aç
removeVault.title="%s" Kasasını Sil
removeVault.message=Kasa silinsin mi?
removeVault.description=Bu, yalnızca Cryptomator'ın bu kasayı unutmasını sağlar. Daha sonra tekrar ekleyebilirsiniz. Şifrelenmiş hiçbir dosya sabit diskinizden silinmez.
-removeVault.confirmBtn=Kasayı Sil
# Change Password
changepassword.title=Parolayı Değiştir
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=Kayıt işleminde bir hata oluştu. Daha
hub.registerFailed.description.deviceAlreadyExists=Bu cihaz zaten farklı bir kullanıcı için kayıtlı. Kullanıcı hesabını değiştirmeyi veya farklı bir cihaz kullanmayı deneyin.
### Unauthorized
hub.unauthorized.message=Erişim engellendi
-hub.unauthorized.description=Cihazınız henüz bu kasaya erişim için yetkilendirilmedi. Kasa sahibinden yetkilendirmesini isteyin.
+hub.unauthorized.description=Bu kasayı açma yetkiniz yok. Erişim talebinde bulunmak için kasanın sahibiyle iletişime geçin.
### Requires Account Initialization
hub.requireAccountInit.message=Eylem gerekli
hub.requireAccountInit.description.0=Devam etmek için lütfen gerekli adımları tamamlayın
@@ -343,7 +343,6 @@ preferences.contribute.sponsor=Destekçi
removeCert.title=Sertifikayı Kaldır
removeCert.message=Destekçi sertifikası kaldırılsın mı?
removeCert.description=Cryptomator'ın temel özellikleri bundan etkilenmez. Ne kasalarınıza erişim kısıtlanır, ne de güvenlik seviyesi düşürülür.
-removeCert.confirmBtn=Kaldır
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +552,12 @@ dokanySupportEnd.message=Dokany için destek sonu
dokanySupportEnd.description=Dokany birim türü artık Cryptomator tarafından desteklenmiyor. Ayarlarınız varsayılan birim türünü kullanacak şekilde değiştirilmiştir. Varsayılan birim türünü tercihlerde görüntüleyebilirsiniz.
dokanySupportEnd.preferencesBtn=Tercihleri Aç
+#Retry If Readonly
+retryIfReadonly.title=Kısıtlı Kasa Erişimi
+retryIfReadonly.message=Kasa dizinine yazma erişimi yok
+retryIfReadonly.description=Cryptomator kasa dizinine yazamıyor. Kasayı salt okunur olarak değiştirebilir ve tekrar deneyebilirsiniz. Bu seçenek kasa seçeneklerinden devre dışı bırakılabilir.
+retryIfReadonly.retry=Değiştir ve Yeniden Dene
+
# Share Vault
shareVault.title=Kasayı Paylaş
shareVault.message=Kasanızı başkalarıyla paylaşmak ister misiniz?
diff --git a/src/main/resources/i18n/strings_ug.properties b/src/main/resources/i18n/strings_ug.properties
index 34786b1ca..1b6ad1c69 100644
--- a/src/main/resources/i18n/strings_ug.properties
+++ b/src/main/resources/i18n/strings_ug.properties
@@ -105,7 +105,6 @@ addvaultwizard.success.unlockNow=ھازىر قۇلۇپسىزلا
removeVault.title=»%s« نى چىقىرىۋەت
removeVault.message=ئامبارنى چىقىرىۋېتەمسىز؟
removeVault.description=بۇ پەقەت Cryptomator نىڭ بۇ ئامبارنى ئۇنتۇشىغا سەۋەب بولىدۇ. سىز ئۇنى قايتا قوشالايسىز. قاتتىق دىسكىڭىزدىكى شىفىرلانغان ھۆججەتلەر ئۆچۈرۈلمەيدۇ.
-removeVault.confirmBtn=ئامبارنى ئۆچۈرۈش
# Change Password
changepassword.title=پارولنى ئۆزگەرتىش
@@ -176,7 +175,6 @@ hub.registerFailed.description.generic=تىزىملىتىش جەريانىدا
hub.registerFailed.description.deviceAlreadyExists=بۇ ئۈسكۈنە ئاللىقاچان باشقا بىر ئىشلەتكۈچى ئۈچۈن تىزىملانغان. ئىشلەتكۈچى ھېساباتىنى ئۆزگەرتىشكە ئۇرۇنۇڭ ياكى باشقا بىر ئۈسكۈنە ئىشلىتىڭ.
### Unauthorized
hub.unauthorized.message=كىرىش رەت قىلىندى
-hub.unauthorized.description=ئۈسكۈنىڭىز تېخى بۇ ئامبارغا كىرىشكە ھوقۇقلاندۇرۇلمىغان. ئامبار ئىگىسىدىن ھوقۇقلاندۇرۇشنى تەلەپ قىلىڭ.
### Requires Account Initialization
hub.requireAccountInit.message=مەشغۇلات تەلەپ قىلىنىدۇ
hub.requireAccountInit.description.0=داۋاملاشتۇرۇش ئۈچۈن، سىزنىڭ
@@ -541,6 +539,8 @@ dokanySupportEnd.message=Dokany نىڭ قوللاش مۇھلىتى توشتى
dokanySupportEnd.description=Dokany نىڭ قۇۋۋەت شەكلى Cryptomator تەرەپدىن ئاندىن قوللانمايدۇ. سەپلىمىلىرىڭىز ھازىر ئاساسىي قۇۋۋەت شەكلىگە ماسلاشتى. ئاساسىي شەكلىنى تەڭشەشتىن كۆرەلەيسىز.
dokanySupportEnd.preferencesBtn=سەپلىمىلەرنى ئېچىش
+#Retry If Readonly
+
# Share Vault
shareVault.title=ئامبارنى ھەمبەھىرلەش
shareVault.message=بۇ ئامبارنى باشقىلار بىلەن ھەمبەھىرلەشنى خالامسىز ؟
diff --git a/src/main/resources/i18n/strings_uk.properties b/src/main/resources/i18n/strings_uk.properties
index 675160860..f23de9ca0 100644
--- a/src/main/resources/i18n/strings_uk.properties
+++ b/src/main/resources/i18n/strings_uk.properties
@@ -14,6 +14,7 @@ generic.button.copied=Скопійовано!
generic.button.done=Завершити
generic.button.next=Далі
generic.button.print=Друкувати
+generic.button.remove=Прибрати
# Error
error.message=Сталася помилка
@@ -106,7 +107,6 @@ addvaultwizard.success.unlockNow=Розблокувати
removeVault.title=Видалити "%s"
removeVault.message=Видалити сховище?
removeVault.description=Це лише змусить Cryptomator забути про це сховище. Його можна буде додати знову пізніше. Зашифровані файли на вашому жорсткому диску не буде втрачено.
-removeVault.confirmBtn=Видалити сховище
# Change Password
changepassword.title=Зміна паролю
@@ -177,7 +177,6 @@ hub.registerFailed.description.generic=Помилка виникла у проц
hub.registerFailed.description.deviceAlreadyExists=Цей пристрій вже зареєстровано для іншого користувача. Спробуйте змінити обліковий запис користувача або скористайтеся іншим пристроєм.
### Unauthorized
hub.unauthorized.message=У доступі відмовлено
-hub.unauthorized.description=Ваш пристрій ще не має прав доступу до цього сховища. Попросіть власника сховища дозволити доступ.
### Requires Account Initialization
hub.requireAccountInit.message=Необхідна дія
hub.requireAccountInit.description.0=Для продовження, будь ласка, завершіть виконання обов'язкових кроків
@@ -302,6 +301,7 @@ preferences.interface.interfaceOrientation=Відображення елемен
preferences.interface.interfaceOrientation.ltr=Зліва направо
preferences.interface.interfaceOrientation.rtl=Справа наліво
preferences.interface.showTrayIcon=Показувати піктограму на панелі завдань (потрібен перезапуск)
+preferences.interface.compactMode=Активувати компактний список сховищ
## Volume
preferences.volume=Віртуальний диск
preferences.volume.type=Тип тому за замовчуванням
@@ -335,9 +335,14 @@ preferences.contribute.registeredFor=Сертифікат помічника з
preferences.contribute.noCertificate=Підтримайте Cryptomator та отримайте сертифікат помічника - це як ліцензійний ключ, але для чудових людей, які користуються безкоштовним програмним забезпеченням. ;-)
preferences.contribute.getCertificate=Ще немає такого? Дізнайтеся, як його отримати.
preferences.contribute.promptText=Вставте код сертифікату помічника тут
+preferences.contribute.thankYou=Дякуємо, що підтримуєте розробку Cryptomator з відкритим вихідним кодом!
+preferences.contribute.donate=Підтримати
+preferences.contribute.sponsor=Спонсор
### Remove License Key Dialog
-removeCert.confirmBtn=Прибрати
+removeCert.title=Видалити сертифікат
+removeCert.message=Видалити сертифікат помічника?
+removeCert.description=Основний функціонал Cryptomator не змінюється. Ні доступ до вашого сховища, а ні рівень безпеки не буде понижено/обмежено.
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -387,7 +392,11 @@ main.vaultlist.contextMenu.unlock=Розблокувати…
main.vaultlist.contextMenu.unlockNow=Розблокувати
main.vaultlist.contextMenu.vaultoptions=Показати параметри сховища
main.vaultlist.contextMenu.reveal=Розгорнути диск
+main.vaultlist.addVaultBtn.menuItemNew=Створити нове сховище...
+main.vaultlist.addVaultBtn.menuItemExisting=Відкрити наявне сховище...
##Notificaition
+main.notification.updateAvailable=Оновлення доступне.
+main.notification.support=Підтримайте Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Дякуємо, що обрали Cryptomator для захисту ваших файлів. Якщо вам потрібна допомога, перегляньте наші інструкції з роботи:
@@ -543,6 +552,8 @@ dokanySupportEnd.message=Закінчення підтримки Dokany
dokanySupportEnd.description=Тип сховища Dokany більше не підтримується в Cryptomator. Тепер ваші налаштування змінено для використання типового типу сховища. Ви можете переглянути тип сховища за замовчуванням в налаштуваннях.
dokanySupportEnd.preferencesBtn=Відкрити налаштування
+#Retry If Readonly
+
# Share Vault
shareVault.title=Поділитися сховищем
shareVault.message=Ви хочете поділитися своїм сховищем з іншими?
diff --git a/src/main/resources/i18n/strings_ur.properties b/src/main/resources/i18n/strings_ur.properties
index 125593fee..16d2016cd 100644
--- a/src/main/resources/i18n/strings_ur.properties
+++ b/src/main/resources/i18n/strings_ur.properties
@@ -118,4 +118,6 @@
#Dokany Support End
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_vi.properties b/src/main/resources/i18n/strings_vi.properties
index 4e5c841f1..77fab0701 100644
--- a/src/main/resources/i18n/strings_vi.properties
+++ b/src/main/resources/i18n/strings_vi.properties
@@ -13,6 +13,7 @@ generic.button.copied=Đã sao chép!
generic.button.done=Hoàn thành
generic.button.next=Tiếp
generic.button.print=In
+generic.button.remove=Xóa
# Error
error.message=Đã xảy ra lỗi
@@ -104,7 +105,6 @@ addvaultwizard.success.unlockNow=Mở khóa bây giờ
removeVault.title=Xóa Vault
removeVault.message=Xoá vault?
removeVault.description=Điều này sẽ chỉ làm cho Cryptomator quên đi vault này. Bạn có thể thêm lại sau. Không có tệp được mã hóa nào sẽ bị xóa khỏi ổ cứng của bạn.
-removeVault.confirmBtn=Xóa Vault
# Change Password
changepassword.title=Đổi mật khẩu
@@ -163,7 +163,6 @@ hub.registerSuccess.unlockBtn=Mở khoá
hub.registerFailed.message=Đăng ký thiết bị thất bại
### Unauthorized
hub.unauthorized.message=Truy cập bị từ chối
-hub.unauthorized.description=Thiết bị của bạn chưa được phép truy cập vault này. Yêu cầu chủ sở hữu cấp phép.
### Requires Account Initialization
### License Exceeded
hub.invalidLicense.message=Giấy phép Hub không hợp lệ
@@ -314,7 +313,6 @@ preferences.contribute.getCertificate=Bạn chưa có? Tìm hiểu cách bạn c
preferences.contribute.promptText=Vui lòng dán mã chứng nhận người hỗ trợ vào đây
### Remove License Key Dialog
-removeCert.confirmBtn=Xóa
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -514,6 +512,8 @@ dokanySupportEnd.title=Thông báo ngừng phát triển
dokanySupportEnd.message=Kết thúc hỗ trợ cho Dokany
dokanySupportEnd.preferencesBtn=Mở Tuỳ chọn
+#Retry If Readonly
+
# Share Vault
shareVault.title=Chia sẻ Vault
shareVault.hubAd.description=Cách an toàn để làm việc theo nhóm
diff --git a/src/main/resources/i18n/strings_zh.properties b/src/main/resources/i18n/strings_zh.properties
index 34c254ce9..c5c798f2b 100644
--- a/src/main/resources/i18n/strings_zh.properties
+++ b/src/main/resources/i18n/strings_zh.properties
@@ -13,14 +13,15 @@ generic.button.copied=已复制!
generic.button.done=完成
generic.button.next=下一步
generic.button.print=打印
+generic.button.remove=删除
# Error
error.message=发生错误
-error.description=糟糕!Cryptomator 未料到会发生这种情况。您可以查找该错误的现有解决方案;或者,如果是新错误,请随时向我们报告。
+error.description=Cryptomator 没有预料到这种情况。您可以查找该错误的现有解决方案;或者,如果是新错误,请随时向我们报告。
error.hyperlink.lookup=查找该错误
error.hyperlink.report=报告该错误
error.technicalDetails=详细信息:
-error.existingSolutionDescription=Cryptomator 没有预料到会发生这种情况。但我们找到了一个现有的解决方案来解决这个错误。请查看以下链接。
+error.existingSolutionDescription=Cryptomator 没有预料到这种情况,但我们找到了一个现有的解决方案来解决这个错误。请查看以下链接。
error.hyperlink.solution=查找解决方案
error.lookupPermissionMessage=Cryptomator 可以在线查找这个问题的解决方案。这将从您的IP地址向我们的问题数据库发送一个请求。
error.dismiss=放弃
@@ -102,10 +103,9 @@ addvaultwizard.success.nextStepsInstructions=已添加保险库 "%s"\n您需要
addvaultwizard.success.unlockNow=立即解锁
# Remove Vault
-removeVault.title=移除保险库
+removeVault.title=删除“%s”
removeVault.message=删除保险库?
removeVault.description=这将只会使 Cryptomator 忘记这个保险库,您可以稍后再添加它。任何加密的文件不会从您的硬盘中删除。
-removeVault.confirmBtn=移除保险库
# Change Password
changepassword.title=更改密码
@@ -130,12 +130,12 @@ unlock.chooseMasterkey.filePickerTitle=选择 Masterkey 文件
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator 主密钥
## Success
unlock.success.message=解锁成功
-unlock.success.description=已成功解锁 "%s"! 您现在可以通过其虚拟驱动器访问它
+unlock.success.description=保险库中的内容 "%s" 现在可以通过其挂载点访问。
unlock.success.rememberChoice=记住选项且不再显示
unlock.success.revealBtn=显示驱动器
## Failure
unlock.error.customPath.message=无法将保险库挂载到自定义路径
-unlock.error.customPath.description.notSupported=如果您仍想使用自定义路径,请转至首选项并选择支持它的卷类型。否则,请转至保险库选项并选择受支持的挂载点
+unlock.error.customPath.description.notSupported=如果您仍想使用自定义路径,请转至首选项并选择支持它的卷类型。否则,请转至保险库选项并选择受支持的挂载点。
unlock.error.customPath.description.notExists=自定义挂载路径不存在,请在您的本地文件系统中创建它或在保险库选项中进行更改
unlock.error.customPath.description.inUse=盘符或自定义挂载路径「%s」已被使用。
unlock.error.customPath.description.hideawayNotDir=用于解锁的临时隐藏文件 "%3$s" 无法被删除。请检查此文件并手动删除
@@ -176,7 +176,7 @@ hub.registerFailed.description.generic=注册过程中出现错误。详情请
hub.registerFailed.description.deviceAlreadyExists=此设备已被注册给另一位用户。请尝试更改用户帐户或使用别的设备。
### Unauthorized
hub.unauthorized.message=拒绝访问
-hub.unauthorized.description=您的设备尚未授权访问此保险库,请联系保险库所有者,
+hub.unauthorized.description=您无权打开此保险库。请联系保险库的所有者以请求访问。
### Requires Account Initialization
hub.requireAccountInit.message=操作请求
hub.requireAccountInit.description.0=要继续,请完成所需的步骤
@@ -301,6 +301,7 @@ preferences.interface.interfaceOrientation=界面方向
preferences.interface.interfaceOrientation.ltr=从左到右
preferences.interface.interfaceOrientation.rtl=从右到左
preferences.interface.showTrayIcon=显示托盘图标(需重启)
+preferences.interface.compactMode=启用紧凑保险库列表视图
## Volume
preferences.volume=虚拟磁盘
preferences.volume.type=默认卷类型
@@ -334,9 +335,14 @@ preferences.contribute.registeredFor=已为 %s 注册支持者证书
preferences.contribute.noCertificate=支持 Cryptomator 并获得一份支持者证书。它类似于许可证密钥,特别之处是提供给使用免费软件的牛人的 ;-)
preferences.contribute.getCertificate=还没有该证书吗?了解您如何获取
preferences.contribute.promptText=在这里粘贴赞助者证书码
+preferences.contribute.thankYou=感谢您支持 Cryptomator 开源项目!
+preferences.contribute.donate=捐赠
+preferences.contribute.sponsor=赞助
### Remove License Key Dialog
-removeCert.confirmBtn=删除
+removeCert.title=删除证书
+removeCert.message=删除支持者证书?
+removeCert.description=Cryptomator 的核心功能不会受此影响。您对保险库的访问不会受到限制,安全级别也不会降低
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -386,7 +392,11 @@ main.vaultlist.contextMenu.unlock=解锁…
main.vaultlist.contextMenu.unlockNow=立即解锁
main.vaultlist.contextMenu.vaultoptions=显示保险库选项
main.vaultlist.contextMenu.reveal=显示驱动器
+main.vaultlist.addVaultBtn.menuItemNew=新建保险库...
+main.vaultlist.addVaultBtn.menuItemExisting=打开现有的保险库...
##Notificaition
+main.notification.updateAvailable=发现新版本
+main.notification.support=支持 Cryptomator
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=感谢您使用 Cryptomator 来保护您的文件。如果您需要任何帮助,请查看我们的快速开始指南:
@@ -457,7 +467,7 @@ vaultOptions.mount.customMountFlags=自定义挂载标志
vaultOptions.mount.winDriveLetterOccupied=已占用
vaultOptions.mount.mountPoint=挂载点
vaultOptions.mount.mountPoint.auto=自动选择一个合适的位置
-vaultOptions.mount.mountPoint.driveLetter=使用分配的驱动器字符
+vaultOptions.mount.mountPoint.driveLetter=使用分配的盘符
vaultOptions.mount.mountPoint.custom=使用选定的目录
vaultOptions.mount.mountPoint.directoryPickerButton=选择...
vaultOptions.mount.mountPoint.directoryPickerTitle=选择目录
@@ -542,6 +552,8 @@ dokanySupportEnd.message=对 Dokany 的支持已终止
dokanySupportEnd.description=Cryptomator 不再支持 Dokany 卷类型。您的设置现已调整为使用默认卷类型。您可以在偏好设置中查看默认类型。
dokanySupportEnd.preferencesBtn=打开首选项
+#Retry If Readonly
+
# Share Vault
shareVault.title=共享保险库
shareVault.message=是否要与他人共享你的保险库?
diff --git a/src/main/resources/i18n/strings_zh_HK.properties b/src/main/resources/i18n/strings_zh_HK.properties
index c0ad4805e..78dc9c25f 100644
--- a/src/main/resources/i18n/strings_zh_HK.properties
+++ b/src/main/resources/i18n/strings_zh_HK.properties
@@ -13,6 +13,7 @@ generic.button.copied=已複製!
generic.button.done=完成
generic.button.next=繼續
generic.button.print=列印
+generic.button.remove=移除
# Error
error.message=發生錯誤
@@ -22,6 +23,9 @@ error.hyperlink.report=報告此錯誤
error.technicalDetails=詳情:
error.existingSolutionDescription=Cryptomator 沒有預料到會發生這種情況。但我們找到了一個現有的解決方案來解決這個錯誤。請查看以下連結。
error.hyperlink.solution=尋找解決方案
+error.lookupPermissionMessage=Cryptomator 可以在線查找此問題的解決方案。這將從您的 IP 地址發送請求至我們的問題資料庫。
+error.dismiss=忽略
+error.lookUpSolution=查找解決方案
# Defaults
defaults.vault.vaultName=加密庫
@@ -38,11 +42,13 @@ traymenu.vault.reveal=展示
# Add Vault Wizard
addvaultwizard.title=新增加密庫
## New
+addvaultwizard.new.title=新增加密檔案庫
### Name
addvaultwizard.new.nameInstruction=為加密庫命名
addvaultwizard.new.namePrompt=加密庫名稱
### Location
addvaultwizard.new.locationInstruction=Cryptomator 應該把加密後的檔案儲存在哪裏?
+addvaultwizard.new.locationLoading=正在檢查本地檔案系統中的預設雲端儲存目錄…
addvaultwizard.new.locationLabel=儲存位置
addvaultwizard.new.locationPrompt=…
addvaultwizard.new.directoryPickerLabel=自訂位置
@@ -87,6 +93,7 @@ addvault.new.readme.accessLocation.2=這是你加密庫的存取位置。
addvault.new.readme.accessLocation.3=所有被加進這個空間的檔案都會被 Cryptomator 加密。你可以把它當做磁碟或資料夾使用。這裡僅顯示出解密後內容,而你在此儲存的檔案總會以加密狀態儲存在磁碟中。
addvault.new.readme.accessLocation.4=你可以放心移除這個檔案。
## Existing
+addvaultwizard.existing.title=新增現有加密檔案庫
addvaultwizard.existing.instruction=請選擇現有加密庫中名為「vault.cryptomator」的檔案。如果只有一個名為「masterkey.cryptomator」的檔案,則選擇該檔案。
addvaultwizard.existing.chooseBtn=選取…
addvaultwizard.existing.filePickerTitle=選取加密庫檔案
@@ -99,7 +106,6 @@ addvaultwizard.success.unlockNow=立即解鎖
removeVault.title=移除加密庫:%s
removeVault.message=移除加密庫?
removeVault.description=這只會讓 Cryptomator 忘記這個加密庫。你可以之後再重新加入。已加密的檔案將不會從硬碟中移除。
-removeVault.confirmBtn=移除加密庫
# Change Password
changepassword.title=更改密碼
@@ -132,9 +138,13 @@ unlock.error.customPath.message=無法掛載加密庫於此自定路徑
unlock.error.customPath.description.notSupported=若要繼續使用自定路徑,請在設定選取支援此自定路徑的空間/加密空間類型;或者,在加密庫選項中選擇一個受支援的掛載點。
unlock.error.customPath.description.notExists=自定路徑不存在。請在本機文件系統指定另一路徑或在加密庫選項中變更。
unlock.error.customPath.description.inUse=磁碟代號或自訂掛載路徑「%s」已被使用。
+unlock.error.customPath.description.hideawayNotDir=用於解鎖的臨時隱藏檔案"%3$s"無法刪除。請檢查該檔案並手動刪除。
unlock.error.customPath.description.couldNotBeCleaned=無法將您的保險庫掛載至路徑「%s」。請再試一次或選擇不同的路徑。
unlock.error.customPath.description.notEmptyDir=自訂掛載路徑「%s」不是一個空資料夾。請選擇一個空資料夾並重試。
unlock.error.customPath.description.generic=您為此保險庫選擇了自訂掛載路徑,但使用時出現了錯誤訊息:%2$s
+unlock.error.restartRequired.message=無法解鎖加密檔案庫
+unlock.error.restartRequired.description=在加密檔案庫選項中更改磁碟區類型或重新啟動 Cryptomator。
+unlock.error.title=解鎖"%s"失敗
## Hub
hub.noKeychain.message=無法訪問設備密鑰
hub.noKeychain.description=為了解鎖 Hub 加密檔案庫需要一個裝置密鑰,該密鑰已被安全地保管在鑰匙串中。為了繼續進行,請啟用「%s」並在偏好設定中選擇一個鑰匙串。
@@ -147,15 +157,30 @@ hub.auth.loginLink=未被轉送?點擊這裡打開
hub.receive.message=正在處理程式回應…
hub.receive.description=Cryptomator正在接收並處理來自Hub的回應。 請等待。
### Register Device
+hub.register.message=新裝置
+hub.register.description=這是此裝置的第一次 Hub 存取。請使用您的帳戶密鑰註冊。
hub.register.nameLabel=設備名稱
+hub.register.invalidAccountKeyLabel=無效的帳戶密鑰
+hub.register.registerBtn=註冊
### Register Device Legacy
+hub.register.legacy.occupiedMsg=名稱已被使用
+hub.register.legacy.description=這是此裝置的第一次 Hub 存取。請註冊它。
### Registration Success
+hub.registerSuccess.message=裝置已註冊
+hub.registerSuccess.description=您的裝置已成功註冊。您現在可以繼續解鎖加密檔案庫。
hub.registerSuccess.unlockBtn=解鎖
+hub.registerSuccess.legacy.description=要存取加密檔案庫,您的裝置需要由加密檔案庫擁有者額外授權。
### Registration Failed
+hub.registerFailed.message=裝置註冊失敗
+hub.registerFailed.description.generic=註冊過程中發生錯誤。欲了解更多詳情,請查閱應用程式日誌。
+hub.registerFailed.description.deviceAlreadyExists=此裝置已註冊為其他使用者。請嘗試更改使用者帳戶或使用其他裝置。
### Unauthorized
hub.unauthorized.message=拒絕存取
-hub.unauthorized.description=您的設備權限尚未允許存取加密庫,請聯絡加密庫擁有者
### Requires Account Initialization
+hub.requireAccountInit.message=需要操作
+hub.requireAccountInit.description.0=請完成您所需的步驟以繼續。
+hub.requireAccountInit.description.1=Hub使用者個人資料
+hub.requireAccountInit.description.2=。
### License Exceeded
hub.invalidLicense.message=Hub 授權無效
hub.invalidLicense.description=此 Cryptomator Hub 實例授權無效,請聯繫管理員升級或續訂授權。
@@ -261,6 +286,7 @@ preferences.general.debugLogging=啟用除錯日誌
preferences.general.debugDirectory=展示日誌檔案
preferences.general.autoStart=系統啟動時同時啟動 Cryptomator
preferences.general.keychainBackend=儲存密碼使用
+preferences.general.quickAccessService=將解鎖的加密檔案庫新增至快速存取區域
## Interface
preferences.interface=界面
preferences.interface.theme=外觀
@@ -274,11 +300,14 @@ preferences.interface.interfaceOrientation=界面排列方向
preferences.interface.interfaceOrientation.ltr=左至右
preferences.interface.interfaceOrientation.rtl=右至左
preferences.interface.showTrayIcon=顯示系統工作列圖示 (需重新啟動)
+preferences.interface.compactMode=啟用緊湊型加密檔案庫清單
## Volume
preferences.volume=虛擬磁碟
+preferences.volume.type=預設磁碟區類型
preferences.volume.type.automatic=自動
preferences.volume.docsTooltip=閱讀文檔以了解各加密空間類型。
preferences.volume.fuseRestartRequired=需要重新啟動 Cryptomator 以應用更改。
+preferences.volume.tcp.port=預設TCP埠
preferences.volume.supportedFeatures=所選擇的磁區空間類別支援下列功能:
preferences.volume.feature.mountAuto=自動選擇掛載路徑
preferences.volume.feature.mountToDir=使用自訂資料夾路徑來掛載
@@ -291,6 +320,13 @@ preferences.updates.currentVersion=目前版本:%s
preferences.updates.autoUpdateCheck=勾選以啟用自動更新
preferences.updates.checkNowBtn=立即檢查
preferences.updates.updateAvailable=有版本 %s 可更新。
+preferences.updates.lastUpdateCheck=上次檢查:%s
+preferences.updates.lastUpdateCheck.never=從未
+preferences.updates.lastUpdateCheck.recently=最近
+preferences.updates.lastUpdateCheck.daysAgo=%s天前
+preferences.updates.lastUpdateCheck.hoursAgo=%s小時前
+preferences.updates.checkFailed=更新失敗。請檢查您網路連線或稍後再試。
+preferences.updates.upToDate=Cryptomator已是最新版本
## Contribution
preferences.contribute=贊助我們
@@ -298,9 +334,14 @@ preferences.contribute.registeredFor=已註冊贊助憑證予 %s
preferences.contribute.noCertificate=支持 Cryptomator 並取得贊助憑證。它就像授權金鑰,但是給使用自由軟體的大好人的。 ;-)
preferences.contribute.getCertificate=還沒有嗎?看看如何取得它。
preferences.contribute.promptText=在這貼上贊助憑證代碼
+preferences.contribute.thankYou=感謝您贊助Cryptomator的開源軟體開發!
+preferences.contribute.donate=捐款
+preferences.contribute.sponsor=贊助
### Remove License Key Dialog
-removeCert.confirmBtn=移除
+removeCert.title=移除憑證
+removeCert.message=移除贊助者憑證?
+removeCert.description=Cryptomator的核心功能不會受此影響。您的加密檔案庫的存取既不會受限,安全性也不會下降。
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -350,7 +391,11 @@ main.vaultlist.contextMenu.unlock=解鎖…
main.vaultlist.contextMenu.unlockNow=立即解鎖
main.vaultlist.contextMenu.vaultoptions=顯示加密庫選項
main.vaultlist.contextMenu.reveal=展示磁碟
+main.vaultlist.addVaultBtn.menuItemNew=新建加密檔案庫...
+main.vaultlist.addVaultBtn.menuItemExisting=開啟現有的加密檔案庫...
##Notificaition
+main.notification.updateAvailable=有可用更新
+main.notification.support=贊助Cryptomator.
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=感謝選用 Cryptomator 保護你的檔案。如需要任何協助,請參照我們的使用指南:
@@ -360,6 +405,7 @@ main.vaultDetail.unlockBtn=解鎖…
main.vaultDetail.unlockNowBtn=立即解鎖
main.vaultDetail.optionsBtn=加密庫選項
main.vaultDetail.passwordSavedInKeychain=密碼已儲存
+main.vaultDetail.share=分享…
### Unlocked
main.vaultDetail.unlockedStatus=已解鎖
main.vaultDetail.accessLocation=加密庫的內容可以在這裏存取
@@ -497,4 +543,6 @@ updateReminder.yesAutomatically=是,自動
#Dokany Support End
dokanySupportEnd.preferencesBtn=開啟偏好設定
+#Retry If Readonly
+
# Share Vault
diff --git a/src/main/resources/i18n/strings_zh_TW.properties b/src/main/resources/i18n/strings_zh_TW.properties
index 4ca820bb5..582bfdf90 100644
--- a/src/main/resources/i18n/strings_zh_TW.properties
+++ b/src/main/resources/i18n/strings_zh_TW.properties
@@ -13,6 +13,7 @@ generic.button.copied=已複製!
generic.button.done=完成
generic.button.next=繼續
generic.button.print=列印
+generic.button.remove=移除
# Error
error.message=出現錯誤
@@ -105,7 +106,6 @@ addvaultwizard.success.unlockNow=立即解鎖
removeVault.title=移除加密檔案庫
removeVault.message=刪除檔案庫?
removeVault.description=這將會讓 Cryptomator 忘記這個加密檔案庫。您未來可以再重新加入。已加密的檔案將不會從您的硬碟中移除。
-removeVault.confirmBtn=移除加密檔案庫
# Change Password
changepassword.title=變更密碼
@@ -176,7 +176,6 @@ hub.registerFailed.description.generic=註冊過程發生錯誤。更多細節
hub.registerFailed.description.deviceAlreadyExists=其他使用者已在此裝置上註冊。請切換至該使用者帳戶或使用其他裝置進行註冊。
### Unauthorized
hub.unauthorized.message=拒絕存取
-hub.unauthorized.description=您的設備權限尚未允許存取檔案庫,請聯絡檔案庫擁有者
### Requires Account Initialization
hub.requireAccountInit.message=需進一步操作
hub.requireAccountInit.description.0=請完成您的
@@ -343,7 +342,6 @@ preferences.contribute.sponsor=贊助者
removeCert.title=移除憑證
removeCert.message=移除贊助者憑證?
removeCert.description=Cryptomator的核心功能不會受此影響。您的加密檔案庫的存取既不會受限,安全性也不會下降。
-removeCert.confirmBtn=移除
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -553,6 +551,8 @@ dokanySupportEnd.message=對Dokany檔案系統結束支援
dokanySupportEnd.description=Cryptomator 不再支援 Dokany 檔案系統。已將您的設定調整為使用預設的檔案系統類型。您可以在偏好設定中查看預設的檔案系統類型。
dokanySupportEnd.preferencesBtn=開啟偏好設定
+#Retry If Readonly
+
# Share Vault
shareVault.title=與其他人共用加密檔案庫
shareVault.message=您想與其他人共用您的加密檔案庫嗎?
diff --git a/src/main/resources/img/logo.png b/src/main/resources/img/logo.png
deleted file mode 100644
index cdbecfa1a..000000000
Binary files a/src/main/resources/img/logo.png and /dev/null differ
diff --git a/src/main/resources/img/logo128.png b/src/main/resources/img/logo128.png
new file mode 100644
index 000000000..785c1e804
Binary files /dev/null and b/src/main/resources/img/logo128.png differ
diff --git a/src/main/resources/img/logo128@2x.png b/src/main/resources/img/logo128@2x.png
new file mode 100644
index 000000000..ebfe07c70
Binary files /dev/null and b/src/main/resources/img/logo128@2x.png differ
diff --git a/src/main/resources/img/logo64.png b/src/main/resources/img/logo64.png
new file mode 100644
index 000000000..7af35f43a
Binary files /dev/null and b/src/main/resources/img/logo64.png differ
diff --git a/src/main/resources/img/logo64@2x.png b/src/main/resources/img/logo64@2x.png
new file mode 100644
index 000000000..785c1e804
Binary files /dev/null and b/src/main/resources/img/logo64@2x.png differ
diff --git a/src/main/resources/img/logo@2x.png b/src/main/resources/img/logo@2x.png
deleted file mode 100644
index de8f79ded..000000000
Binary files a/src/main/resources/img/logo@2x.png and /dev/null differ
diff --git a/src/main/resources/img/supporter_cert_stamp.png b/src/main/resources/img/supporter_cert_stamp.png
new file mode 100644
index 000000000..47dc01565
Binary files /dev/null and b/src/main/resources/img/supporter_cert_stamp.png differ
diff --git a/src/main/resources/img/supporter_cert_stamp@2x.png b/src/main/resources/img/supporter_cert_stamp@2x.png
new file mode 100644
index 000000000..028ca3064
Binary files /dev/null and b/src/main/resources/img/supporter_cert_stamp@2x.png differ
diff --git a/suppression.xml b/suppression.xml
index f146e6054..308280a8d 100644
--- a/suppression.xml
+++ b/suppression.xml
@@ -70,4 +70,25 @@
^pkg:maven/org\.apache\.jackrabbit/jackrabbit\-webdav@.*$CVE-2023-37895
+
+
+ ^pkg:maven/org\.eclipse\.jetty/jetty-(http|server|io)@.*$
+ CVE-2024-6763
+ CVE-2024-6763
+
+
+
+
+
+ ^pkg:maven/org\.eclipse\.jetty/jetty-.*$
+ CVE-2024-6763
+ CVE-2024-6763
+
+