Merge branch 'develop' into feature/hub

# Conflicts:
#	dist/mac/dmg/build.sh
#	dist/win/build.ps1
#	pom.xml
This commit is contained in:
Armin Schrenk
2022-06-22 09:55:02 +02:00
70 changed files with 1156 additions and 344 deletions

63
.github/workflows/dl-stats.yml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: Report Download Stats
on:
schedule:
- cron: '0/15 * * * *' # run every 15 min - don't forget to adjust the "interval" in the json sent to the metrics endpoint
jobs:
report-download-stats:
runs-on: ubuntu-latest
steps:
- name: Get download count of latest releases
id: get-stats
uses: actions/github-script@v6
with:
script: |
const query = `query($owner:String!, $name:String!) {
repository(owner:$owner, name:$name){
releases(first: 10, orderBy: {field: CREATED_AT, direction: DESC}) {
nodes {
isPrerelease
tagName
releaseAssets(first: 20) {
nodes {
name
downloadCount
}
}
}
}
}
}`;
const variables = {
owner: context.repo.owner,
name: context.repo.repo
}
return await github.graphql(query, variables)
- name: Transform Results
id: transform-stats
run: |
TIME=$(($(date +%s) / $INTERVAL * $INTERVAL))
echo ${JSON_DATA} | jq --arg TIME "$TIME" --arg INTERVAL "$INTERVAL" -c '.repository.releases.nodes[] | select(.isPrerelease == false) | .tagName as $tagName | .releaseAssets.nodes[] | {filename: .name, downloads: .downloadCount, release: $tagName, time: ($TIME|tonumber), interval: ($INTERVAL|tonumber)}' > input.json
jq -c 'select(.filename|endswith("-x86_64.AppImage")) | {name: "github.releases.downloads", tags: ["file=AppImage", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
jq -c 'select(.filename|endswith("_amd64.deb")) | {name: "github.releases.downloads", tags: ["file=deb", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
jq -c 'select(.filename|endswith("-x64.msi")) | {name: "github.releases.downloads", tags: ["file=msi", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
jq -c 'select(.filename|endswith("-x64.exe")) | {name: "github.releases.downloads", tags: ["file=exe", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
jq -c 'select(.filename|endswith("-arm64.dmg")) | {name: "github.releases.downloads", tags: ["file=dmg", "version=\(.release)", "arch=arm64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
jq -c 'select(.filename|endswith(".dmg")) | select(.filename|endswith("-arm64.dmg")|not) | {name: "github.releases.downloads", tags: ["file=dmg", "version=\(.release)", "arch=amd64"], value: .downloads, interval: .interval, time: .time}' input.json >> output.json
RESULT=$(jq -s -c "." output.json)
echo "::set-output name=result::${RESULT}"
env:
INTERVAL: 900
JSON_DATA: ${{ steps.get-stats.outputs.result }}
- name: Upload Results
uses: fjogeleit/http-request-action@v1
with:
url: 'https://graphite-us-central1.grafana.net/metrics'
method: 'POST'
contentType: 'application/json'
bearerToken: ${{ secrets.GRAFANA_GRAPHITE_TOKEN }}
data: ${{ steps.transform-stats.outputs.result }}
continue-on-error: true # currently there seems to be a problem with the metrics endpoint, failing every now and then

View File

@@ -91,6 +91,7 @@ jobs:
--java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\""
--java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/Cryptomator/key.p12\""
--java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\""
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"Cryptomator\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"dmg-${{ steps.versions.outputs.revNum }}\""
--mac-package-identifier org.cryptomator
@@ -188,33 +189,14 @@ jobs:
Cryptomator-${VERSION_NO}.dmg dmg
env:
VERSION_NO: ${{ steps.versions.outputs.semVerNum }}
- name: Install notarization credentials
if: startsWith(github.ref, 'refs/tags/')
run: |
# create temporary keychain
KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
security create-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
security set-keychain-settings -lut 900 ${KEYCHAIN_PATH}
security unlock-keychain -p "${NOTARIZATION_TMP_KEYCHAIN_PW}" ${KEYCHAIN_PATH}
# import credentials from secrets
sudo xcode-select -s /Applications/Xcode_13.0.app
xcrun notarytool store-credentials "${NOTARIZATION_KEYCHAIN_PROFILE}" --apple-id "${NOTARIZATION_APPLE_ID}" --password "${NOTARIZATION_PW}" --team-id "${NOTARIZATION_TEAM_ID}" --keychain "${KEYCHAIN_PATH}"
env:
NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
NOTARIZATION_APPLE_ID: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
NOTARIZATION_PW: ${{ secrets.MACOS_NOTARIZATION_PW }}
NOTARIZATION_TEAM_ID: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
NOTARIZATION_TMP_KEYCHAIN_PW: ${{ secrets.MACOS_NOTARIZATION_TMP_KEYCHAIN_PW }}
- name: Notarize .dmg
if: startsWith(github.ref, 'refs/tags/')
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/notarization.keychain-db
sudo xcode-select -s /Applications/Xcode_13.0.app
xcrun notarytool submit Cryptomator-*.dmg --keychain-profile "${NOTARIZATION_KEYCHAIN_PROFILE}" --keychain "${KEYCHAIN_PATH}" --wait
xcrun stapler staple Cryptomator-*.dmg
env:
NOTARIZATION_KEYCHAIN_PROFILE: ${{ secrets.MACOS_NOTARIZATION_KEYCHAIN_PROFILE }}
uses: cocoalibs/xcode-notarization-action@v1
with:
app-path: 'Cryptomator-*.dmg'
apple-id: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
password: ${{ secrets.MACOS_NOTARIZATION_PW }}
team-id: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
- name: Add possible alpha/beta tags to installer name
run: mv Cryptomator-*.dmg Cryptomator-${{ steps.versions.outputs.semVerStr }}.dmg
- name: Create detached GPG signature with key 615D449FE6E6A235
@@ -228,10 +210,6 @@ jobs:
if: ${{ always() }}
run: security delete-keychain $RUNNER_TEMP/codesign.keychain-db
continue-on-error: true
- name: Clean up notarization credentials
if: ${{ always() }}
run: security delete-keychain $RUNNER_TEMP/notarization.keychain-db
continue-on-error: true
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:

View File

@@ -98,6 +98,7 @@ jobs:
--java-options "-Dcryptomator.mountPointsDir=\"~/Cryptomator\""
--java-options "-Dcryptomator.showTrayIcon=true"
--java-options "-Dcryptomator.buildNumber=\"msi-${{ steps.versions.outputs.revNum }}\""
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
--resource-dir dist/win/resources
--icon dist/win/resources/Cryptomator.ico
- name: Patch Application Directory
@@ -189,6 +190,19 @@ jobs:
semVerStr: ${{ steps.versions.outputs.semVerStr }}
revNum: ${{ steps.versions.outputs.revNum }}
publish-winget:
name: Publish on winget repo
runs-on: windows-latest
needs: [build-msi]
steps:
- name: Submit package to Windows Package Manager Community Repository
run: |
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
$github = Get-Content '${{ github.event_path }}' | ConvertFrom-Json
$installerUrl = $github.release.assets | Where-Object -Property name -match 'Cryptomator-*.msi' | Select -ExpandProperty browser_download_url -First 1
.\wingetcreate.exe update Cryptomator.Cryptomator -s -v $github.release.tag_name -u $installerUrl -t ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
shell: pwsh
build-exe:
name: Build .exe installer
runs-on: windows-latest

18
.gitignore vendored
View File

@@ -5,25 +5,9 @@
*.war
*.ear
# Eclipse Settings Files #
.settings
.project
.classpath
# Maven #
target/
pom.xml.versionsBackup
# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/shelf
.idea/dictionaries/**
!.idea/dictionaries/dict_*
.idea/compiler.xml
.idea/jarRepositories.xml
.idea/uiDesigner.xml
.idea/**/libraries/
*.iml
# Java Crash Logs
hs_err_pid*.log

13
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,13 @@
# see https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems
# Default ignored files
/shelf/
/workspace.xml
/usage.statistics.xml
/dictionaries/
# generated from Maven
/jarRepositories.xml
/modules.xml
/*.iml
/libraries/*.xml

51
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
</profile>
<profile name="Annotation profile for Cryptomator Desktop App" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<option name="dagger.fastInit" value="enabled" />
<option name="dagger.formatGeneratedSource" value="enabled" />
<processorPath useClasspath="false">
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.41/dagger-compiler-2.41.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.41/dagger-2.41.jar" />
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.41/dagger-producers-2.41.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.41/dagger-spi-2.41.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/devtools/ksp/symbol-processing-api/1.5.30-1.0.0/symbol-processing-api-1.5.30-1.0.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5.32/kotlin-stdlib-jdk8-1.5.32.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.5.32/kotlin-stdlib-1.5.32.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.5.32/kotlin-stdlib-common-1.5.32.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5.32/kotlin-stdlib-jdk7-1.5.32.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.13.0/javapoet-1.13.0.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/googlejavaformat/google-java-format/1.5/google-java-format-1.5.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/javac-shaded/9-dev-r4023-3/javac-shaded-9-dev-r4023-3.jar" />
<entry name="$MAVEN_REPOSITORY$/net/ltgt/gradle/incap/incap/0.2/incap-0.2.jar" />
<entry name="$MAVEN_REPOSITORY$/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.3.0/kotlinx-metadata-jvm-0.3.0.jar" />
</processorPath>
<module name="cryptomator" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="cryptomator" options="-Adagger.fastInit=enabled -Adagger.formatGeneratedSource=enabled" />
</option>
</component>
</project>

View File

@@ -66,6 +66,7 @@
</content_rating>
<releases>
<release date="2022-05-03" version="1.6.10"/>
<release date="2022-04-27" version="1.6.9"/>
<release date="2022-03-30" version="1.6.8"/>
<release date="2021-12-16" version="1.6.5"/>

63
dist/mac/dmg/build.sh vendored
View File

@@ -14,9 +14,17 @@ while getopts ":s:" o; do
done
shift "$((OPTIND-1))"
# prepare working dir and variables
# prepare working dir
cd $(dirname $0)
rm -rf runtime dmg
rm -rf runtime dmg *.app *.dmg
# set variables
APP_NAME="Cryptomator"
VENDOR="Skymatic GmbH"
COPYRIGHT_YEARS="2016 - 2022"
PACKAGE_IDENTIFIER="org.cryptomator"
MAIN_JAR_GLOB="cryptomator-*.jar"
MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
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'`
@@ -31,7 +39,7 @@ fi
# compile
mvn -B -f../../../pom.xml clean package -DskipTests -Pmac
cp ../../../target/cryptomator-*.jar ../../../target/mods
cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
# add runtime
${JAVA_HOME}/bin/jlink \
@@ -51,11 +59,11 @@ ${JAVA_HOME}/bin/jpackage \
--runtime-image runtime \
--input ../../../target/libs \
--module-path ../../../target/mods \
--module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator \
--module ${MODULE_AND_MAIN_CLASS} \
--dest . \
--name Cryptomator \
--vendor "Skymatic GmbH" \
--copyright "(C) 2016 - 2022 Skymatic GmbH" \
--name ${APP_NAME} \
--vendor "${VENDOR}" \
--copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
--app-version "${VERSION_NO}" \
--java-options "-Xss5m" \
--java-options "-Xmx256m" \
@@ -63,20 +71,21 @@ ${JAVA_HOME}/bin/jpackage \
--java-options "-Dapple.awt.enableTemplateImages=true" \
--java-options "-Dsun.java2d.metal=true" \
--java-options "-Dcryptomator.appVersion=\"${VERSION_NO}\"" \
--java-options "-Dcryptomator.logDir=\"~/Library/Logs/Cryptomator\"" \
--java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/Cryptomator/Plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/Cryptomator/settings.json\"" \
--java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/Cryptomator/key.p12\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/Cryptomator/ipc.socket\"" \
--java-options "-Dcryptomator.logDir=\"~/Library/Logs/${APP_NAME}\"" \
--java-options "-Dcryptomator.pluginDir=\"~/Library/Application Support/${APP_NAME}/Plugins\"" \
--java-options "-Dcryptomator.settingsPath=\"~/Library/Application Support/${APP_NAME}/settings.json\"" \
--java-options "-Dcryptomator.ipcSocketPath=\"~/Library/Application Support/${APP_NAME}/ipc.socket\"" \
--java-options "-Dcryptomator.p12Path=\"~/Library/Application Support/${APP_NAME}/key.p12\"" \
--java-options "-Dcryptomator.integrationsMac.keychainServiceName=\"${APP_NAME}\"" \
--java-options "-Dcryptomator.showTrayIcon=true" \
--java-options "-Dcryptomator.buildNumber=\"dmg-${REVISION_NO}\"" \
--mac-package-identifier org.cryptomator \
--mac-package-identifier ${PACKAGE_IDENTIFIER} \
--resource-dir ../resources
# transform app dir
cp ../resources/Cryptomator-Vault.icns Cryptomator.app/Contents/Resources/
sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" Cryptomator.app/Contents/Info.plist
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" Cryptomator.app/Contents/Info.plist
cp ../resources/${APP_NAME}-Vault.icns ${APP_NAME}.app/Contents/Resources/
sed -i '' "s|###BUNDLE_SHORT_VERSION_STRING###|${VERSION_NO}|g" ${APP_NAME}.app/Contents/Info.plist
sed -i '' "s|###BUNDLE_VERSION###|${REVISION_NO}|g" ${APP_NAME}.app/Contents/Info.plist
# generate license
mvn -B -f../../../pom.xml license:add-third-party \
@@ -90,8 +99,8 @@ mvn -B -f../../../pom.xml license:add-third-party \
# codesign
if [ -n "${CODESIGN_IDENTITY}" ]; then
find Cryptomator.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
for JAR_PATH in `find Cryptomator.app -name "*.jar"`; do
find ${APP_NAME}.app/Contents/runtime/Contents/MacOS -name '*.dylib' -exec codesign --force -s ${CODESIGN_IDENTITY} {} \;
for JAR_PATH in `find ${APP_NAME}.app -name "*.jar"`; do
if [[ `unzip -l ${JAR_PATH} | grep '.dylib\|.jnilib'` ]]; then
JAR_FILENAME=$(basename ${JAR_PATH})
OUTPUT_PATH=${JAR_PATH%.*}
@@ -106,25 +115,25 @@ if [ -n "${CODESIGN_IDENTITY}" ]; then
rm -r ${OUTPUT_PATH}
fi
done
echo "Codesigning Cryptomator.app..."
codesign --force --deep --entitlements ../Cryptomator.entitlements -o runtime -s ${CODESIGN_IDENTITY} Cryptomator.app
echo "Codesigning ${APP_NAME}.app..."
codesign --force --deep --entitlements ../${APP_NAME}.entitlements -o runtime -s ${CODESIGN_IDENTITY} ${APP_NAME}.app
fi
# prepare dmg contents
mkdir dmg
mv Cryptomator.app dmg
mv ${APP_NAME}.app dmg
cp resources/macFUSE.webloc dmg
# create dmg
create-dmg \
--volname Cryptomator \
--volicon "resources/Cryptomator-Volume.icns" \
--background "resources/Cryptomator-background.tiff" \
--volname ${APP_NAME} \
--volicon "resources/${APP_NAME}-Volume.icns" \
--background "resources/${APP_NAME}-background.tiff" \
--window-pos 400 100 \
--window-size 640 694 \
--icon-size 128 \
--icon "Cryptomator.app" 128 245 \
--hide-extension "Cryptomator.app" \
--icon "${APP_NAME}.app" 128 245 \
--hide-extension "${APP_NAME}.app" \
--icon "macFUSE.webloc" 320 501 \
--hide-extension "macFUSE.webloc" \
--app-drop-link 512 245 \
@@ -132,4 +141,4 @@ create-dmg \
--icon ".background" 128 758 \
--icon ".fseventsd" 320 758 \
--icon ".VolumeIcon.icns" 512 758 \
Cryptomator-${VERSION_NO}.dmg dmg
${APP_NAME}-${VERSION_NO}.dmg dmg

23
dist/win/build.bat vendored
View File

@@ -1,2 +1,23 @@
@echo off
powershell -NoLogo -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1
:: Default values for Cryptomator builds
SET APPNAME="Cryptomator"
SET MAIN_JAR_GLOB="cryptomator-*"
SET UPGRADE_UUID="bda45523-42b1-4cae-9354-a45475ed4775"
SET VENDOR="Skymatic GmbH"
SET FIRST_COPYRIGHT_YEAR=2016
SET ABOUT_URL="https://cryptomator.org"
SET UPDATE_URL="https://cryptomator.org/downloads/"
SET HELP_URL="https://cryptomator.org/contact/"
SET MODULE_AND_MAIN_CLASS="org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator"
powershell -NoLogo -NoExit -ExecutionPolicy Unrestricted -Command .\build.ps1^
-AppName %APPNAME%^
-MainJarGlob "%MAIN_JAR_GLOB%"^
-ModuleAndMainClass "%MODULE_AND_MAIN_CLASS%"^
-UpgradeUUID "%UPGRADE_UUID%"^
-Vendor ""%VENDOR%""^
-CopyrightStartYear %FIRST_COPYRIGHT_YEAR%^
-AboutUrl "%ABOUT_URL%"^
-HelpUrl "%HELP_URL%"^
-UpdateUrl "%UPDATE_URL%"^
-Clean 1

78
dist/win/build.ps1 vendored
View File

@@ -1,5 +1,15 @@
# check parameters
$clean = $args[0] -eq "fresh"
Param(
[Parameter(Mandatory, HelpMessage="Please provide a name for the app")][string] $AppName,
[Parameter(Mandatory, HelpMessage="Please provide the glob pattern to identify the main jar")][string] $MainJarGlob,
[Parameter(Mandatory, HelpMessage="Please provide the module- and main class path to start the app")][string] $ModuleAndMainClass,
[Parameter(Mandatory, HelpMessage="Please provide the windows upgrade uuid for the installer")][string] $UpgradeUUID,
[Parameter(Mandatory, HelpMessage="Please provide the name of the vendor")][string] $Vendor,
[Parameter(Mandatory, HelpMessage="Please provide the starting year for the copyright notice")][int] $CopyrightStartYear,
[Parameter(Mandatory, HelpMessage="Please provide a help url")][string] $HelpUrl,
[Parameter(Mandatory, HelpMessage="Please provide an update url")][string] $UpdateUrl,
[Parameter(Mandatory, HelpMessage="Please provide an about url")][string] $AboutUrl,
[bool] $clean
)
# check preconditions
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
@@ -24,12 +34,11 @@ Write-Output "`$revisionNo=$revisionNo"
Write-Output "`$buildDir=$buildDir"
Write-Output "`$Env:JAVA_HOME=$Env:JAVA_HOME"
$vendor = "Skymatic GmbH"
$copyright = "(C) 2016 - 2022 Skymatic GmbH"
$copyright = "(C) $CopyrightStartYear - $((Get-Date).Year) $Vendor"
# compile
&mvn -B -f $buildDir/../../pom.xml clean package -DskipTests -Pwin
Copy-Item "$buildDir\..\..\target\cryptomator-*.jar" -Destination "$buildDir\..\..\target\mods"
Copy-Item "$buildDir\..\..\target\$MainJarGlob.jar" -Destination "$buildDir\..\..\target\mods"
# add runtime
$runtimeImagePath = '.\runtime'
@@ -48,7 +57,7 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
--strip-debug `
--compress=1
$appPath = '.\Cryptomator'
$appPath = ".\$AppName"
if ($clean -and (Test-Path -Path $appPath)) {
Remove-Item -Path $appPath -Force -Recurse
}
@@ -60,27 +69,28 @@ if ($clean -and (Test-Path -Path $appPath)) {
--runtime-image runtime `
--input ../../target/libs `
--module-path ../../target/mods `
--module org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator `
--module $ModuleAndMainClass `
--dest . `
--name Cryptomator `
--vendor $vendor `
--name $AppName `
--vendor $Vendor `
--copyright $copyright `
--java-options "-Xss5m" `
--java-options "-Xmx256m" `
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
--app-version "$semVerNo.$revisionNo" `
--java-options "-Dfile.encoding=`"utf-8`"" `
--java-options "-Dcryptomator.logDir=`"~/AppData/Roaming/Cryptomator`"" `
--java-options "-Dcryptomator.pluginDir=`"~/AppData/Roaming/Cryptomator/Plugins`"" `
--java-options "-Dcryptomator.settingsPath=`"~/AppData/Roaming/Cryptomator/settings.json`"" `
--java-options "-Dcryptomator.p12Path=`"~/AppData/Roaming/Cryptomator/key.p12`"" `
--java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/Cryptomator/ipc.socket`"" `
--java-options "-Dcryptomator.keychainPath=`"~/AppData/Roaming/Cryptomator/keychain.json`"" `
--java-options "-Dcryptomator.mountPointsDir=`"~/Cryptomator`"" `
--java-options "-Dcryptomator.logDir=`"~/AppData/Roaming/$AppName`"" `
--java-options "-Dcryptomator.pluginDir=`"~/AppData/Roaming/$AppName/Plugins`"" `
--java-options "-Dcryptomator.settingsPath=`"~/AppData/Roaming/$AppName/settings.json`"" `
--java-options "-Dcryptomator.ipcSocketPath=`"~/AppData/Roaming/$AppName/ipc.socket`"" `
--java-options "-Dcryptomator.keychainPath=`"~/AppData/Roaming/$AppName/keychain.json`"" `
--java-options "-Dcryptomator.p12Path=`"~/AppData/Roaming/$AppName/key.p12`"" `
--java-options "-Dcryptomator.mountPointsDir=`"~/$AppName`"" `
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
--java-options "-Dcryptomator.showTrayIcon=true" `
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
--resource-dir resources `
--icon resources/Cryptomator.ico
--icon resources/$AppName.ico
#Create RTF license for msi
&mvn -B -f $buildDir/../../pom.xml license:add-third-party `
@@ -93,33 +103,29 @@ if ($clean -and (Test-Path -Path $appPath)) {
"-Dlicense.licenseMergesUrl=file:///$buildDir/../../license/merges"
# patch app dir
Copy-Item "contrib\*" -Destination "Cryptomator"
attrib -r "Cryptomator\Cryptomator.exe"
$aboutUrl="https://cryptomator.org"
$updateUrl="https://cryptomator.org/downloads/"
$helpUrl="https://cryptomator.org/contact/"
Copy-Item "contrib\*" -Destination "$AppName"
attrib -r "$AppName\$AppName.exe"
# create .msi
$Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
& "$Env:JAVA_HOME\bin\jpackage" `
--verbose `
--type msi `
--win-upgrade-uuid bda45523-42b1-4cae-9354-a45475ed4775 `
--app-image Cryptomator `
--win-upgrade-uuid $UpgradeUUID `
--app-image $AppName `
--dest installer `
--name Cryptomator `
--vendor $vendor `
--name $AppName `
--vendor $Vendor `
--copyright $copyright `
--app-version "$semVerNo" `
--win-menu `
--win-dir-chooser `
--win-shortcut-prompt `
--win-update-url $updateUrl `
--win-menu-group Cryptomator `
--win-menu-group $AppName `
--resource-dir resources `
--about-url $aboutUrl `
--license-file resources/license.rtf `
--win-update-url $UpdateUrl `
--about-url $AboutUrl `
--file-associations resources/FAvaultFile.properties
#Create RTF license for bundle
@@ -140,14 +146,14 @@ Write-Output "Downloading ${winfspMsiUrl}..."
Invoke-WebRequest $winfspMsiUrl -OutFile ".\bundle\resources\winfsp.msi" # redirects are followed by default
# copy MSI to bundle resources
Copy-Item ".\installer\Cryptomator-*.msi" -Destination ".\bundle\resources\Cryptomator.msi"
Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi"
# create bundle including winfsp
& "$env:WIX\bin\candle.exe" .\bundle\bundleWithWinfsp.wxs -ext WixBalExtension -out bundle\ `
-dBundleVersion="$semVerNo.$revisionNo" `
-dBundleVendor="$vendor" `
-dBundleVendor="$Vendor" `
-dBundleCopyright="$copyright" `
-dAboutUrl="$aboutUrl" `
-dHelpUrl="$helpUrl" `
-dUpdateUrl="$updateUrl"
& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -out installer\Cryptomator-Installer.exe
-dAboutUrl="$AboutUrl" `
-dHelpUrl="$HelpUrl" `
-dUpdateUrl="$UpdateUrl"
& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -out installer\$AppName-Installer.exe

View File

@@ -1,3 +1,7 @@
@echo off
:: Default values for Cryptomator builds
SET LOOPBACK_ALIAS="cryptomator-vault"
cd %~dp0
powershell -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -Command .\patchWebDAV.ps1
powershell -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -Command .\patchWebDAV.ps1^
-LoopbackAlias %LOOPBACK_ALIAS%

View File

@@ -1,10 +1,16 @@
#Requires -RunAsAdministrator
Param(
[Parameter(Mandatory, HelpMessage="Please provide an alias for 127.0.0.1")][string] $LoopbackAlias
)
# Adds for address 127.0.0.1 the 'cryptomator-vault' alias to the hosts file
# Adds an alias for 127.0.0.1 to the hosts file
function Add-AliasToHost {
param (
[string]$LoopbackAlias
)
$sysdir = [Environment]::SystemDirectory
$hostsFile = "$sysdir\drivers\etc\hosts"
$aliasLine = '127.0.0.1 cryptomator-vault'
$aliasLine = "127.0.0.1 $LoopbackAlias"
foreach ($line in Get-Content $hostsFile) {
if ($line -eq $aliasLine){
@@ -49,7 +55,7 @@ function Edit-ProviderOrder {
}
Add-AliasToHost
Add-AliasToHost $LoopbackAlias
Write-Output 'Ensured alias exists in hosts file'
Set-WebDAVFileSizeLimit

View File

@@ -91,7 +91,7 @@
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
</Control>
<Control Id="DescriptionReason2" Type="Text" X="135" Y="170" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Hidden="yes" >
<Text>Cryptomator was still running during installation.</Text>
<Text>Application to update was still running during installation.</Text>
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
</Control>
</Dialog>

View File

@@ -86,12 +86,12 @@
<!-- Non-Opening ProgID -->
<DirectoryRef Id="INSTALLDIR">
<Component Win64="yes" Id="nonStartingProgID" >
<File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\Cryptomator-Vault.ico" Name="Cryptomator-Vault.ico"></File>
<ProgId Id="Cryptomator.Encrypted.1" Description="Cryptomator Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
<Extension Id="c9r" Advertise="no" ContentType="application/vnd.cryptomator.encrypted">
<MIME ContentType="application/vnd.cryptomator.encrypted" Default="yes"></MIME>
<File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\$(var.IconFileC9rC9s)" Name="$(var.IconFileC9rC9s)"></File>
<ProgId Id="$(var.JpAppName).Encrypted.1" Description="$(var.JpAppName) Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
<Extension Id="c9r" Advertise="no" ContentType="$(var.ProgIdContentType)">
<MIME ContentType="$(var.ProgIdContentType)" Default="yes"></MIME>
</Extension>
<Extension Id="c9s" Advertise="no" ContentType="application/vnd.cryptomator.encrypted"/>
<Extension Id="c9s" Advertise="no" ContentType="$(var.ProgIdContentType)"/>
</ProgId>
</Component>
</DirectoryRef>
@@ -130,12 +130,12 @@
<!-- Running App detection and exit -->
<Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
<util:CloseApplication
Id="CloseCryptomator"
Target="cryptomator.exe"
Target="$(var.CloseApplicationTarget)"
Id="Close$(var.JpAppName)"
CloseMessage="no"
RebootPrompt="no"
PromptToContinue="yes"
Description="A running instance of Cryptomator is found. Please close it to continue."
Description="A running instance of $(var.JpAppName) is found. Please close it to continue."
Property="FOUNDRUNNINGAPP"
>
</util:CloseApplication>

39
dist/win/resources/overrides.wxi vendored Normal file
View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Stub by design -->
<!--
overrides.wxi is a placeholder to set/alter WiX variables referenced from default
main.wxs file.
Put custom overrides.wxi in resource directory to replace this default file.
Override default overrides.wxi if configuring of msi installers through jpackage
command line is not sufficient.
WiX variables referenced from default main.wxs that can be altered in custom overrides.wxi:
- JpProductLanguage
Value of `Language` attribute of `Product` WiX element. Default value is 1033.
- JpInstallerVersion
Value of `InstallerVersion` attribute of `Package` WiX element. Default value is 200.
- JpCompressedMsi
Value of `Compressed` attribute of `Package` WiX element. Default value is `yes`.
- JpAllowDowngrades
Should be defined to enable downgrades and undefined to disable downgrades.
Default value is `yes`.
- JpAllowUpgrades
Should be defined to enable upgrades and undefined to disable upgrades.
Default value is `yes`.
-->
<!-- Non-opening ProgID settings-->
<?define IconFileC9rC9s= "Cryptomator-Vault.ico" ?>
<?define ProgIdContentType= "application/vnd.cryptomator.encrypted" ?>
<!-- Close Application util -->
<?define CloseApplicationTarget= "cryptomator.exe" ?>
<Include/>

View File

@@ -28,12 +28,12 @@
<!-- cryptomator dependencies -->
<cryptomator.cryptolib.version>2.1.0-beta3</cryptomator.cryptolib.version>
<cryptomator.cryptofs.version>2.4.1</cryptomator.cryptofs.version>
<cryptomator.cryptofs.version>2.4.2</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.1.0</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.1.0</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.1.0</cryptomator.integrations.mac.version>
<cryptomator.integrations.win.version>1.1.1</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.1.1</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.1.0</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>1.3.3</cryptomator.fuse.version>
<cryptomator.fuse.version>1.3.4</cryptomator.fuse.version>
<cryptomator.dokany.version>1.3.3</cryptomator.dokany.version>
<cryptomator.webdav.version>1.2.7</cryptomator.webdav.version>

View File

@@ -0,0 +1,92 @@
package org.cryptomator.common;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform;
import javafx.concurrent.Task;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
//Inspired by: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/ThreadPoolExecutor.html#afterExecute(java.lang.Runnable,java.lang.Throwable)
public final class CatchingExecutors {
private static final Logger LOG = LoggerFactory.getLogger(CatchingExecutors.class);
private CatchingExecutors() { /* NO-OP */ }
public static class CatchingScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
public CatchingScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) {
super(corePoolSize, threadFactory);
}
@Override
protected void afterExecute(Runnable runnable, Throwable throwable) {
super.afterExecute(runnable, throwable);
afterExecuteInternal(runnable, throwable);
}
}
public static class CatchingThreadPoolExecutor extends ThreadPoolExecutor {
public CatchingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
}
@Override
protected void afterExecute(Runnable runnable, Throwable throwable) {
super.afterExecute(runnable, throwable);
afterExecuteInternal(runnable, throwable);
}
}
private static void afterExecuteInternal(Runnable runnable, Throwable throwable) {
if (throwable != null) {
callHandler(Thread.currentThread(), throwable);
} else if (runnable instanceof Task<?> t) {
afterExecuteTask(t);
} else if (runnable instanceof Future<?> f) {
afterExecuteFuture(f);
}
//Errors in this method are delegated to the UncaughtExceptionHandler of the current thread
}
private static void callHandler(Thread thread, Throwable throwable) {
Objects.requireNonNullElseGet(thread.getUncaughtExceptionHandler(), CatchingExecutors::fallbackHandler).uncaughtException(thread, throwable);
}
private static Thread.UncaughtExceptionHandler fallbackHandler() {
return (thread, throwable) -> LOG.error("FALLBACK: Uncaught exception in " + thread.getName(), throwable);
}
private static void afterExecuteTask(Task<?> task) {
var caller = Thread.currentThread();
Platform.runLater(() -> {
if (task.getOnFailed() == null) {
callHandler(caller, task.getException());
}
});
}
private static void afterExecuteFuture(Future<?> future) {
assert future.isDone();
try {
future.get();
} catch (CancellationException ce) {
callHandler(Thread.currentThread(), ce);
} catch (ExecutionException ee) {
callHandler(Thread.currentThread(), ee.getCause());
} catch (InterruptedException ie) {
//Ignore/Reset
Thread.currentThread().interrupt();
}
}
}

View File

@@ -12,9 +12,7 @@ import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.keychain.KeychainModule;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultComponent;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.common.vaults.VaultListModule;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.frontend.webdav.WebDavServer;
@@ -25,16 +23,13 @@ import javax.inject.Named;
import javax.inject.Singleton;
import javafx.beans.binding.Binding;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Comparator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@@ -93,7 +88,7 @@ public abstract class CommonsModule {
@Singleton
static ScheduledExecutorService provideScheduledExecutorService(ShutdownHook shutdownHook) {
final AtomicInteger threadNumber = new AtomicInteger(1);
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(NUM_SCHEDULER_THREADS, r -> {
ScheduledExecutorService executorService = new CatchingExecutors.CatchingScheduledThreadPoolExecutor(NUM_SCHEDULER_THREADS, r -> {
String name = String.format("App Scheduled Executor %02d", threadNumber.getAndIncrement());
Thread t = new Thread(r);
t.setName(name);
@@ -110,7 +105,7 @@ public abstract class CommonsModule {
@Singleton
static ExecutorService provideExecutorService(ShutdownHook shutdownHook) {
final AtomicInteger threadNumber = new AtomicInteger(1);
ExecutorService executorService = new ThreadPoolExecutor(NUM_CORE_BG_THREADS, Integer.MAX_VALUE, BG_THREAD_KEEPALIVE_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<>(), r -> {
ExecutorService executorService = new CatchingExecutors.CatchingThreadPoolExecutor(NUM_CORE_BG_THREADS, Integer.MAX_VALUE, BG_THREAD_KEEPALIVE_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<>(), r -> {
String name = String.format("App Background Thread %03d", threadNumber.getAndIncrement());
Thread t = new Thread(r);
t.setName(name);

View File

@@ -6,6 +6,7 @@ public interface Constants {
String MASTERKEY_BACKUP_SUFFIX = ".bkup";
String VAULTCONFIG_FILENAME = "vault.cryptomator";
String CRYPTOMATOR_FILENAME_EXT = ".cryptomator";
String CRYPTOMATOR_FILENAME_GLOB = "*.cryptomator";
byte[] PEPPER = new byte[0];
}

View File

@@ -0,0 +1,64 @@
package org.cryptomator.common;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
/**
* Enum of common cloud providers and their default local storage location path.
*/
public enum LocationPreset {
DROPBOX("Dropbox", "~/Dropbox"),
ICLOUDDRIVE("iCloud Drive", "~/Library/Mobile Documents/com~apple~CloudDocs", "~/iCloudDrive"),
GDRIVE("Google Drive", "~/Google Drive/My Drive", "~/Google Drive"),
MEGA("MEGA", "~/MEGA"),
ONEDRIVE("OneDrive", "~/OneDrive"),
PCLOUD("pCloud", "~/pCloudDrive"),
LOCAL("local");
private final String name;
private final List<Path> candidates;
LocationPreset(String name, String... candidates) {
this.name = name;
this.candidates = Arrays.stream(candidates).map(UserHome::resolve).map(Path::of).toList();
}
/**
* Checks for this LocationPreset if any of the associated paths exist.
*
* @return the first existing path or null, if none exists.
*/
public Path existingPath() {
return candidates.stream().filter(Files::isDirectory).findFirst().orElse(null);
}
public String getDisplayName() {
return name;
}
@Override
public String toString() {
return getDisplayName();
}
//this contruct is needed, since static members are initialized after every enum member is initialized
//TODO: refactor this to normal class and use this also in different parts of the project
private static class UserHome {
private static final String USER_HOME = System.getProperty("user.home");
private static String resolve(String path) {
if (path.startsWith("~/")) {
return UserHome.USER_HOME + path.substring(1);
} else {
return path;
}
}
}
}

View File

@@ -36,7 +36,7 @@ public class Settings {
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final WebDavUrlScheme DEFAULT_GVFS_SCHEME = WebDavUrlScheme.DAV;
public static final boolean DEFAULT_DEBUG_MODE = false;
public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = SystemUtils.IS_OS_WINDOWS ? VolumeImpl.DOKANY : VolumeImpl.FUSE;
public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = VolumeImpl.FUSE;
public static final UiTheme DEFAULT_THEME = UiTheme.LIGHT;
@Deprecated // to be changed to "whatever is available" eventually
public static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : "org.cryptomator.linux.keychain.SecretServiceKeychainAccess";

View File

@@ -10,6 +10,7 @@ package org.cryptomator.common.vaults;
import com.google.common.base.Strings;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Constants;
import org.cryptomator.common.mountpoint.InvalidMountPointException;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.vaults.Volume.VolumeException;
@@ -125,6 +126,7 @@ public class Vault {
.withKeyLoader(keyLoader) //
.withFlags(flags) //
.withMaxCleartextNameLength(vaultSettings.maxCleartextFilenameLength().get()) //
.withVaultConfigFilename(Constants.VAULTCONFIG_FILENAME) //
.build();
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
}

View File

@@ -19,22 +19,13 @@ public interface VaultComponent {
Vault vault();
@Subcomponent.Builder
interface Builder {
@Subcomponent.Factory
interface Factory {
@BindsInstance
Builder vaultSettings(VaultSettings vaultSettings);
VaultComponent create(@BindsInstance VaultSettings vaultSettings, //
@BindsInstance VaultConfigCache configCache, //
@BindsInstance VaultState.Value vaultState, //
@BindsInstance @Nullable @Named("lastKnownException") Exception initialErrorCause);
@BindsInstance
Builder vaultConfigCache(VaultConfigCache configCache);
@BindsInstance
Builder initialVaultState(VaultState.Value vaultState);
@BindsInstance
Builder initialErrorCause(@Nullable @Named("lastKnownException") Exception initialErrorCause);
VaultComponent build();
}
}
}

View File

@@ -38,15 +38,15 @@ public class VaultListManager {
private static final Logger LOG = LoggerFactory.getLogger(VaultListManager.class);
private final AutoLocker autoLocker;
private final VaultComponent.Builder vaultComponentBuilder;
private final VaultComponent.Factory vaultComponentFactory;
private final ObservableList<Vault> vaultList;
private final String defaultVaultName;
@Inject
public VaultListManager(ObservableList<Vault> vaultList, AutoLocker autoLocker, VaultComponent.Builder vaultComponentBuilder, ResourceBundle resourceBundle, Settings settings) {
public VaultListManager(ObservableList<Vault> vaultList, AutoLocker autoLocker, VaultComponent.Factory vaultComponentFactory, ResourceBundle resourceBundle, Settings settings) {
this.vaultList = vaultList;
this.autoLocker = autoLocker;
this.vaultComponentBuilder = vaultComponentBuilder;
this.vaultComponentFactory = vaultComponentFactory;
this.defaultVaultName = resourceBundle.getString("defaults.vault.vaultName");
addAll(settings.getDirectories());
@@ -93,21 +93,17 @@ public class VaultListManager {
}
private Vault create(VaultSettings vaultSettings) {
VaultComponent.Builder compBuilder = vaultComponentBuilder.vaultSettings(vaultSettings);
var wrapper = new VaultConfigCache(vaultSettings);
try {
VaultState.Value vaultState = determineVaultState(vaultSettings.path().get());
VaultConfigCache wrapper = new VaultConfigCache(vaultSettings);
compBuilder.vaultConfigCache(wrapper); //first set the wrapper in the builder, THEN try to load config
var vaultState = determineVaultState(vaultSettings.path().get());
if (vaultState == LOCKED) { //for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
wrapper.reloadConfig();
}
compBuilder.initialVaultState(vaultState);
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
} catch (IOException e) {
LOG.warn("Failed to determine vault state for " + vaultSettings.path().get(), e);
compBuilder.initialVaultState(ERROR);
compBuilder.initialErrorCause(e);
return vaultComponentFactory.create(vaultSettings, wrapper, ERROR, e).vault();
}
return compBuilder.build().vault();
}
public static VaultState.Value redetermineVaultState(Vault vault) {

View File

@@ -83,7 +83,7 @@ public class VaultState extends ObservableValueBase<VaultState.Value> implements
if (success) {
fireValueChangedEvent();
} else {
LOG.debug("Failed transiting into state {}: Expected state was not{}.", fromState, toState);
LOG.debug("Failed transiting into state {}: Expected state was not {}.", fromState, toState);
}
return success;
}

View File

@@ -17,7 +17,7 @@ public class SupportedLanguages {
// these are BCP 47 language codes, not ISO. Note the "-" instead of the "_":
public static final List<String> LANGUAGAE_TAGS = List.of("en", "ar", "bn", "bs", "ca", "cs", "de", "el", "es", "fil", "fr", "gl", "he", //
"hi", "hr", "hu", "id", "it", "ja", "ko", "lv", "mk", "nb", "nl", "nn", "no", "pa", "pl", "pt", "pt-BR", "ro", "ru", "sk", "sr", //
"sr-Latn", "sv", "ta", "te", "th", "tr", "uk", "zh", "zh-HK", "zh-TW");
"sr-Latn", "sv", "sw", "ta", "te", "th", "tr", "uk", "zh", "zh-HK", "zh-TW");
@Nullable
private final String preferredLanguage;

View File

@@ -25,6 +25,8 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.ResourceBundle;
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
@AddVaultWizardScoped
public class ChooseExistingVaultController implements FxController {
@@ -73,7 +75,7 @@ public class ChooseExistingVaultController implements FxController {
public void chooseFileAndNext() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("addvaultwizard.existing.filePickerTitle"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Vault", "*.cryptomator"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(resourceBundle.getString("addvaultwizard.existing.filePickerMimeDesc"), CRYPTOMATOR_FILENAME_GLOB));
File masterkeyFile = fileChooser.showOpenDialog(window);
if (masterkeyFile != null) {
vaultPath.setValue(masterkeyFile.toPath().toAbsolutePath().getParent());

View File

@@ -46,7 +46,7 @@ public class CreateNewVaultLocationController implements FxController {
private final Stage window;
private final Lazy<Scene> chooseNameScene;
private final Lazy<Scene> choosePasswordScene;
private final LocationPresets locationPresets;
private final ObservedLocationPresets locationPresets;
private final ObjectProperty<Path> vaultPath;
private final StringProperty vaultName;
private final ResourceBundle resourceBundle;
@@ -71,7 +71,7 @@ public class CreateNewVaultLocationController implements FxController {
public FontAwesome5IconView badLocation;
@Inject
CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, LocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, ObservedLocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
this.window = window;
this.chooseNameScene = chooseNameScene;
this.choosePasswordScene = choosePasswordScene;
@@ -197,7 +197,7 @@ public class CreateNewVaultLocationController implements FxController {
return validVaultPath.get();
}
public LocationPresets getLocationPresets() {
public ObservedLocationPresets getObservedLocationPresets() {
return locationPresets;
}

View File

@@ -1,23 +1,15 @@
package org.cryptomator.ui.addvaultwizard;
import org.cryptomator.common.LocationPreset;
import javax.inject.Inject;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@AddVaultWizardScoped
public class LocationPresets {
private static final String USER_HOME = System.getProperty("user.home");
private static final String[] ICLOUDDRIVE_LOCATIONS = {"~/Library/Mobile Documents/iCloud~com~setolabs~Cryptomator/Documents", "~/iCloudDrive/iCloud~com~setolabs~Cryptomator"};
private static final String[] DROPBOX_LOCATIONS = {"~/Dropbox"};
private static final String[] GDRIVE_LOCATIONS = {"~/Google Drive/My Drive", "~/Google Drive"};
private static final String[] ONEDRIVE_LOCATIONS = {"~/OneDrive"};
private static final String[] MEGA_LOCATIONS = {"~/MEGA"};
private static final String[] PCLOUD_LOCATIONS = {"~/pCloudDrive"};
public class ObservedLocationPresets {
private final ReadOnlyObjectProperty<Path> iclouddriveLocation;
private final ReadOnlyObjectProperty<Path> dropboxLocation;
@@ -33,13 +25,13 @@ public class LocationPresets {
private final BooleanBinding foundPcloud;
@Inject
public LocationPresets() {
this.iclouddriveLocation = new SimpleObjectProperty<>(existingWritablePath(ICLOUDDRIVE_LOCATIONS));
this.dropboxLocation = new SimpleObjectProperty<>(existingWritablePath(DROPBOX_LOCATIONS));
this.gdriveLocation = new SimpleObjectProperty<>(existingWritablePath(GDRIVE_LOCATIONS));
this.onedriveLocation = new SimpleObjectProperty<>(existingWritablePath(ONEDRIVE_LOCATIONS));
this.megaLocation = new SimpleObjectProperty<>(existingWritablePath(MEGA_LOCATIONS));
this.pcloudLocation = new SimpleObjectProperty<>(existingWritablePath(PCLOUD_LOCATIONS));
public ObservedLocationPresets() {
this.iclouddriveLocation = new SimpleObjectProperty<>(LocationPreset.ICLOUDDRIVE.existingPath());
this.dropboxLocation = new SimpleObjectProperty<>(LocationPreset.DROPBOX.existingPath());
this.gdriveLocation = new SimpleObjectProperty<>(LocationPreset.GDRIVE.existingPath());
this.onedriveLocation = new SimpleObjectProperty<>(LocationPreset.ONEDRIVE.existingPath());
this.megaLocation = new SimpleObjectProperty<>(LocationPreset.MEGA.existingPath());
this.pcloudLocation = new SimpleObjectProperty<>(LocationPreset.PCLOUD.existingPath());
this.foundIclouddrive = iclouddriveLocation.isNotNull();
this.foundDropbox = dropboxLocation.isNotNull();
this.foundGdrive = gdriveLocation.isNotNull();
@@ -48,24 +40,6 @@ public class LocationPresets {
this.foundPcloud = pcloudLocation.isNotNull();
}
private static Path existingWritablePath(String... candidates) {
for (String candidate : candidates) {
Path path = Paths.get(resolveHomePath(candidate));
if (Files.isDirectory(path)) {
return path;
}
}
return null;
}
private static String resolveHomePath(String path) {
if (path.startsWith("~/")) {
return USER_HOME + path.substring(1);
} else {
return path;
}
}
/* Observables */
public ReadOnlyObjectProperty<Path> iclouddriveLocationProperty() {

View File

@@ -43,7 +43,9 @@ public abstract class UpdateCheckerModule {
@FxApplicationScoped
static Optional<HttpClient> provideHttpClient() {
try {
return Optional.of(HttpClient.newHttpClient());
return Optional.of(HttpClient.newBuilder() //
.followRedirects(HttpClient.Redirect.NORMAL) // from version 1.6.11 onwards, Cryptomator can follow redirects, in case this URL ever changes
.build());
} catch (UncheckedIOException e) {
LOG.error("HttpClient for update check cannot be created.", e);
return Optional.empty();

View File

@@ -15,6 +15,8 @@ import java.nio.file.Path;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
@ChooseMasterkeyFileScoped
public class ChooseMasterkeyFileController implements FxController {
@@ -46,7 +48,7 @@ public class ChooseMasterkeyFileController implements FxController {
LOG.trace("proceed()");
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("unlock.chooseMasterkey.filePickerTitle"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(resourceBundle.getString("unlock.chooseMasterkey.filePickerMimeDesc"), CRYPTOMATOR_FILENAME_GLOB));
File masterkeyFile = fileChooser.showOpenDialog(window);
if (masterkeyFile != null) {
LOG.debug("Chose masterkey file: {}", masterkeyFile);

View File

@@ -21,13 +21,13 @@ public class VaultDetailLockedController implements FxController {
private final ReadOnlyObjectProperty<Vault> vault;
private final FxApplicationWindows appWindows;
private final VaultOptionsComponent.Builder vaultOptionsWindow;
private final VaultOptionsComponent.Factory vaultOptionsWindow;
private final KeychainManager keychain;
private final Stage mainWindow;
private final BooleanExpression passwordSaved;
@Inject
VaultDetailLockedController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, VaultOptionsComponent.Builder vaultOptionsWindow, KeychainManager keychain, @MainWindow Stage mainWindow) {
VaultDetailLockedController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, VaultOptionsComponent.Factory vaultOptionsWindow, KeychainManager keychain, @MainWindow Stage mainWindow) {
this.vault = vault;
this.appWindows = appWindows;
this.vaultOptionsWindow = vaultOptionsWindow;
@@ -47,12 +47,12 @@ public class VaultDetailLockedController implements FxController {
@FXML
public void showVaultOptions() {
vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
vaultOptionsWindow.create(vault.get()).showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
}
@FXML
public void showKeyVaultOptions() {
vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow(SelectedVaultOptionsTab.KEY);
vaultOptionsWindow.create(vault.get()).showVaultOptionsWindow(SelectedVaultOptionsTab.KEY);
}
/* Getter/Setter */

View File

@@ -13,6 +13,8 @@ import javafx.stage.Stage;
import java.io.File;
import java.util.ResourceBundle;
import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB;
@MainWindowScoped
public class VaultDetailMissingVaultController implements FxController {
@@ -45,7 +47,7 @@ public class VaultDetailMissingVaultController implements FxController {
// copied from ChooseExistingVaultController class
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("addvaultwizard.existing.filePickerTitle"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator"));
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(resourceBundle.getString("addvaultwizard.existing.filePickerMimeDesc"), CRYPTOMATOR_FILENAME_GLOB));
File masterkeyFile = fileChooser.showOpenDialog(window);
if (masterkeyFile != null) {
vault.get().getVaultSettings().path().setValue(masterkeyFile.toPath().toAbsolutePath().getParent());

View File

@@ -31,7 +31,7 @@ public class VaultListContextMenuController implements FxController {
private final VaultService vaultService;
private final KeychainManager keychain;
private final RemoveVaultComponent.Builder removeVault;
private final VaultOptionsComponent.Builder vaultOptionsWindow;
private final VaultOptionsComponent.Factory vaultOptionsWindow;
private final OptionalBinding<VaultState.Value> selectedVaultState;
private final Binding<Boolean> selectedVaultPassphraseStored;
private final Binding<Boolean> selectedVaultRemovable;
@@ -39,7 +39,7 @@ public class VaultListContextMenuController implements FxController {
private final Binding<Boolean> selectedVaultLockable;
@Inject
VaultListContextMenuController(ObjectProperty<Vault> selectedVault, @MainWindow Stage mainWindow, FxApplicationWindows appWindows, VaultService vaultService, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Builder vaultOptionsWindow) {
VaultListContextMenuController(ObjectProperty<Vault> selectedVault, @MainWindow Stage mainWindow, FxApplicationWindows appWindows, VaultService vaultService, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Factory vaultOptionsWindow) {
this.selectedVault = EasyBind.wrapNullable(selectedVault);
this.mainWindow = mainWindow;
this.appWindows = appWindows;
@@ -69,7 +69,7 @@ public class VaultListContextMenuController implements FxController {
@FXML
public void didClickShowVaultOptions() {
selectedVault.ifValuePresent(v -> {
vaultOptionsWindow.vault(v).build().showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
vaultOptionsWindow.create(v).showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
});
}

View File

@@ -48,11 +48,6 @@ public class VolumePreferencesController implements FxController {
webDavPortField.setText(String.valueOf(settings.port().get()));
changeWebDavPortButton.visibleProperty().bind(settings.port().asString().isNotEqualTo(webDavPortField.textProperty()));
changeWebDavPortButton.disableProperty().bind(Bindings.createBooleanBinding(this::validateWebDavPort, webDavPortField.textProperty()).not());
webDavPortField.focusedProperty().addListener((observableValue, wasFocused, isFocused) -> {
if(!isFocused) {
webDavPortField.setText(String.valueOf(settings.port().get()));
}
});
webDavUrlSchemeChoiceBox.getItems().addAll(WebDavUrlScheme.values());
webDavUrlSchemeChoiceBox.valueProperty().bindBidirectional(settings.preferredGvfsScheme());

View File

@@ -36,13 +36,10 @@ public interface VaultOptionsComponent {
stage.requestFocus();
}
@Subcomponent.Builder
interface Builder {
@Subcomponent.Factory
interface Factory {
@BindsInstance
Builder vault(@VaultOptionsWindow Vault vault);
VaultOptionsComponent build();
VaultOptionsComponent create(@BindsInstance @VaultOptionsWindow Vault vault);
}
}

View File

@@ -16,10 +16,6 @@
src: url('opensans-bold.ttf');
}
@font-face {
src: url('quicksand-bold.ttf');
}
/*******************************************************************************
* *
* Root Styling & Colors *
@@ -46,6 +42,8 @@
GRAY_8: #D3DCE1;
GRAY_9: #EDF3F7;
GREEN_3: PRIMARY_D1;
GREEN_5: PRIMARY;
RED_5: #E74C3C;
ORANGE_5: #E67E22;
YELLOW_5: #F1C40F;
@@ -179,14 +177,6 @@
-fx-background-insets: 0, 0 0 1px 0;
}
.main-window .title .label {
-fx-font-family: 'Quicksand';
-fx-font-size: 16px;
-fx-font-style: normal;
-fx-font-weight: 700;
-fx-text-fill: TITLE_TEXT_FILL;
}
.main-window .title .button {
-fx-pref-height: 30px;
-fx-pref-width: 30px;
@@ -405,7 +395,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';
@@ -439,11 +428,11 @@
}
.password-strength-indicator.strength-3 .segment.active {
-fx-background-color: PRIMARY;
-fx-background-color: GREEN_5;
}
.password-strength-indicator.strength-4 .segment.active {
-fx-background-color: PRIMARY_D1;
-fx-background-color: GREEN_3;
}
/*******************************************************************************
@@ -834,6 +823,7 @@
-fx-background-color: PROGRESS_BAR_BG;
-fx-background-radius: 4px;
}
/*******************************************************************************
* *
* I/O Statistics *
@@ -884,6 +874,7 @@
.default-color0.chart-series-area-line {
-fx-stroke: PRIMARY;
}
.default-color0.chart-series-area-fill {
-fx-fill: linear-gradient(to bottom, PRIMARY, transparent);
-fx-stroke: transparent;

View File

@@ -16,10 +16,6 @@
src: url('opensans-bold.ttf');
}
@font-face {
src: url('quicksand-bold.ttf');
}
/*******************************************************************************
* *
* Root Styling & Colors *
@@ -46,6 +42,8 @@
GRAY_8: #E1E1E1;
GRAY_9: #F7F7F7;
GREEN_3: PRIMARY_D1;
GREEN_5: PRIMARY;
RED_5: #E74C3C;
ORANGE_5: #E67E22;
YELLOW_5: #F1C40F;
@@ -178,14 +176,6 @@
-fx-background-color: TITLE_BG;
}
.main-window .title .label {
-fx-font-family: 'Quicksand';
-fx-font-size: 16px;
-fx-font-style: normal;
-fx-font-weight: 700;
-fx-text-fill: TITLE_TEXT_FILL;
}
.main-window .title .button {
-fx-pref-height: 30px;
-fx-pref-width: 30px;
@@ -437,11 +427,11 @@
}
.password-strength-indicator.strength-3 .segment.active {
-fx-background-color: PRIMARY;
-fx-background-color: GREEN_5;
}
.password-strength-indicator.strength-4 .segment.active {
-fx-background-color: PRIMARY_D1;
-fx-background-color: GREEN_3;
}
/*******************************************************************************
@@ -832,22 +822,12 @@
-fx-background-color: PROGRESS_BAR_BG;
-fx-background-radius: 4px;
}
/*******************************************************************************
* *
* I/O Statistics *
* *
******************************************************************************/
.chart {
-fx-padding: 10px;
}
.chart-plot-background {
-fx-background-color: MAIN_BG;
-fx-padding: 20px;
}
/* content */
.cache-arc-background {
-fx-fill: transparent;
@@ -893,6 +873,7 @@
.default-color0.chart-series-area-line {
-fx-stroke: PRIMARY;
}
.default-color0.chart-series-area-fill {
-fx-fill: linear-gradient(to bottom, PRIMARY, transparent);
-fx-stroke: transparent;

View File

@@ -31,12 +31,12 @@
<VBox spacing="6">
<Label wrapText="true" text="%addvaultwizard.new.locationInstruction"/>
<RadioButton fx:id="iclouddriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="iCloud Drive" visible="${controller.locationPresets.foundIclouddrive}" managed="${controller.locationPresets.foundIclouddrive}"/>
<RadioButton fx:id="dropboxRadioButton" toggleGroup="${predefinedLocationToggler}" text="Dropbox" visible="${controller.locationPresets.foundDropbox}" managed="${controller.locationPresets.foundDropbox}"/>
<RadioButton fx:id="gdriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="Google Drive" visible="${controller.locationPresets.foundGdrive}" managed="${controller.locationPresets.foundGdrive}"/>
<RadioButton fx:id="onedriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="OneDrive" visible="${controller.locationPresets.foundOnedrive}" managed="${controller.locationPresets.foundOnedrive}"/>
<RadioButton fx:id="megaRadioButton" toggleGroup="${predefinedLocationToggler}" text="MEGA" visible="${controller.locationPresets.foundMega}" managed="${controller.locationPresets.foundMega}"/>
<RadioButton fx:id="pcloudRadioButton" toggleGroup="${predefinedLocationToggler}" text="pCloud" visible="${controller.locationPresets.foundPcloud}" managed="${controller.locationPresets.foundPcloud}"/>
<RadioButton fx:id="iclouddriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="iCloud Drive" visible="${controller.observedLocationPresets.foundIclouddrive}" managed="${controller.observedLocationPresets.foundIclouddrive}"/>
<RadioButton fx:id="dropboxRadioButton" toggleGroup="${predefinedLocationToggler}" text="Dropbox" visible="${controller.observedLocationPresets.foundDropbox}" managed="${controller.observedLocationPresets.foundDropbox}"/>
<RadioButton fx:id="gdriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="Google Drive" visible="${controller.observedLocationPresets.foundGdrive}" managed="${controller.observedLocationPresets.foundGdrive}"/>
<RadioButton fx:id="onedriveRadioButton" toggleGroup="${predefinedLocationToggler}" text="OneDrive" visible="${controller.observedLocationPresets.foundOnedrive}" managed="${controller.observedLocationPresets.foundOnedrive}"/>
<RadioButton fx:id="megaRadioButton" toggleGroup="${predefinedLocationToggler}" text="MEGA" visible="${controller.observedLocationPresets.foundMega}" managed="${controller.observedLocationPresets.foundMega}"/>
<RadioButton fx:id="pcloudRadioButton" toggleGroup="${predefinedLocationToggler}" text="pCloud" visible="${controller.observedLocationPresets.foundPcloud}" managed="${controller.observedLocationPresets.foundPcloud}"/>
<HBox spacing="12" alignment="CENTER_LEFT">
<RadioButton fx:id="customRadioButton" toggleGroup="${predefinedLocationToggler}" text="%addvaultwizard.new.directoryPickerLabel"/>
<Button contentDisplay="LEFT" text="%addvaultwizard.new.directoryPickerButton" onAction="#chooseCustomVaultPath" disable="${controller.usePresetPath}">

View File

@@ -21,7 +21,7 @@
<Region VBox.vgrow="ALWAYS"/>
<ImageView VBox.vgrow="ALWAYS" fitHeight="128" preserveRatio="true" smooth="true" cache="true">
<Image url="@../img/bot/bot.png"/>
<Image url="@../img/logo.png"/>
</ImageView>
<Region VBox.vgrow="ALWAYS"/>

View File

@@ -26,7 +26,7 @@
<HBox VBox.vgrow="ALWAYS">
<VBox alignment="CENTER" minWidth="175" maxWidth="175">
<ImageView VBox.vgrow="ALWAYS" fitHeight="128" preserveRatio="true" smooth="true" cache="true">
<Image url="@../img/bot/bot.png"/>
<Image url="@../img/logo.png"/>
</ImageView>
</VBox>
<VBox HBox.hgrow="ALWAYS" alignment="CENTER">

View File

@@ -7,6 +7,8 @@
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<HBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:id="titleBar"
@@ -20,7 +22,9 @@
<Insets bottom="6" left="12" right="12" top="6"/>
</padding>
<children>
<Label text="CRYPTOMATOR"/>
<ImageView HBox.hgrow="ALWAYS" fitHeight="14" preserveRatio="true" cache="true">
<Image url="@../img/title-logo.png"/>
</ImageView>
<Region HBox.hgrow="ALWAYS"/>

View File

@@ -18,7 +18,7 @@
<children>
<HBox spacing="12" VBox.vgrow="NEVER">
<ImageView VBox.vgrow="ALWAYS" fitHeight="64" preserveRatio="true" smooth="true" cache="true">
<Image url="@../img/bot/bot.png"/>
<Image url="@../img/logo.png"/>
</ImageView>
<VBox spacing="3" HBox.hgrow="ALWAYS" alignment="CENTER_LEFT">
<FormattedLabel styleClass="label-large" format="Cryptomator %s" arg1="${controller.applicationVersion}"/>

View File

@@ -11,7 +11,7 @@
spacing="24">
<children>
<ImageView VBox.vgrow="ALWAYS" fitHeight="128" preserveRatio="true" smooth="true" cache="true">
<Image url="@../img/bot/bot.png"/>
<Image url="@../img/logo.png"/>
</ImageView>
<TextFlow styleClass="text-flow" prefWidth="-Infinity" visible="${controller.noVaultPresent}" managed="${controller.noVaultPresent}">

View File

@@ -79,6 +79,7 @@ addvault.new.readme.accessLocation.4=Feel free to remove this file.
addvaultwizard.existing.instruction=Choose the "vault.cryptomator" file of your existing vault. If only a file named "masterkey.cryptomator" exists, select that instead.
addvaultwizard.existing.chooseBtn=Choose…
addvaultwizard.existing.filePickerTitle=Select Vault File
addvaultwizard.existing.filePickerMimeDesc=Cryptomator Vault
## Success
addvaultwizard.success.nextStepsInstructions=Added vault "%s".\nYou need to unlock this vault to access or add contents. Alternatively you can unlock it at any later point in time.
addvaultwizard.success.unlockNow=Unlock Now
@@ -108,6 +109,7 @@ unlock.chooseMasterkey.title=Select Masterkey of "%s"
unlock.chooseMasterkey.prompt=Could not find the masterkey file for this vault at its expected location. Please choose the key file manually.
unlock.chooseMasterkey.chooseBtn=Choose…
unlock.chooseMasterkey.filePickerTitle=Select Masterkey File
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator Masterkey
## Success
unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible via its virtual drive.
unlock.success.rememberChoice=Remember choice, don't show this again

View File

@@ -44,7 +44,7 @@ addvaultwizard.new.namePrompt=Tresorname
addvaultwizard.new.locationInstruction=Wo soll Cryptomator die verschlüsselten Dateien deines Tresors ablegen?
addvaultwizard.new.locationLabel=Speicherort
addvaultwizard.new.locationPrompt=
addvaultwizard.new.directoryPickerLabel=Benutzerdefinierter Ort
addvaultwizard.new.directoryPickerLabel=Eigener Ort
addvaultwizard.new.directoryPickerButton=Durchsuchen 
addvaultwizard.new.directoryPickerTitle=Verzeichnis auswählen
addvaultwizard.new.fileAlreadyExists=Eine Datei oder ein Ordner dieses Namens besteht bereits
@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Du kannst diese Datei löschen.
addvaultwizard.existing.instruction=Wähle die Datei „vault.cryptomator“ deines bestehenden Tresors aus. Falls nur eine Datei mit der Bezeichnung „masterkey.cryptomator“ vorhanden ist, nutze stattdessen diese.
addvaultwizard.existing.chooseBtn=Durchsuchen 
addvaultwizard.existing.filePickerTitle=Tresordatei auswählen
addvaultwizard.existing.filePickerMimeDesc=Cryptomator-Tresor
## Success
addvaultwizard.success.nextStepsInstructions=Tresor „%s“ wurde hinzugefügt.\nUm auf Inhalte zuzugreifen oder welche hinzuzufügen, musst du den Tresor entsperren. Du kannst ihn aber auch zu jedem späteren Zeitpunkt entsperren.
addvaultwizard.success.unlockNow=Jetzt entsperren
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Masterkey von „%s“ auswählen
unlock.chooseMasterkey.prompt=Die Masterkey-Datei dieses Tresors konnte nicht gefunden werden. Bitte wähle die Masterkey-Datei manuell aus.
unlock.chooseMasterkey.chooseBtn=Durchsuchen 
unlock.chooseMasterkey.filePickerTitle=Masterkey-Datei auswählen
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator-Masterkey
## Success
unlock.success.message=„%s“ erfolgreich entsperrt! Du kannst nun über das virtuelle Laufwerk auf deinen Tresor zugreifen.
unlock.success.rememberChoice=Auswahl speichern und nicht mehr anzeigen
@@ -357,8 +359,8 @@ vaultOptions.masterkey.recoverPasswordBtn=Passwort wiederherstellen
# Recovery Key
recoveryKey.title=Wiederherstellungsschlüssel
recoveryKey.enterPassword.prompt=Geben Sie Ihr Passwort ein, um den Wiederherstellungsschlüssel für "%s" anzuzeigen:
recoveryKey.display.message=Der folgende Wiederherstellungsschlüssel kann verwendet werden, um den Zugriff auf "%s" wiederherzustellen:
recoveryKey.enterPassword.prompt=Gib dein Passwort ein, um den Wiederherstellungsschlüssel für %s anzuzeigen:
recoveryKey.display.message=Mit dem folgenden Wiederherstellungsschlüssel kannst du den Zugriff auf %s wiederherstellen:
recoveryKey.display.StorageHints=Bewahre ihn möglichst sicher auf, z. B.\n • in einem Passwortmanager\n • auf einem USB-Speicherstick\n • auf Papier ausgedruckt
recoveryKey.recover.prompt=Gib deinen Wiederherstellungsschlüssel für „%s“ ein:
recoveryKey.recover.validKey=Dies ist ein gültiger Wiederherstellungsschlüssel

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Μπορείτε ελεύθερα να αφ
addvaultwizard.existing.instruction=Επιλέξτε το αρχείο "vault.cryptomator" της υπάρχοντος κρύπτης. Αν υπάρχει μόνο ένα αρχείο με όνομα "masterkey.cryptomator", επιλέξτε αυτό.
addvaultwizard.existing.chooseBtn=Επιλογή…
addvaultwizard.existing.filePickerTitle=Επιλέξτε Αρχείο Κρύπτης
addvaultwizard.existing.filePickerMimeDesc=Κρύπτη Cryptomator
## Success
addvaultwizard.success.nextStepsInstructions=Προστέθηκε το vault "%s".\nΠρέπει να ξεκλειδώσετε αυτό το vault για να έχετε πρόσβαση ή να προσθέσετε περιεχόμενο. Εναλλακτικά μπορείτε να το ξεκλειδώσετε κάποια άλλη στιγμή.
addvaultwizard.success.unlockNow=Ξεκλείδωμα τώρα
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Επιλέξτε το Masterkey του "%s"
unlock.chooseMasterkey.prompt=Αδυναμία εύρεσης του αρχείου masterkey για αυτό το vault στην αναμενόμενη τοποθεσία. Παρακαλώ επιλέξτε το αρχείο χειροκίνητα.
unlock.chooseMasterkey.chooseBtn=Επιλογή…
unlock.chooseMasterkey.filePickerTitle=Επιλέξτε το αρχείο Masterkey
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator Masterkey
## Success
unlock.success.message=Ξεκλειδώθηκε "%s" επιτυχώς! Το vault σας είναι διαθέσιμο μέσω του εικονικού δίσκου του.
unlock.success.rememberChoice=Απομνημόνευση επιλογής, μην ρωτήσεις ξανά
@@ -266,7 +268,7 @@ main.closeBtn.tooltip=Κλείσιμο
main.minimizeBtn.tooltip=Ελαχιστοποίηση
main.preferencesBtn.tooltip=Προτιμήσεις
main.debugModeEnabled.tooltip=Έχει ενεργοποιηθεί η λειτουργία αποσφαλμάτωσης
main.supporterCertificateMissing.tooltip=Παρακαλώ σκεφτείτε τη δωρεά
main.supporterCertificateMissing.tooltip=Παρακαλούμε σκεφτείτε να κάνετε δωρεά
## Drag 'n' Drop
main.dropZone.dropVault=Προσθήκη vault
main.dropZone.unknownDragboardContent=Αν θέλετε να προσθέσετε ένα vault, σύρετε το σε αυτό το παράθυρο

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=No dude en eliminar este archivo.
addvaultwizard.existing.instruction=Elija el archivo "vault.cryptomator" de su bóveda existente. Si solo existe un archivo llamado "masterkey.cryptomator", selecciónelo en su lugar.
addvaultwizard.existing.chooseBtn=Elegir…
addvaultwizard.existing.filePickerTitle=Seleccionar archivo de bóveda
addvaultwizard.existing.filePickerMimeDesc=Bóveda de Cryptomator
## Success
addvaultwizard.success.nextStepsInstructions=Bóveda "%s" añadida.\nSe necesita desbloquear esta bóveda para acceder o añadir contenido. Alternativamente se \n puede desbloquear en otro momento.
addvaultwizard.success.unlockNow=Desbloquear ahora
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Seleccionar clave maestra de "%s"
unlock.chooseMasterkey.prompt=No se pudo encontrar el archivo de la clave maestra de esta bóveda en la ubicación esperada. Por favor, elija manualmente el archivo de la clave.
unlock.chooseMasterkey.chooseBtn=Elegir…
unlock.chooseMasterkey.filePickerTitle=Seleccione el archivo de la clave maestra
unlock.chooseMasterkey.filePickerMimeDesc=Clave maestra de Cryptomator
## Success
unlock.success.message=¡Desbloqueo de "%s" exitoso! Su bóveda ahora es accesible a través de su unidad virtual.
unlock.success.rememberChoice=Recordar opción y no mostrar de nuevo

View File

@@ -76,6 +76,7 @@ unlock.unlockBtn=بازکردن قفل
## Write
# Main Window
main.supporterCertificateMissing.tooltip=لطفا کمک مالی در نظر بگیرند
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=قفل

View File

@@ -9,7 +9,7 @@ generic.button.change=Modifier
generic.button.close=Fermer
generic.button.copy=Copier
generic.button.copied=Copié !
generic.button.done=Ok
generic.button.done=OK
generic.button.next=Suivant
generic.button.print=Imprimer
## Error
@@ -62,7 +62,7 @@ addvault.new.readme.storageLocation.fileName=IMPORTANT.rtf
addvault.new.readme.storageLocation.1=Fichiers de coffre-fort
addvault.new.readme.storageLocation.2=Ceci est le chemin de votre coffre-fort.
addvault.new.readme.storageLocation.3=NE PAS
addvault.new.readme.storageLocation.4=Modifier n'importe quel fichier dans ce répertoire ou
addvault.new.readme.storageLocation.4=• modifier les fichiers dans ce répertoire ni
addvault.new.readme.storageLocation.5=• coller de fichier à chiffrer dans ce répertoire.
addvault.new.readme.storageLocation.6=Si vous voulez chiffrer les fichiers et afficher le contenu du coffre, faites ce qui suit :
addvault.new.readme.storageLocation.7=1. Ajouter ce coffre à Cryptomator.
@@ -75,9 +75,10 @@ addvault.new.readme.accessLocation.2=Ceci est le chemin d'accès de votre coffre
addvault.new.readme.accessLocation.3=Tous les fichiers ajoutés à ce volume seront chiffrés par Cryptomator. Vous pouvez l'utiliser comme n'importe quel lecteur/répertoire. Ceci est seulement une vue déchiffrée de son contenu, vos fichiers restent chiffrés dans votre disque dur en permanence.
addvault.new.readme.accessLocation.4=Vous pouvez supprimer ce fichier.
## Existing
addvaultwizard.existing.instruction=Choisissez le fichier "vault.cryptomator" de votre coffre existant. S'il existe seulement un fichier "masterkey.cryptomator", sélectionnez celui-ci.
addvaultwizard.existing.instruction=Choisissez le fichier "vault.cryptomator" de votre volume existant. Si seul le fichier "masterkey.cryptomator" est présent, sélectionnez celui-.
addvaultwizard.existing.chooseBtn=Choisir...
addvaultwizard.existing.filePickerTitle=Sélectionnez le fichier du coffre
addvaultwizard.existing.filePickerTitle=Sélectionnez le fichier correspondant au volume chiffré
addvaultwizard.existing.filePickerMimeDesc=Coffre-fort Cryptomator
## Success
addvaultwizard.success.nextStepsInstructions=Coffre “%s” ajouté.\nIl faudra déverrouiller ce coffre afin dy accéder ou dy ajouter du contenu. Cette action peut être réalisée ultérieurement.
addvaultwizard.success.unlockNow=Déverrouiller
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Sélectionner la clé principale de "%s"
unlock.chooseMasterkey.prompt=Impossible de trouver le fichier clef à l'adresse attendue pour ce coffre. Veuillez sélectionner le fichier clef manuellement.
unlock.chooseMasterkey.chooseBtn=Choisir...
unlock.chooseMasterkey.filePickerTitle=Sélectionner le fichier clef
unlock.chooseMasterkey.filePickerMimeDesc=\ clé principale Cryptomator
## Success
unlock.success.message=“%s” déverrouillé ! Le contenu de votre coffre est maintenant accessible par son lecteur virtuel.
unlock.success.rememberChoice=Se souvenir de mon choix et ne plus me demander
@@ -116,7 +118,7 @@ unlock.error.heading=Impossible de déverrouiller le coffre
### Invalid Mount Point
unlock.error.invalidMountPoint.notExisting=Le point de montage «%s» n'est pas un répertoire, n'est pas vide ou n'existe pas.
unlock.error.invalidMountPoint.existing=Le point de montage/le répertoire existe déjà ou le répertoire parent est manquant: %s
unlock.error.invalidMountPoint.driveLetterOccupied=Le lecteur "%s" est en déjà utilisé.
unlock.error.invalidMountPoint.driveLetterOccupied=Le lecteur "%s" est déjà utilisé.
# Lock
## Force
@@ -156,35 +158,35 @@ migration.impossible.moreInfo=Le coffre-fort peut encore être ouvert avec une v
## Start
health.title=Vérifier l'état de "%s"
health.intro.header=Vérifier l'état
health.intro.text=Le bilan de santé est une série de vérifications pour détecter et corriger d'éventuels problèmes de structure interne au coffre. Rappelez-vous :
health.intro.text=La vérification de l'état est une série de tests pour détecter et corriger d'éventuels problèmes de structure interne au volume. Rappelez-vous :
health.intro.remarkSync=S'assurer que tous les appareils sont complètement synchronisés résout la plupart des problèmes.
health.intro.remarkFix=Certains problèmes ne peuvent pas être corrigés.
health.intro.remarkBackup=Si des données sont corrompues, la seule solution est une sauvegarde.
health.intro.affirmation=J'ai lu et compris les informations ci-dessus
## Start Failure
health.fail.header=Erreur lors du chargement de la configuration du coffre
health.fail.header=Erreur lors du chargement de la configuration du volume chiffré
health.fail.ioError=Une erreur s'est produite lors de l'accès et de la lecture du fichier de configuration.
health.fail.parseError=Une erreur est survenue pendant la lecture de la configuration du coffre.
health.fail.parseError=Une erreur est survenue pendant la lecture de la configuration du volume.
health.fail.moreInfo=Plus d'informations
## Check Selection
health.checkList.description=Sélectionnez les contrôles dans la liste de gauche ou utilisez les boutons ci-dessous.
health.checkList.selectAllButton=Sélectionner toutes les vérifications
health.checkList.deselectAllButton=Désélectionner toutes les vérifications
health.check.runBatchBtn=Exécuter les vérifications sélectionnées
health.checkList.description=Sélectionnez les tests dans la liste de gauche ou utilisez les boutons ci-dessous.
health.checkList.selectAllButton=Sélectionner tous les tests
health.checkList.deselectAllButton=Désélectionner tous les tests
health.check.runBatchBtn=Exécuter les tests sélectionnés
## Detail view
health.check.detail.noSelectedCheck=Pour les résultats, sélectionnez un bilan de santé terminé dans la liste de gauche.
health.check.detail.checkScheduled=La vérification est programmée.
health.check.detail.checkRunning=Vérification en cours d'exécution…
health.check.detail.checkSkipped=La vérification n'a pas été sélectionnée pour être exécutée.
health.check.detail.checkSkipped=Le test n'a pas été sélectionné pour être exécuté.
health.check.detail.checkFinished=La vérification s'est terminée avec succès.
health.check.detail.checkFinishedAndFound=La vérification s'est terminée. Veuillez vérifier les résultats.
health.check.detail.checkFinishedAndFound=Le test est terminé. Veuillez vérifier les résultats.
health.check.detail.checkFailed=La vérification s'est arrêtée en raison d'une erreur.
health.check.detail.checkCancelled=Vérification annulée.
health.check.exportBtn=Exporter le rapport
## Fix Application
health.fix.fixBtn=Réparer
health.fix.successTip=Réparation réussie
health.fix.failTip=Correction échouée, voir le journal pour plus de détails
health.fix.failTip=Réparation ratée, voir le journal pour plus de détails
# Preferences
preferences.title=Préférences
@@ -207,7 +209,7 @@ preferences.interface.language.auto=Valeur du système
preferences.interface.interfaceOrientation=Orientation de l'interface
preferences.interface.interfaceOrientation.ltr=De gauche à droite
preferences.interface.interfaceOrientation.rtl=De droite à gauche
preferences.interface.showMinimizeButton=Afficher le bouton de réduction
preferences.interface.showMinimizeButton=Afficher le bouton Réduire
preferences.interface.showTrayIcon=Montrer l'icône de service (redémarrage nécessaire)
## Volume
preferences.volume=Disque virtuel
@@ -217,7 +219,7 @@ preferences.volume.webdav.scheme=Schéma WebDAV
## Updates
preferences.updates=Mises à jour
preferences.updates.currentVersion=Version actuelle : “%s”
preferences.updates.autoUpdateCheck=Vérifier automatiquement si des formations sont disponibles
preferences.updates.autoUpdateCheck=Vérifier automatiquement lexistence de mise à jour
preferences.updates.checkNowBtn=Vérifier maintenant
preferences.updates.updateAvailable=Mise à jour “%s” disponible.
## Contribution
@@ -268,72 +270,72 @@ main.preferencesBtn.tooltip=Préférences
main.debugModeEnabled.tooltip=Le mode débogage est activé
main.supporterCertificateMissing.tooltip=Merci d'envisager un don
## Drag 'n' Drop
main.dropZone.dropVault=Ajouter ce coffre
main.dropZone.unknownDragboardContent=Si vous voulez ajouter un coffre, faites-le glisser dans cette fenêtre
main.dropZone.dropVault=Ajouter ce volume chiffré
main.dropZone.unknownDragboardContent=Si vous voulez ajouter un volume chiffré, faites-le glisser dans cette fenêtre
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Cliquez ici pour ajouter un coffre
main.vaultlist.emptyList.onboardingInstruction=Cliquez ici pour ajouter un volume chiffré
main.vaultlist.contextMenu.remove=Retirer…
main.vaultlist.contextMenu.lock=Verrouiller
main.vaultlist.contextMenu.unlock=Déverrouiller…
main.vaultlist.contextMenu.unlockNow=Déverrouiller maintenant
main.vaultlist.contextMenu.vaultoptions=Afficher les options du coffre
main.vaultlist.contextMenu.reveal=Révéler le lecteur
main.vaultlist.addVaultBtn=Ajouter un coffre
main.vaultlist.contextMenu.vaultoptions=Afficher les options du volume chiffré
main.vaultlist.contextMenu.reveal=Afficher le lecteur
main.vaultlist.addVaultBtn=Ajouter un volume chiffré
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Merci d'avoir choisi Cryptomateur pour protéger vos fichiers. Si vous avez besoin d'aide, consultez nos guides de démarrage :
### Locked
main.vaultDetail.lockedStatus=VERROUILLÉ
main.vaultDetail.unlockBtn=Déverrouiller…
main.vaultDetail.unlockNowBtn=Déverouiller
main.vaultDetail.optionsBtn=Option du coffre
main.vaultDetail.unlockNowBtn=Déverrouiller maintenant
main.vaultDetail.optionsBtn=Options du volume chiffré
main.vaultDetail.passwordSavedInKeychain=Mot de passe enregistré
### Unlocked
main.vaultDetail.unlockedStatus=DÉVERROUILLÉ
main.vaultDetail.accessLocation=Le contenu de votre coffre est accessible ici :
main.vaultDetail.revealBtn=Révéler le lecteur
main.vaultDetail.revealBtn=Afficher le lecteur
main.vaultDetail.lockBtn=Verrouiller
main.vaultDetail.bytesPerSecondRead=Lecture :
main.vaultDetail.bytesPerSecondWritten=Écriture:
main.vaultDetail.throughput.idle=inactif
main.vaultDetail.throughput.kbps=%.1fkB/s
main.vaultDetail.throughput.mbps=%.1fMB/s
main.vaultDetail.stats=Statistiques du coffre
main.vaultDetail.throughput.kbps=%.1f Ko/s
main.vaultDetail.throughput.mbps=%.1f Mo/s
main.vaultDetail.stats=Statistiques du volume chiffré
### Missing
main.vaultDetail.missing.info=Cryptomateur n'a pas pu trouver de coffre-fort dans ce chemin d'accès.
main.vaultDetail.missing.info=Cryptomator n'a pas pu trouver de volume chiffré dans ce chemin d'accès.
main.vaultDetail.missing.recheck=Revérifier
main.vaultDetail.missing.remove=Retirer de la liste des coffres…
main.vaultDetail.missing.changeLocation=Changer l'Emplacement du Coffre…
main.vaultDetail.missing.remove=Retirer de la liste des volumes…
main.vaultDetail.missing.changeLocation=Changer l'emplacement du volume…
### Needs Migration
main.vaultDetail.migrateButton=Mettre à jour le coffre
main.vaultDetail.migrateButton=Mettre le volume à jour
main.vaultDetail.migratePrompt=Votre coffre doit être converti dans un nouveau format avant d'y accéder
### Error
main.vaultDetail.error.info=Une erreur s'est produite lors du chargement du coffre depuis le disque.
main.vaultDetail.error.info=Une erreur s'est produite lors du chargement du volume depuis le disque.
main.vaultDetail.error.reload=Actualiser
main.vaultDetail.error.windowTitle=Erreur lors du chargement du coffre
main.vaultDetail.error.windowTitle=Erreur lors du chargement du volume
# Wrong File Alert
wrongFileAlert.title=Comment chiffrer ses données
wrongFileAlert.header.title=Avez-vous tenté de chiffrer ces fichiers ?
wrongFileAlert.header.lead=Pour faire cela, Cryptomateur fournit un volume dans votre gestionnaire système de fichiers.
wrongFileAlert.header.lead=Pour faire cela, Cryptomator fournit un volume dans le Finder.
wrongFileAlert.instruction.0=Pour chiffrer des fichiers, suivez ces étapes :
wrongFileAlert.instruction.1=1. Déverrouillez votre coffre.
wrongFileAlert.instruction.2=2. Cliquez sur "Révéler" pour ouvrir le volume dans votre gestionnaire de fichiers.
wrongFileAlert.instruction.1=1. Déverrouillez votre volume chiffré.
wrongFileAlert.instruction.2=2. Cliquez sur "Montrer" pour ouvrir le volume dans le Finder.
wrongFileAlert.instruction.3=3. Ajoutez vos fichiers à ce volume.
wrongFileAlert.link=Pour toute aide supplémentaire, visitez
# Vault Options
## General
vaultOptions.general=Général
vaultOptions.general.vaultName=Nom du coffre-fort
vaultOptions.general.vaultName=Nom du volume chiffré
vaultOptions.general.autoLock.lockAfterTimePart1=Verrouiler en cas d'inactivité pendant
vaultOptions.general.autoLock.lockAfterTimePart2=minutes
vaultOptions.general.unlockAfterStartup=Déverrouiller le coffre au démarrage
vaultOptions.general.unlockAfterStartup=Déverrouiller le volume chiffré au démarrage
vaultOptions.general.actionAfterUnlock=Après un déverrouillage réussi
vaultOptions.general.actionAfterUnlock.ignore=Ne rien faire
vaultOptions.general.actionAfterUnlock.reveal=Afficher le disque
vaultOptions.general.actionAfterUnlock.reveal=Afficher le volume
vaultOptions.general.actionAfterUnlock.ask=Demander
vaultOptions.general.startHealthCheckBtn=Commencer le contrôle de santé
vaultOptions.general.startHealthCheckBtn=Commencer la vérification de l'état
## Mount
vaultOptions.mount=Montage
@@ -350,19 +352,19 @@ vaultOptions.mount.mountPoint.directoryPickerTitle=Choisir un répertoire vide
vaultOptions.masterkey=Mot de passe
vaultOptions.masterkey.changePasswordBtn=Modifier le mot de passe
vaultOptions.masterkey.forgetSavedPasswordBtn=Oublier le mot de passe enregistré
vaultOptions.masterkey.recoveryKeyExplanation=Une clé de récupération est votre seul moyen de rétablir l'accès à un coffre-fort, si vous perdez votre mot de passe.
vaultOptions.masterkey.recoveryKeyExplanation=Une clé de récupération est votre seul moyen de rétablir l'accès à un volume chiffré, si vous perdez votre mot de passe.
vaultOptions.masterkey.showRecoveryKeyBtn=Afficher la clé de récupération
vaultOptions.masterkey.recoverPasswordBtn=Récupération du mot de passe
# Recovery Key
recoveryKey.title=Clé de récupération
recoveryKey.enterPassword.prompt=Entrez votre mot de passe pour afficher la clé de récupération pour "%s":
recoveryKey.enterPassword.prompt=Entrez votre mot de passe pour afficher la clé de récupération de "%s" :
recoveryKey.display.message=La clé de récupération suivante peut être utilisée pour restaurer l'accès à "%s " :
recoveryKey.display.StorageHints=Gardez-le quelque part de façon très sûr, par ex. :\n • Stockez le en utilisant un gestionnaire de mot de passe\n • Enregistrez-le sur une clé USB\n • Imprimez-le sur papier
recoveryKey.display.StorageHints=Gardez-la dans un endroit sûr, par ex. :\n • Stockez-la en utilisant un gestionnaire de mot de passe\n • Enregistrez-la sur une clé USB\n • Imprimez-la
recoveryKey.recover.prompt=Entrez votre clé de récupération pour "%s":
recoveryKey.recover.validKey=Cette clé de récupération est valide
recoveryKey.printout.heading=Clé de récupération Cryptomateur\n"%s"\n
recoveryKey.printout.heading=Clé de récupération Cryptomator "%s"\n
# New Password
newPassword.promptText=Entrer un nouveau mot de passe
@@ -377,5 +379,5 @@ passwordStrength.messageLabel.3=Fort
passwordStrength.messageLabel.4=Très fort
# Quit
quit.prompt=Quitter l'application ? Il y a des coffres déverrouillées.
quit.prompt=Quitter l'application ? Il y a des volumes chiffrés déverrouillés.
quit.lockAndQuit=Verrouiller et quitter

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=תרגיש/י בנוח להסיר את הק
addvaultwizard.existing.instruction=בחר את קובץ "vault.cryptomator" של כספת קיימת. אם קיים קובץ בשם "masterkey.cryptomator" בלבד, בחר/י אותו במקום.
addvaultwizard.existing.chooseBtn=בחר...
addvaultwizard.existing.filePickerTitle=בחר קובץ כספת
addvaultwizard.existing.filePickerMimeDesc=Cryptomator Vault
## Success
addvaultwizard.success.nextStepsInstructions=נוספה כספת "%s".\nהנך צריך/ה לבטל נעילת כספת זו בכדי לקבל גישה או להוסיף קבצים. לחילופין תוכל/י לבטל נעילה בכל נקודת זמן מאוחרת יותר.
addvaultwizard.success.unlockNow=בטל נעילה כעת
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=בחר/י מפתח מאסטר של "%s"
unlock.chooseMasterkey.prompt=מפתח מאסטר של כספת זו לא נמצא במיקום הצפוי. בחר/י בבקשה את המפתח באופן ידני.
unlock.chooseMasterkey.chooseBtn=בחר...
unlock.chooseMasterkey.filePickerTitle=בחר/י קובץ מפתח מאסטר
unlock.chooseMasterkey.filePickerMimeDesc=מפתח ראשי של Cryptomator
## Success
unlock.success.message=הנעילה ל-"%s" בוטלה בהצלחה! הכספת שלך נגישה כעת דרך כונן ווירטואלי.
unlock.success.rememberChoice=זכור בחירה, אל תראה שוב
@@ -174,6 +176,7 @@ preferences.updates=עדכונים
# Main Window
main.closeBtn.tooltip=סגור
main.preferencesBtn.tooltip=העדפות
main.supporterCertificateMissing.tooltip=תרומתך תתקבל בברכה
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=נעילה

View File

@@ -115,6 +115,7 @@ preferences.general=सामान्य
# Main Window
main.closeBtn.tooltip=बंद करें
main.preferencesBtn.tooltip=प्राथमिकताएं
main.supporterCertificateMissing.tooltip=कृपया दान पर विचार करें।
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=लॉक करें

View File

@@ -54,7 +54,7 @@ addvaultwizard.new.locationIsOk=Prikladna lokacija za Vaš trezor
addvaultwizard.new.invalidName=Neispravan naziv trezora. Razmislite o uobičajenom nazivu mape.
### Password
addvaultwizard.new.createVaultBtn=Stvori trezor
addvaultwizard.new.generateRecoveryKeyChoice=Nećete moći pristupiti svojim podacima bez lozinke. Želite li ključ za oporavak za slučaj da izgubite lozinku?
addvaultwizard.new.generateRecoveryKeyChoice=Nećete moći pristupiti svojim podacima bez lozinke. Želite li ključ za oporavak za slučaj gubitka lozinke?
addvaultwizard.new.generateRecoveryKeyChoice.yes=Da molim, bolje spriječiti nego liječiti
addvaultwizard.new.generateRecoveryKeyChoice.no=Ne hvala, neću izgubiti lozinku
### Information
@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Slobodno uklonite ovu datoteku.
addvaultwizard.existing.instruction=Odaberite "vault.cryptomator" datoteku postojećeg trezora. Ako postoji samo datoteka "masterkey.cryptomator", odaberite nju umjesto toga.
addvaultwizard.existing.chooseBtn=Odaberite…
addvaultwizard.existing.filePickerTitle=Odaberite datoteku trezora
addvaultwizard.existing.filePickerMimeDesc=Cryptomator trezor
## Success
addvaultwizard.success.nextStepsInstructions=Dodajte trezor "%s".\nMorate otključati ovaj trezor kako biste pristupili ili dodavali sadržaje. Alternativno, možete ga otključati u bilo koje drugo vrijeme.
addvaultwizard.success.unlockNow=Otključaj sada
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Odaberi glavni ključ za "%s"
unlock.chooseMasterkey.prompt=Nije moguće pronaći datoteku glavnog ključa za ovaj trezor na njegovoj očekivanoj lokaciji. Molimo da ručno odaberete datoteku ključa.
unlock.chooseMasterkey.chooseBtn=Odaberite…
unlock.chooseMasterkey.filePickerTitle=Odaberi datoteku glavnog ključa
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator glavni ključ
## Success
unlock.success.message=Uspješno otključan "%s"! Vaš trezor je sada dostupan kroz svoj virtualni pogon.
unlock.success.rememberChoice=Zapamti izbor, ne prikazuj ovo više
@@ -194,7 +196,7 @@ preferences.general.startHidden=Sakrij prozor kod pokretanja Cryptomator-a
preferences.general.debugLogging=Omogući zapisivanje otklanjanja pogrešaka
preferences.general.debugDirectory=Prikaži datoteke zapisa
preferences.general.autoStart=Pokreni Cryptomator kod pokretanja sustava
preferences.general.keychainBackend=Pohrani lozinka s
preferences.general.keychainBackend=Pohrani lozinke s
## Interface
preferences.interface=Sučelje
preferences.interface.theme=Izgled i Osjećaj
@@ -350,7 +352,7 @@ vaultOptions.mount.mountPoint.directoryPickerTitle=Odaberi praznu mapu
vaultOptions.masterkey=Lozinka
vaultOptions.masterkey.changePasswordBtn=Promijeni lozinku
vaultOptions.masterkey.forgetSavedPasswordBtn=Zaboravi pohranjenu lozinku
vaultOptions.masterkey.recoveryKeyExplanation=Ključ za oporavak je jedini način povrata pristupa trezoru u slučaju da izgubite lozinku.
vaultOptions.masterkey.recoveryKeyExplanation=Ključ za oporavak je jedini način povrata pristupa trezoru u slučaju gubitka lozinke.
vaultOptions.masterkey.showRecoveryKeyBtn=Prikaži ključ za oporavak
vaultOptions.masterkey.recoverPasswordBtn=Obnovi lozinku

View File

@@ -5,7 +5,7 @@
generic.button.apply=Applica
generic.button.back=Indietro
generic.button.cancel=Annulla
generic.button.change=Modifica
generic.button.change=Aggiorna
generic.button.close=Chiudi
generic.button.copy=Copia
generic.button.copied=Copiato!
@@ -14,7 +14,7 @@ generic.button.next=Avanti
generic.button.print=Stampa
## Error
generic.error.title=Errore %s
generic.error.instruction=Ops! Cryptomator non si aspettava che ciò succedesse. Puoi cercare le soluzioni esistenti per questo errore. O se non è stato ancora segnalato, sentiti libero di farlo.
generic.error.instruction=Oops! Cryptomator non si aspettava che ciò accadesse. Puoi cercare soluzioni esistenti per questo errore. Oppure se non è ancora stato segnalato, sentitevi liberi di farlo.
generic.error.hyperlink.lookup=Cerca questo errore
generic.error.hyperlink.report=Segnala questo errore
generic.error.technicalDetails=Dettagli:
@@ -23,13 +23,13 @@ generic.error.technicalDetails=Dettagli:
defaults.vault.vaultName=Cassaforte
# Tray Menu
traymenu.showMainWindow=Mostra
traymenu.showMainWindow=Visualizza
traymenu.showPreferencesWindow=Preferenze
traymenu.lockAllVaults=Blocca Tutto
traymenu.quitApplication=Esci
traymenu.vault.unlock=Sblocca
traymenu.vault.lock=Blocca
traymenu.vault.reveal=Rivela
traymenu.vault.reveal=Mostra
# Add Vault Wizard
addvaultwizard.title=Aggiungi Cassaforte
@@ -41,17 +41,17 @@ addvaultwizard.welcome.existingButton=Apri Cassaforte Esistente
addvaultwizard.new.nameInstruction=Scegli un nome per la cassaforte
addvaultwizard.new.namePrompt=Nome della Cassaforte
### Location
addvaultwizard.new.locationInstruction=Dove Cryptomator dovrebbe memorizzare i file crittografati della tua cassaforte?
addvaultwizard.new.locationLabel=Posizione d'archiviazione
addvaultwizard.new.locationInstruction=Dove dovrebbe memorizzare Cryptomator i file crittografati della tua cassaforte?
addvaultwizard.new.locationLabel=Posizione archivio
addvaultwizard.new.locationPrompt=
addvaultwizard.new.directoryPickerLabel=Posizione Personalizzata
addvaultwizard.new.directoryPickerButton=Scegli…
addvaultwizard.new.directoryPickerTitle=Seleziona la Cartella
addvaultwizard.new.directoryPickerTitle=Seleziona Cartella
addvaultwizard.new.fileAlreadyExists=Un file o una cartella con il nome della cassaforte esiste già
addvaultwizard.new.locationDoesNotExist=Una cartella nel percorso specificato non esiste o non è accessibile
addvaultwizard.new.locationIsNotWritable=Nessun accesso di scrittura al percorso specificato
addvaultwizard.new.locationIsNotWritable=Nessun accesso in scrittura nel percorso specificato
addvaultwizard.new.locationIsOk=Posizione idonea per la tua cassaforte
addvaultwizard.new.invalidName=Nome della cassaforte non valido. Sei pregato di considerare un nome della cartella regolare.
addvaultwizard.new.invalidName=Nome della cassaforte non valido. Sei pregato di considerare un nome valido per la cartella.
### Password
addvaultwizard.new.createVaultBtn=Crea Cassaforte
addvaultwizard.new.generateRecoveryKeyChoice=Non potrai accedere ai tuoi dati senza la tua password. Desideri una chiave di recupero nel caso dovessi perdere la password?
@@ -62,9 +62,9 @@ addvault.new.readme.storageLocation.fileName=IMPORTANTE.rtf
addvault.new.readme.storageLocation.1=⚠️ FILE DELLA CASSAFORTE ⚠️
addvault.new.readme.storageLocation.2=Questa è la posizione d'archiviazione della tua cassaforte.
addvault.new.readme.storageLocation.3=NON
addvault.new.readme.storageLocation.4=• alterare alcun file in questa cartella o
addvault.new.readme.storageLocation.4=• alterare nessun file in questa cartella o
addvault.new.readme.storageLocation.5=• incollare alcun file per la crittografia in questa cartella.
addvault.new.readme.storageLocation.6=Se vuoi crittografare i file e visualizzare il contenuto della cassaforte, fa quanto segue:
addvault.new.readme.storageLocation.6=Se si desidera crittografare i file e visualizzare il contenuto della cassaforte, effettuare le seguenti operazioni:
addvault.new.readme.storageLocation.7=1. Aggiungi questa cassaforte a Cryptomator.
addvault.new.readme.storageLocation.8=2. Sblocca la cassaforte su Cryptomator.
addvault.new.readme.storageLocation.9=3. Apri la posizione d'accesso cliccando sul pulsante "Rivela".
@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Sentiti libero di rimuovere questo file.
addvaultwizard.existing.instruction=Scegliere il file "vault.cryptomator" della tua cassaforte. Se esiste solo un file chiamato "masterkey.cryptomator", allora scegli quello.
addvaultwizard.existing.chooseBtn=Scegli…
addvaultwizard.existing.filePickerTitle=Seleziona file cassaforte
addvaultwizard.existing.filePickerMimeDesc=Cassaforte di Cryptomator
## Success
addvaultwizard.success.nextStepsInstructions=Cassaforte "%s" aggiunta.\nDevi sbloccare questa cassaforte per accedere o aggiungere contenuti. Altrimenti, puoi sbloccarla in qualsiasi momento successivo.
addvaultwizard.success.unlockNow=Sblocca Ora
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Seleziona Masterkey di "%s"
unlock.chooseMasterkey.prompt=Impossibile trovare il file Masterkey per questa cassaforte alla sua posizione prevista. Sei pregato di sceglierlo manualmente.
unlock.chooseMasterkey.chooseBtn=Scegli…
unlock.chooseMasterkey.filePickerTitle=Seleziona il File Masterkey
unlock.chooseMasterkey.filePickerMimeDesc=Chiave principale di Cryptomator
## Success
unlock.success.message="%s" sbloccato correttamente! La tua cassaforte è ora accessibile tramite la sua unità virtuale.
unlock.success.rememberChoice=Ricorda la scelta, non mostrarmelo più
@@ -266,7 +268,7 @@ main.closeBtn.tooltip=Chiudi
main.minimizeBtn.tooltip=Minimizza
main.preferencesBtn.tooltip=Preferenze
main.debugModeEnabled.tooltip=La modalità di debug è abilitata
main.supporterCertificateMissing.tooltip=Sei pregato di considerare di donare
main.supporterCertificateMissing.tooltip=Per favore, considera le donazioni
## Drag 'n' Drop
main.dropZone.dropVault=Aggiungi questa cassaforte
main.dropZone.unknownDragboardContent=Se desideri aggiungere una cassaforte, trascinala a questa finestra

View File

@@ -103,9 +103,12 @@ unlock.passwordPrompt=Skriv inn passordet for "%s":
unlock.savePassword=Husk passord
unlock.unlockBtn=Lås opp
## Select
unlock.chooseMasterkey.title=Velg Hovednøkkel for "%s"
unlock.chooseMasterkey.prompt=Kunne ikke finne hovednøkkelfilen for dette hvelvet på forventet sted. Venligst velg nøkkelfilen manuelt.
unlock.chooseMasterkey.chooseBtn=Velg…
unlock.chooseMasterkey.filePickerTitle=Velg hovednøkkelfil
## Success
unlock.success.message=Vellykket opplåsing av "%s"! Hvelvet ditt er nå tilgjengelig via sin virtuelle stasjon.
unlock.success.rememberChoice=Husk valget - ikke vis dette igjen
unlock.success.revealBtn=Gjør enheten synlig
## Failure
@@ -113,6 +116,7 @@ unlock.error.heading=Klarer ikke å låse opp hvelvet
### Invalid Mount Point
unlock.error.invalidMountPoint.notExisting=Monteringspunktet "%s" er enten ikke en mappe, ikke tom eller eksisterer ikke.
unlock.error.invalidMountPoint.existing=Monteringspunktet "%s" finnes enten allerede eller at overordnet mappe mangler.
unlock.error.invalidMountPoint.driveLetterOccupied=Stasjonsbokstav "%s" er allerede i bruk.
# Lock
## Force
@@ -150,11 +154,32 @@ migration.impossible.moreInfo=Hvelvet kan fortsatt åpnes hvis du bruker en eldr
# Health Check
## Start
health.title=Helsesjekk av "%s"
health.intro.header=Helsesjekk
health.intro.text=Helsesjekk er en samling av kontroller for å detektere og muligens fikse problemer i den interne strukturen av hvelvet ditt. Vennligst husk:
health.intro.remarkSync=Sørg for at alle enheter er helt synkronisert, dette løser de fleste problemer.
health.intro.remarkFix=Ikke alle problemer kan løses.
health.intro.remarkBackup=Hvis data er korrupt, kan bare en sikkerhetskopi hjelpe.
health.intro.affirmation=Jeg har lest og forstått informasjonen ovenfor
## Start Failure
health.fail.header=Feil ved lasting av konfigurasjon til hvelvet
health.fail.ioError=En feil oppstod ved tilgang og lesing av konfigurasjonsfilen.
health.fail.parseError=En feil oppstod ved analysering av konfigurasjonen til hvelvet.
health.fail.moreInfo=Mer informasjon
## Check Selection
health.checkList.description=Velg sjekker i listen til venstre eller bruk knappene nedenfor.
health.checkList.selectAllButton=Velg Alle Sjekkene
health.checkList.deselectAllButton=Fjern valget av alle sjekkene
health.check.runBatchBtn=Kjør de valgte sjekkene
## Detail view
health.check.detail.noSelectedCheck=For å se resultater, velg en fullført helsesjekk i listen til venstre.
health.check.detail.checkScheduled=Helsesjekken er planlagt.
health.check.detail.checkRunning=Helsesjekken kjører for øyeblikket…
health.check.detail.checkSkipped=Helsesjekken ble ikke valgt for å kjøre.
health.check.detail.checkFinished=Helsesjekken ble fullført vellyket.
health.check.detail.checkFinishedAndFound=Helsesjekken er ferdig å kjøre. Vennligst se resultatene.
health.check.detail.checkFailed=Helsesjekken avsluttet på grunn av en feil.
health.check.detail.checkCancelled=Helsesjekken ble avbrutt.
health.check.exportBtn=Eksporter rapport
## Fix Application
health.fix.fixBtn=Reparer
@@ -171,8 +196,19 @@ preferences.general.debugDirectory=Vis loggfiler
preferences.general.autoStart=Start Cryptomator ved systemstart
preferences.general.keychainBackend=Lagre passord med
## Interface
preferences.interface=Grensesnitt
preferences.interface.theme=Utseende og preg
preferences.interface.theme.automatic=Automatisk
preferences.interface.theme.dark=Mørk
preferences.interface.theme.light=Lys
preferences.interface.unlockThemes=Lås opp mørk modus
preferences.interface.language=Språk (krever omstart)
preferences.interface.language.auto=Systemstandard
preferences.interface.interfaceOrientation=Grensesnittorientering
preferences.interface.interfaceOrientation.ltr=Fra venstre til høyre
preferences.interface.interfaceOrientation.rtl=Fra høyre til venstre
preferences.interface.showMinimizeButton=Vis minimer knapp
preferences.interface.showTrayIcon=Vis verktøykasseikon (krever omstart)
## Volume
preferences.volume=Virtuell enhet
preferences.volume.type=Volumtype
@@ -186,6 +222,10 @@ preferences.updates.checkNowBtn=Sjekk nå
preferences.updates.updateAvailable=Oppdatering til versjon %s er tilgjengelig.
## Contribution
preferences.contribute=Støtt oss
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
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
@@ -236,6 +276,7 @@ main.vaultlist.contextMenu.remove=Fjern…
main.vaultlist.contextMenu.lock=Lås
main.vaultlist.contextMenu.unlock=Lås opp…
main.vaultlist.contextMenu.unlockNow=Lås opp nå
main.vaultlist.contextMenu.vaultoptions=Alternativer for hvelvet
main.vaultlist.contextMenu.reveal=Gjør enheten synlig
main.vaultlist.addVaultBtn=Legg til hvelv
## Vault Detail
@@ -267,6 +308,9 @@ main.vaultDetail.missing.changeLocation=Endre hvelvplassering…
main.vaultDetail.migrateButton=Oppgrader hvelv
main.vaultDetail.migratePrompt=Hvelvet ditt må oppgraderes til et nytt format før du kan få tilgang til det
### Error
main.vaultDetail.error.info=Det oppstod en feil under lasting av hvelvet fra stasjonen.
main.vaultDetail.error.reload=Last på nytt
main.vaultDetail.error.windowTitle=Feil ved lasting av hvelvet
# Wrong File Alert
wrongFileAlert.title=Slik krypterer du filer
@@ -282,12 +326,14 @@ wrongFileAlert.link=For ytterligere hjelp, besøk
## General
vaultOptions.general=Generelt
vaultOptions.general.vaultName=Navn på hvelvet
vaultOptions.general.autoLock.lockAfterTimePart1=Lås når inaktiv i
vaultOptions.general.autoLock.lockAfterTimePart2=minutter
vaultOptions.general.unlockAfterStartup=Lås opp hvelvet når du starter Cryptomator
vaultOptions.general.actionAfterUnlock=Etter vellykket opplåsing
vaultOptions.general.actionAfterUnlock.ignore=Ikke gjør noe
vaultOptions.general.actionAfterUnlock.reveal=Gjør enheten synlig
vaultOptions.general.actionAfterUnlock.ask=Spør
vaultOptions.general.startHealthCheckBtn=Start helsesjekk
## Mount
vaultOptions.mount=Montering

View File

@@ -266,7 +266,7 @@ main.closeBtn.tooltip=Sluiten
main.minimizeBtn.tooltip=Minimaliseer
main.preferencesBtn.tooltip=Voorkeuren
main.debugModeEnabled.tooltip=Foutopsporingsmodus is ingeschakeld
main.supporterCertificateMissing.tooltip=Overweeg alstublieft om een donatie te doen
main.supporterCertificateMissing.tooltip=Overweeg alstublieft om te doneren
## Drag 'n' Drop
main.dropZone.dropVault=Voeg deze kluis toe
main.dropZone.unknownDragboardContent=Als u een kluis wilt toevoegen, sleep deze dan naar dit venster

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Jeśli chcesz możesz spokojnie usunąć te
addvaultwizard.existing.instruction=Wybierz plik "vault.cryptomator" w istniejącym sejfie. Jeśli istnieje tylko plik "masterkey.cryptomator", wybierz ten plik.
addvaultwizard.existing.chooseBtn=Wybierz…
addvaultwizard.existing.filePickerTitle=Wybierz plik sejfu
addvaultwizard.existing.filePickerMimeDesc=Sejf Cryptomator-a
## Success
addvaultwizard.success.nextStepsInstructions=Dodano sejf "%s".\nMusisz odblokować ten sejf, aby uzyskać dostęp lub dodać zawartość. Możesz go również odblokować kiedy indziej.
addvaultwizard.success.unlockNow=Odblokuj teraz
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Wybierz Masterkey z "%s"
unlock.chooseMasterkey.prompt=Brak pliku Masterkey dla tego sejfu w oczekiwanej lokalizacji. Proszę wybrać plik klucza ręcznie.
unlock.chooseMasterkey.chooseBtn=Wybierz…
unlock.chooseMasterkey.filePickerTitle=Wybierz plik Masterkey
unlock.chooseMasterkey.filePickerMimeDesc=Klucz główny Cryptomator-a
## Success
unlock.success.message=Odblokowano "%s" pomyślnie! Twój sejf jest teraz dostępny za pomocą dysku wirtualnego.
unlock.success.rememberChoice=Zapamiętaj wybór, nie pokazuj tego ponownie
@@ -196,8 +198,19 @@ preferences.general.debugDirectory=Pokaż pliki logowania
preferences.general.autoStart=Uruchom Cryptomator po uruchomieniu systemu
preferences.general.keychainBackend=Przechowuj hasła za pomocą
## Interface
preferences.interface=Interfejs
preferences.interface.theme=Wygląd
preferences.interface.theme.automatic=Automatyczny
preferences.interface.theme.dark=Ciemny
preferences.interface.theme.light=Jasny
preferences.interface.unlockThemes=Odblokuj ciemny tryb
preferences.interface.language=Język (wymaga restartu)
preferences.interface.language.auto=Domyślny z systemu
preferences.interface.interfaceOrientation=Układ interfejsu
preferences.interface.interfaceOrientation.ltr=Od lewej do prawej
preferences.interface.interfaceOrientation.rtl=Od prawej do lewej
preferences.interface.showMinimizeButton=Pokaż przycisk minimalizacji
preferences.interface.showTrayIcon=Pokaż ikonę zasobnika (wymaga restartu)
## Volume
preferences.volume=Dysk wirtualny
preferences.volume.type=Typ udziału

View File

@@ -72,15 +72,19 @@ addvault.new.readme.storageLocation.10=Se precisar de ajuda, visite a documenta
addvault.new.readme.accessLocation.fileName=BEM-VINDO.rtf
addvault.new.readme.accessLocation.1=🔐 VOLUME CRIPTOGRAFADO 🔐
addvault.new.readme.accessLocation.2=Este é o local de acesso do seu cofre.
addvault.new.readme.accessLocation.3=Qualquer ficheiro adicionado a este volume será encriptado pelo Cryptomator. Poderá trabalhar nestes normalmente como em qualquer outra unidade/pasta. Esta é apenas uma visualização desencriptada do seu conteúdo, os seus ficheiros continuam encriptados no seu disco rígido.
addvault.new.readme.accessLocation.4=Sinta-se livre para remover este ficheiro.
## Existing
addvaultwizard.existing.instruction=Escolha o ficheiro "vault.cryptomator" do seu cofre. Se encontrar unicamente o ficheiro "masterkey.cryptomator", selecione-o.
addvaultwizard.existing.chooseBtn=Escolher…
addvaultwizard.existing.filePickerTitle=Selecionar o ficheiro do cofre
## Success
addvaultwizard.success.nextStepsInstructions=Adicionado cofre "%s".\nPrecisa de destrancar este cofre para aceder ou adicionar conteúdo. Como alternativa, pode destrancá-lo a qualquer momento mais tarde.
addvaultwizard.success.unlockNow=Destrancar agora
# Remove Vault
removeVault.title=Remover Cofre
removeVault.information=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
@@ -90,44 +94,90 @@ changepassword.finalConfirmation=Eu entendo que não poderei aceder aos meus dad
# Forget Password
forgetPassword.title=Esqueci a Senha
forgetPassword.information=Isto irá apagar a palavra-passe deste cofre guardada no porta-chaves do seu sistema.
forgetPassword.confirmBtn=Esqueci a Senha
# Unlock
unlock.title=Desbloquear "%s"
unlock.passwordPrompt=Insira a senha para "%s":
unlock.savePassword=Recordar a palavra-passe
unlock.unlockBtn=Destrancar
## Select
unlock.chooseMasterkey.title=Selecione a Masterkey de "%s"
unlock.chooseMasterkey.prompt=Não foi possível encontrar o ficheiro masterkey no local predefinido para este cofre. Por favor, escolha o ficheiro chave manualmente.
unlock.chooseMasterkey.chooseBtn=Escolher…
unlock.chooseMasterkey.filePickerTitle=Selecionar ficheiro MasterKey
## Success
unlock.success.message="%s" desbloqueado com sucesso! O seu cofre está agora acessível na correspondente unidade virtual.
unlock.success.rememberChoice=Lembrar escolha, não mostrar isto novamente
unlock.success.revealBtn=Revelar unidade
## Failure
unlock.error.heading=Não foi possível desbloquear o cofre
### Invalid Mount Point
unlock.error.invalidMountPoint.notExisting=O ponto de montagem "%s" não é um diretório, não está vazio ou não existe.
unlock.error.invalidMountPoint.existing=O ponto de montagem "%s" já existe ou a pasta antecedente está em falta.
unlock.error.invalidMountPoint.driveLetterOccupied=A letra de unidade "%s" já está sendo usada.
# Lock
## Force
lock.forced.heading=Cadeado falhou\nOr\nBloqueio falhou
lock.forced.message=Bloquear "%s" foi impossibilitado por operações pendentes ou ficheiros abertos. Poderá forçar o bloqueio deste cofre, sob a possiblidade da perda de dados não guardados.
lock.forced.retryBtn=Tente novamente
lock.forced.forceBtn=Forçar bloqueio
## Failure
lock.fail.heading=O bloqueio do cofre falhou.
lock.fail.message=O cofre "%s" não pode ser bloqueado. Certifique-se de que o trabalho não guardado está a salvo noutro lugar e operações importantes de leitura/escrita finalizaram. Para fechar o cofre, termine o processo do Cryptomator.
# Migration
migration.title=Atualizar Cofre
## Start
migration.start.prompt=O seu cofre "%s" precisa de ser atualizado para um formato mais recente. Antes de prosseguir, certifique-se de que não existe nenhuma sincronização pendente neste cofre.
migration.start.confirm=Sim, o meu cofre está completamente sincronizado
## Run
migration.run.enterPassword=Introduza a palavra-passe de "%s"
migration.run.startMigrationBtn=Migrar Cofre
migration.run.progressHint=Isso pode levar algum tempo…
## Success
migration.success.nextStepsInstructions="%s" foi migrado com sucesso.\nPoderá desbloquear o seu cofre agora.
migration.success.unlockNow=Destrancar agora
## Missing file system capabilities
migration.error.missingFileSystemCapabilities.title=Sistema de ficheiros não suportado
migration.error.missingFileSystemCapabilities.description=O processo de migração não foi iniciado, porque o seu cofre está localizado num sistema de ficheiros inadequado.
migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=O sistema de ficheiros não suporta nomes de ficheiro longos.
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=O sistema de ficheiros não suporta nomes de caminho longos.
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=O sistema de ficheiros não permite a sua leitura.
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=O sistema de ficheiros não permite ser guardado.
## Impossible
migration.impossible.heading=Não foi possível migrar o cofre
migration.impossible.reason=Não foi possível migrar o cofre automaticamente porque a sua localização de armazenamento ou o ponto de acesso não é compatível.
migration.impossible.moreInfo=O cofre poderá ser aberto com uma versão mais antiga. Para instruções sobre como migrar um cofre manualmente, visite
# Health Check
## Start
health.title=Análise da saúde de "%s"
health.intro.header=Análise de saúde
health.intro.text=A análise de saúde é uma coleção de verificações para detetar e potencialmente corrigir problemas na estrutura interna do seu cofre. Lembre-se de:
health.intro.remarkSync=Certifique-se de que todos os dispositivos estejam completamente sincronizados, pois isto resolve a maioria dos problemas.
health.intro.remarkFix=Nem todos os problemas podem ser corrigidos.
health.intro.remarkBackup=Se os dados estiverem corrompidos, apenas um backup prévio poderá ajudar.
health.intro.affirmation=Li e entendi as informações acima
## Start Failure
health.fail.header=Erro ao carregar a configuração do cofre
health.fail.ioError=Ocorreu um erro ao aceder e ler o arquivo de configuração.
health.fail.parseError=Ocorreu um erro ao analisar a configuração do cofre.
health.fail.moreInfo=Mais informações
## Check Selection
health.checkList.description=Selecione as verificações na lista esquerda ou use os botões abaixo.
health.checkList.selectAllButton=Selecionar Todas as Verificações
health.checkList.deselectAllButton=Desmarcar Todas as Verificações
health.check.runBatchBtn=Executar as Verificações Selecionadas
## Detail view
health.check.detail.noSelectedCheck=Para resultados, selecione uma análise de saúde terminada na lista à esquerda.
health.check.detail.checkScheduled=A verificação está programada.
health.check.detail.checkRunning=A verificação está atualmente a decorrer…
health.check.detail.checkSkipped=A verificação não foi selecionada para ser executada.
health.check.detail.checkFinished=A verificação foi concluída com sucesso.
health.check.detail.checkFinishedAndFound=A verificação concluiu. Por favor, reveja os resultados.
## Fix Application
# Preferences
@@ -158,16 +208,19 @@ preferences.about=Sobre
main.closeBtn.tooltip=Fechar
main.minimizeBtn.tooltip=Minimizar
main.preferencesBtn.tooltip=Preferências
main.supporterCertificateMissing.tooltip=Por favor, considere doar
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=Trancar
main.vaultlist.contextMenu.unlockNow=Destrancar agora
main.vaultlist.contextMenu.reveal=Revelar unidade
main.vaultlist.addVaultBtn=Adicionar Cofre
## Vault Detail
### Welcome
### Locked
main.vaultDetail.unlockNowBtn=Destrancar agora
### Unlocked
main.vaultDetail.revealBtn=Revelar unidade
main.vaultDetail.lockBtn=Trancar
main.vaultDetail.throughput.idle=inativo
main.vaultDetail.throughput.kbps=%.1f kiB/s
@@ -192,6 +245,7 @@ vaultOptions.general=Geral
vaultOptions.general.vaultName=Nome do Cofre
vaultOptions.general.unlockAfterStartup=Destrancar o cofre ao iniciar o Cryptomator
vaultOptions.general.actionAfterUnlock=Após destrancar com sucesso
vaultOptions.general.actionAfterUnlock.reveal=Revelar unidade
vaultOptions.general.actionAfterUnlock.ask=Perguntar
## Mount

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Sinta-se livre para apagar este arquivo.
addvaultwizard.existing.instruction=Escolha o arquivo "vault.cryptomator" do seu cofre existente. Se existir apenas um arquivo chamado "masterkey.cryptomator", selecione outro.
addvaultwizard.existing.chooseBtn=Selecionar…
addvaultwizard.existing.filePickerTitle=Selecionar arquivo do Cofre
addvaultwizard.existing.filePickerMimeDesc=Cofre Cryptomator
## Success
addvaultwizard.success.nextStepsInstructions=Cofre "%s" adicionado.\nVocê precisa desbloquear este cofre para acessar ou adicionar conteúdo. Você também pode desbloqueá-lo a qualquer momento.
addvaultwizard.success.unlockNow=Desbloquear Agora
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Selecione o Masterkey de "%s"
unlock.chooseMasterkey.prompt=Não foi possível encontrar o arquivo Masterkey deste cofre no local esperado. Por favor selecione o arquivo chave manualmente.
unlock.chooseMasterkey.chooseBtn=Escolher…
unlock.chooseMasterkey.filePickerTitle=Selecionar Arquivo Masterkey
unlock.chooseMasterkey.filePickerMimeDesc=Chave mestra do Cryptomator
## Success
unlock.success.message="%s" desbloqueado com êxito! Seu cofre agora está acessível na unidade virtual.
unlock.success.rememberChoice=Lembrar opção escolhida, não mostrar isto novamente
@@ -266,7 +268,7 @@ main.closeBtn.tooltip=Fechar
main.minimizeBtn.tooltip=Minimizar
main.preferencesBtn.tooltip=Preferências
main.debugModeEnabled.tooltip=Modo de depuração ativado
main.supporterCertificateMissing.tooltip=Por favor, considere uma doação
main.supporterCertificateMissing.tooltip=Por favor, considere doar para esse projeto
## Drag 'n' Drop
main.dropZone.dropVault=Adicionar este cofre
main.dropZone.unknownDragboardContent=Se você quer adicionar um cofre, arraste-o para esta janela

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Этот файл можно удалить
addvaultwizard.existing.instruction=Выберите файл "vault.cryptomator" существующего хранилища. Если имеется только файл "masterkey.cryptomator", выберите его.
addvaultwizard.existing.chooseBtn=Выбрать…
addvaultwizard.existing.filePickerTitle=Выберите файл хранилища
addvaultwizard.existing.filePickerMimeDesc=Хранилище Cryptomator
## Success
addvaultwizard.success.nextStepsInstructions=Добавлено хранилище "%s".\nДля добавления данных или доступа к содержимому нужно разблокировать хранилище. Его можно разблокировать и позже.
addvaultwizard.success.unlockNow=Разблокировать
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Выберите файл MasterKey для "%s"
unlock.chooseMasterkey.prompt=Не удалось найти файл MasterKey для этого хранилища в ожидаемом месте. Выберите ключевой файл вручную.
unlock.chooseMasterkey.chooseBtn=Выбрать…
unlock.chooseMasterkey.filePickerTitle=Выберите файл MasterKey
unlock.chooseMasterkey.filePickerMimeDesc=Мастер-ключ Cryptomator
## Success
unlock.success.message=Разблокировка "%s" успешно выполнена! Доступ в хранилище открыт через его виртуальный диск.
unlock.success.rememberChoice=Запомнить выбор и больше не спрашивать

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Tento súbor môžete kedykoľvek odstráni
addvaultwizard.existing.instruction=Zvoľte "vault.cryptomator" súbor Vášho existujúceho trezora. Ak existuje iba súbor s menom "masterkey.cryptomator", vyberte ho namiesto.
addvaultwizard.existing.chooseBtn=Vybrať…
addvaultwizard.existing.filePickerTitle=Zvoľte súbor trezora
addvaultwizard.existing.filePickerMimeDesc=Trezor Cryptomátora
## Success
addvaultwizard.success.nextStepsInstructions=Pridaný trezor "%s".\nAk chcete získať prístup alebo pridať obsah, musíte tento trezor odomknúť. Prípadne ju môžete odomknúť kedykoľvek neskôr.
addvaultwizard.success.unlockNow=Odomknúť teraz
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=Vyberte súbor s hlavným kľúčom "%s"
unlock.chooseMasterkey.prompt=Nemožno nájsť hlavný kľúčový súbor pre tento trezor na jeho očakávanom mieste. Prosím zvoľte kľúčový súbor manuálne.
unlock.chooseMasterkey.chooseBtn=Vybrať…
unlock.chooseMasterkey.filePickerTitle=Zvoľte hlavný kľúčový súbor
unlock.chooseMasterkey.filePickerMimeDesc=Hlavný kľúč Cryptomátora
## Success
unlock.success.message=Odomknutie "%s" úspešné! Váš trezor je už prístupný cez jeho virtuálny disk.
unlock.success.rememberChoice=Zapamätať voľbu, už viac nezobrazovať

View File

@@ -0,0 +1,378 @@
# Locale Specific CSS files such as CJK, RTL,...
# Generics
## Button
generic.button.apply=Tekeleza
generic.button.back=Rudi
generic.button.cancel=Katisha
generic.button.change=Badilisha
generic.button.close=Futa
generic.button.copy=Nakili
generic.button.copied=Nakiliwa!
generic.button.done=Tayari
generic.button.next=Nyingine
generic.button.print=Chapisha
## Error
generic.error.title=Kosa %s
generic.error.instruction=Lo! Cryptomator haikutarajia hii kutokea. Unaweza kutafuta suluhu zilizopo za kosa hili. Au ikiwa haijaripotiwa bado, jisikie huru kufanya hivyo.
generic.error.hyperlink.lookup=Angalia kosa hili
generic.error.hyperlink.report=Ripoti kosa hili
generic.error.technicalDetails=Maelezo:
# Defaults
defaults.vault.vaultName=Kuba
# Tray Menu
traymenu.showMainWindow=Onyesha
traymenu.showPreferencesWindow=Mapendeleo
traymenu.lockAllVaults=Funga yote
traymenu.quitApplication=Aga
traymenu.vault.unlock=Fungua
traymenu.vault.lock=Funga
traymenu.vault.reveal=Kufunua
# Add Vault Wizard
addvaultwizard.title=Ongeza Kuba
## Welcome
addvaultwizard.welcome.newButton=Unda kuba mpya
addvaultwizard.welcome.existingButton=Fungua Kuba iliyopo
## New
### Name
addvaultwizard.new.nameInstruction=Chagua jina la kuba
addvaultwizard.new.namePrompt=Jina la kuba
### Location
addvaultwizard.new.locationInstruction=Cryptomator inapaswa kuhifadhi wapi mafaili yaliyosimbwa kwa njia fiche za kuba yako?
addvaultwizard.new.locationLabel=Mahali pa kuhifadhi
addvaultwizard.new.locationPrompt=
addvaultwizard.new.directoryPickerLabel=Mahali Maalum
addvaultwizard.new.directoryPickerButton=Chagua…
addvaultwizard.new.directoryPickerTitle=Teua Mpangilio orodha
addvaultwizard.new.fileAlreadyExists=Faili au saraka iliyo na jina la kuba tayari ipo
addvaultwizard.new.locationDoesNotExist=Faili au saraka iliyo na jina la kuba tayari ipo
addvaultwizard.new.locationIsNotWritable=Hakuna ufikivu wa kuandika katika njia iliyobainishwa
addvaultwizard.new.locationIsOk=Mahali panapofaa kwa kuba yako
addvaultwizard.new.invalidName=Jina batili la kuba. Tafadhali fikiria jina la kawaida la saraka.
### Password
addvaultwizard.new.createVaultBtn=Unda Kuba
addvaultwizard.new.generateRecoveryKeyChoice=Hutaweza kufikia data yako bila neno la siri lako. Unataka ufunguo wa kurejesha kwa kesi unayopoteza neno lako la siri?
addvaultwizard.new.generateRecoveryKeyChoice.yes=Ndio, tafadhali, salama zaidi kuliko kujuta
addvaultwizard.new.generateRecoveryKeyChoice.no=Hapana asante, sitapoteza neno langu la siri
### Information
addvault.new.readme.storageLocation.fileName=MUHIMU.rtf
addvault.new.readme.storageLocation.1=⚠️ MAFAILI YA KUBA ⚠️
addvault.new.readme.storageLocation.2=Hii ni mahali pa kuhifadhi kuba yako.
addvault.new.readme.storageLocation.3=LA
addvault.new.readme.storageLocation.4=• kubadilisha faili zozote ndani ya saraka hii au
addvault.new.readme.storageLocation.5=• ubandike faili zozote za usimbaji fiche kwenye saraka hii.
addvault.new.readme.storageLocation.6=Ikiwa unataka kusimba faili na kuona maudhui ya kuba, fanya yafuatayo:
addvault.new.readme.storageLocation.7=1. Ongeza kuba hii kwenye Cryptomator.
addvault.new.readme.storageLocation.8=2. Fungua kuba katika Cryptomator.
addvault.new.readme.storageLocation.9=Fungua eneo la ufikiaji kwa kubofya kitufe cha "Reveal".
addvault.new.readme.storageLocation.10=Ikiwa unahitaji msaada, tembelea nyaraka: %s
addvault.new.readme.accessLocation.fileName=KARIBU.rtf
addvault.new.readme.accessLocation.1=🔐️ SAUTI ILIYOSIMBWA KWA NJE FICHE 🔐️
addvault.new.readme.accessLocation.2=Hii ni eneo la ufikiaji wa kuba yako.
addvault.new.readme.accessLocation.3=Faili zozote zilizoongezwa kwenye sauti hii zitasimbwa kwa njia fiche na Cryptomator. Unaweza kufanya kazi juu yake kama kwenye kiendeshi/folda nyingine yoyote. Huu ni mwonekano uliosimbwa tu wa maudhui yake, faili zako zinabaki zimesimbwa kwa njia fiche kwenye diski yako kuu wakati wote.
addvault.new.readme.accessLocation.4=Jisikie huru kuondoa faili hii.
## Existing
addvaultwizard.existing.instruction=Chagua faili ya "vault.cryptomator" ya kuba yako iliyopo. Ikiwa faili tu inayoitwa "masterkey.cryptomator" ipo, chagua hiyo badala yake.
addvaultwizard.existing.chooseBtn=Chagua…
addvaultwizard.existing.filePickerTitle=Teua Faili ya Kuba
## Success
addvaultwizard.success.nextStepsInstructions=Kuba iliyoongezwa "%s".\n Unahitaji kufungua kuba hii ili kufikia au kuongeza yaliyomo. Vinginevyo unaweza kuifungua wakati wowote wa baadaye kwa wakati.
addvaultwizard.success.unlockNow=Fungua Sasa
# Remove Vault
removeVault.title=Ondoa Kuba
removeVault.information=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
changepassword.enterOldPassword=Ingiza neno la siri la sasa ya "%s"
changepassword.finalConfirmation=Ninaelewa kuwa sitaweza kufikia data yangu ikiwa nitasahau nenosiri langu
# Forget Password
forgetPassword.title=Sahau Neno la siri
forgetPassword.information=Hii itafuta neno la siri iliyohifadhiwa ya kuba hii kutoka kwa kitufe cha mfumo wako.
forgetPassword.confirmBtn=Sahau Neno la siri
# Unlock
unlock.title=Fungua "%s"
unlock.passwordPrompt=Weka neno la siri ya "%s":
unlock.savePassword=Kumbuka neno la siri
unlock.unlockBtn=Fungua
## Select
unlock.chooseMasterkey.title=Chagua Masterkey ya "%s"
unlock.chooseMasterkey.prompt=Haikuweza kupata faili kuu ya kuba hii katika mahali pake palipotarajiwa. Tafadhali chagua faili muhimu kwa mikono.
unlock.chooseMasterkey.chooseBtn=Chagua…
unlock.chooseMasterkey.filePickerTitle=Teua Faili ya Masterkey
## Success
unlock.success.message=Imefunguliwa "%s" kwa mafanikio! Kuba yako sasa inapatikana kupitia kiendeshi chake cha kawaida.
unlock.success.rememberChoice=Kumbuka chaguo, usionyeshe hii tena
unlock.success.revealBtn=Fichua Kiendeshaji
## Failure
unlock.error.heading=Haiwezi kufungua kuba
### Invalid Mount Point
unlock.error.invalidMountPoint.notExisting=Sehemu ya mlima "%s" sio saraka, sio tupu au haipo.
unlock.error.invalidMountPoint.existing=Sehemu ya mlima "%s" tayari ipo au folda kuu haipo.
unlock.error.invalidMountPoint.driveLetterOccupied=Barua ya Hifadhi "%s" tayari inatumika.
# Lock
## Force
lock.forced.heading=Funga imeshindikana
lock.forced.message=Kufunga "%s" kulizuiwa na shughuli zinazosubiri au kufungua mafaili. Unaweza kulazimisha kufunga kuba hii, hata hivyo kukatiza I/O kunaweza kusababisha upotezaji wa data isiyohifadhiwa.
lock.forced.retryBtn=Jaribu tena
lock.forced.forceBtn=Lazimisha Kufunga
## Failure
lock.fail.heading=Kufunga kuba kumeshindikana.
lock.fail.message=Kuba "%s" haikuweza kufungwa. Hakikisha kazi isiyohifadhiwa imehifadhiwa mahali pengine na shughuli muhimu za Kusoma/Kuandika zimekamilika. Ili kufunga kuba, kuua mchakato wa Cryptomator.
# Migration
migration.title=Pandisha daraja Kuba
## Start
migration.start.prompt=Kuba yako "%s" inahitaji kusasishwa hadi umbizo jipya zaidi. Kabla ya kuendelea, hakikisha hakuna ulandanishi unaosubiri unaoathiri kuba hii.
migration.start.confirm=Ndio, kuba yangu imesawazishwa kikamilifu
## Run
migration.run.enterPassword=Ingiza neno la siri ya "%s"
migration.run.startMigrationBtn=Hamisha Kuba
migration.run.progressHint=Hii inaweza kuchukua muda…
## Success
migration.success.nextStepsInstructions=Kuhamia "%s" kwa mafanikio.\nSasa unaweza kufungua kuba yako.
migration.success.unlockNow=Fungua Sasa
## Missing file system capabilities
migration.error.missingFileSystemCapabilities.title=Mfumo wa Faili Usiotegemezwa
migration.error.missingFileSystemCapabilities.description=Uhamiaji haukuanzishwa, kwa sababu kuba yako iko kwenye mfumo duni wa faili.
migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Mfumo wa faili hautegemezi majina marefu ya faili.
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Mfumo wa faili hautegemezi njia ndefu.
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Mfumo wa faili hauruhusu kusomwa.
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Mfumo wa faili hauruhusu kuandikwa.
## Impossible
migration.impossible.heading=Haiwezi kuhamisha kuba
migration.impossible.reason=Kuba haiwezi kuhamishwa kiotomatiki kwa sababu mahali pake pa kuhifadhi au mahali pa ufikivu havioani.
migration.impossible.moreInfo=Kuba bado inaweza kufunguliwa na toleo la zamani. Kwa maagizo juu ya jinsi ya kuhamisha kuba kwa mikono, tembelea
# Health Check
## Start
health.title=Uchunguzi wa afya wa "%s"
health.intro.header=Uchunguzi wa afya
health.intro.text=Ukaguzi wa afya ni mkusanyiko wa hundi ili kugundua na uwezekano wa kurekebisha matatizo katika muundo wa ndani wa vault yako. Tafadhali kumbuka:
health.intro.remarkSync=Hakikisha vifaa vyote vimesawazishwa kabisa, hii inatatua matatizo mengi.
health.intro.remarkFix=Sio matatizo yote yanaweza kutatuliwa.
health.intro.remarkBackup=Ikiwa data imeharibika, chelezo tu inaweza kusaidia.
health.intro.affirmation=Nimesoma na kuelewa habari hapo juu
## Start Failure
health.fail.header=Kosa la kupakia Usanidi wa Kuba
health.fail.ioError=Kosa limetokea wakati wa kufikia na kusoma faili ya usanidi.
health.fail.parseError=Kosa limetokea wakati wa kupambanua usanidi wa kuba.
health.fail.moreInfo=Maelezo Zaidi
## Check Selection
health.checkList.description=Chagua hundi katika orodha ya kushoto au tumia vitufe hapa chini.
health.checkList.selectAllButton=Teua Ukaguzi Wote
health.checkList.deselectAllButton=Ondoa Ukaguzi Wote
health.check.runBatchBtn=Endesha Ukaguzi Ulioteuliwa
## Detail view
health.check.detail.noSelectedCheck=Kwa matokeo chagua ukaguzi wa afya uliomalizika katika orodha ya kushoto.
health.check.detail.checkScheduled=Ukaguzi umepangwa.
health.check.detail.checkRunning=Ukaguzi unaendelea kwa sasa…
health.check.detail.checkSkipped=Ukaguzi haukuteuliwa kuendesha.
health.check.detail.checkFinished=Ukaguzi umekamilika kwa ufanisi.
health.check.detail.checkFinishedAndFound=Ukaguzi ulimaliza kukimbia. Tafadhali angalia matokeo.
health.check.detail.checkFailed=Ukaguzi ulitoka kwa sababu ya kosa.
health.check.detail.checkCancelled=Ukaguzi ulikatishwa.
health.check.exportBtn=Hamisha Ripoti
## Fix Application
health.fix.fixBtn=Kurekebisha
health.fix.successTip=Rekebisha imefanikiwa
health.fix.failTip=Rekebisha imeshindwa, angalia logi kwa maelezo
# Preferences
preferences.title=Mapendeleo
## General
preferences.general=Jumla
preferences.general.startHidden=Ficha dirisha wakati wa kuanza Cryptomator
preferences.general.debugLogging=Wezesha utatuzi wa ufunguaji
preferences.general.debugDirectory=Fichua faili za logi
preferences.general.autoStart=Zindua Cryptomator kwenye kuanza kwa mfumo
preferences.general.keychainBackend=Hifadhi neno la siri na
## Interface
preferences.interface.theme=Angalia & Jisikie
preferences.interface.theme.automatic=Otomatiki
preferences.interface.theme.dark=Giza
preferences.interface.theme.light=Mwanga
preferences.interface.unlockThemes=Fungua hali ya giza
preferences.interface.language=Lugha (inahitaji kuanzisha upya)
preferences.interface.language.auto=Chaguo-msingi la Mfumo
preferences.interface.interfaceOrientation=Mwelekeo wa Kiolesura
preferences.interface.interfaceOrientation.ltr=Kushoto kwenda Kulia
preferences.interface.interfaceOrientation.rtl=Kulia hadi Kushoto
preferences.interface.showMinimizeButton=Onyesha kitufe cha kupunguza
preferences.interface.showTrayIcon=Onyesha ikoni ya trei (inahitaji kuanzisha upya)
## Volume
preferences.volume=Kiendeshi pepe
preferences.volume.type=Aina ya Sauti
preferences.volume.webdav.port=Kituo tarishi cha WebDAV
preferences.volume.webdav.scheme=Mpango wa WebDAV
## Updates
preferences.updates=Sasishi
preferences.updates.currentVersion=Toleo la Sasa: %s
preferences.updates.autoUpdateCheck=Kagua sasishi otomatiki
preferences.updates.checkNowBtn=Angalia Sasa
preferences.updates.updateAvailable=Sasisha hadi toleo %s inapatikana.
## Contribution
preferences.contribute=Tusaidie
preferences.contribute.registeredFor=Cheti cha kiungaji mkono kimesajiliwa kwa %s
preferences.contribute.noCertificate=Msaada Cryptomator na kupokea cheti cha msaidizi. Ni kama ufunguo wa leseni lakini kwa watu wa kushangaza wanaotumia programu ya bure. ;-)
preferences.contribute.getCertificate=Je, si kuwa na moja tayari? Jifunze jinsi unaweza kupata.
preferences.contribute.promptText=Bandika msimbo wa cheti cha msaidizi hapa
#<-- Add entries for donations and code/translation/documentation contribution -->
## About
preferences.about=Kuhusu
# Vault Statistics
stats.title=Takwimu za %s
stats.cacheHitRate=Kiwango cha Hit ya Akiba
## Read
stats.read.throughput.idle=Soma: bila kazi
stats.read.throughput.kibs=Soma:%.2f kiB/s
stats.read.throughput.mibs=Soma:%.2fMiB/s
stats.read.total.data.none=Data soma: -
stats.read.total.data.kib=Data soma:%.1f kiB
stats.read.total.data.mib=Data soma: %.1f MiB
stats.read.total.data.gib=Data soma: %.1f GiB
stats.decr.total.data.none=Data iliyosimbwa kwa njia fiche: -
stats.decr.total.data.kib=Data iliyosimbwa kwa njia fiche: %.1f kiB
stats.decr.total.data.mib=Data iliyosimbwa kwa njia fiche: %.1fMiB
stats.decr.total.data.gib=Data iliyosimbwa kwa njia fiche: %.1f GiB
stats.read.accessCount=Jumla ya kusoma: %d
## Write
stats.write.throughput.idle=Andika: bila kazi
stats.write.throughput.kibs=Andika:%.2f kiB/s
stats.write.throughput.mibs=Andika: %.2f MiB/s
stats.write.total.data.none=Data iliyoandikwa: -
stats.write.total.data.kib=Data iliyoandikwa: %.1f kiB
stats.write.total.data.mib=Data iliyoandikwa: %.1f MiB
stats.write.total.data.gib=Data iliyoandikwa: %.1f GiB
stats.encr.total.data.none=Data iliyosimbwa kwa njia fiche: -
stats.encr.total.data.kib=Data iliyosimbwa kwa njia fiche: %.1f kiB
stats.encr.total.data.mib=Data iliyosimbwa kwa njia fiche: %.1f MiB
stats.encr.total.data.gib=Data iliyosimbwa kwa njia fiche: %.1f GiB
stats.write.accessCount=Jumla ya maandishi anaandika: %d
# Main Window
main.closeBtn.tooltip=Futa
main.minimizeBtn.tooltip=Kupunguza
main.preferencesBtn.tooltip=Mapendeleo
main.debugModeEnabled.tooltip=Hali ya utatuzi imewezeshwa
main.supporterCertificateMissing.tooltip=Tafadhali fikiria kuchangia
## Drag 'n' Drop
main.dropZone.dropVault=Ongeza kuba hii
main.dropZone.unknownDragboardContent=Ikiwa unataka kuongeza kuba, iburute kwenye dirisha hili
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Bofya hapa ili kuongeza kuba
main.vaultlist.contextMenu.remove=Ondoa…
main.vaultlist.contextMenu.lock=Funga
main.vaultlist.contextMenu.unlock=Fungua…
main.vaultlist.contextMenu.unlockNow=Fungua Sasa
main.vaultlist.contextMenu.vaultoptions=Onyesha Machaguo ya Kuba
main.vaultlist.contextMenu.reveal=Fichua Kiendeshaji
main.vaultlist.addVaultBtn=Ongeza Kuba
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Shukrani kwa kuchagua Cryptomator kulinda faili zako. Ikiwa unahitaji msaada wowote, angalia miongozo yetu ya kuanza:
### Locked
main.vaultDetail.lockedStatus=IMEFUNGWA
main.vaultDetail.unlockBtn=Fungua…
main.vaultDetail.unlockNowBtn=Fungua Sasa
main.vaultDetail.optionsBtn=Machaguo ya Kuba
main.vaultDetail.passwordSavedInKeychain=Neno la siri limehifadhiwa
### Unlocked
main.vaultDetail.unlockedStatus=IMEFUNGULIWA
main.vaultDetail.accessLocation=Yaliyomo kwenye kuba yako yanapatikana hapa:
main.vaultDetail.revealBtn=Fichua Kiendeshaji
main.vaultDetail.lockBtn=Funga
main.vaultDetail.bytesPerSecondRead=Soma:
main.vaultDetail.bytesPerSecondWritten=Andika:
main.vaultDetail.throughput.idle=imezubaa
main.vaultDetail.throughput.kbps=%.1f kiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Takwimu za Kuba
### Missing
main.vaultDetail.missing.info=Cryptomator haikuweza kupata kuba katika njia hii.
main.vaultDetail.missing.recheck=Kagua upya
main.vaultDetail.missing.remove=Ondoa kutoka kwenye Orodha ya Kuba…
main.vaultDetail.missing.changeLocation=Badilisha Mahali pa Kuba…
### Needs Migration
main.vaultDetail.migrateButton=Pandisha daraja Kuba
main.vaultDetail.migratePrompt=Kuba yako inahitaji kuboreshwa hadi umbizo jipya, kabla ya kuipata
### Error
main.vaultDetail.error.info=Kosa limetokea kupakia kuba kutoka kwenye diski.
main.vaultDetail.error.reload=Upya
main.vaultDetail.error.windowTitle=Kosa la kupakia kuba
# Wrong File Alert
wrongFileAlert.title=Jinsi ya Kusimba Faili
wrongFileAlert.header.title=Ulijaribu kusimba faili hizi?
wrongFileAlert.header.lead=Kwa kusudi hili, Cryptomator hutoa sauti katika meneja wako wa faili ya mfumo.
wrongFileAlert.instruction.0=Ili kusimba faili, fuata hatua hizi:
wrongFileAlert.instruction.1=1. Fungua kuba yako.
wrongFileAlert.instruction.2=2. Bonyeza "Reveal" ili kufungua sauti katika kidhibiti faili chako.
wrongFileAlert.instruction.3=3. Ongeza faili zako kwenye sauti hii.
wrongFileAlert.link=Kwa msaada zaidi, tembelea
# Vault Options
## General
vaultOptions.general=Jumla
vaultOptions.general.vaultName=Jina la kuba
vaultOptions.general.autoLock.lockAfterTimePart1=Funga wakati haina kazi kwa
vaultOptions.general.autoLock.lockAfterTimePart2=dakika
vaultOptions.general.unlockAfterStartup=Fungua kuba wakati wa kuanza Cryptomator
vaultOptions.general.actionAfterUnlock=Baada ya kufungua mafanikio
vaultOptions.general.actionAfterUnlock.ignore=Usifanye chochote
vaultOptions.general.actionAfterUnlock.reveal=Fichua Kiendeshaji
vaultOptions.general.actionAfterUnlock.ask=Uliza
vaultOptions.general.startHealthCheckBtn=Anza Ukaguzi wa Afya
## Mount
vaultOptions.mount.readonly=Soma-Tu
vaultOptions.mount.customMountFlags=Vipepea Vya Mlima Maalum
vaultOptions.mount.winDriveLetterOccupied=ulichukua
vaultOptions.mount.mountPoint.auto=Chagua otomatiki mahali panapofaa
vaultOptions.mount.mountPoint.driveLetter=Tumia barua kiendeshi kilichopangiwa
vaultOptions.mount.mountPoint.custom=Kijia maalum
vaultOptions.mount.mountPoint.directoryPickerButton=Chagua…
vaultOptions.mount.mountPoint.directoryPickerTitle=Chagua mpangilio orodha tupu
## Master Key
vaultOptions.masterkey=Neno la siri
vaultOptions.masterkey.changePasswordBtn=Badilisha Neno la siri
vaultOptions.masterkey.forgetSavedPasswordBtn=Kusahau Neno la siri Iliyohifadhiwa
vaultOptions.masterkey.recoveryKeyExplanation=Ufunguo wa kurejesha ni njia yako pekee ya kurejesha ufikiaji wa kuba ikiwa utapoteza nenosiri lako.
vaultOptions.masterkey.showRecoveryKeyBtn=Onyesha Ufunguo wa Ufufuzi
vaultOptions.masterkey.recoverPasswordBtn=Fufua Neno la siri
# Recovery Key
recoveryKey.title=Ufunguo wa Ufufuzi
recoveryKey.enterPassword.prompt=Ingiza neno la siri lako ili kuonyesha ufunguo wa kurejesha kwa "%s":
recoveryKey.display.message=Ufunguo ufuatao wa kurejesha unaweza kutumika kurejesha ufikiaji wa "%s":
recoveryKey.display.StorageHints=Weka mahali salama sana, kwa mfano:\n • Hifadhi kwa kutumia msimamizi wa nywila\n • Hifadhi kwenye kiendeshi cha USB flash\n • Chapisha kwenye karatasi
recoveryKey.recover.prompt=Ingiza ufunguo wako wa kurejesha kwa "%s":
recoveryKey.recover.validKey=Hii ni ufunguo halali wa kurejesha
recoveryKey.printout.heading=Ufunguo wa Urejeshaji wa Cryptomator\n"%s"\n
# New Password
newPassword.promptText=Ingiza neno jipya la siri
newPassword.reenterPassword=Thibitisha neno la siri jipya
newPassword.passwordsMatch=Maneno ya siri yanaoana!
newPassword.passwordsDoNotMatch=Maneno ya siri hayaoani
passwordStrength.messageLabel.tooShort=Tumia angalau %d vibambo
passwordStrength.messageLabel.0=Dhaifu sana
passwordStrength.messageLabel.1=Dhaifu
passwordStrength.messageLabel.2=Haki
passwordStrength.messageLabel.3=Imara
passwordStrength.messageLabel.4=Imara sana
# Quit
quit.prompt=Acha maombi? Kuna kuba zilizofunguliwa.
quit.lockAndQuit=Funga na Acha

View File

@@ -126,6 +126,7 @@ preferences.title=การตั้งค่า
# Main Window
main.closeBtn.tooltip=ปิด
main.preferencesBtn.tooltip=การตั้งค่า
main.supporterCertificateMissing.tooltip=โปรดพิจารณาเงินบริจาค
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=ล็อก

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=Bu dosyayı silmeye çekinmeyin.
addvaultwizard.existing.instruction=Mevcut kasanızın "vault.cryptomator" dosyasını seçin. Yalnızca "masterkey.cryptomator" adlı bir dosya varsa, bunun yerine onu seçin.
addvaultwizard.existing.chooseBtn=Seç…
addvaultwizard.existing.filePickerTitle=Kasa Dosyasını Seçin
addvaultwizard.existing.filePickerMimeDesc=Cryptomator Kasası
## Success
addvaultwizard.success.nextStepsInstructions="%s" kasası eklendi.\nİçeriğe erişmek veya içerik eklemek için bu kasanın kilidini açmanız gerekir. Alternatif olarak, daha sonra herhangi bir zamanda kilidini açabilirsiniz.
addvaultwizard.success.unlockNow=Kilidi Şimdi Aç
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title="%s" ait Ana anahtarı seçin
unlock.chooseMasterkey.prompt=Bu kasa için masterkey dosyası beklenen konumda bulunamadı. Lütfen anahtar dosyasını manuel olarak seçin.
unlock.chooseMasterkey.chooseBtn=Seç…
unlock.chooseMasterkey.filePickerTitle=Masterkey Dosyasını Seç
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator Ana anahtarı
## Success
unlock.success.message="%s" 'nin kilidi başarıyla açıldı! Kasanız şimdi sanal sürücüsü ile erişilebilir durumda.
unlock.success.rememberChoice=Seçimi hatırla, bunu bir daha gösterme

View File

@@ -78,6 +78,7 @@ addvault.new.readme.accessLocation.4=您可以随时删除此文件。
addvaultwizard.existing.instruction=请选择现有保险库中的“vault.cryptomator”文件。如果只有一个名为“masterkey.cryptomator”的文件则改为选择该文件。
addvaultwizard.existing.chooseBtn=选择...
addvaultwizard.existing.filePickerTitle=请选择保险库对应文件
addvaultwizard.existing.filePickerMimeDesc=Cryptomator 保险库
## Success
addvaultwizard.success.nextStepsInstructions=已添加保险库 "%s"\n您需要先解锁此保险库才能访问或添加内容。或者您可以在稍后任何时候再解锁它
addvaultwizard.success.unlockNow=立即解锁
@@ -107,6 +108,7 @@ unlock.chooseMasterkey.title=选择 %s 的 Masterkey 文件
unlock.chooseMasterkey.prompt=在指定路径找不到该保险库的 masterkey 文件,请手动选择密钥文件
unlock.chooseMasterkey.chooseBtn=选择...
unlock.chooseMasterkey.filePickerTitle=选择 Masterkey 文件
unlock.chooseMasterkey.filePickerMimeDesc=Cryptomator 主密钥
## Success
unlock.success.message=已成功解锁 "%s"! 您现在可以通过其虚拟驱动器访问它
unlock.success.rememberChoice=记住选项且不再显示

View File

@@ -196,8 +196,19 @@ preferences.general.debugDirectory=顯示日誌檔
preferences.general.autoStart=系統啟動時同時啟動 Cryptomator
preferences.general.keychainBackend=儲存密碼使用
## Interface
preferences.interface=介面
preferences.interface.theme=配色與設計
preferences.interface.theme.automatic=自動
preferences.interface.theme.dark=暗色
preferences.interface.theme.light=亮色
preferences.interface.unlockThemes=解鎖暗色模式
preferences.interface.language=語言 (需要重新啟動)
preferences.interface.language.auto=系統指定的
preferences.interface.interfaceOrientation=界面排版方向
preferences.interface.interfaceOrientation.ltr=由左至右
preferences.interface.interfaceOrientation.rtl=由右至左
preferences.interface.showMinimizeButton=顯示最小化按鈕
preferences.interface.showTrayIcon=顯示系統工作列圖示 (需要重新啟動)
## Volume
preferences.volume=虛擬磁碟
preferences.volume.type=磁區類型

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB