mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-14 16:51:28 +00:00
Compare commits
109 Commits
continuous
...
1.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee5505362c | ||
|
|
82f388d420 | ||
|
|
70e733f341 | ||
|
|
3af5d5f267 | ||
|
|
28bf9e2ab1 | ||
|
|
2f3a576de9 | ||
|
|
bbe1ef3dbc | ||
|
|
078a127182 | ||
|
|
240bf122dd | ||
|
|
f2f8f9b28c | ||
|
|
af03e0d73d | ||
|
|
7844078203 | ||
|
|
da62a22faf | ||
|
|
c36a1a4aef | ||
|
|
f760347d9d | ||
|
|
8fc647eb2b | ||
|
|
69b1bf5a26 | ||
|
|
6951edac96 | ||
|
|
76c84b34e9 | ||
|
|
1362720011 | ||
|
|
3f15352ebf | ||
|
|
fdedee49d3 | ||
|
|
b506493c13 | ||
|
|
bc09f28120 | ||
|
|
eba0935900 | ||
|
|
050a6e6a57 | ||
|
|
dbcb407a7c | ||
|
|
b1acdf9e61 | ||
|
|
9c6a0b3e0c | ||
|
|
f6df442948 | ||
|
|
29038a679f | ||
|
|
2e042423d0 | ||
|
|
e08c2b7dc3 | ||
|
|
d5d0589dec | ||
|
|
a760edcab9 | ||
|
|
a759455473 | ||
|
|
50d2f16f71 | ||
|
|
8afa09007b | ||
|
|
194f373c08 | ||
|
|
5f11e1aa8b | ||
|
|
0ac1b406b7 | ||
|
|
ade2db7cc0 | ||
|
|
eb911aeb6c | ||
|
|
a58259d4f0 | ||
|
|
963a731202 | ||
|
|
5ea0fc4b6f | ||
|
|
4becdf7e1e | ||
|
|
8ab8798381 | ||
|
|
c3f8fa1662 | ||
|
|
59d019f34a | ||
|
|
ee99e9994e | ||
|
|
019b7ac643 | ||
|
|
7392a99da5 | ||
|
|
e909269ae0 | ||
|
|
45ad496f41 | ||
|
|
a272bf2614 | ||
|
|
119e0724d5 | ||
|
|
76a9cb9a06 | ||
|
|
acb8d4cd0c | ||
|
|
ffe8887114 | ||
|
|
d8c8c2380a | ||
|
|
fe5ce79802 | ||
|
|
bf7a8686a6 | ||
|
|
143070d02d | ||
|
|
06827a7466 | ||
|
|
5add862ce8 | ||
|
|
2b8d7c6c3b | ||
|
|
f5da13d3b4 | ||
|
|
03dfd3e887 | ||
|
|
8241559362 | ||
|
|
c289040624 | ||
|
|
767acbd922 | ||
|
|
ccd4cedb08 | ||
|
|
0ddd6d767d | ||
|
|
6a5a1e5bae | ||
|
|
b3d76bb394 | ||
|
|
1924a7dec9 | ||
|
|
b65da30899 | ||
|
|
7de8b3da02 | ||
|
|
48ac8da1a7 | ||
|
|
86ae35c7eb | ||
|
|
8421a8fc7b | ||
|
|
b579e03bc8 | ||
|
|
9217b11e61 | ||
|
|
e16bd7373c | ||
|
|
ef53561bf0 | ||
|
|
3165c4ba86 | ||
|
|
f1bf157cac | ||
|
|
9c75dd48dd | ||
|
|
74d4b4ea47 | ||
|
|
6f66f4cbf1 | ||
|
|
874c5506a7 | ||
|
|
aed35c17c8 | ||
|
|
873e438759 | ||
|
|
5b45893c7b | ||
|
|
5515258af1 | ||
|
|
dd5d52d25a | ||
|
|
24236f3844 | ||
|
|
458866f7d6 | ||
|
|
525b0a7982 | ||
|
|
d53af61b58 | ||
|
|
b0ab46b7b6 | ||
|
|
9107d296c3 | ||
|
|
6be95963a1 | ||
|
|
09c9361e94 | ||
|
|
5e7cea216d | ||
|
|
6d91992102 | ||
|
|
5a23ee0be6 | ||
|
|
31e186dd15 |
4
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
4
CONTRIBUTING.md → .github/CONTRIBUTING.md
vendored
@@ -4,7 +4,7 @@
|
||||
|
||||
- Ensure you're running the latest version of Cryptomator.
|
||||
- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS and Android app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues) and [Cryptomator for Android issues list](https://github.com/cryptomator/cryptomator-android/issues) respectively.
|
||||
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/faq).
|
||||
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/kb/faq).
|
||||
- If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new).
|
||||
|
||||
## Did you write a patch that fixes a bug?
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/CODE_OF_CONDUCT.md).
|
||||
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Above all, thank you for your contributions
|
||||
|
||||
@@ -4,8 +4,8 @@ Before creating a new issue make sure that you
|
||||
- searched existing (and closed) issues: https://github.com/cryptomator/cryptomator/issues
|
||||
- searched the knowledge base: https://community.cryptomator.org/c/kb
|
||||
- have read the support guide: https://github.com/cryptomator/cryptomator/blob/develop/SUPPORT.md
|
||||
- have read the contribution guide: https://github.com/cryptomator/cryptomator/blob/develop/CONTRIBUTING.md
|
||||
- have read the code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/CODE_OF_CONDUCT.md
|
||||
- have read the contribution guide: https://github.com/cryptomator/cryptomator/blob/develop/.github/CONTRIBUTING.md
|
||||
- have read the code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
|
||||
|
||||
## Basic Info
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/1.4.0-beta-testing.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/1.4.0-beta-testing.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
## 1.4.0 Beta Issue Checklist
|
||||
- Existing 1.4.0 Beta Issues: https://github.com/cryptomator/cryptomator/milestone/27
|
||||
- Contribution Guide: https://github.com/cryptomator/cryptomator/blob/develop/.github/CONTRIBUTING.md
|
||||
- Code of Conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
|
||||
|
||||
## Software Used During the Test
|
||||
- Cryptomator 1.4.0 Beta 1
|
||||
- Ubuntu 16.04 / macOS 10.11.6 / etc
|
||||
- Linux Kernel x.y.z
|
||||
- Gnome x.y.z
|
||||
- OpenOffice x.y.z
|
||||
- ...
|
||||
|
||||
## Description
|
||||
What doesn't work? What did you do? How can the bug be reproduced?
|
||||
13
.github/no-response.yml
vendored
Normal file
13
.github/no-response.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Configuration for probot-no-response - https://github.com/probot/no-response
|
||||
|
||||
# Number of days of inactivity before an Issue is closed for lack of response
|
||||
daysUntilClose: 14
|
||||
# Label requiring a response
|
||||
responseRequiredLabel: state:awaiting-response
|
||||
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed because there has been no response
|
||||
to our request for more information from the original author. With only the
|
||||
information that is currently in the issue, we don't have enough information
|
||||
to take action. Please reach out if you have or find the answers we need so
|
||||
that we can investigate further.
|
||||
19
.github/stale.yml
vendored
Normal file
19
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- type:security-issue # never close automatically
|
||||
- state:awaiting-response # handled by different bot
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: true
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: state:stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -9,15 +9,13 @@
|
||||
.settings
|
||||
.project
|
||||
.classpath
|
||||
|
||||
# Maven #
|
||||
target/
|
||||
test-output/
|
||||
|
||||
# IntelliJ Settings Files #
|
||||
.idea/
|
||||
out/
|
||||
.idea_modules/
|
||||
*.iws
|
||||
*.iml
|
||||
|
||||
# Temporary file created by test launcher
|
||||
main/launcher/.ipcPort.tmp
|
||||
# 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/dictionaries
|
||||
.idea/**/libraries/
|
||||
*.iml
|
||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
Cryptomator
|
||||
51
.idea/codeStyles/Project.xml
generated
Normal file
51
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="LINE_SEPARATOR" value=" " />
|
||||
<option name="RIGHT_MARGIN" value="220" />
|
||||
<option name="FORMATTER_TAGS_ENABLED" value="true" />
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="30" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="10" />
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
|
||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
||||
</JavaCodeStyleSettings>
|
||||
<codeStyleSettings language="Groovy">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
||||
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
|
||||
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
16
.idea/compiler.xml
generated
Normal file
16
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
<?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" />
|
||||
<module name="commons" />
|
||||
<module name="keychain" />
|
||||
<module name="launcher" />
|
||||
<module name="ui" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
10
.idea/encodings.xml
generated
Normal file
10
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/main" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/main/commons" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/main/keychain" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/main/launcher" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/main/ui" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/main/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_10" project-jdk-name="10" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
72
.travis.yml
72
.travis.yml
@@ -2,71 +2,49 @@ language: java
|
||||
sudo: false
|
||||
jdk:
|
||||
- oraclejdk9
|
||||
branches:
|
||||
except:
|
||||
- continuous # To avoid infinite loops, as this tag is created by this Travis config
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
env:
|
||||
global:
|
||||
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" # COVERITY_SCAN_TOKEN
|
||||
- secure: "lV9OwUbHMrMpLUH1CY+Z4puLDdFXytudyPlG1eGRsesdpuG6KM3uQVz6uAtf6lrU8DRbMM/T7ML+PmvQ4UoPPYLdLxESLLBat2qUPOIVBOhTSlCc7I0DmGy04CSvkeMy8dPaQC0ukgNiR7zwoNzfcpGRN/U9S8tziDruuHoZSrg=" # BINTRAY_API_KEY
|
||||
- secure: "HftEaabMmWn5GwKFKksUkOcelc3Mn7xazwAEy+4d4gL1+F8VhID/6DCK7nas+afUymWnxTano8Rv4Ci5MWryNkNkTH+FUPWmF3xWezc3hajSyS7RB92IZ8VPetl4Fo8UI1WwM5apDEaugalPxkIf8a7N+lpG5X/Gpumwzo3Be3w=" # BINTRAY_API_KEY
|
||||
- secure: "oWFgRTVP6lyTa7qVxlvkpm20MtVc3BtmsNXQJS6bfg2A0o/iCQMNx7OD59BaafCLGRKvCcJVESiC8FlSylVMS7CDSyYu0gg70NUiIuHp4NBM5inFWYCy/PdQsCTzr5uvNG+rMFQpMFRaCV0FrfM3tLondcVkhsHL68l93Xoexx4=" # CODACY_PROJECT_TOKEN
|
||||
- secure: "zJxgytA2Ks5Xzv+7kUaUq+EBFNQw9Qec63lcMJVuXVWczjL16nKW1EzzV515ag+OWL46z3lEPForDhufw0VtFnNmaX68jkO0mp01eLrHApc1llN2Y/U8GBXfNNazN4+Kom4H+z/AO+wJr8EsKMMUczCdQ3APgd9uVI0hzXw/Z3M=" # GITHUB_API_KEY
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- haveged
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "cryptomator/cryptomator"
|
||||
notification_email: sebastian.stenzel@cryptomator.org
|
||||
build_command: "mvn -fmain/pom.xml clean test -DskipTests"
|
||||
branch_pattern: release.*
|
||||
install:
|
||||
- curl -o $HOME/.m2/settings.xml https://gist.githubusercontent.com/cryptobot/cf5fbd909c4782aaeeeb7c7f4a1a43da/raw/e60ee486e34ee0c79f89f947abe2c83b4290c6bb/settings.xml
|
||||
- mvn -fmain/pom.xml clean install -DskipTests org.codehaus.mojo:versions-maven-plugin:help dependency:go-offline -Pcoverage,release # "clean install" needed until we can exclude artifacts currently in the reactor, see https://maven.apache.org/plugins/maven-dependency-plugin/go-offline-mojo.html#excludeReactor and https://issues.apache.org/jira/browse/MDEP-568
|
||||
script:
|
||||
- mvn --update-snapshots -fmain/pom.xml clean test jacoco:report verify -Pcoverage
|
||||
- mvn --update-snapshots -fmain/pom.xml clean test verify -Pcoverage
|
||||
after_success:
|
||||
- jdk_switcher use oraclejdk8
|
||||
- curl -o ~/codacy-coverage-reporter-assembly-latest.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/2.0.1/codacy-coverage-reporter-2.0.1-assembly.jar
|
||||
- $JAVA_HOME/bin/java -cp ~/codacy-coverage-reporter-assembly-latest.jar com.codacy.CodacyCoverageReporter -l Java -r main/jacoco-report/target/site/jacoco-aggregate/jacoco.xml
|
||||
- curl -o ~/codacy-coverage-reporter.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/4.0.2/codacy-coverage-reporter-4.0.2-assembly.jar
|
||||
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/commons/target/site/jacoco/jacoco.xml --partial
|
||||
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/keychain/target/site/jacoco/jacoco.xml --partial
|
||||
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/ui/target/site/jacoco/jacoco.xml --partial
|
||||
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/launcher/target/site/jacoco/jacoco.xml --partial
|
||||
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar final
|
||||
before_deploy:
|
||||
- jdk_switcher use oraclejdk9
|
||||
- |
|
||||
if [[ $TRAVIS_BRANCH == "develop" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]]; then
|
||||
CONTINUOUS_RELEASE_URL=`curl -s https://api.github.com/repos/cryptomator/cryptomator/releases/tags/continuous | jq -re '.url'`
|
||||
echo "Existing continuous release: ${CONTINUOUS_RELEASE_URL}"
|
||||
if [[ $CONTINUOUS_RELEASE_URL == http* ]]; then
|
||||
curl -u cryptobot:$GITHUB_API_KEY -X DELETE $CONTINUOUS_RELEASE_URL
|
||||
fi
|
||||
fi
|
||||
- |
|
||||
if [[ -n "$TRAVIS_TAG" ]]; then
|
||||
mvn -fmain/pom.xml org.codehaus.mojo:versions-maven-plugin:set -DnewVersion=$TRAVIS_TAG
|
||||
elif [[ $TRAVIS_BRANCH == "develop" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]]; then
|
||||
mvn -fmain/pom.xml org.codehaus.mojo:versions-maven-plugin:set -DnewVersion=SNAPSHOT-$(echo $TRAVIS_COMMIT | head -c7)
|
||||
git tag -f continuous
|
||||
git remote add gh https://cryptobot:${GITHUB_API_KEY}@github.com/cryptomator/cryptomator.git
|
||||
git push -f gh continuous
|
||||
git remote remove gh
|
||||
fi
|
||||
- mvn -fmain/pom.xml clean package -Prelease -DskipTests
|
||||
deploy:
|
||||
- provider: releases # CONTINUOUS
|
||||
prerelease: true
|
||||
api-key: $GITHUB_API_KEY
|
||||
tag_name: continuous
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
file:
|
||||
- "main/uber-jar/target/Cryptomator-*.jar"
|
||||
- "main/ant-kit/target/antkit.tar.gz"
|
||||
- provider: script # SNAPSHOTS
|
||||
skip_cleanup: true
|
||||
name: Cryptomator continuous build
|
||||
body: Automatically built on $(date +'%F %T %Z').
|
||||
script: >-
|
||||
curl -T main/ant-kit/target/antkit.zip
|
||||
-u cryptobot:${BINTRAY_API_KEY}
|
||||
-H "X-Bintray-Package:ant-kit"
|
||||
-H "X-Bintray-Version:continuous"
|
||||
-H "X-Bintray-Override:1"
|
||||
-H "X-Bintray-Publish:1"
|
||||
https://api.bintray.com/content/cryptomator/cryptomator/antkit-continuous.zip
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
branch: develop
|
||||
@@ -76,18 +54,20 @@ deploy:
|
||||
api_key: $GITHUB_API_KEY
|
||||
file:
|
||||
- "main/uber-jar/target/Cryptomator-$TRAVIS_TAG.jar"
|
||||
- "main/ant-kit/target/antkit.tar.gz"
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
tags: true
|
||||
- provider: script
|
||||
script: "curl -X POST -u cryptobot:${BINTRAY_API_KEY} -H 'Content-Type: application/json' -d '{\"name\": \"${TRAVIS_TAG}\", \"vcs_tag\": \"${TRAVIS_TAG}\"}' https://api.bintray.com/packages/cryptomator/cryptomator/cryptomator-win/versions"
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
tags: true
|
||||
- provider: script
|
||||
script: "curl -X POST -u cryptobot:${BINTRAY_API_KEY} -H 'Content-Type: application/json' -d '{\"name\": \"${TRAVIS_TAG}\", \"vcs_tag\": \"${TRAVIS_TAG}\"}' https://api.bintray.com/packages/cryptomator/cryptomator/cryptomator-osx/versions"
|
||||
skip_cleanup: true
|
||||
script: >-
|
||||
curl -T main/ant-kit/target/antkit.zip
|
||||
-u cryptobot:${BINTRAY_API_KEY}
|
||||
-H "X-Bintray-Package:ant-kit"
|
||||
-H "X-Bintray-Version:${TRAVIS_TAG}"
|
||||
-H "X-Bintray-Override:1"
|
||||
-H "X-Bintray-Publish:1"
|
||||
https://api.bintray.com/content/cryptomator/cryptomator/antkit-${TRAVIS_TAG}.zip
|
||||
on:
|
||||
repo: cryptomator/cryptomator
|
||||
tags: true
|
||||
|
||||
@@ -46,8 +46,7 @@ For more information on the security details visit [cryptomator.org](https://cry
|
||||
|
||||
### Dependencies
|
||||
|
||||
* Java 8 (min. 8u51, we recommend to use the current version)
|
||||
* [JCE unlimited strength policy files](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) (needed for 256-bit keys)
|
||||
* Java 10 (min. 10.0.1, we recommend to use the current version)
|
||||
* Maven 3
|
||||
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Linux](https://github.com/cryptomator/builder-containers))
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<id>tarball</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<artifactId>ant-kit</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
@@ -73,7 +73,7 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- create antkit.tar.gz: -->
|
||||
<!-- create antkit.zip: -->
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
|
||||
@@ -4,9 +4,14 @@
|
||||
|
||||
<!-- Define application to build -->
|
||||
<fx:application id="Cryptomator" name="Cryptomator" version="${project.version}" mainClass="org.cryptomator.launcher.Cryptomator" />
|
||||
|
||||
<!-- Print build environment properties -->
|
||||
<target name="check-env">
|
||||
<echoproperties/>
|
||||
</target>
|
||||
|
||||
<!-- Create main application jar -->
|
||||
<target name="create-jar">
|
||||
<target name="create-jar" depends="check-env">
|
||||
<fx:jar destfile="antbuild/Cryptomator-${project.version}.jar">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:fileset dir="libs" includes="launcher-${project.version}.jar" />
|
||||
@@ -21,27 +26,26 @@
|
||||
</fx:jar>
|
||||
</target>
|
||||
|
||||
<!-- Create Image package -->
|
||||
<!-- Create Image -->
|
||||
<target name="image" depends="create-jar">
|
||||
<fx:deploy nativeBundles="image" outdir="antbuild" verbose="true">
|
||||
<fx:application refid="Cryptomator" />
|
||||
<fx:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="GPL" category="Utility"/>
|
||||
<fx:platform j2se="9.0">
|
||||
<fx:property name="logback.configurationFile" value="logback.xml" />
|
||||
<fx:property name="cryptomator.settingsPath" value="~/.Cryptomator/settings.json" />
|
||||
<fx:property name="cryptomator.ipcPortPath" value="~/.Cryptomator/ipcPort.bin" />
|
||||
<fx:platform j2se="10">
|
||||
<fx:property name="logback.configurationFile" value="\${antbuild.logback.configurationFile}" />
|
||||
<fx:property name="cryptomator.settingsPath" value="\${antbuild.cryptomator.settingsPath}" />
|
||||
<fx:property name="cryptomator.ipcPortPath" value="\${antbuild.cryptomator.ipcPortPath}" />
|
||||
<fx:property name="cryptomator.keychainPath" value="\${antbuild.cryptomator.keychainPath}"/>
|
||||
<fx:jvmarg value="-Xss2m"/>
|
||||
<fx:jvmarg value="-Xmx512m"/>
|
||||
<fx:jvmarg value="--add-modules"/>
|
||||
<fx:jvmarg value="jdk.incubator.httpclient"/>
|
||||
</fx:platform>
|
||||
<fx:resources>
|
||||
<fx:fileset dir="." type="data" includes="logback.xml" />
|
||||
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
|
||||
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="launcher-${project.version}.jar"/>
|
||||
</fx:resources>
|
||||
<fx:permissions elevated="false" />
|
||||
<fx:preferences install="true" />
|
||||
<fx:bundleArgument arg="dropinResourcesRoot" value="\${antbuild.dropinResourcesRoot}"/>
|
||||
</fx:deploy>
|
||||
</target>
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration scan="true" debug="true">
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${user.home}/.Cryptomator/cryptomator.log</file>
|
||||
<append>false</append>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
||||
<fileNamePattern>${user.home}/.Cryptomator/cryptomator%i.log</fileNamePattern>
|
||||
<minIndex>0</minIndex>
|
||||
<maxIndex>9</maxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="org.cryptomator.logging.LaunchBasedTriggeringPolicy" />
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="UPGRADE_FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>${user.home}/.Cryptomator/upgrade.log</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.cryptomator" level="INFO" />
|
||||
<logger name="org.eclipse.jetty.server.HttpChannel" level="INFO" />
|
||||
<logger name="org.cryptomator.ui.model" level="INFO">
|
||||
<appender-ref ref="UPGRADE_FILE" />
|
||||
</logger>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<artifactId>commons</artifactId>
|
||||
<name>Cryptomator Commons</name>
|
||||
|
||||
@@ -8,39 +8,34 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Settings {
|
||||
|
||||
public static final int MIN_PORT = 1024;
|
||||
public static final int MAX_PORT = 65535;
|
||||
public static final boolean DEFAULT_CHECK_FOR_UDPATES = true;
|
||||
public static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
|
||||
public static final boolean DEFAULT_CHECK_FOR_UDPATES = false;
|
||||
public static final int DEFAULT_PORT = 42427;
|
||||
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
|
||||
public static final String DEFAULT_GVFS_SCHEME = "dav";
|
||||
public static final boolean DEFAULT_DEBUG_MODE = false;
|
||||
public static final VolumeImpl DEFAULT_VOLUME_IMPL = VolumeImpl.FUSE;
|
||||
public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = System.getProperty("os.name").toLowerCase().contains("windows") ? VolumeImpl.DOKANY : VolumeImpl.FUSE;
|
||||
|
||||
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
|
||||
private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK);
|
||||
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES);
|
||||
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
|
||||
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
|
||||
private final StringProperty preferredGvfsScheme = new SimpleStringProperty(DEFAULT_GVFS_SCHEME);
|
||||
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
|
||||
private final ObjectProperty<VolumeImpl> volumeImpl = new SimpleObjectProperty<>(DEFAULT_VOLUME_IMPL);
|
||||
private final ObjectProperty<VolumeImpl> preferredVolumeImpl = new SimpleObjectProperty<>(DEFAULT_PREFERRED_VOLUME_IMPL);
|
||||
|
||||
private Consumer<Settings> saveCmd;
|
||||
|
||||
@@ -49,12 +44,13 @@ public class Settings {
|
||||
*/
|
||||
Settings() {
|
||||
directories.addListener((ListChangeListener.Change<? extends VaultSettings> change) -> this.save());
|
||||
askedForUpdateCheck.addListener(this::somethingChanged);
|
||||
checkForUpdates.addListener(this::somethingChanged);
|
||||
port.addListener(this::somethingChanged);
|
||||
numTrayNotifications.addListener(this::somethingChanged);
|
||||
preferredGvfsScheme.addListener(this::somethingChanged);
|
||||
debugMode.addListener(this::somethingChanged);
|
||||
volumeImpl.addListener(this::somethingChanged);
|
||||
preferredVolumeImpl.addListener(this::somethingChanged);
|
||||
}
|
||||
|
||||
void setSaveCmd(Consumer<Settings> saveCmd) {
|
||||
@@ -77,6 +73,10 @@ public class Settings {
|
||||
return directories;
|
||||
}
|
||||
|
||||
public BooleanProperty askedForUpdateCheck() {
|
||||
return askedForUpdateCheck;
|
||||
}
|
||||
|
||||
public BooleanProperty checkForUpdates() {
|
||||
return checkForUpdates;
|
||||
}
|
||||
@@ -97,8 +97,8 @@ public class Settings {
|
||||
return debugMode;
|
||||
}
|
||||
|
||||
public ObjectProperty<VolumeImpl> volumeImpl() {
|
||||
return volumeImpl;
|
||||
public ObjectProperty<VolumeImpl> preferredVolumeImpl() {
|
||||
return preferredVolumeImpl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,17 +5,16 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
|
||||
@@ -28,12 +27,13 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
out.beginObject();
|
||||
out.name("directories");
|
||||
writeVaultSettingsArray(out, value.getDirectories());
|
||||
out.name("askedForUpdateCheck").value(value.askedForUpdateCheck().get());
|
||||
out.name("checkForUpdatesEnabled").value(value.checkForUpdates().get());
|
||||
out.name("port").value(value.port().get());
|
||||
out.name("numTrayNotifications").value(value.numTrayNotifications().get());
|
||||
out.name("preferredGvfsScheme").value(value.preferredGvfsScheme().get());
|
||||
out.name("debugMode").value(value.debugMode().get());
|
||||
out.name("volumeImpl").value(value.volumeImpl().get().name());
|
||||
out.name("preferredVolumeImpl").value(value.preferredVolumeImpl().get().name());
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
@@ -56,6 +56,9 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
case "directories":
|
||||
settings.getDirectories().addAll(readVaultSettingsArray(in));
|
||||
break;
|
||||
case "askedForUpdateCheck":
|
||||
settings.askedForUpdateCheck().set(in.nextBoolean());
|
||||
break;
|
||||
case "checkForUpdatesEnabled":
|
||||
settings.checkForUpdates().set(in.nextBoolean());
|
||||
break;
|
||||
@@ -71,8 +74,8 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
case "debugMode":
|
||||
settings.debugMode().set(in.nextBoolean());
|
||||
break;
|
||||
case "volumeImpl":
|
||||
settings.volumeImpl().set(parseNioAdapterName(in.nextString()));
|
||||
case "preferredVolumeImpl":
|
||||
settings.preferredVolumeImpl().set(parsePreferredVolumeImplName(in.nextString()));
|
||||
break;
|
||||
default:
|
||||
LOG.warn("Unsupported vault setting found in JSON: " + name);
|
||||
@@ -84,11 +87,11 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
|
||||
return settings;
|
||||
}
|
||||
|
||||
private VolumeImpl parseNioAdapterName(String nioAdapterName) {
|
||||
private VolumeImpl parsePreferredVolumeImplName(String nioAdapterName) {
|
||||
try {
|
||||
return VolumeImpl.valueOf(nioAdapterName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return Settings.DEFAULT_VOLUME_IMPL;
|
||||
return Settings.DEFAULT_PREFERRED_VOLUME_IMPL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,16 +5,6 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
@@ -22,11 +12,23 @@ import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* The settings specific to a single vault.
|
||||
* TODO: Change the name of individualMountPath and its derivatives to customMountPath
|
||||
*/
|
||||
public class VaultSettings {
|
||||
|
||||
public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
|
||||
public static final boolean DEFAULT_MOUNT_AFTER_UNLOCK = true;
|
||||
public static final boolean DEFAULT_REAVEAL_AFTER_MOUNT = true;
|
||||
public static final boolean DEFAULT_USES_INDIVIDUAL_MOUNTPATH = false;
|
||||
|
||||
@@ -35,7 +37,6 @@ public class VaultSettings {
|
||||
private final StringProperty mountName = new SimpleStringProperty();
|
||||
private final StringProperty winDriveLetter = new SimpleStringProperty();
|
||||
private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP);
|
||||
private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty(DEFAULT_MOUNT_AFTER_UNLOCK);
|
||||
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REAVEAL_AFTER_MOUNT);
|
||||
private final BooleanProperty usesIndividualMountPath = new SimpleBooleanProperty(DEFAULT_USES_INDIVIDUAL_MOUNTPATH);
|
||||
private final StringProperty individualMountPath = new SimpleStringProperty();
|
||||
@@ -47,7 +48,7 @@ public class VaultSettings {
|
||||
}
|
||||
|
||||
Observable[] observables() {
|
||||
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, mountAfterUnlock, revealAfterMount, usesIndividualMountPath, individualMountPath};
|
||||
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, usesIndividualMountPath, individualMountPath};
|
||||
}
|
||||
|
||||
private void deriveMountNameFromPath(Path path) {
|
||||
@@ -118,10 +119,6 @@ public class VaultSettings {
|
||||
return unlockAfterStartup;
|
||||
}
|
||||
|
||||
public BooleanProperty mountAfterUnlock() {
|
||||
return mountAfterUnlock;
|
||||
}
|
||||
|
||||
public BooleanProperty revealAfterMount() {
|
||||
return revealAfterMount;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
class VaultSettingsJsonAdapter {
|
||||
|
||||
@@ -25,11 +24,9 @@ class VaultSettingsJsonAdapter {
|
||||
out.name("mountName").value(value.mountName().get());
|
||||
out.name("winDriveLetter").value(value.winDriveLetter().get());
|
||||
out.name("unlockAfterStartup").value(value.unlockAfterStartup().get());
|
||||
out.name("mountAfterUnlock").value(value.mountAfterUnlock().get());
|
||||
out.name("revealAfterMount").value(value.revealAfterMount().get());
|
||||
out.name("usesIndividualMountPath").value(value.usesIndividualMountPath().get());
|
||||
//TODO: should this always be written? ( because it could contain metadata, which the user does not want to save!)
|
||||
out.name("individualMountPath").value(value.individualMountPath().get());
|
||||
out.name("individualMountPath").value(value.individualMountPath().get()); //TODO: should this always be written? ( because it could contain metadata, which the user may not want to save!)
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
@@ -40,7 +37,6 @@ class VaultSettingsJsonAdapter {
|
||||
String individualMountPath = null;
|
||||
String winDriveLetter = null;
|
||||
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
|
||||
boolean mountAfterUnlock = VaultSettings.DEFAULT_MOUNT_AFTER_UNLOCK;
|
||||
boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT;
|
||||
boolean usesIndividualMountPath = VaultSettings.DEFAULT_USES_INDIVIDUAL_MOUNTPATH;
|
||||
|
||||
@@ -63,9 +59,6 @@ class VaultSettingsJsonAdapter {
|
||||
case "unlockAfterStartup":
|
||||
unlockAfterStartup = in.nextBoolean();
|
||||
break;
|
||||
case "mountAfterUnlock":
|
||||
mountAfterUnlock = in.nextBoolean();
|
||||
break;
|
||||
case "revealAfterMount":
|
||||
revealAfterMount = in.nextBoolean();
|
||||
break;
|
||||
@@ -87,7 +80,6 @@ class VaultSettingsJsonAdapter {
|
||||
vaultSettings.path().set(Paths.get(path));
|
||||
vaultSettings.winDriveLetter().set(winDriveLetter);
|
||||
vaultSettings.unlockAfterStartup().set(unlockAfterStartup);
|
||||
vaultSettings.mountAfterUnlock().set(mountAfterUnlock);
|
||||
vaultSettings.revealAfterMount().set(revealAfterMount);
|
||||
vaultSettings.usesIndividualMountPath().set(usesIndividualMountPath);
|
||||
vaultSettings.individualMountPath().set(individualMountPath);
|
||||
|
||||
@@ -4,7 +4,8 @@ import java.util.Arrays;
|
||||
|
||||
public enum VolumeImpl {
|
||||
WEBDAV("WebDAV"),
|
||||
FUSE("FUSE");
|
||||
FUSE("FUSE"),
|
||||
DOKANY("Dokany");
|
||||
|
||||
private String displayName;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public class SettingsJsonAdapterTest {
|
||||
+ "\"checkForUpdatesEnabled\": true,"//
|
||||
+ "\"port\": 8080,"//
|
||||
+ "\"numTrayNotifications\": 42,"//
|
||||
+ "\"volumeImpl\": \"FUSE\"}";
|
||||
+ "\"preferredVolumeImpl\": \"FUSE\"}";
|
||||
|
||||
Settings settings = adapter.fromJson(json);
|
||||
|
||||
@@ -31,7 +31,7 @@ public class SettingsJsonAdapterTest {
|
||||
Assert.assertEquals(8080, settings.port().get());
|
||||
Assert.assertEquals(42, settings.numTrayNotifications().get());
|
||||
Assert.assertEquals("dav", settings.preferredGvfsScheme().get());
|
||||
Assert.assertEquals(VolumeImpl.FUSE, settings.volumeImpl().get());
|
||||
Assert.assertEquals(VolumeImpl.FUSE, settings.preferredVolumeImpl().get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1
main/jacoco-report/.gitignore
vendored
1
main/jacoco-report/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/target/
|
||||
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jacoco-report</artifactId>
|
||||
<name>Cryptomator Code Coverage Report</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- all modules containing unit tests: -->
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>keychain</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>ui</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>launcher</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>report-aggregate</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>report-aggregate</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<artifactId>keychain</artifactId>
|
||||
<name>System Keychain Access</name>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<artifactId>launcher</artifactId>
|
||||
<name>Cryptomator Launcher</name>
|
||||
|
||||
@@ -37,6 +37,8 @@ public class Cryptomator {
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to initiate inter-process communication.", e);
|
||||
} catch (Throwable e) {
|
||||
LOG.error("Error during startup", e);
|
||||
}
|
||||
System.exit(0); // end remaining non-daemon threads.
|
||||
}
|
||||
|
||||
@@ -5,25 +5,23 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.launcher;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
import org.cryptomator.ui.controllers.MainController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class MainApplication extends Application {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainApplication.class);
|
||||
private Stage primaryStage;
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
public void start(Stage primaryStage) {
|
||||
LOG.info("JavaFX application started.");
|
||||
this.primaryStage = primaryStage;
|
||||
setupFXMLClassLoader();
|
||||
primaryStage.setMinWidth(652.0);
|
||||
primaryStage.setMinHeight(440.0);
|
||||
|
||||
LauncherModule launcherModule = new LauncherModule(this, primaryStage);
|
||||
LauncherComponent launcherComponent = DaggerLauncherComponent.builder() //
|
||||
@@ -34,30 +32,14 @@ public class MainApplication extends Application {
|
||||
|
||||
MainController mainCtrl = launcherComponent.fxmlLoader().load("/fxml/main.fxml");
|
||||
mainCtrl.initStage(primaryStage);
|
||||
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
public void stop() {
|
||||
assert primaryStage != null;
|
||||
primaryStage.hide();
|
||||
LOG.info("JavaFX application stopped.");
|
||||
}
|
||||
|
||||
// fix discussed in https://github.com/cryptomator/cryptomator/pull/29
|
||||
private void setupFXMLClassLoader() {
|
||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
FXMLLoader.setDefaultClassLoader(contextClassLoader);
|
||||
Platform.runLater(() -> {
|
||||
/*
|
||||
* This fixes a bug on OSX where the magic file open handler leads to no context class loader being set in the AppKit (event)
|
||||
* thread if the application is not started opening a file.
|
||||
*/
|
||||
if (Thread.currentThread().getContextClassLoader() == null) {
|
||||
Thread.currentThread().setContextClassLoader(contextClassLoader);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
59
main/pom.xml
59
main/pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.4.1</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Cryptomator</name>
|
||||
|
||||
@@ -24,27 +24,28 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<!-- dependency versions -->
|
||||
<cryptomator.cryptolib.version>1.2.0</cryptomator.cryptolib.version>
|
||||
<cryptomator.cryptofs.version>1.5.1</cryptomator.cryptofs.version>
|
||||
<cryptomator.webdav.version>1.0.4</cryptomator.webdav.version>
|
||||
<cryptomator.cryptolib.version>1.2.1</cryptomator.cryptolib.version>
|
||||
<cryptomator.cryptofs.version>1.6.2</cryptomator.cryptofs.version>
|
||||
<cryptomator.jni.version>2.0.0</cryptomator.jni.version>
|
||||
<cryptomator.fuse.version>0.1.3</cryptomator.fuse.version>
|
||||
<cryptomator.fuse.version>1.0.3</cryptomator.fuse.version>
|
||||
<cryptomator.dokany.version>1.1.1</cryptomator.dokany.version>
|
||||
<cryptomator.webdav.version>1.0.5</cryptomator.webdav.version>
|
||||
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-lang3.version>3.6</commons-lang3.version>
|
||||
<commons-io.version>2.6</commons-io.version>
|
||||
<commons-lang3.version>3.8.1</commons-lang3.version>
|
||||
|
||||
<easybind.version>1.0.3</easybind.version>
|
||||
|
||||
<guava.version>23.6-jre</guava.version>
|
||||
<dagger.version>2.14.1</dagger.version>
|
||||
<gson.version>2.8.2</gson.version>
|
||||
|
||||
|
||||
<guava.version>27.0-jre</guava.version>
|
||||
<dagger.version>2.20</dagger.version>
|
||||
<gson.version>2.8.5</gson.version>
|
||||
|
||||
<slf4j.version>1.7.25</slf4j.version>
|
||||
<logback.version>1.2.3</logback.version>
|
||||
|
||||
|
||||
<junit.version>4.12</junit.version>
|
||||
<junit.hierarchicalrunner.version>4.12.1</junit.hierarchicalrunner.version>
|
||||
<mockito.version>2.11.0</mockito.version>
|
||||
<mockito.version>2.23.0</mockito.version>
|
||||
<hamcrest.version>1.3</hamcrest.version> <!-- keep in sync with version required by JUnit -->
|
||||
</properties>
|
||||
|
||||
@@ -59,6 +60,10 @@
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jcenter</id>
|
||||
<url>http://jcenter.bintray.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -101,6 +106,11 @@
|
||||
<artifactId>fuse-nio-adapter</artifactId>
|
||||
<version>${cryptomator.fuse.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>dokany-nio-adapter</artifactId>
|
||||
<version>${cryptomator.dokany.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>webdav-nio-adapter</artifactId>
|
||||
@@ -245,9 +255,6 @@
|
||||
</profile>
|
||||
<profile>
|
||||
<id>coverage</id>
|
||||
<modules>
|
||||
<module>jacoco-report</module>
|
||||
</modules>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -264,7 +271,7 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-libs</id>
|
||||
@@ -281,7 +288,7 @@
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.7.9</version>
|
||||
<version>0.8.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare-agent</id>
|
||||
@@ -289,6 +296,12 @@
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>report</id>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<excludes>
|
||||
@@ -302,15 +315,9 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
<release>9</release>
|
||||
<compilerArgs>
|
||||
<arg>--add-modules</arg>
|
||||
<arg>jdk.incubator.httpclient</arg>
|
||||
</compilerArgs>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<artifactId>uber-jar</artifactId>
|
||||
<name>Single über jar with all dependencies</name>
|
||||
|
||||
@@ -4,35 +4,40 @@
|
||||
<parent>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>main</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<artifactId>ui</artifactId>
|
||||
<name>Cryptomator GUI</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>keychain</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>commons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>cryptofs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>webdav-nio-adapter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>jni</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>keychain</artifactId>
|
||||
<artifactId>fuse-nio-adapter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>fuse-nio-adapter</artifactId>
|
||||
<artifactId>dokany-nio-adapter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cryptomator</groupId>
|
||||
<artifactId>webdav-nio-adapter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- CryptoLib -->
|
||||
|
||||
@@ -53,6 +53,7 @@ public class ExitUtil {
|
||||
private final Localization localization;
|
||||
private final Settings settings;
|
||||
private final Optional<MacFunctions> macFunctions;
|
||||
private TrayIcon trayIcon;
|
||||
|
||||
@Inject
|
||||
public ExitUtil(@Named("mainWindow") Stage mainWindow, Localization localization, Settings settings, Optional<MacFunctions> macFunctions) {
|
||||
@@ -82,7 +83,7 @@ public class ExitUtil {
|
||||
}
|
||||
|
||||
private void initTrayIconExitHandler(Runnable exitCommand) {
|
||||
final TrayIcon trayIcon = createTrayIcon(exitCommand);
|
||||
trayIcon = createTrayIcon(exitCommand);
|
||||
try {
|
||||
// double clicking tray icon should open Cryptomator
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
@@ -118,14 +119,7 @@ public class ExitUtil {
|
||||
exitItem.addActionListener(e -> exitCommand.run());
|
||||
popup.add(exitItem);
|
||||
|
||||
final Image image;
|
||||
if (SystemUtils.IS_OS_MAC_OSX && isMacMenuBarDarkMode()) {
|
||||
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/tray_icon_mac_white.png"));
|
||||
} else if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/tray_icon_mac_black.png"));
|
||||
} else {
|
||||
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/tray_icon.png"));
|
||||
}
|
||||
final Image image = getAppropriateTrayIconImage(true);
|
||||
|
||||
return new TrayIcon(image, localization.getString("app.name"), popup);
|
||||
}
|
||||
@@ -202,4 +196,23 @@ public class ExitUtil {
|
||||
});
|
||||
}
|
||||
|
||||
public void updateTrayIcon(boolean areAllVaultsLocked) {
|
||||
if (trayIcon != null) {
|
||||
Image image = getAppropriateTrayIconImage(areAllVaultsLocked);
|
||||
trayIcon.setImage(image);
|
||||
}
|
||||
}
|
||||
|
||||
private Image getAppropriateTrayIconImage(boolean areAllVaultsLocked) {
|
||||
String resourceName;
|
||||
if (SystemUtils.IS_OS_MAC_OSX && isMacMenuBarDarkMode()) {
|
||||
resourceName = areAllVaultsLocked ? "/tray_icon_mac_white.png" : "/tray_icon_unlocked_mac_white.png";
|
||||
} else if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
resourceName = areAllVaultsLocked ? "/tray_icon_mac_black.png" : "/tray_icon_unlocked_mac_black.png";
|
||||
} else {
|
||||
resourceName = areAllVaultsLocked ? "/tray_icon.png" : "/tray_icon_unlocked.png";
|
||||
}
|
||||
return Toolkit.getDefaultToolkit().getImage(getClass().getResource(resourceName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ package org.cryptomator.ui;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.inject.Named;
|
||||
@@ -32,16 +34,38 @@ import org.fxmisc.easybind.EasyBind;
|
||||
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class}, subcomponents = {VaultComponent.class})
|
||||
public class UiModule {
|
||||
|
||||
private static final int NUM_SCHEDULER_THREADS = 4;
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Settings provideSettings(SettingsProvider settingsProvider) {
|
||||
return settingsProvider.get();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ScheduledExecutorService provideScheduledExecutorService(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
|
||||
final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(NUM_SCHEDULER_THREADS, r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("Scheduler Thread " + threadNumber.getAndIncrement());
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
});
|
||||
shutdownTaskScheduler.accept(executorService::shutdown);
|
||||
return executorService;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ExecutorService provideExecutorService(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
|
||||
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
ExecutorService executorService = Executors.newCachedThreadPool(r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("Background Thread " + threadNumber.getAndIncrement());
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
});
|
||||
shutdownTaskScheduler.accept(executorService::shutdown);
|
||||
return executorService;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
* Jean-Noël Charon - confirmation dialog on vault removal
|
||||
@@ -110,7 +110,7 @@ public class MainController implements ViewController {
|
||||
|
||||
@Inject
|
||||
public MainController(@Named("mainWindow") Stage mainWindow, ExecutorService executorService, @Named("fileOpenRequests") BlockingQueue<Path> fileOpenRequests, ExitUtil exitUtil, Localization localization,
|
||||
VaultFactory vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, VaultList vaults, AutoUnlocker autoUnlocker) {
|
||||
VaultFactory vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, VaultList vaults, AutoUnlocker autoUnlocker) {
|
||||
this.mainWindow = mainWindow;
|
||||
this.executorService = executorService;
|
||||
this.fileOpenRequests = fileOpenRequests;
|
||||
@@ -125,6 +125,7 @@ public class MainController implements ViewController {
|
||||
this.upgradeStrategyForSelectedVault = EasyBind.monadic(selectedVault).map(upgradeStrategies::getUpgradeStrategy);
|
||||
this.areAllVaultsLocked = Bindings.isEmpty(FXCollections.observableList(vaults, Vault::observables).filtered(Vault.NOT_LOCKED));
|
||||
|
||||
EasyBind.subscribe(areAllVaultsLocked, exitUtil::updateTrayIcon);
|
||||
EasyBind.subscribe(areAllVaultsLocked, Platform::setImplicitExit);
|
||||
autoUnlocker.unlockAllSilently();
|
||||
|
||||
@@ -216,7 +217,26 @@ public class MainController implements ViewController {
|
||||
|
||||
private void gracefulShutdown() {
|
||||
vaults.filtered(Vault.NOT_LOCKED).forEach(Vault::prepareForShutdown);
|
||||
Platform.runLater(Platform::exit);
|
||||
if (!vaults.filtered(Vault.NOT_LOCKED).isEmpty()) {
|
||||
ButtonType tryAgainButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.tryAgain"));
|
||||
ButtonType forceShutdownButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.forceShutdown"));
|
||||
Alert gracefulShutdownDialog = DialogBuilderUtil.buildGracefulShutdownDialog(
|
||||
localization.getString("main.gracefulShutdown.dialog.title"), localization.getString("main.gracefulShutdown.dialog.header"), localization.getString("main.gracefulShutdown.dialog.content"),
|
||||
forceShutdownButtonType, ButtonType.CANCEL, forceShutdownButtonType, tryAgainButtonType);
|
||||
|
||||
Optional<ButtonType> choice = gracefulShutdownDialog.showAndWait();
|
||||
choice.ifPresent(btnType -> {
|
||||
if (tryAgainButtonType.equals(btnType)) {
|
||||
gracefulShutdown();
|
||||
} else if (forceShutdownButtonType.equals(btnType)) {
|
||||
Platform.runLater(Platform::exit);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Platform.runLater(Platform::exit);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFont(String resourcePath) {
|
||||
@@ -313,7 +333,7 @@ public class MainController implements ViewController {
|
||||
|
||||
/**
|
||||
* adds the given directory or selects it if it is already in the list of directories.
|
||||
*
|
||||
*
|
||||
* @param path to a vault directory or masterkey file
|
||||
*/
|
||||
public void addVault(final Path path, boolean select) {
|
||||
@@ -395,7 +415,7 @@ public class MainController implements ViewController {
|
||||
return;
|
||||
}
|
||||
if (newValue.getState() != Vault.State.LOCKED) {
|
||||
this.showUnlockedView(newValue);
|
||||
this.showUnlockedView(newValue, false);
|
||||
} else if (!newValue.doesVaultDirectoryExist()) {
|
||||
this.showNotFoundView();
|
||||
} else if (newValue.isValidVaultDirectory() && upgradeStrategyForSelectedVault.isPresent()) {
|
||||
@@ -414,7 +434,13 @@ public class MainController implements ViewController {
|
||||
}
|
||||
|
||||
private void didPressKeyOnRoot(KeyEvent event) {
|
||||
if ((event.isMetaDown() || event.isControlDown()) && event.getCode().isDigitKey()) {
|
||||
boolean triggered;
|
||||
if (SystemUtils.IS_OS_MAC) {
|
||||
triggered = event.isMetaDown();
|
||||
} else {
|
||||
triggered = event.isControlDown() && !event.isAltDown();
|
||||
}
|
||||
if (triggered && event.getCode().isDigitKey()) {
|
||||
int digit = Integer.valueOf(event.getText());
|
||||
switch (digit) {
|
||||
case 0: {
|
||||
@@ -494,22 +520,25 @@ public class MainController implements ViewController {
|
||||
|
||||
public void didUnlock(Vault vault) {
|
||||
if (vault.equals(selectedVault.getValue())) {
|
||||
this.showUnlockedView(vault);
|
||||
this.showUnlockedView(vault, vault.getVaultSettings().revealAfterMount().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void showUnlockedView(Vault vault) {
|
||||
final UnlockedController ctrl = unlockedVaults.computeIfAbsent(vault, k -> {
|
||||
return viewControllerLoader.load("/fxml/unlocked.fxml");
|
||||
});
|
||||
private void showUnlockedView(Vault vault, boolean reveal) {
|
||||
final UnlockedController ctrl = unlockedVaults.computeIfAbsent(vault, k -> viewControllerLoader.load("/fxml/unlocked.fxml"));
|
||||
ctrl.setVault(vault);
|
||||
ctrl.setListener(this::didLock);
|
||||
if (reveal) {
|
||||
ctrl.revealVault(vault);
|
||||
}
|
||||
activeController.set(ctrl);
|
||||
}
|
||||
|
||||
public void didLock(UnlockedController ctrl) {
|
||||
unlockedVaults.remove(ctrl.getVault());
|
||||
showUnlockView(UnlockController.State.UNLOCKING);
|
||||
if (ctrl.getVault().getId() == selectedVault.get().getId()) {
|
||||
showUnlockView(UnlockController.State.UNLOCKING);
|
||||
}
|
||||
activeController.get().focus();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,17 +8,13 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Strings;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.CheckBox;
|
||||
@@ -26,13 +22,18 @@ import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.util.StringConverter;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VolumeImpl;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VolumeImpl;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Volume;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
public class SettingsController implements ViewController {
|
||||
@@ -48,16 +49,13 @@ public class SettingsController implements ViewController {
|
||||
this.localization = localization;
|
||||
this.settings = settings;
|
||||
this.applicationVersion = applicationVersion;
|
||||
this.webdavSettings = new Group();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private CheckBox checkForUpdatesCheckbox;
|
||||
|
||||
@FXML
|
||||
private GridPane webdavVolume;
|
||||
|
||||
@FXML
|
||||
private GridPane fuseVolume;
|
||||
private Group webdavSettings;
|
||||
|
||||
@FXML
|
||||
private Label portFieldLabel;
|
||||
@@ -77,9 +75,6 @@ public class SettingsController implements ViewController {
|
||||
@FXML
|
||||
private ChoiceBox<String> prefGvfsScheme;
|
||||
|
||||
@FXML
|
||||
private Label volumeLabel;
|
||||
|
||||
@FXML
|
||||
private ChoiceBox<VolumeImpl> volume;
|
||||
|
||||
@@ -96,19 +91,21 @@ public class SettingsController implements ViewController {
|
||||
checkForUpdatesCheckbox.setSelected(settings.checkForUpdates().get() && !areUpdatesManagedExternally());
|
||||
|
||||
//NIOADAPTER
|
||||
volume.getItems().addAll(getSupportedAdapters());
|
||||
volume.setValue(settings.volumeImpl().get());
|
||||
volume.setVisible(true);
|
||||
volume.getItems().addAll(Volume.getCurrentSupportedAdapters());
|
||||
volume.setValue(settings.preferredVolumeImpl().get());
|
||||
volume.setConverter(new NioAdapterImplStringConverter());
|
||||
volume.valueProperty().addListener(this::setVisibilityGvfsElements);
|
||||
|
||||
//WEBDAV
|
||||
webdavVolume.visibleProperty().bind(volume.valueProperty().isEqualTo(VolumeImpl.WEBDAV));
|
||||
webdavVolume.managedProperty().bind(webdavVolume.visibleProperty());
|
||||
prefGvfsScheme.managedProperty().bind(webdavVolume.visibleProperty());
|
||||
prefGvfsSchemeLabel.managedProperty().bind(webdavVolume.visibleProperty());
|
||||
portFieldLabel.managedProperty().bind(webdavVolume.visibleProperty());
|
||||
changePortButton.managedProperty().bind(webdavVolume.visibleProperty());
|
||||
portField.managedProperty().bind(webdavVolume.visibleProperty());
|
||||
webdavSettings.visibleProperty().bind(volume.valueProperty().isEqualTo(VolumeImpl.WEBDAV));
|
||||
webdavSettings.managedProperty().bind(webdavSettings.visibleProperty());
|
||||
prefGvfsScheme.managedProperty().bind(webdavSettings.visibleProperty());
|
||||
prefGvfsSchemeLabel.managedProperty().bind(webdavSettings.visibleProperty());
|
||||
portFieldLabel.managedProperty().bind(webdavSettings.visibleProperty());
|
||||
portFieldLabel.visibleProperty().bind(webdavSettings.visibleProperty());
|
||||
changePortButton.managedProperty().bind(webdavSettings.visibleProperty());
|
||||
portField.managedProperty().bind(webdavSettings.visibleProperty());
|
||||
portField.visibleProperty().bind(webdavSettings.visibleProperty());
|
||||
portField.setText(String.valueOf(settings.port().intValue()));
|
||||
portField.addEventFilter(KeyEvent.KEY_TYPED, this::filterNumericKeyEvents);
|
||||
changePortButton.visibleProperty().bind(settings.port().asString().isNotEqualTo(portField.textProperty()));
|
||||
@@ -119,23 +116,14 @@ public class SettingsController implements ViewController {
|
||||
prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX);
|
||||
prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX);
|
||||
|
||||
//FUSE
|
||||
fuseVolume.visibleProperty().bind(volume.valueProperty().isEqualTo(VolumeImpl.FUSE));
|
||||
fuseVolume.managedProperty().bind(fuseVolume.visibleProperty());
|
||||
|
||||
debugModeCheckbox.setSelected(settings.debugMode().get());
|
||||
|
||||
settings.checkForUpdates().bind(checkForUpdatesCheckbox.selectedProperty());
|
||||
settings.preferredGvfsScheme().bind(prefGvfsScheme.valueProperty());
|
||||
settings.volumeImpl().bind(volume.valueProperty());
|
||||
settings.preferredVolumeImpl().bind(volume.valueProperty());
|
||||
settings.debugMode().bind(debugModeCheckbox.selectedProperty());
|
||||
}
|
||||
|
||||
//TODO: how to implement this?
|
||||
private VolumeImpl[] getSupportedAdapters() {
|
||||
return new VolumeImpl[]{VolumeImpl.FUSE, VolumeImpl.WEBDAV};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parent getRoot() {
|
||||
return root;
|
||||
@@ -171,6 +159,11 @@ public class SettingsController implements ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private void setVisibilityGvfsElements(Observable obs, Object oldValue, Object newValue) {
|
||||
prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
|
||||
prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
|
||||
}
|
||||
|
||||
private boolean areUpdatesManagedExternally() {
|
||||
return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
|
||||
}
|
||||
|
||||
@@ -8,40 +8,8 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.apache.commons.lang3.CharUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VolumeImpl;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
|
||||
import org.cryptomator.frontend.webdav.ServerLifecycleException;
|
||||
import org.cryptomator.keychain.KeychainAccess;
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.WindowsDriveLetters;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -61,6 +29,33 @@ import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.StringConverter;
|
||||
import org.apache.commons.lang3.CharUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.common.settings.VolumeImpl;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
|
||||
import org.cryptomator.frontend.webdav.ServerLifecycleException;
|
||||
import org.cryptomator.keychain.KeychainAccess;
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.InvalidSettingsException;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.WindowsDriveLetters;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.cryptomator.ui.util.Tasks;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public class UnlockController implements ViewController {
|
||||
|
||||
@@ -73,23 +68,23 @@ public class UnlockController implements ViewController {
|
||||
|
||||
private final Application app;
|
||||
private final Localization localization;
|
||||
private final AsyncTaskService asyncTaskService;
|
||||
private final WindowsDriveLetters driveLetters;
|
||||
private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange;
|
||||
private final Optional<KeychainAccess> keychainAccess;
|
||||
private final Settings settings;
|
||||
private final ExecutorService executor;
|
||||
private Vault vault;
|
||||
private Optional<UnlockListener> listener = Optional.empty();
|
||||
private Subscription vaultSubs = Subscription.EMPTY;
|
||||
|
||||
@Inject
|
||||
public UnlockController(Application app, Localization localization, AsyncTaskService asyncTaskService, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess, Settings settings) {
|
||||
public UnlockController(Application app, Localization localization, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess, Settings settings, ExecutorService executor) {
|
||||
this.app = app;
|
||||
this.localization = localization;
|
||||
this.asyncTaskService = asyncTaskService;
|
||||
this.driveLetters = driveLetters;
|
||||
this.keychainAccess = keychainAccess;
|
||||
this.settings = settings;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -107,9 +102,6 @@ public class UnlockController implements ViewController {
|
||||
@FXML
|
||||
private CheckBox savePassword;
|
||||
|
||||
@FXML
|
||||
private CheckBox mountAfterUnlock;
|
||||
|
||||
@FXML
|
||||
private TextField mountName;
|
||||
|
||||
@@ -123,19 +115,13 @@ public class UnlockController implements ViewController {
|
||||
private ChoiceBox<Character> winDriveLetter;
|
||||
|
||||
@FXML
|
||||
private CheckBox useOwnMountPath;
|
||||
private CheckBox useCustomMountPath;
|
||||
|
||||
@FXML
|
||||
private HBox mountPathBox;
|
||||
private Label customMountPathLabel;
|
||||
|
||||
@FXML
|
||||
private Label mountPathLabel;
|
||||
|
||||
@FXML
|
||||
private TextField mountPath;
|
||||
|
||||
@FXML
|
||||
private Button changeMountPathButton;
|
||||
private TextField customMountPathField;
|
||||
|
||||
@FXML
|
||||
private ProgressIndicator progressIndicator;
|
||||
@@ -159,43 +145,41 @@ public class UnlockController implements ViewController {
|
||||
public void initialize() {
|
||||
advancedOptions.managedProperty().bind(advancedOptions.visibleProperty());
|
||||
unlockButton.disableProperty().bind(passwordField.textProperty().isEmpty());
|
||||
mountName.disableProperty().bind(mountAfterUnlock.selectedProperty().not());
|
||||
revealAfterMount.disableProperty().bind(mountAfterUnlock.selectedProperty().not());
|
||||
mountName.addEventFilter(KeyEvent.KEY_TYPED, this::filterAlphanumericKeyEvents);
|
||||
mountName.textProperty().addListener(this::mountNameDidChange);
|
||||
savePassword.setDisable(!keychainAccess.isPresent());
|
||||
unlockAfterStartup.disableProperty().bind(savePassword.disabledProperty().or(savePassword.selectedProperty().not()));
|
||||
|
||||
mountPathLabel.setVisible(false);
|
||||
mountPathBox.visibleProperty().bind(mountPathLabel.visibleProperty());
|
||||
mountPathBox.managedProperty().bind(mountPathLabel.managedProperty());
|
||||
mountPath.visibleProperty().bind(mountPathLabel.visibleProperty());
|
||||
mountPath.managedProperty().bind(mountPathLabel.managedProperty());
|
||||
changeMountPathButton.visibleProperty().bind(mountPathLabel.visibleProperty());
|
||||
changeMountPathButton.managedProperty().bind(mountPathLabel.managedProperty());
|
||||
customMountPathLabel.visibleProperty().bind(useCustomMountPath.selectedProperty());
|
||||
customMountPathLabel.managedProperty().bind(useCustomMountPath.selectedProperty());
|
||||
customMountPathField.visibleProperty().bind(useCustomMountPath.selectedProperty());
|
||||
customMountPathField.managedProperty().bind(useCustomMountPath.selectedProperty());
|
||||
customMountPathField.textProperty().addListener(this::mountPathDidChange);
|
||||
winDriveLetter.setConverter(new WinDriveLetterLabelConverter());
|
||||
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
winDriveLetter.setConverter(new WinDriveLetterLabelConverter());
|
||||
useOwnMountPath.setVisible(false);
|
||||
useOwnMountPath.setManaged(false);
|
||||
mountPathLabel.setManaged(false);
|
||||
//dirty cheat
|
||||
mountPathBox.setMouseTransparent(true);
|
||||
} else {
|
||||
if (!SystemUtils.IS_OS_WINDOWS) {
|
||||
winDriveLetterLabel.setVisible(false);
|
||||
winDriveLetterLabel.setManaged(false);
|
||||
winDriveLetter.setVisible(false);
|
||||
winDriveLetter.setManaged(false);
|
||||
if (VolumeImpl.WEBDAV.equals(settings.volumeImpl().get())) {
|
||||
useOwnMountPath.setVisible(false);
|
||||
useOwnMountPath.setManaged(false);
|
||||
mountPathLabel.setManaged(false);
|
||||
}
|
||||
|
||||
if (VolumeImpl.WEBDAV.equals(settings.preferredVolumeImpl().get())) {
|
||||
useCustomMountPath.setVisible(false);
|
||||
useCustomMountPath.setManaged(false);
|
||||
customMountPathField.setMouseTransparent(true);
|
||||
} else {
|
||||
useCustomMountPath.setVisible(true);
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
winDriveLetter.visibleProperty().bind(useCustomMountPath.selectedProperty().not());
|
||||
winDriveLetter.managedProperty().bind(useCustomMountPath.selectedProperty().not());
|
||||
winDriveLetterLabel.visibleProperty().bind(useCustomMountPath.selectedProperty().not());
|
||||
winDriveLetterLabel.managedProperty().bind(useCustomMountPath.selectedProperty().not());
|
||||
}
|
||||
}
|
||||
changeMountPathButton.disableProperty().bind(Bindings.createBooleanBinding(this::isDirVaild, mountPath.textProperty()).not());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Parent getRoot() {
|
||||
return root;
|
||||
@@ -230,13 +214,11 @@ public class UnlockController implements ViewController {
|
||||
winDriveLetter.getItems().addAll(driveLetters.getAvailableDriveLetters());
|
||||
winDriveLetter.getItems().sort(new WinDriveLetterComparator());
|
||||
winDriveLetter.valueProperty().addListener(driveLetterChangeListener);
|
||||
chooseSelectedDriveLetter();
|
||||
}
|
||||
downloadsPageLink.setVisible(false);
|
||||
messageText.setText(null);
|
||||
mountName.setText(vault.getMountName());
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
chooseSelectedDriveLetter();
|
||||
}
|
||||
savePassword.setSelected(false);
|
||||
// auto-fill pw from keychain:
|
||||
if (keychainAccess.isPresent()) {
|
||||
@@ -250,20 +232,16 @@ public class UnlockController implements ViewController {
|
||||
}
|
||||
VaultSettings vaultSettings = vault.getVaultSettings();
|
||||
unlockAfterStartup.setSelected(savePassword.isSelected() && vaultSettings.unlockAfterStartup().get());
|
||||
mountAfterUnlock.setSelected(vaultSettings.mountAfterUnlock().get());
|
||||
revealAfterMount.setSelected(vaultSettings.revealAfterMount().get());
|
||||
useOwnMountPath.setSelected(vaultSettings.usesIndividualMountPath().get());
|
||||
|
||||
if (!settings.preferredVolumeImpl().get().equals(VolumeImpl.WEBDAV)) {
|
||||
useCustomMountPath.setSelected(vaultSettings.usesIndividualMountPath().get());
|
||||
customMountPathField.textProperty().setValue(vaultSettings.individualMountPath().getValueSafe());
|
||||
}
|
||||
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(unlockAfterStartup.selectedProperty(), vaultSettings.unlockAfterStartup()::set));
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(mountAfterUnlock.selectedProperty(), vaultSettings.mountAfterUnlock()::set));
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(revealAfterMount.selectedProperty(), vaultSettings.revealAfterMount()::set));
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(useOwnMountPath.selectedProperty(), vaultSettings.usesIndividualMountPath()::set));
|
||||
|
||||
changeMountPathButton.visibleProperty().bind(
|
||||
vaultSettings.individualMountPath().isNotEqualTo(mountPath.textProperty())
|
||||
);
|
||||
mountPath.textProperty().setValue(vaultSettings.individualMountPath().getValueSafe());
|
||||
mountPathLabel.visibleProperty().bind(useOwnMountPath.selectedProperty());
|
||||
vaultSubs = vaultSubs.and(EasyBind.subscribe(useCustomMountPath.selectedProperty(), vaultSettings.usesIndividualMountPath()::set));
|
||||
|
||||
}
|
||||
|
||||
@@ -291,28 +269,6 @@ public class UnlockController implements ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void didClickchangeMountPathButton(ActionEvent event) {
|
||||
assert isDirVaild();
|
||||
vault.setMountPath(mountPath.getText());
|
||||
}
|
||||
|
||||
private boolean isDirVaild() {
|
||||
try {
|
||||
if (!mountPath.textProperty().isEmpty().get()) {
|
||||
Path p = Paths.get(mountPath.textProperty().get());
|
||||
return Files.isDirectory(p) && Files.isReadable(p) && Files.isWritable(p) && Files.isExecutable(p);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (InvalidPathException e) {
|
||||
LOG.info("Invalid path");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void filterAlphanumericKeyEvents(KeyEvent t) {
|
||||
if (!Strings.isNullOrEmpty(t.getCharacter()) && !ALPHA_NUMERIC_MATCHER.matchesAllOf(t.getCharacter())) {
|
||||
t.consume();
|
||||
@@ -328,6 +284,10 @@ public class UnlockController implements ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private void mountPathDidChange(ObservableValue<? extends String> property, String oldValue, String newValue) {
|
||||
vault.setCustomMountPath(newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts 'C' to "C:" to translate between model and GUI.
|
||||
*/
|
||||
@@ -427,10 +387,12 @@ public class UnlockController implements ViewController {
|
||||
@FXML
|
||||
private void didClickUnlockButton(ActionEvent event) {
|
||||
advancedOptions.setDisable(true);
|
||||
advancedOptions.setVisible(false);
|
||||
progressIndicator.setVisible(true);
|
||||
|
||||
CharSequence password = passwordField.getCharacters();
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
Tasks.create(() -> {
|
||||
messageText.setText(localization.getString("unlock.pendingMessage.unlocking"));
|
||||
vault.unlock(password);
|
||||
if (keychainAccess.isPresent() && savePassword.isSelected()) {
|
||||
keychainAccess.get().storePassphrase(vault.getId(), password);
|
||||
@@ -439,6 +401,10 @@ public class UnlockController implements ViewController {
|
||||
messageText.setText(null);
|
||||
downloadsPageLink.setVisible(false);
|
||||
listener.ifPresent(lstnr -> lstnr.didUnlock(vault));
|
||||
}).onError(InvalidSettingsException.class, e -> {
|
||||
messageText.setText(localization.getString("unlock.errorMessage.invalidMountPath"));
|
||||
advancedOptions.setVisible(true);
|
||||
customMountPathField.setStyle("-fx-border-color: red;");
|
||||
}).onError(InvalidPassphraseException.class, e -> {
|
||||
messageText.setText(localization.getString("unlock.errorMessage.wrongPassword"));
|
||||
passwordField.selectAll();
|
||||
@@ -457,7 +423,7 @@ public class UnlockController implements ViewController {
|
||||
}).onError(ServerLifecycleException.class, e -> {
|
||||
LOG.error("Unlock failed for technical reasons.", e);
|
||||
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
|
||||
}).onError(IOException.class, e -> {
|
||||
}).onError(Exception.class, e -> {
|
||||
LOG.error("Unlock failed for technical reasons.", e);
|
||||
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
|
||||
}).andFinally(() -> {
|
||||
@@ -466,7 +432,10 @@ public class UnlockController implements ViewController {
|
||||
}
|
||||
advancedOptions.setDisable(false);
|
||||
progressIndicator.setVisible(false);
|
||||
}).run();
|
||||
if (advancedOptions.isVisible()) { //dirty programming, but otherwise the focus is wrong
|
||||
customMountPathField.requestFocus();
|
||||
}
|
||||
}).runOnce(executor);
|
||||
}
|
||||
|
||||
/* callback */
|
||||
|
||||
@@ -8,29 +8,13 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.frontend.webdav.ServerLifecycleException;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.util.concurrent.Runnables;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.beans.binding.ObjectExpression;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.event.ActionEvent;
|
||||
@@ -46,13 +30,19 @@ import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.input.Clipboard;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.PopupWindow.AnchorLocation;
|
||||
import javafx.util.Duration;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.cryptomator.ui.util.Tasks;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
public class UnlockedController implements ViewController {
|
||||
|
||||
@@ -62,9 +52,8 @@ public class UnlockedController implements ViewController {
|
||||
private static final double IO_SAMPLING_INTERVAL = 0.25;
|
||||
|
||||
private final Localization localization;
|
||||
private final AsyncTaskService asyncTaskService;
|
||||
private final ExecutorService executor;
|
||||
private final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
|
||||
private final ObjectExpression<Vault.State> vaultState = ObjectExpression.objectExpression(EasyBind.select(vault).selectObject(Vault::stateProperty));
|
||||
private Optional<LockListener> listener = Optional.empty();
|
||||
private Timeline ioAnimation;
|
||||
|
||||
@@ -83,30 +72,17 @@ public class UnlockedController implements ViewController {
|
||||
@FXML
|
||||
private ContextMenu moreOptionsMenu;
|
||||
|
||||
@FXML
|
||||
private MenuItem mountVaultMenuItem;
|
||||
|
||||
@FXML
|
||||
private MenuItem unmountVaultMenuItem;
|
||||
|
||||
@FXML
|
||||
private MenuItem revealVaultMenuItem;
|
||||
|
||||
@FXML
|
||||
private VBox root;
|
||||
|
||||
@Inject
|
||||
public UnlockedController(Localization localization, AsyncTaskService asyncTaskService) {
|
||||
public UnlockedController(Localization localization, ExecutorService executor) {
|
||||
this.localization = localization;
|
||||
this.asyncTaskService = asyncTaskService;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
mountVaultMenuItem.disableProperty().bind(vaultState.isEqualTo(Vault.State.UNLOCKED).not()); // enable when unlocked
|
||||
unmountVaultMenuItem.disableProperty().bind(vaultState.isEqualTo(Vault.State.MOUNTED).not()); // enable when mounted
|
||||
revealVaultMenuItem.disableProperty().bind(vaultState.isEqualTo(Vault.State.MOUNTED).not()); // enable when mounted
|
||||
|
||||
EasyBind.subscribe(vault, this::vaultChanged);
|
||||
EasyBind.subscribe(moreOptionsMenu.showingProperty(), moreOptionsButton::setSelected);
|
||||
}
|
||||
@@ -121,10 +97,6 @@ public class UnlockedController implements ViewController {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newVault.getState() == Vault.State.UNLOCKED && newVault.getVaultSettings().mountAfterUnlock().get()) {
|
||||
mountVault(newVault);
|
||||
}
|
||||
|
||||
// (re)start throughput statistics:
|
||||
stopIoSampling();
|
||||
startIoSampling();
|
||||
@@ -132,75 +104,22 @@ public class UnlockedController implements ViewController {
|
||||
|
||||
@FXML
|
||||
private void didClickLockVault(ActionEvent event) {
|
||||
regularUnmountVault(this::lockVault);
|
||||
regularLockVault(this::lockVaultSucceeded);
|
||||
}
|
||||
|
||||
private void lockVault() {
|
||||
try {
|
||||
vault.get().lock();
|
||||
} catch (ServerLifecycleException | IOException e) {
|
||||
LOG.error("Lock failed", e);
|
||||
}
|
||||
private void lockVaultSucceeded() {
|
||||
listener.ifPresent(listener -> listener.didLock(this));
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void didClickMoreOptions(ActionEvent event) {
|
||||
if (moreOptionsMenu.isShowing()) {
|
||||
moreOptionsMenu.hide();
|
||||
} else {
|
||||
moreOptionsMenu.setAnchorLocation(AnchorLocation.CONTENT_TOP_RIGHT);
|
||||
moreOptionsMenu.show(moreOptionsButton, Side.BOTTOM, moreOptionsButton.getWidth(), 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickMountVault(ActionEvent event) {
|
||||
mountVault(vault.get());
|
||||
}
|
||||
|
||||
private void mountVault(Vault vault) {
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
vault.mount();
|
||||
}).onSuccess(() -> {
|
||||
LOG.trace("Mount succeeded.");
|
||||
messageLabel.setText(null);
|
||||
if (vault.getVaultSettings().revealAfterMount().get()) {
|
||||
revealVault(vault);
|
||||
}
|
||||
}).onError(CommandFailedException.class, e -> {
|
||||
LOG.error("Mount failed.", e);
|
||||
// TODO Markus Kreusch #393: hyperlink auf FAQ oder sowas?
|
||||
messageLabel.setText(localization.getString("unlocked.label.mountFailed"));
|
||||
}).run();
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void didClickUnmountVault(ActionEvent event) {
|
||||
regularUnmountVault(Runnables.doNothing());
|
||||
}
|
||||
|
||||
private void regularUnmountVault(Runnable onSuccess) {
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
vault.get().unmount();
|
||||
private void regularLockVault(Runnable onSuccess) {
|
||||
Tasks.create(() -> {
|
||||
vault.get().lock(false);
|
||||
}).onSuccess(() -> {
|
||||
LOG.trace("Regular unmount succeeded.");
|
||||
onSuccess.run();
|
||||
}).onError(Exception.class, e -> {
|
||||
onRegularUnmountVaultFailed(e, onSuccess);
|
||||
}).run();
|
||||
}
|
||||
|
||||
private void forcedUnmountVault(Runnable onSuccess) {
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
vault.get().unmountForced();
|
||||
}).onSuccess(() -> {
|
||||
LOG.trace("Forced unmount succeeded.");
|
||||
onSuccess.run();
|
||||
}).onError(Exception.class, e -> {
|
||||
LOG.error("Forced unmount failed.", e);
|
||||
messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
|
||||
}).run();
|
||||
}).runOnce(executor);
|
||||
}
|
||||
|
||||
private void onRegularUnmountVaultFailed(Exception e, Runnable onSuccess) {
|
||||
@@ -214,7 +133,7 @@ public class UnlockedController implements ViewController {
|
||||
|
||||
Optional<ButtonType> choice = confirmDialog.showAndWait();
|
||||
if (ButtonType.YES.equals(choice.get())) {
|
||||
forcedUnmountVault(onSuccess);
|
||||
forcedLockVault(onSuccess);
|
||||
} else {
|
||||
LOG.trace("Unmount cancelled.", e);
|
||||
}
|
||||
@@ -224,29 +143,43 @@ public class UnlockedController implements ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private void forcedLockVault(Runnable onSuccess) {
|
||||
Tasks.create(() -> {
|
||||
vault.get().lock(true);
|
||||
}).onSuccess(() -> {
|
||||
LOG.trace("Forced unmount succeeded.");
|
||||
onSuccess.run();
|
||||
}).onError(Exception.class, e -> {
|
||||
LOG.error("Forced unmount failed.", e);
|
||||
messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
|
||||
}).runOnce(executor);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void didClickMoreOptions(ActionEvent event) {
|
||||
if (moreOptionsMenu.isShowing()) {
|
||||
moreOptionsMenu.hide();
|
||||
} else {
|
||||
moreOptionsMenu.setAnchorLocation(AnchorLocation.CONTENT_TOP_RIGHT);
|
||||
moreOptionsMenu.show(moreOptionsButton, Side.BOTTOM, moreOptionsButton.getWidth(), 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void didClickRevealVault(ActionEvent event) {
|
||||
revealVault(vault.get());
|
||||
}
|
||||
|
||||
private void revealVault(Vault vault) {
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
void revealVault(Vault vault) {
|
||||
Tasks.create(() -> {
|
||||
vault.reveal();
|
||||
}).onSuccess(() -> {
|
||||
LOG.trace("Reveal succeeded.");
|
||||
messageLabel.setText(null);
|
||||
}).onError(CommandFailedException.class, e -> {
|
||||
}).onError(Exception.class, e -> {
|
||||
LOG.error("Reveal failed.", e);
|
||||
messageLabel.setText(localization.getString("unlocked.label.revealFailed"));
|
||||
}).run();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void didClickCopyUrl(ActionEvent event) {
|
||||
ClipboardContent clipboardContent = new ClipboardContent();
|
||||
clipboardContent.putUrl(vault.get().getFilesystemRootUrl());
|
||||
clipboardContent.putString(vault.get().getFilesystemRootUrl());
|
||||
Clipboard.getSystemClipboard().setContent(clipboardContent);
|
||||
}).runOnce(executor);
|
||||
}
|
||||
|
||||
// ****************************************
|
||||
|
||||
@@ -5,19 +5,10 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.UpgradeStrategies;
|
||||
import org.cryptomator.ui.model.UpgradeStrategy;
|
||||
import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javafx.beans.binding.BooleanExpression;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
@@ -30,19 +21,26 @@ import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.model.UpgradeStrategies;
|
||||
import org.cryptomator.ui.model.UpgradeStrategy;
|
||||
import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.Tasks;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
public class UpgradeController implements ViewController {
|
||||
|
||||
private final ObjectProperty<UpgradeStrategy> strategy = new SimpleObjectProperty<>();
|
||||
private final UpgradeStrategies strategies;
|
||||
private final AsyncTaskService asyncTaskService;
|
||||
private final ExecutorService executor;
|
||||
private Optional<UpgradeListener> listener = Optional.empty();
|
||||
private Vault vault;
|
||||
|
||||
@Inject
|
||||
public UpgradeController(Localization localization, UpgradeStrategies strategies, AsyncTaskService asyncTaskService) {
|
||||
public UpgradeController(UpgradeStrategies strategies, ExecutorService executor) {
|
||||
this.strategies = strategies;
|
||||
this.asyncTaskService = asyncTaskService;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -122,8 +120,8 @@ public class UpgradeController implements ViewController {
|
||||
private void upgrade(UpgradeStrategy instruction) {
|
||||
passwordField.setDisable(true);
|
||||
progressIndicator.setVisible(true);
|
||||
asyncTaskService //
|
||||
.asyncTaskOf(() -> {
|
||||
Tasks //
|
||||
.create(() -> {
|
||||
if (!instruction.isApplicable(vault)) {
|
||||
throw new IllegalStateException("No ugprade needed for " + vault.getPath());
|
||||
}
|
||||
@@ -137,7 +135,7 @@ public class UpgradeController implements ViewController {
|
||||
progressIndicator.setVisible(false);
|
||||
passwordField.setDisable(false);
|
||||
passwordField.swipe();
|
||||
}).run();
|
||||
}).runOnce(executor);
|
||||
}
|
||||
|
||||
private void showNextUpgrade() {
|
||||
|
||||
@@ -2,24 +2,27 @@
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@@ -30,20 +33,20 @@ import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.layout.VBox;
|
||||
import jdk.incubator.http.HttpClient;
|
||||
import jdk.incubator.http.HttpRequest;
|
||||
import jdk.incubator.http.HttpResponse;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.cryptomator.ui.util.Tasks;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.cryptomator.ui.util.DialogBuilderUtil.buildYesNoDialog;
|
||||
|
||||
@Singleton
|
||||
public class WelcomeController implements ViewController {
|
||||
|
||||
@@ -54,17 +57,17 @@ public class WelcomeController implements ViewController {
|
||||
private final Localization localization;
|
||||
private final Settings settings;
|
||||
private final Comparator<String> semVerComparator;
|
||||
private final AsyncTaskService asyncTaskService;
|
||||
private final ScheduledExecutorService executor;
|
||||
|
||||
@Inject
|
||||
public WelcomeController(Application app, @Named("applicationVersion") Optional<String> applicationVersion, Localization localization, Settings settings, @Named("SemVer") Comparator<String> semVerComparator,
|
||||
AsyncTaskService asyncTaskService) {
|
||||
ScheduledExecutorService executor) {
|
||||
this.app = app;
|
||||
this.applicationVersion = applicationVersion;
|
||||
this.localization = localization;
|
||||
this.settings = settings;
|
||||
this.semVerComparator = semVerComparator;
|
||||
this.asyncTaskService = asyncTaskService;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -86,6 +89,8 @@ public class WelcomeController implements ViewController {
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
if (areUpdatesManagedExternally()) {
|
||||
checkForUpdatesContainer.setVisible(false);
|
||||
} else if (!settings.askedForUpdateCheck().get()) {
|
||||
this.askForUpdateCheck();
|
||||
} else if (settings.checkForUpdates().get()) {
|
||||
this.checkForUpdates();
|
||||
}
|
||||
@@ -104,34 +109,63 @@ public class WelcomeController implements ViewController {
|
||||
return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
|
||||
}
|
||||
|
||||
private void askForUpdateCheck() {
|
||||
Tasks.create(() -> {}).onSuccess(() -> {
|
||||
Optional<ButtonType> result = buildYesNoDialog(
|
||||
localization.getString("welcome.askForUpdateCheck.dialog.title"),
|
||||
localization.getString("welcome.askForUpdateCheck.dialog.header"),
|
||||
localization.getString("welcome.askForUpdateCheck.dialog.content"),
|
||||
ButtonType.YES).showAndWait();
|
||||
if (result.isPresent()) {
|
||||
settings.askedForUpdateCheck().set(true);
|
||||
settings.checkForUpdates().set(result.get().equals(ButtonType.YES));
|
||||
}
|
||||
if (settings.checkForUpdates().get()) {
|
||||
this.checkForUpdates();
|
||||
}
|
||||
}).scheduleOnce(executor, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void checkForUpdates() {
|
||||
checkForUpdatesStatus.setText(localization.getString("welcome.checkForUpdates.label.currentlyChecking"));
|
||||
checkForUpdatesIndicator.setVisible(true);
|
||||
asyncTaskService.asyncTaskOf(() -> {
|
||||
Tasks.create(() -> {
|
||||
String userAgent = String.format("Cryptomator VersionChecker/%s %s %s (%s)", applicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.GET()
|
||||
.uri(new URI("https://api.cryptomator.org/updates/latestVersion.json"))
|
||||
.header("User-Agent", userAgent)
|
||||
.timeout(Duration.ofSeconds(5))
|
||||
.build();
|
||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandler.asString(StandardCharsets.UTF_8));
|
||||
if (response.statusCode() == 200) {
|
||||
URL url = URI.create("https://api.cryptomator.org/updates/latestVersion.json").toURL();
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.addRequestProperty("User-Agent", userAgent);
|
||||
conn.connect();
|
||||
try {
|
||||
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||
return Optional.<byte[]>empty();
|
||||
}
|
||||
try (InputStream in = conn.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
in.transferTo(out);
|
||||
return Optional.of(out.toByteArray());
|
||||
}
|
||||
} finally {
|
||||
conn.disconnect();
|
||||
}
|
||||
}).onSuccess(response -> {
|
||||
response.ifPresent(bytes -> {
|
||||
Gson gson = new GsonBuilder().setLenient().create();
|
||||
Map<String, String> map = gson.fromJson(response.body(), new TypeToken<Map<String, String>>() {
|
||||
String json = new String(bytes, StandardCharsets.UTF_8);
|
||||
Map<String, String> map = gson.fromJson(json, new TypeToken<Map<String, String>>() {
|
||||
}.getType());
|
||||
if (map != null) {
|
||||
this.compareVersions(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}).onError(Exception.class, e -> {
|
||||
LOG.warn("Error checking for updates", e);
|
||||
}).andFinally(() -> {
|
||||
checkForUpdatesStatus.setText("");
|
||||
checkForUpdatesIndicator.setVisible(false);
|
||||
}).run();
|
||||
}).runOnce(executor);
|
||||
}
|
||||
|
||||
private void compareVersions(final Map<String, String> latestVersions) {
|
||||
assert Platform.isFxApplicationThread();
|
||||
final String latestVersion;
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
latestVersion = latestVersions.get("mac");
|
||||
@@ -147,11 +181,9 @@ public class WelcomeController implements ViewController {
|
||||
LOG.info("Current version: {}, lastest version: {}", currentVersion, latestVersion);
|
||||
if (currentVersion != null && semVerComparator.compare(currentVersion, latestVersion) < 0) {
|
||||
final String msg = String.format(localization.getString("welcome.newVersionMessage"), latestVersion, currentVersion);
|
||||
Platform.runLater(() -> {
|
||||
this.updateLink.setText(msg);
|
||||
this.updateLink.setVisible(true);
|
||||
this.updateLink.setDisable(false);
|
||||
});
|
||||
this.updateLink.setText(msg);
|
||||
this.updateLink.setVisible(true);
|
||||
this.updateLink.setDisable(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,9 +68,7 @@ public class DirectoryListCell extends DraggableListCell<Vault> {
|
||||
}
|
||||
switch (state) {
|
||||
case UNLOCKED:
|
||||
case MOUNTED:
|
||||
case MOUNTING:
|
||||
case UNMOUNTING:
|
||||
case PROCESSING:
|
||||
return "\uf09c";
|
||||
case LOCKED:
|
||||
default:
|
||||
@@ -84,9 +82,7 @@ public class DirectoryListCell extends DraggableListCell<Vault> {
|
||||
}
|
||||
switch (state) {
|
||||
case UNLOCKED:
|
||||
case MOUNTED:
|
||||
case MOUNTING:
|
||||
case UNMOUNTING:
|
||||
case PROCESSING:
|
||||
return UNLOCKED_ICON_COLOR;
|
||||
case LOCKED:
|
||||
default:
|
||||
|
||||
@@ -73,33 +73,21 @@ public class AutoUnlocker {
|
||||
}
|
||||
try {
|
||||
vault.unlock(CharBuffer.wrap(storedPw));
|
||||
mountSilently(vault);
|
||||
} catch (IOException | CryptoException e) {
|
||||
revealSilently(vault);
|
||||
} catch (IOException | CryptoException | Volume.VolumeException e) {
|
||||
LOG.error("Auto unlock failed.", e);
|
||||
} finally {
|
||||
Arrays.fill(storedPw, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
private void mountSilently(Vault unlockedVault) {
|
||||
if (!unlockedVault.getVaultSettings().mountAfterUnlock().get()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
unlockedVault.mount();
|
||||
revealSilently(unlockedVault);
|
||||
} catch (CommandFailedException e) {
|
||||
LOG.error("Auto unlock succeded, but mounting the drive failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void revealSilently(Vault mountedVault) {
|
||||
if (!mountedVault.getVaultSettings().revealAfterMount().get()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mountedVault.reveal();
|
||||
} catch (CommandFailedException e) {
|
||||
} catch (Volume.VolumeException e) {
|
||||
LOG.error("Auto unlock succeded, but revealing the drive failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
public class CommandFailedException extends Exception {
|
||||
|
||||
public CommandFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CommandFailedException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public CommandFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
||||
import org.cryptomator.frontend.dokany.Mount;
|
||||
import org.cryptomator.frontend.dokany.MountFactory;
|
||||
import org.cryptomator.frontend.dokany.MountFailedException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public class DokanyVolume implements Volume {
|
||||
|
||||
private static final String FS_TYPE_NAME = "Cryptomator File System";
|
||||
|
||||
private final VaultSettings vaultSettings;
|
||||
private final MountFactory mountFactory;
|
||||
private final WindowsDriveLetters windowsDriveLetters;
|
||||
private Mount mount;
|
||||
|
||||
@Inject
|
||||
public DokanyVolume(VaultSettings vaultSettings, ExecutorService executorService, WindowsDriveLetters windowsDriveLetters) {
|
||||
this.vaultSettings = vaultSettings;
|
||||
this.mountFactory = new MountFactory(executorService);
|
||||
this.windowsDriveLetters = windowsDriveLetters;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return DokanyVolume.isSupportedStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mount(CryptoFileSystem fs) throws VolumeException {
|
||||
Path mountPath = Paths.get(getMountPathString());
|
||||
String mountName = vaultSettings.mountName().get();
|
||||
try {
|
||||
this.mount = mountFactory.mount(fs.getPath("/"), mountPath, mountName, FS_TYPE_NAME);
|
||||
} catch (MountFailedException e) {
|
||||
throw new VolumeException("Unable to mount Filesystem", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getMountPathString() throws VolumeException {
|
||||
if (vaultSettings.usesIndividualMountPath().get()) {
|
||||
return vaultSettings.individualMountPath().get();
|
||||
} else if (!Strings.isNullOrEmpty(vaultSettings.winDriveLetter().get())) {
|
||||
return vaultSettings.winDriveLetter().get().charAt(0) + ":\\";
|
||||
} else {
|
||||
//auto assign drive letter
|
||||
if (!windowsDriveLetters.getAvailableDriveLetters().isEmpty()) {
|
||||
return windowsDriveLetters.getAvailableDriveLetters().iterator().next() + ":\\";
|
||||
} else {
|
||||
throw new VolumeException("No free drive letter available.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reveal() throws VolumeException {
|
||||
boolean success = mount.reveal();
|
||||
if (!success) {
|
||||
throw new VolumeException("Reveal failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmount() {
|
||||
mount.close();
|
||||
}
|
||||
|
||||
public static boolean isSupportedStatic() {
|
||||
return MountFactory.isApplicable();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package org.cryptomator.ui.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryNotEmptyException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -11,6 +12,7 @@ import javax.inject.Inject;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
||||
import org.cryptomator.frontend.fuse.mount.CommandFailedException;
|
||||
import org.cryptomator.frontend.fuse.mount.EnvironmentVariables;
|
||||
import org.cryptomator.frontend.fuse.mount.FuseMountFactory;
|
||||
import org.cryptomator.frontend.fuse.mount.FuseNotSupportedException;
|
||||
@@ -18,7 +20,6 @@ import org.cryptomator.frontend.fuse.mount.Mount;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@VaultModule.PerVault
|
||||
public class FuseVolume implements Volume {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FuseVolume.class);
|
||||
@@ -30,34 +31,21 @@ public class FuseVolume implements Volume {
|
||||
private static final String DEFAULT_MOUNTROOTPATH_LINUX = System.getProperty("user.home") + "/.Cryptomator";
|
||||
|
||||
private final VaultSettings vaultSettings;
|
||||
private final WindowsDriveLetters windowsDriveLetters;
|
||||
|
||||
private Mount fuseMnt;
|
||||
private CryptoFileSystem cfs;
|
||||
private Path mountPath;
|
||||
private boolean extraDirCreated;
|
||||
|
||||
@Inject
|
||||
public FuseVolume(VaultSettings vaultSettings, WindowsDriveLetters windowsDriveLetters) {
|
||||
public FuseVolume(VaultSettings vaultSettings) {
|
||||
this.vaultSettings = vaultSettings;
|
||||
this.windowsDriveLetters = windowsDriveLetters;
|
||||
this.extraDirCreated = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare(CryptoFileSystem fs) throws IOException, FuseNotSupportedException {
|
||||
this.cfs = fs;
|
||||
public void mount(CryptoFileSystem fs) throws IOException, FuseNotSupportedException, VolumeException {
|
||||
String mountPath;
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
//windows case
|
||||
if (vaultSettings.winDriveLetter().get() != null) {
|
||||
// specific drive letter selected
|
||||
mountPath = vaultSettings.winDriveLetter().get() + ":\\";
|
||||
} else {
|
||||
// auto assign drive letter
|
||||
mountPath = windowsDriveLetters.getAvailableDriveLetters().iterator().next() + ":\\";
|
||||
}
|
||||
} else if (vaultSettings.usesIndividualMountPath().get()) {
|
||||
if (vaultSettings.usesIndividualMountPath().get()) {
|
||||
//specific path given
|
||||
mountPath = vaultSettings.individualMountPath().get();
|
||||
} else {
|
||||
@@ -66,57 +54,59 @@ public class FuseVolume implements Volume {
|
||||
extraDirCreated = true;
|
||||
}
|
||||
this.mountPath = Paths.get(mountPath).toAbsolutePath();
|
||||
mount(fs.getPath("/"));
|
||||
}
|
||||
|
||||
private String createDirIfNotExist(String prefix, String dirName) throws IOException {
|
||||
Path p = Paths.get(prefix, dirName + vaultSettings.getId());
|
||||
if (Files.isDirectory(p) && !Files.newDirectoryStream(p).iterator().hasNext()) {
|
||||
throw new DirectoryNotEmptyException("Mount point is not empty.");
|
||||
if (Files.isDirectory(p)) {
|
||||
try (DirectoryStream<Path> emptyCheck = Files.newDirectoryStream(p)) {
|
||||
if (emptyCheck.iterator().hasNext()) {
|
||||
throw new DirectoryNotEmptyException("Mount point is not empty.");
|
||||
} else {
|
||||
LOG.info("Directory already exists and is empty. Using it as mount point.");
|
||||
return p.toString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Files.createDirectory(p);
|
||||
return p.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mount() throws CommandFailedException {
|
||||
private void mount(Path root) throws VolumeException {
|
||||
try {
|
||||
EnvironmentVariables envVars = EnvironmentVariables.create()
|
||||
.withMountName(vaultSettings.mountName().getValue())
|
||||
.withMountPath(mountPath)
|
||||
.build();
|
||||
this.fuseMnt = FuseMountFactory.getMounter().mount(cfs.getPath("/"), envVars);
|
||||
} catch (org.cryptomator.frontend.fuse.mount.CommandFailedException e) {
|
||||
throw new CommandFailedException("Unable to mount Filesystem", e);
|
||||
this.fuseMnt = FuseMountFactory.getMounter().mount(root, envVars);
|
||||
} catch (CommandFailedException e) {
|
||||
throw new VolumeException("Unable to mount Filesystem", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reveal() throws CommandFailedException {
|
||||
public void reveal() throws VolumeException {
|
||||
try {
|
||||
fuseMnt.revealInFileManager();
|
||||
} catch (org.cryptomator.frontend.fuse.mount.CommandFailedException e) {
|
||||
} catch (CommandFailedException e) {
|
||||
LOG.info("Revealing the vault in file manger failed: " + e.getMessage());
|
||||
throw new CommandFailedException(e);
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unmount() throws CommandFailedException {
|
||||
public synchronized void unmount() throws VolumeException {
|
||||
try {
|
||||
fuseMnt.close();
|
||||
} catch (org.cryptomator.frontend.fuse.mount.CommandFailedException e) {
|
||||
throw new CommandFailedException(e);
|
||||
} catch (CommandFailedException e) {
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unmountForced() throws CommandFailedException {
|
||||
unmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
private void cleanup() {
|
||||
if (extraDirCreated) {
|
||||
try {
|
||||
Files.delete(mountPath);
|
||||
@@ -126,19 +116,13 @@ public class FuseVolume implements Volume {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMountUri() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return FuseMountFactory.isFuseSupported();
|
||||
return FuseVolume.isSupportedStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsForcedUnmount() {
|
||||
return false;
|
||||
public static boolean isSupportedStatic() {
|
||||
return (SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_LINUX) && FuseMountFactory.isFuseSupported();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
public class InvalidSettingsException extends RuntimeException {
|
||||
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitOption;
|
||||
import java.nio.file.FileVisitResult;
|
||||
@@ -19,11 +19,7 @@ import java.util.EnumSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.codec.binary.Base32;
|
||||
import org.apache.commons.codec.binary.BaseNCodec;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.cryptomator.cryptolib.Cryptors;
|
||||
import org.cryptomator.cryptolib.api.Cryptor;
|
||||
@@ -32,6 +28,8 @@ import org.cryptomator.ui.l10n.Localization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
* Contains the collective knowledge of all creatures who were alive during the development of vault format 3.
|
||||
* This class uses no external classes from the crypto or shortening layer by purpose, so we don't need legacy code inside these.
|
||||
@@ -50,7 +48,7 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
|
||||
private static final String NEW_FOLDER_PREFIX = "0";
|
||||
|
||||
private final MessageDigest sha1 = MessageDigestSupplier.SHA1.get();
|
||||
private final BaseNCodec base32 = new Base32();
|
||||
private final BaseEncoding base32 = BaseEncoding.base32();
|
||||
|
||||
@Inject
|
||||
public UpgradeVersion3to4(Localization localization) {
|
||||
@@ -155,7 +153,7 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
|
||||
String oldLongName = new String(Files.readAllBytes(oldMetadataFile), UTF_8);
|
||||
if (oldLongName.endsWith(OLD_FOLDER_SUFFIX)) {
|
||||
String newLongName = NEW_FOLDER_PREFIX + StringUtils.removeEnd(oldLongName, OLD_FOLDER_SUFFIX);
|
||||
String newCanonicalBase32 = base32.encodeAsString(sha1.digest(newLongName.getBytes(UTF_8)));
|
||||
String newCanonicalBase32 = base32.encode(sha1.digest(newLongName.getBytes(UTF_8)));
|
||||
String newCanonicalName = newCanonicalBase32 + LONG_FILENAME_EXT;
|
||||
Path newMetadataFile = metadataDir.resolve(newCanonicalName.substring(0, 2)).resolve(newCanonicalName.substring(2, 4)).resolve(newCanonicalName);
|
||||
String newName = newCanonicalBase32 + oldNameSuffix + LONG_FILENAME_EXT;
|
||||
|
||||
@@ -8,18 +8,14 @@
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.LazyInitializer;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
@@ -29,20 +25,22 @@ import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.ui.model.VaultModule.PerVault;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@PerVault
|
||||
public class Vault {
|
||||
|
||||
@@ -53,20 +51,21 @@ public class Vault {
|
||||
|
||||
private final Settings settings;
|
||||
private final VaultSettings vaultSettings;
|
||||
private final Provider<Volume> volumeProvider;
|
||||
private final AtomicReference<CryptoFileSystem> cryptoFileSystem = new AtomicReference<>();
|
||||
private final ObjectProperty<State> state = new SimpleObjectProperty<State>(State.LOCKED);
|
||||
|
||||
private Volume volume;
|
||||
|
||||
public enum State {
|
||||
LOCKED, UNLOCKED, MOUNTING, MOUNTED, UNMOUNTING
|
||||
LOCKED, PROCESSING, UNLOCKED
|
||||
}
|
||||
|
||||
@Inject
|
||||
Vault(Settings settings, VaultSettings vaultSettings, Volume volume) {
|
||||
Vault(Settings settings, VaultSettings vaultSettings, Provider<Volume> volumeProvider) {
|
||||
this.settings = settings;
|
||||
this.vaultSettings = vaultSettings;
|
||||
this.volume = volume;
|
||||
this.volumeProvider = volumeProvider;
|
||||
}
|
||||
|
||||
// ******************************************************************************
|
||||
@@ -98,51 +97,40 @@ public class Vault {
|
||||
CryptoFileSystemProvider.changePassphrase(getPath(), MASTERKEY_FILENAME, oldPassphrase, newPassphrase);
|
||||
}
|
||||
|
||||
public synchronized void unlock(CharSequence passphrase) throws CryptoException, IOException {
|
||||
CryptoFileSystem fs = getCryptoFileSystem(passphrase);
|
||||
volume.prepare(fs);
|
||||
Platform.runLater(() -> {
|
||||
state.set(State.UNLOCKED);
|
||||
});
|
||||
public synchronized void unlock(CharSequence passphrase) throws InvalidSettingsException, CryptoException, IOException, Volume.VolumeException {
|
||||
Platform.runLater(() -> state.set(State.PROCESSING));
|
||||
try {
|
||||
if (vaultSettings.usesIndividualMountPath().and(vaultSettings.individualMountPath().isEmpty()).get()) {
|
||||
throw new InvalidSettingsException();
|
||||
}
|
||||
CryptoFileSystem fs = getCryptoFileSystem(passphrase);
|
||||
volume = volumeProvider.get();
|
||||
volume.mount(fs);
|
||||
Platform.runLater(() -> {
|
||||
state.set(State.UNLOCKED);
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Platform.runLater(() -> state.set(State.LOCKED));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void mount() throws CommandFailedException {
|
||||
public synchronized void lock(boolean forced) throws Volume.VolumeException {
|
||||
Platform.runLater(() -> {
|
||||
state.set(State.MOUNTING);
|
||||
});
|
||||
volume.mount();
|
||||
Platform.runLater(() -> {
|
||||
state.set(State.MOUNTED);
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void unmountForced() throws CommandFailedException {
|
||||
unmount(true);
|
||||
}
|
||||
|
||||
public synchronized void unmount() throws CommandFailedException {
|
||||
unmount(false);
|
||||
}
|
||||
|
||||
private synchronized void unmount(boolean forced) throws CommandFailedException {
|
||||
Platform.runLater(() -> {
|
||||
state.set(State.UNMOUNTING);
|
||||
state.set(State.PROCESSING);
|
||||
});
|
||||
if (forced && volume.supportsForcedUnmount()) {
|
||||
volume.unmountForced();
|
||||
} else {
|
||||
volume.unmount();
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
state.set(State.UNLOCKED);
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void lock() throws IOException {
|
||||
volume.stop();
|
||||
CryptoFileSystem fs = cryptoFileSystem.getAndSet(null);
|
||||
if (fs != null) {
|
||||
fs.close();
|
||||
try {
|
||||
fs.close();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error closing file system.", e);
|
||||
}
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
state.set(State.LOCKED);
|
||||
@@ -154,26 +142,21 @@ public class Vault {
|
||||
*/
|
||||
public void prepareForShutdown() {
|
||||
try {
|
||||
unmount();
|
||||
} catch (CommandFailedException e) {
|
||||
lock(false);
|
||||
} catch (Volume.VolumeException e) {
|
||||
if (volume.supportsForcedUnmount()) {
|
||||
try {
|
||||
unmountForced();
|
||||
} catch (CommandFailedException e1) {
|
||||
LOG.warn("Failed to force unmount vault.");
|
||||
lock(true);
|
||||
} catch (Volume.VolumeException e1) {
|
||||
LOG.warn("Failed to force lock vault.", e1);
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Failed to gracefully unmount vault.");
|
||||
LOG.warn("Failed to gracefully lock vault.", e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
lock();
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Failed to lock vault.");
|
||||
}
|
||||
}
|
||||
|
||||
public void reveal() throws CommandFailedException {
|
||||
public void reveal() throws Volume.VolumeException {
|
||||
volume.reveal();
|
||||
}
|
||||
|
||||
@@ -257,11 +240,11 @@ public class Vault {
|
||||
return vaultSettings.mountName().get();
|
||||
}
|
||||
|
||||
public StringProperty getMountPathProperty() {
|
||||
return vaultSettings.individualMountPath();
|
||||
public String getCustomMountPath() {
|
||||
return vaultSettings.individualMountPath().getValueSafe();
|
||||
}
|
||||
|
||||
public void setMountPath(String mountPath) {
|
||||
public void setCustomMountPath(String mountPath) {
|
||||
vaultSettings.individualMountPath().set(mountPath);
|
||||
}
|
||||
|
||||
@@ -289,10 +272,6 @@ public class Vault {
|
||||
}
|
||||
}
|
||||
|
||||
public String getFilesystemRootUrl() {
|
||||
return volume.getMountUri();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return vaultSettings.getId();
|
||||
}
|
||||
|
||||
@@ -18,10 +18,13 @@ import org.cryptomator.common.settings.VaultSettings;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Module
|
||||
public class VaultModule {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(VaultModule.class);
|
||||
private final VaultSettings vaultSettings;
|
||||
|
||||
public VaultModule(VaultSettings vaultSettings) {
|
||||
@@ -42,21 +45,18 @@ public class VaultModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
@PerVault
|
||||
public Volume provideNioAdpater(Settings settings, WebDavVolume webDavVolume, FuseVolume fuseVolume) {
|
||||
VolumeImpl impl = settings.volumeImpl().get();
|
||||
switch (impl) {
|
||||
case FUSE:
|
||||
if (fuseVolume.isSupported()) {
|
||||
return fuseVolume;
|
||||
} else {
|
||||
settings.volumeImpl().set(VolumeImpl.WEBDAV);
|
||||
// fallthrough to WEBDAV
|
||||
}
|
||||
case WEBDAV:
|
||||
return webDavVolume;
|
||||
default:
|
||||
throw new IllegalStateException("Unsupported NioAdapter: " + impl);
|
||||
public Volume provideVolume(Settings settings, WebDavVolume webDavVolume, FuseVolume fuseVolume, DokanyVolume dokanyVolume) {
|
||||
VolumeImpl preferredImpl = settings.preferredVolumeImpl().get();
|
||||
if (VolumeImpl.DOKANY == preferredImpl && dokanyVolume.isSupported()) {
|
||||
return dokanyVolume;
|
||||
} else if (VolumeImpl.FUSE == preferredImpl && fuseVolume.isSupported()) {
|
||||
return fuseVolume;
|
||||
} else {
|
||||
if (VolumeImpl.WEBDAV != preferredImpl) {
|
||||
LOG.warn("Using WebDAV, because {} is not supported.", preferredImpl.getDisplayName());
|
||||
}
|
||||
assert webDavVolume.isSupported();
|
||||
return webDavVolume;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,75 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import org.cryptomator.common.settings.VolumeImpl;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Takes a Volume and usess it to mount an unlocked vault
|
||||
*/
|
||||
public interface Volume {
|
||||
|
||||
void prepare(CryptoFileSystem fs) throws IOException;
|
||||
/**
|
||||
* Checks in constant time whether this volume type is supported on the system running Cryptomator.
|
||||
*
|
||||
* @return true if this volume can be mounted
|
||||
*/
|
||||
boolean isSupported();
|
||||
|
||||
void mount() throws CommandFailedException;
|
||||
/**
|
||||
* @param fs
|
||||
* @throws IOException
|
||||
*/
|
||||
void mount(CryptoFileSystem fs) throws IOException, VolumeException;
|
||||
|
||||
default void reveal() throws CommandFailedException {
|
||||
throw new CommandFailedException("Not implemented.");
|
||||
}
|
||||
void reveal() throws VolumeException;
|
||||
|
||||
void unmount() throws CommandFailedException;
|
||||
void unmount() throws VolumeException;
|
||||
|
||||
default void unmountForced() throws CommandFailedException {
|
||||
throw new CommandFailedException("Operation not supported.");
|
||||
}
|
||||
|
||||
void stop();
|
||||
|
||||
String getMountUri();
|
||||
|
||||
default boolean isSupported() {
|
||||
return false;
|
||||
}
|
||||
// optional forced unmounting:
|
||||
|
||||
default boolean supportsForcedUnmount() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default void unmountForced() throws VolumeException {
|
||||
throw new VolumeException("Operation not supported.");
|
||||
}
|
||||
|
||||
static VolumeImpl[] getCurrentSupportedAdapters() {
|
||||
return Stream.of(VolumeImpl.values()).filter(impl -> {
|
||||
switch (impl) {
|
||||
case WEBDAV:
|
||||
return WebDavVolume.isSupportedStatic();
|
||||
case DOKANY:
|
||||
return DokanyVolume.isSupportedStatic();
|
||||
case FUSE:
|
||||
return FuseVolume.isSupportedStatic();
|
||||
default:
|
||||
return false;//throw new IllegalStateException("Adapter not implemented.");
|
||||
}
|
||||
}).toArray(VolumeImpl[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when a volume-specific command such as mount/unmount/reveal failed.
|
||||
*/
|
||||
class VolumeException extends Exception {
|
||||
|
||||
public VolumeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public VolumeException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public VolumeException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import javax.inject.Provider;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@VaultModule.PerVault
|
||||
public class WebDavVolume implements Volume {
|
||||
|
||||
private static final String LOCALHOST_ALIAS = "cryptomator-vault";
|
||||
@@ -36,7 +35,7 @@ public class WebDavVolume implements Volume {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare(CryptoFileSystem fs) {
|
||||
public void mount(CryptoFileSystem fs) throws VolumeException {
|
||||
if (server == null) {
|
||||
server = serverProvider.get();
|
||||
}
|
||||
@@ -45,10 +44,10 @@ public class WebDavVolume implements Volume {
|
||||
}
|
||||
servlet = server.createWebDavServlet(fs.getPath("/"), vaultSettings.getId() + "/" + vaultSettings.mountName().get());
|
||||
servlet.start();
|
||||
mount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mount() throws CommandFailedException {
|
||||
private void mount() throws VolumeException {
|
||||
if (servlet == null) {
|
||||
throw new IllegalStateException("Mounting requires unlocked WebDAV servlet.");
|
||||
}
|
||||
@@ -61,32 +60,38 @@ public class WebDavVolume implements Volume {
|
||||
this.mount = servlet.mount(mountParams); // might block this thread for a while
|
||||
} catch (Mounter.CommandFailedException e) {
|
||||
e.printStackTrace();
|
||||
throw new CommandFailedException(e);
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reveal() throws CommandFailedException {
|
||||
public void reveal() throws VolumeException {
|
||||
try {
|
||||
mount.reveal();
|
||||
} catch (Mounter.CommandFailedException e) {
|
||||
e.printStackTrace();
|
||||
throw new CommandFailedException(e);
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unmount() throws CommandFailedException {
|
||||
public synchronized void unmount() throws VolumeException {
|
||||
try {
|
||||
mount.unmount();
|
||||
} catch (Mounter.CommandFailedException e) {
|
||||
throw new CommandFailedException(e);
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unmountForced() {
|
||||
mount.forced();
|
||||
public synchronized void unmountForced() throws VolumeException {
|
||||
try {
|
||||
mount.forced().orElseThrow(IllegalStateException::new).unmount();
|
||||
} catch (Mounter.CommandFailedException e) {
|
||||
throw new VolumeException(e);
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
private String getLocalhostAliasOrNull() {
|
||||
@@ -102,29 +107,25 @@ public class WebDavVolume implements Volume {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
private void cleanup() {
|
||||
if (servlet != null) {
|
||||
servlet.stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public synchronized String getMountUri() {
|
||||
return servlet.getServletRootUri().toString() + "/";
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: what to check wether it is implemented?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return true;
|
||||
return WebDavVolume.isSupportedStatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsForcedUnmount() {
|
||||
return mount != null && mount.forced().isPresent();
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSupportedStatic() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.common.ConsumerThrowingException;
|
||||
import org.cryptomator.common.RunnableThrowingException;
|
||||
import org.cryptomator.common.SupplierThrowingException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@Singleton
|
||||
public class AsyncTaskService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AsyncTaskService.class);
|
||||
|
||||
private final ExecutorService executor;
|
||||
|
||||
@Inject
|
||||
public AsyncTaskService(ExecutorService executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new async task
|
||||
*
|
||||
* @param task Tasks to be invoked in a background thread.
|
||||
* @return The async task
|
||||
*/
|
||||
public AsyncTaskWithoutSuccessHandler<Void> asyncTaskOf(RunnableThrowingException<?> task) {
|
||||
return new AsyncTaskImpl<>(() -> {
|
||||
task.run();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new async task
|
||||
*
|
||||
* @param task Tasks to be invoked in a background thread.
|
||||
* @return The async task
|
||||
*/
|
||||
public <ResultType> AsyncTaskWithoutSuccessHandler<ResultType> asyncTaskOf(SupplierThrowingException<ResultType, ?> task) {
|
||||
return new AsyncTaskImpl<>(task);
|
||||
}
|
||||
|
||||
private class AsyncTaskImpl<ResultType> implements AsyncTaskWithoutSuccessHandler<ResultType> {
|
||||
|
||||
private final SupplierThrowingException<ResultType, ?> task;
|
||||
|
||||
private ConsumerThrowingException<ResultType, ?> successHandler = value -> {
|
||||
};
|
||||
private final List<ErrorHandler<Throwable>> errorHandlers = new ArrayList<>();
|
||||
private RunnableThrowingException<?> finallyHandler = () -> {
|
||||
};
|
||||
|
||||
public AsyncTaskImpl(SupplierThrowingException<ResultType, ?> task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncTaskWithoutErrorHandler onSuccess(ConsumerThrowingException<ResultType, ?> handler) {
|
||||
successHandler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncTaskWithoutErrorHandler onSuccess(RunnableThrowingException<?> handler) {
|
||||
return onSuccess(result -> handler.run());
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
@Override
|
||||
public <ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, ConsumerThrowingException<ErrorType, ?> handler) {
|
||||
errorHandlers.add((ErrorHandler) new ErrorHandler<>(type, handler));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, RunnableThrowingException<?> handler) {
|
||||
return onError(type, error -> handler.run());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncTask andFinally(RunnableThrowingException<?> handler) {
|
||||
finallyHandler = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
errorHandlers.add(ErrorHandler.LOGGING_HANDLER);
|
||||
executor.execute(() -> logExceptions(() -> {
|
||||
try {
|
||||
ResultType result = task.get();
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
successHandler.accept(result);
|
||||
} catch (Throwable e) {
|
||||
LOG.error("Uncaught exception", e);
|
||||
}
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
ErrorHandler<Throwable> errorHandler = errorHandlerFor(e);
|
||||
Platform.runLater(toRunnableLoggingException(() -> errorHandler.accept(e)));
|
||||
} finally {
|
||||
Platform.runLater(toRunnableLoggingException(finallyHandler));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private ErrorHandler<Throwable> errorHandlerFor(Throwable e) {
|
||||
return errorHandlers.stream().filter(handler -> handler.handles(e)).findFirst().get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Runnable toRunnableLoggingException(RunnableThrowingException<?> delegate) {
|
||||
return () -> logExceptions(delegate);
|
||||
}
|
||||
|
||||
private static void logExceptions(RunnableThrowingException<?> delegate) {
|
||||
try {
|
||||
delegate.run();
|
||||
} catch (Throwable e) {
|
||||
LOG.error("Uncaught exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ErrorHandler<ErrorType> implements ConsumerThrowingException<ErrorType, Throwable> {
|
||||
|
||||
public static final ErrorHandler<Throwable> LOGGING_HANDLER = new ErrorHandler<Throwable>(Throwable.class, error -> {
|
||||
LOG.error("Uncaught exception", error);
|
||||
});
|
||||
|
||||
private final Class<ErrorType> type;
|
||||
private final ConsumerThrowingException<ErrorType, ?> delegate;
|
||||
|
||||
public ErrorHandler(Class<ErrorType> type, ConsumerThrowingException<ErrorType, ?> delegate) {
|
||||
this.type = type;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public boolean handles(Throwable error) {
|
||||
return type.isInstance(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ErrorType error) throws Throwable {
|
||||
delegate.accept(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface AsyncTaskWithoutSuccessHandler<ResultType> extends AsyncTaskWithoutErrorHandler {
|
||||
|
||||
/**
|
||||
* @param handler Tasks to be invoked on the JavaFX application thread.
|
||||
* @return The async task
|
||||
*/
|
||||
AsyncTaskWithoutErrorHandler onSuccess(ConsumerThrowingException<ResultType, ?> handler);
|
||||
|
||||
/**
|
||||
* @param handler Tasks to be invoked on the JavaFX application thread.
|
||||
* @return The async task
|
||||
*/
|
||||
AsyncTaskWithoutErrorHandler onSuccess(RunnableThrowingException<?> handler);
|
||||
|
||||
}
|
||||
|
||||
public interface AsyncTaskWithoutErrorHandler extends AsyncTaskWithoutFinallyHandler {
|
||||
|
||||
/**
|
||||
* @param type Exception type to catch
|
||||
* @param handler Tasks to be invoked on the JavaFX application thread.
|
||||
* @return The async task
|
||||
*/
|
||||
<ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, ConsumerThrowingException<ErrorType, ?> handler);
|
||||
|
||||
/**
|
||||
* @param type Exception type to catch
|
||||
* @param handler Tasks to be invoked on the JavaFX application thread.
|
||||
* @return The async task
|
||||
*/
|
||||
<ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, RunnableThrowingException<?> handler);
|
||||
|
||||
}
|
||||
|
||||
public interface AsyncTaskWithoutFinallyHandler extends AsyncTask {
|
||||
|
||||
/**
|
||||
* @param handler Tasks to be invoked on the JavaFX application thread.
|
||||
* @return The async task
|
||||
*/
|
||||
AsyncTask andFinally(RunnableThrowingException<?> handler);
|
||||
|
||||
}
|
||||
|
||||
public interface AsyncTask extends Runnable {
|
||||
|
||||
/**
|
||||
* Starts the async task.
|
||||
*/
|
||||
@Override
|
||||
void run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,10 @@ public class DialogBuilderUtil {
|
||||
return buildDialog(title, header, content, Alert.AlertType.CONFIRMATION, defaultButton, ButtonType.YES, ButtonType.NO);
|
||||
}
|
||||
|
||||
public static Alert buildGracefulShutdownDialog(String title, String header, String content, ButtonType defaultButton, ButtonType... buttons) {
|
||||
return buildDialog(title, header, content, Alert.AlertType.WARNING, defaultButton, buttons);
|
||||
}
|
||||
|
||||
private static Alert buildDialog(String title, String header, String content, Alert.AlertType type, ButtonType defaultButton, ButtonType... buttons) {
|
||||
Text contentText = new Text(content);
|
||||
contentText.setWrappingWidth(360.0);
|
||||
|
||||
@@ -28,6 +28,8 @@ import javafx.scene.paint.Color;
|
||||
@Singleton
|
||||
public class PasswordStrengthUtil {
|
||||
|
||||
private static final int PW_TRUNC_LEN = 100; // truncate very long passwords, since zxcvbn memory and runtime depends vastly on the length
|
||||
|
||||
private final Zxcvbn zxcvbn;
|
||||
private final List<String> sanitizedInputs;
|
||||
private final Localization localization;
|
||||
@@ -43,10 +45,9 @@ public class PasswordStrengthUtil {
|
||||
public int computeRate(String password) {
|
||||
if (Strings.isNullOrEmpty(password)) {
|
||||
return -1;
|
||||
} else if (password.length() > 100) {
|
||||
return 4; // assume this is strong. zxcvbn memory and runtime depends vastly on the password length
|
||||
} else {
|
||||
return zxcvbn.measure(password, sanitizedInputs).getScore();
|
||||
int numCharsToRate = Math.min(PW_TRUNC_LEN, password.length());
|
||||
return zxcvbn.measure(password.substring(0, numCharsToRate), sanitizedInputs).getScore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
192
main/ui/src/main/java/org/cryptomator/ui/util/Tasks.java
Normal file
192
main/ui/src/main/java/org/cryptomator/ui/util/Tasks.java
Normal file
@@ -0,0 +1,192 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.concurrent.ScheduledService;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.util.Duration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class Tasks {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Tasks.class);
|
||||
public static <T> TaskBuilder<T> create(Callable<T> callable) {
|
||||
return new TaskBuilder<>(callable);
|
||||
}
|
||||
|
||||
public static TaskBuilder<Void> create(VoidCallable callable) {
|
||||
return create(() -> {
|
||||
callable.call();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public static class TaskBuilder<T> {
|
||||
|
||||
private final Callable<T> callable;
|
||||
private Consumer<T> successHandler = x -> {
|
||||
};
|
||||
private List<ErrorHandler<?>> errorHandlers = new ArrayList<>();
|
||||
private Runnable finallyHandler = () -> {};
|
||||
|
||||
TaskBuilder(Callable<T> callable) {
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
public TaskBuilder<T> onSuccess(Runnable successHandler) {
|
||||
this.successHandler = x -> {
|
||||
successHandler.run();
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
public TaskBuilder<T> onSuccess(Consumer<T> successHandler) {
|
||||
this.successHandler = successHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public <E extends Throwable> TaskBuilder<T> onError(Class<E> type, Consumer<E> exceptionHandler) {
|
||||
errorHandlers.add(new ErrorHandler<>(type, exceptionHandler));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TaskBuilder<T> andFinally(Runnable finallyHandler) {
|
||||
this.finallyHandler = finallyHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
private Task<T> build() {
|
||||
return new TaskImpl<>(callable, successHandler, errorHandlers, finallyHandler);
|
||||
}
|
||||
|
||||
public Task<T> runOnce(ExecutorService executorService) {
|
||||
Task<T> task = build();
|
||||
executorService.submit(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public Task<T> scheduleOnce(ScheduledExecutorService executorService, long delay, TimeUnit unit) {
|
||||
Task<T> task = build();
|
||||
executorService.schedule(task, delay, unit);
|
||||
return task;
|
||||
}
|
||||
|
||||
public ScheduledService<T> schedulePeriodically(ExecutorService executorService, Duration initialDelay, Duration period) {
|
||||
ScheduledService<T> service = new RestartingService<>(this::build);
|
||||
service.setExecutor(executorService);
|
||||
service.setDelay(initialDelay);
|
||||
service.setPeriod(period);
|
||||
Platform.runLater(service::start);
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ErrorHandler<ErrorType extends Throwable> {
|
||||
|
||||
private final Class<ErrorType> type;
|
||||
private final Consumer<ErrorType> errorHandler;
|
||||
|
||||
public ErrorHandler(Class<ErrorType> type, Consumer<ErrorType> errorHandler) {
|
||||
this.type = type;
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
public boolean handles(Throwable error) {
|
||||
return type.isInstance(error);
|
||||
}
|
||||
|
||||
public void handle(Throwable error) throws ClassCastException {
|
||||
ErrorType typedError = type.cast(error);
|
||||
errorHandler.accept(typedError);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter between java.util.function.* and javafx.concurrent.*
|
||||
*/
|
||||
private static class TaskImpl<T> extends Task<T> {
|
||||
|
||||
private final Callable<T> callable;
|
||||
private final Consumer<T> successHandler;
|
||||
private List<ErrorHandler<?>> errorHandlers;
|
||||
private final Runnable finallyHandler;
|
||||
|
||||
TaskImpl(Callable<T> callable, Consumer<T> successHandler, List<ErrorHandler<?>> errorHandlers, Runnable finallyHandler) {
|
||||
this.callable = callable;
|
||||
this.successHandler = successHandler;
|
||||
this.errorHandlers = errorHandlers;
|
||||
this.finallyHandler = finallyHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T call() throws Exception {
|
||||
return callable.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void succeeded() {
|
||||
try {
|
||||
successHandler.accept(getValue());
|
||||
} finally {
|
||||
finallyHandler.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void failed() {
|
||||
try {
|
||||
Throwable exception = getException();
|
||||
errorHandlers.stream().filter(handler -> handler.handles(exception)).findFirst().ifPresentOrElse(exceptionHandler -> {
|
||||
exceptionHandler.handle(exception);
|
||||
}, () -> {
|
||||
LOG.error("Unhandled exception", exception);
|
||||
});
|
||||
} finally {
|
||||
finallyHandler.run();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A service that keeps executing the next task long as tasks are succeeding.
|
||||
*/
|
||||
private static class RestartingService<T> extends ScheduledService<T> {
|
||||
|
||||
private final Supplier<Task<T>> taskFactory;
|
||||
|
||||
RestartingService(Supplier<Task<T>> taskFactory) {
|
||||
this.taskFactory = taskFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Task<T> createTask() {
|
||||
return taskFactory.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface VoidCallable {
|
||||
|
||||
void call() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
Contributors:
|
||||
Sebastian Stenzel - initial API and implementation
|
||||
-->
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
@@ -27,8 +26,8 @@
|
||||
</padding>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints percentWidth="38.2"/>
|
||||
<ColumnConstraints percentWidth="61.8"/>
|
||||
<ColumnConstraints percentWidth="45.00"/>
|
||||
<ColumnConstraints percentWidth="55.00"/>
|
||||
</columnConstraints>
|
||||
|
||||
<children>
|
||||
@@ -45,21 +44,15 @@
|
||||
<ChoiceBox GridPane.rowIndex="2" GridPane.columnIndex="1" fx:id="volume" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3 Alt 1-->
|
||||
<GridPane fx:id="webdavVolume" vgap="12.0" hgap="12.0" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" visible="true" cacheShape="true" cache="true">
|
||||
<Label fx:id="portFieldLabel" GridPane.rowIndex="3" GridPane.columnIndex="0" text="%settings.webdav.port.label" cacheShape="true" cache="true" />
|
||||
<HBox GridPane.rowIndex="3" GridPane.columnIndex="1" spacing="6.0">
|
||||
<TextField fx:id="portField" cacheShape="true" cache="true" promptText="%settings.webdav.port.prompt" />
|
||||
<Button text="%settings.webdav.port.apply" fx:id="changePortButton" onAction="#changePort"/>
|
||||
</HBox>
|
||||
<Label fx:id="portFieldLabel" GridPane.rowIndex="3" GridPane.columnIndex="0" text="%settings.webdav.port.label" cacheShape="true" cache="true" />
|
||||
<HBox GridPane.rowIndex="3" GridPane.columnIndex="1" spacing="6.0">
|
||||
<TextField fx:id="portField" cacheShape="true" cache="true" promptText="%settings.webdav.port.prompt" />
|
||||
<Button text="%settings.webdav.port.apply" fx:id="changePortButton" onAction="#changePort"/>
|
||||
</HBox>
|
||||
|
||||
<!-- Row 4 -->
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.webdav.prefGvfsScheme.label" cacheShape="true" cache="true" />
|
||||
<ChoiceBox GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
</GridPane>
|
||||
|
||||
<!-- Row 3 Alt 2-->
|
||||
<GridPane fx:id="fuseVolume" vgap="12.0" hgap="12.0" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" visible="false" cacheShape="true" cache="true">
|
||||
</GridPane>
|
||||
<!-- Row 4 -->
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.webdav.prefGvfsScheme.label" cacheShape="true" cache="true" />
|
||||
<ChoiceBox GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
</children>
|
||||
</GridPane>
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
Contributors:
|
||||
Sebastian Stenzel - initial API and implementation
|
||||
-->
|
||||
<?import java.net.URL?>
|
||||
<?import java.lang.String?>
|
||||
<?import org.cryptomator.ui.controls.SecPasswordField?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ProgressIndicator?>
|
||||
@@ -24,12 +22,13 @@
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.control.ChoiceBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<GridPane fx:controller="org.cryptomator.ui.controllers.UnlockController" fx:id="root" vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
|
||||
<padding>
|
||||
<Insets top="24.0" right="12.0" bottom="24.0" left="12.0" />
|
||||
</padding>
|
||||
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints percentWidth="38.2"/>
|
||||
<ColumnConstraints percentWidth="61.8"/>
|
||||
@@ -45,7 +44,7 @@
|
||||
<Button fx:id="advancedOptionsButton" text="%unlock.button.advancedOptions.show" prefWidth="150.0" onAction="#didClickAdvancedOptionsButton" cacheShape="true" cache="true" />
|
||||
<Button fx:id="unlockButton" text="%unlock.button.unlock" defaultButton="true" prefWidth="150.0" onAction="#didClickUnlockButton" disable="true" cacheShape="true" cache="true" />
|
||||
</HBox>
|
||||
|
||||
|
||||
<!-- Row 3 -->
|
||||
<Label fx:id="successMessage" cacheShape="true" cache="true" visible="true" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2"/>
|
||||
|
||||
@@ -54,12 +53,12 @@
|
||||
<padding>
|
||||
<Insets top="24.0" />
|
||||
</padding>
|
||||
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints percentWidth="38.2"/>
|
||||
<ColumnConstraints percentWidth="61.8"/>
|
||||
</columnConstraints>
|
||||
|
||||
|
||||
<!-- Row 3.0 -->
|
||||
<Separator GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true"/>
|
||||
<HBox alignment="CENTER" prefWidth="400.0" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
|
||||
@@ -69,53 +68,47 @@
|
||||
</padding>
|
||||
</Label>
|
||||
</HBox>
|
||||
|
||||
|
||||
<!-- Row 3.1 -->
|
||||
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="savePassword" text="%unlock.label.savePassword" onAction="#didClickSavePasswordCheckbox" cacheShape="true" cache="true" />
|
||||
|
||||
|
||||
<!-- Row 3.2 -->
|
||||
<CheckBox GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="unlockAfterStartup" text="%unlock.label.unlockAfterStartup" cacheShape="true" cache="true" />
|
||||
|
||||
|
||||
<!-- Row 3.3 -->
|
||||
<CheckBox GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="mountAfterUnlock" text="%unlock.label.mountAfterUnlock" cacheShape="true" cache="true" />
|
||||
|
||||
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />
|
||||
<TextField GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="mountName" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.4 -->
|
||||
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />
|
||||
<TextField GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="mountName" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="revealAfterMount" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.5 -->
|
||||
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="revealAfterMount" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />
|
||||
|
||||
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="useCustomMountPath" text="%unlock.label.useOwnMountPath" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.6 Alt1 -->
|
||||
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="winDriveLetterLabel" text="%unlock.label.winDriveLetter" cacheShape="true" cache="true" />
|
||||
<ChoiceBox GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="winDriveLetter" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 3.6 Alt2 -->
|
||||
<CheckBox GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="useOwnMountPath" text="%unlock.label.useOwnMountPath" cacheShape="true" cache="true" />
|
||||
|
||||
<Label GridPane.rowIndex="7" GridPane.columnIndex="0" fx:id="mountPathLabel" text="%unlock.label.mountPath" cacheShape="true" cache="true" />
|
||||
|
||||
<HBox GridPane.rowIndex="7" GridPane.columnIndex="1" fx:id="mountPathBox" spacing="6.0">
|
||||
<TextField GridPane.rowIndex="7" GridPane.columnIndex="1" fx:id="mountPath" cacheShape="true" cache="true" />
|
||||
<Button text="%unlock.label.mountPathButton" fx:id="changeMountPathButton" onAction="#didClickchangeMountPathButton"/>
|
||||
</HBox>
|
||||
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="customMountPathLabel" text="%unlock.label.mountPath" cacheShape="true" cache="true" />
|
||||
<TextField GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="customMountPathField" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
|
||||
|
||||
</GridPane>
|
||||
|
||||
|
||||
<!-- Row 4 -->
|
||||
<TextFlow GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
|
||||
<GridPane.margin>
|
||||
<Insets top="24.0"/>
|
||||
</GridPane.margin>
|
||||
<children>
|
||||
<Text fx:id="messageText" cache="true" />
|
||||
<Hyperlink fx:id="downloadsPageLink" text="%unlock.label.downloadsPageLink" visible="false" onAction="#didClickDownloadsLink" cacheShape="true" cache="true" />
|
||||
</children>
|
||||
</TextFlow>
|
||||
|
||||
<!-- Row 5-->
|
||||
<ProgressIndicator progress="-1" fx:id="progressIndicator" GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" cacheShape="true" cache="true" cacheHint="SPEED" />
|
||||
|
||||
<!-- Row 5 -->
|
||||
<VBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" spacing="12.0" alignment="CENTER" cacheShape="true" cache="true">
|
||||
<ProgressIndicator progress="-1" fx:id="progressIndicator" cacheShape="true" cache="true" cacheHint="SPEED" />
|
||||
<Text fx:id="messageText" cache="true" />
|
||||
</VBox>
|
||||
</children>
|
||||
</GridPane>
|
||||
|
||||
|
||||
|
||||
@@ -28,18 +28,9 @@
|
||||
<fx:define>
|
||||
<ContextMenu fx:id="moreOptionsMenu">
|
||||
<items>
|
||||
<MenuItem fx:id="mountVaultMenuItem" text="%unlocked.moreOptions.mount" onAction="#didClickMountVault">
|
||||
<graphic><Label text="" styleClass="ionicons"/></graphic>
|
||||
</MenuItem>
|
||||
<MenuItem fx:id="unmountVaultMenuItem" text="%unlocked.moreOptions.unmount" onAction="#didClickUnmountVault">
|
||||
<graphic><Label text="" styleClass="ionicons"/></graphic>
|
||||
</MenuItem>
|
||||
<MenuItem fx:id="revealVaultMenuItem" text="%unlocked.moreOptions.reveal" onAction="#didClickRevealVault">
|
||||
<graphic><Label text="" styleClass="ionicons"/></graphic>
|
||||
</MenuItem>
|
||||
<MenuItem text="%unlocked.moreOptions.copyUrl" onAction="#didClickCopyUrl">
|
||||
<graphic><Label text="" styleClass="ionicons"/></graphic>
|
||||
</MenuItem>
|
||||
</items>
|
||||
</ContextMenu>
|
||||
</fx:define>
|
||||
|
||||
@@ -7,31 +7,28 @@
|
||||
Contributors:
|
||||
Sebastian Stenzel - initial API and implementation
|
||||
-->
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.image.Image?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Hyperlink?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.control.ProgressIndicator?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
|
||||
<VBox fx:controller="org.cryptomator.ui.controllers.WelcomeController" fx:id="root" prefWidth="400.0" prefHeight="400.0" spacing="24.0" alignment="CENTER" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
|
||||
|
||||
|
||||
<VBox fx:id="checkForUpdatesContainer" spacing="6.0" alignment="CENTER" cacheShape="true" cache="true" prefHeight="64.0">
|
||||
<HBox alignment="CENTER" spacing="5.0" cacheShape="true" cache="true">
|
||||
<Label fx:id="checkForUpdatesStatus" cacheShape="true" cache="true" />
|
||||
<ProgressIndicator fx:id="checkForUpdatesIndicator" progress="-1" prefWidth="15.0" prefHeight="15.0" cacheShape="true" cache="true" cacheHint="SPEED" />
|
||||
<ProgressIndicator fx:id="checkForUpdatesIndicator" progress="-1" prefWidth="15.0" prefHeight="15.0" visible="false" cacheShape="true" cache="true" cacheHint="SPEED" />
|
||||
</HBox>
|
||||
<Hyperlink wrapText="true" textAlignment="CENTER" fx:id="updateLink" onAction="#didClickUpdateLink" cacheShape="true" cache="true" disable="true" />
|
||||
</VBox>
|
||||
|
||||
|
||||
<ImageView fitHeight="200.0" preserveRatio="true" smooth="true" cache="true" style="-fx-background-color: green;">
|
||||
<Image url="/bot_welcome.png"/>
|
||||
</ImageView>
|
||||
|
||||
|
||||
<VBox prefHeight="64.0"/>
|
||||
|
||||
</VBox>
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = فشل فك التشفير
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = اغلاق المحفظة
|
||||
unlocked.moreOptions.reveal = Reveal Drive
|
||||
unlocked.moreOptions.copyUrl = نسخ رابط ويب داف ( WebDAV )
|
||||
unlocked.label.revealFailed = Command failed
|
||||
unlocked.label.unmountFailed = Ejecting drive failed
|
||||
unlocked.label.statsEncrypted = مشفر
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPath = Mount path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Неуспешно декрипт
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Заключване на Сейфа
|
||||
unlocked.moreOptions.reveal = Покажи диска
|
||||
unlocked.moreOptions.copyUrl = Копиране адреса на WebDAV
|
||||
unlocked.label.revealFailed = Командата е неуспешна
|
||||
unlocked.label.unmountFailed = Изваждането на диска е неуспешно
|
||||
unlocked.label.statsEncrypted = криптирано
|
||||
@@ -57,7 +56,7 @@ settings.checkForUpdates.label = Проверка за обновления
|
||||
settings.requiresRestartLabel = * Криптоматор трябва да се рестартира
|
||||
# tray icon
|
||||
tray.menu.open = Отворяне
|
||||
tray.menu.quit = Излизане
|
||||
tray.menu.quit = Изход
|
||||
tray.infoMsg.title = Все още върви
|
||||
tray.infoMsg.msg = Криптоматор все още върви. Излезте от иконата в трея.
|
||||
tray.infoMsg.msg.osx = Криптоматор все още върви. Излезте от иконата в менюто.
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = Обновяване на сейф от 3-та до
|
||||
upgrade.version4to5.title = Обновяване на сейф от 4-та до 5-та версия
|
||||
upgrade.version4to5.msg = Този сейф трябва да бъде променен към по-нов формат.\nКриптираните файлове ще бъдат обновени.\nМоля, проверете дали сихронизацията е приключила преди да продължите.\n\nЗабележка\: Датата на промяна на всички файлове ще бъде обновена до момента.
|
||||
upgrade.version4to5.err.io = Преместването провалено поради грешка в диска. Вижте лог файла за детайли.
|
||||
unlock.label.mountAfterUnlock = Закачане на диска
|
||||
unlock.label.revealAfterMount = Показване на диска
|
||||
unlocked.lock.force.confirmation.title = Заключването на %1$s провалено
|
||||
unlocked.lock.force.confirmation.header = Желаете ли принудително заключване?
|
||||
unlocked.lock.force.confirmation.content = Това е може би защото други програми все още използват файловете в сейфа или защото има някакъв друг проблем.\n\nПрограмите, имащи достъп до файловете, може да не работят правилно и информацията, незаписана от тези програми, може да бъде изгубена.
|
||||
unlock.label.unlockAfterStartup = Автоматично отключване при стартиране (Експериментално)
|
||||
unlock.errorMessage.unlockFailed = Грешка при отключване. Вижте лог файла за детайли.
|
||||
unlocked.moreOptions.mount = Закачане на диск
|
||||
unlocked.moreOptions.unmount = Изваждане на диск
|
||||
upgrade.version5toX.title = Обновяване на версията на сейфа
|
||||
upgrade.version5toX.msg = Този сейф трябва да бъде обновен до по-нов формат.\nМоля, уверете се, че сихронизацията е приключила, преди да продължите.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
main.createVault.nonEmptyDir.title = Неуспешно създаване на сейф
|
||||
main.createVault.nonEmptyDir.header = Избраната директория не е празна
|
||||
main.createVault.nonEmptyDir.content = Избраната директория съдържа файлове /може би скрити/. Сейфът може да бъде създаден само в празна директория
|
||||
unlock.label.mountPath = Път за монтиране
|
||||
unlock.label.mountPathButton = Приложи
|
||||
settings.webdav.port.label = WebCAM порт
|
||||
settings.webdav.port.prompt = 0 \= Автоматично избиране
|
||||
settings.webdav.port.apply = Приложи
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV схема
|
||||
settings.volume.label = Метод за точка
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
settings.volume.fuse = Предпазител
|
||||
unlock.successLabel.vaultCreated = Сейфът беше създаден успешно
|
||||
unlock.successLabel.passwordChanged = Паролата беше сменена успешно
|
||||
unlock.successLabel.upgraded = Криптоматор беше обновен
|
||||
unlock.label.useOwnMountPath = Използвайте собствена точка за монтиране
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -1,6 +1,6 @@
|
||||
app.name = Cryptomator
|
||||
# main.fxml
|
||||
main.emptyListInstructions = Trezor přidáte kliknutím sem
|
||||
main.emptyListInstructions = Trezor přidáte kliknutím zde\n
|
||||
main.directoryList.contextMenu.remove = Odstranit ze seznamu
|
||||
main.directoryList.contextMenu.changePassword = Změnit heslo
|
||||
main.addDirectory.contextMenu.new = Vytvořit nový trezor
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Nepodařilo se rozšifrovat
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Uzamknout trezor
|
||||
unlocked.moreOptions.reveal = Odkrýt jednotku
|
||||
unlocked.moreOptions.copyUrl = Zkopírovat WebDAV odkaz
|
||||
unlocked.label.revealFailed = Vykonání příkazu se nezdařilo
|
||||
unlocked.label.unmountFailed = Odpojení jednotky se nezdařilo
|
||||
unlocked.label.statsEncrypted = zašifrováno
|
||||
@@ -88,29 +87,38 @@ upgrade.version3to4.title = Aktualizace trezoru z verze 3 na 4
|
||||
upgrade.version4to5.title = Aktualizace trezoru z verze 4 na 5
|
||||
upgrade.version4to5.msg = Tento trezor je třeba aktualizovat na novější formát.\nZašifrované soubory budou aktualizovány.\nNež budete pokračovat ověřte, že synchronizace byla dokončena.\n\nPozn.\: Datum úpravy bude v rámci toho u všech dotčených souborů změněn na aktuální datum a čas.
|
||||
upgrade.version4to5.err.io = Převod se nezdařil kvůli chybě na vstupu nebo výstupu. Podrobnosti naleznete v souboru se záznamem událostí (log).
|
||||
unlock.label.mountAfterUnlock = Připojit (mount) jednotku
|
||||
unlock.label.revealAfterMount = Odkrýt jednotku
|
||||
unlocked.lock.force.confirmation.title = Zamykání %1$s se nezdařilo
|
||||
unlocked.lock.force.confirmation.header = Chcete vynutit uzamčení?
|
||||
unlocked.lock.force.confirmation.content = Toto může být způsobeno tím, že ostatní aplikace stále ještě přistupují k souborům v trezoru nebo došlo k nějakému jinému problému.\n\nMůže se ovšem stát, že aplikace které stáje ještě pracují se soubory z trezoru to nemusí ustát a může dojít ke ztrátě ještě neuložených dat.
|
||||
unlock.label.unlockAfterStartup = Automatické odemknutí při spuštění (experimentální)
|
||||
unlock.errorMessage.unlockFailed = Odemknutí se nezdařilo. Podrobnosti naleznete v souboru se záznamem událostí (log).
|
||||
unlocked.moreOptions.mount = Připojit jednotku
|
||||
unlocked.moreOptions.unmount = Odpojit jednotku
|
||||
upgrade.version5toX.title = Aktualizace verze trezoru
|
||||
upgrade.version5toX.msg = Tento trezor je třeba aktualizovat na novější formát.\nNež budete pokračovat ověřte, že byla dokončena synchronizace.
|
||||
main.createVault.nonEmptyDir.title = Vytvoření trezoru se nezdařilo
|
||||
main.createVault.nonEmptyDir.header = Zvolená složka není prázdná
|
||||
main.createVault.nonEmptyDir.content = Zvolená složka už obsahuje soubory (možná skryté). Trezor je možné vytvořit pouze v prázdné složce.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
unlock.label.mountPath = Popis umístění přípojného bodu
|
||||
unlock.label.mountPathButton = Použít
|
||||
settings.webdav.port.label = Port WebDAV
|
||||
settings.webdav.port.prompt = 0 \= zvolit automaticky
|
||||
settings.webdav.port.apply = Použít
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV schéma
|
||||
settings.volume.label = Způsob připojení (mount)
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Trezor byl úspěšně vytvořen.
|
||||
unlock.successLabel.passwordChanged = Heslo bylo úspěšně změněno.
|
||||
unlock.successLabel.upgraded = Cryptomator byl úspěšně povýšen na novou verzi.
|
||||
unlock.label.useOwnMountPath = Použít vlastní přípojný bod
|
||||
welcome.askForUpdateCheck.dialog.title = Zjišťování aktualizací
|
||||
welcome.askForUpdateCheck.dialog.header = Zjišťovat automaticky nové verze?
|
||||
welcome.askForUpdateCheck.dialog.content = Ke zjištění aktualizací, Cryptomator stáhne aktuální verzi z instalačních serverů a zobrazí nápovědu, když je k dispozici novější verze, než je nainstalovaná.\n\nDoporučujeme zapnout zjišťování aktualizací a zajistit tak, že vždy budete mít nejnovější verzi Cryptomator, se všemi opravami zabezpečení nainstalovanými. Pokud automatické zjišťování nezapnete, je možné ručně stahovat nejnovější verzi z https\://cryptomator.org/downloads/.\n\nToto nastavení je možné kdykoli změnit v nastavení aplikace.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Individuální přípojný bod není nastaven
|
||||
main.gracefulShutdown.dialog.title = Zamčení trezorů se nezdařilo
|
||||
main.gracefulShutdown.dialog.header = Trezory v používání
|
||||
main.gracefulShutdown.dialog.content = Jeden nebo více trezorů je stále v používání ostatními programy. Ukončete je aby se Cryptomator mohl správně vypnout a zkuste to znovu.\n\nPokud to nezabere, Cryptomator je možné vypnout vynuceně, ale to může vést ke ztrátě dat a není proto doporučeno.
|
||||
main.gracefulShutdown.button.tryAgain = Zkusit znovu
|
||||
main.gracefulShutdown.button.forceShutdown = Vynutit vypnutí
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Dekryptering fejlede
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Lås Vault
|
||||
unlocked.moreOptions.reveal = Vis drev
|
||||
unlocked.moreOptions.copyUrl = Kopier WebDAV URL
|
||||
unlocked.label.revealFailed = Kommando fejlede
|
||||
unlocked.label.unmountFailed = Afmontering af drev fejlede
|
||||
unlocked.label.statsEncrypted = Krypteret
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = Vault Version 3 til 4 Opgradering
|
||||
upgrade.version4to5.title = Vault Version 4 til 5 Opgradering
|
||||
upgrade.version4to5.msg = Denne Vault skal migreres til et nyere format.\nDe krypterede filer vil blive opdateret.\nVent venligst til al synkronisering er gennemført, inden du fortsætter.\n\nNote\: Denne proces vil påvirke ændringsdato og -tidspunkt for samtlige filer.
|
||||
upgrade.version4to5.err.io = Migrering fejlede pga. en I/O fejl. Se logfilen for yderligere detaljer.
|
||||
unlock.label.mountAfterUnlock = Monter drev
|
||||
unlock.label.revealAfterMount = Vis drev
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPath = Mount path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -7,7 +7,7 @@ main.addDirectory.contextMenu.new = Tresor erstellen
|
||||
main.addDirectory.contextMenu.open = Tresor öffnen
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking = Prüfe auf Updates...
|
||||
welcome.newVersionMessage = Version %1$s kann heruntergeladen werden.\nMomentane Version %2$s.
|
||||
welcome.newVersionMessage = Version %1$s kann heruntergeladen werden.\nInstallierte Version %2$s.
|
||||
# initialize.fxml
|
||||
initialize.label.password = Passwort
|
||||
initialize.label.retypePassword = Passwort bestätigen
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Entschlüsselung fehlgeschlagen
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Tresor sperren
|
||||
unlocked.moreOptions.reveal = Laufwerk anzeigen
|
||||
unlocked.moreOptions.copyUrl = WebDAV-URL kopieren
|
||||
unlocked.label.revealFailed = Befehl fehlgeschlagen
|
||||
unlocked.label.unmountFailed = Trennen des Laufwerks fehlgeschlagen
|
||||
unlocked.label.statsEncrypted = verschlüsselt
|
||||
@@ -86,15 +85,12 @@ upgrade.version3to4.title = Upgrade Tresor-Version 3 zu 4
|
||||
upgrade.version4to5.title = Upgrade Tresor-Version 4 zu 5
|
||||
upgrade.version4to5.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nVerschlüsselte Dateien werden dabei aktualisiert.\nStellen Sie sicher, dass keine Synchronisation stattfindet, bevor Sie fortfahren.\n\nHinweis\: Beim Upgrade wird das Änderungsdatum aller Dateien auf das aktuelle Datum geändert.
|
||||
upgrade.version4to5.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.
|
||||
unlock.label.mountAfterUnlock = Laufwerk verbinden
|
||||
unlock.label.revealAfterMount = Laufwerk anzeigen
|
||||
unlocked.lock.force.confirmation.title = Sperren von %1$s fehlgeschlagen
|
||||
unlocked.lock.force.confirmation.header = Möchten Sie das Sperren erzwingen?
|
||||
unlocked.lock.force.confirmation.content = Dies kann passieren, wenn andere Programme weiterhin auf Dateien im Tresor zugreifen. Oder es ist ein anderes Problem aufgetreten.\n\nProgramme, die weiterhin auf die Dateien zugreifen, könnten nicht mehr richtig funktionieren, oder Daten, die durch diese Programme noch nicht geschrieben wurden, könnten verloren gehen.
|
||||
unlock.label.unlockAfterStartup = Automatisch entsperren beim Start (Experimentell)
|
||||
unlock.errorMessage.unlockFailed = Entsperren fehlgeschlagen. Siehe Log-Datei für Details.
|
||||
unlocked.moreOptions.mount = Laufwerk verbinden
|
||||
unlocked.moreOptions.unmount = Laufwerk auswerfen
|
||||
upgrade.version5toX.title = Upgrade Tresor-Version 5 zu X
|
||||
upgrade.version5toX.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nStellen Sie sicher, dass keine Synchronisation stattfindet, bevor Sie fortfahren.
|
||||
main.createVault.nonEmptyDir.title = Erstellung des Tresors fehlgeschlagen
|
||||
@@ -102,13 +98,25 @@ main.createVault.nonEmptyDir.header = Ausgewählter Ordner ist nicht leer
|
||||
main.createVault.nonEmptyDir.content = Der ausgewählte Ordner enthält bereits Dateien (möglicherweise unsichtbar). Ein Tresor kann nur innerhalb eines leeren Ordners erstellt werden.
|
||||
unlock.label.mountPath = Verzeichnis
|
||||
unlock.label.mountPathButton = Anwenden
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.label = WebDAV-Port
|
||||
settings.webdav.port.prompt = 0 \= automatische Auswahl
|
||||
settings.webdav.port.apply = Anwenden
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV URL Schema
|
||||
settings.volume.label = Laufwerkseinbindung
|
||||
settings.volume.label = Laufwerkseinbindung *
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Der Tresor wurde erfolgreich erstellt.
|
||||
unlock.successLabel.passwordChanged = Das Passwort wurde erfolgreich geändert.
|
||||
unlock.successLabel.upgraded = Das Cryptomator Upgrade wurde erfolgreich abgeschlossen.
|
||||
unlock.label.useOwnMountPath = Eigenes Laufwerksverzeichnis nutzen
|
||||
welcome.askForUpdateCheck.dialog.title = Auf Updates prüfen
|
||||
welcome.askForUpdateCheck.dialog.header = Eingebaute Update-Prüfung aktivieren?
|
||||
welcome.askForUpdateCheck.dialog.content = Empfehlung\: Aktivieren Sie die Update-Prüfung, um sicherzustellen, dass Sie stets die neueste Cryptomator-Version mit allen Sicherheits-Patches verwenden.\n\nDiese Einstellung können Sie jederzeit im Einstellungs-Menü ändern.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Individueller Mount-Punkt ist nicht gesetzt.
|
||||
main.gracefulShutdown.dialog.title = Sperren des Tresors gescheitert
|
||||
main.gracefulShutdown.dialog.header = Tresor in Gebrauch
|
||||
main.gracefulShutdown.dialog.content = Ein oder mehrere Tresore werden noch von anderen Programmen genutzt. Bitte schliessen Sie die Programme um es Cryptomator zu ermöglichen richtig herunter zu fahren. Versuchen Sie es danach erneut.\n\nFalls dies nicht klappt, kann Cryptomator das Beenden erzwingen. Dies kann zu einem Datenverlust führen und ist nicht empfohlen.
|
||||
main.gracefulShutdown.button.tryAgain = Versuchen Sie es erneut
|
||||
main.gracefulShutdown.button.forceShutdown = Herunterfahren erzwingen
|
||||
unlock.pendingMessage.unlocking = Entsperre Tresor...
|
||||
@@ -19,10 +19,18 @@ main.directoryList.remove.confirmation.content=The vault will only be removed fr
|
||||
main.createVault.nonEmptyDir.title=Creating vault failed
|
||||
main.createVault.nonEmptyDir.header=Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content=The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
main.gracefulShutdown.dialog.title=Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header=Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content=One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain=Try again
|
||||
main.gracefulShutdown.button.forceShutdown=Force shutdown
|
||||
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking=Checking for Updates...
|
||||
welcome.newVersionMessage=Version %1$s can be downloaded.\nThis is %2$s.
|
||||
welcome.askForUpdateCheck.dialog.title=Update check
|
||||
welcome.askForUpdateCheck.dialog.header=Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content=Recommended: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
|
||||
# initialize.fxml
|
||||
initialize.label.password=Password
|
||||
@@ -62,13 +70,12 @@ upgrade.version5toX.msg=This vault needs to be migrated to a newer format.\nPlea
|
||||
# unlock.fxml
|
||||
unlock.label.password=Password
|
||||
unlock.label.savePassword=Save Password
|
||||
unlock.label.mountAfterUnlock=Mount Drive
|
||||
unlock.label.mountName=Drive Name
|
||||
unlock.label.unlockAfterStartup=Auto-Unlock on Start (Experimental)
|
||||
unlock.label.revealAfterMount=Reveal Drive
|
||||
unlock.label.winDriveLetter=Drive Letter
|
||||
unlock.label.useOwnMountPath=Use own Mount point
|
||||
unlock.label.mountPath=Mount Path
|
||||
unlock.label.useOwnMountPath=Use Custom Mount Point
|
||||
unlock.label.mountPath=Mount path
|
||||
unlock.label.mountPathButton=Apply
|
||||
unlock.label.downloadsPageLink=All Cryptomator versions
|
||||
unlock.label.advancedHeading=Advanced Options
|
||||
@@ -79,7 +86,10 @@ unlock.savePassword.delete.confirmation.title=Delete Saved Password
|
||||
unlock.savePassword.delete.confirmation.header=Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content=The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save Password" option enabled.
|
||||
unlock.choicebox.winDriveLetter.auto=Assign automatically
|
||||
unlock.pendingMessage.unlocking=Unlocking vault...
|
||||
unlock.errorMessage.wrongPassword=Wrong password
|
||||
unlock.errorMessage.wrongPassword=Wrong Password
|
||||
unlock.errorMessage.invalidMountPath=Use of custom mount path selected, but no path given.
|
||||
unlock.errorMessage.unlockFailed=Unlock failed. See log file for details.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Unsupported vault. This vault has been created with an older version of Cryptomator.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Unsupported vault. This vault has been created with a newer version of Cryptomator.
|
||||
@@ -100,10 +110,7 @@ changePassword.errorMessage.decryptionFailed=Decryption failed
|
||||
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock=Lock Vault
|
||||
unlocked.moreOptions.mount=Mount Drive
|
||||
unlocked.moreOptions.unmount=Eject Drive
|
||||
unlocked.moreOptions.reveal=Reveal Drive
|
||||
unlocked.moreOptions.copyUrl=Copy Filesystem URL
|
||||
unlocked.label.mountFailed=Connecting drive failed
|
||||
unlocked.label.revealFailed=Command failed
|
||||
unlocked.label.unmountFailed=Ejecting drive failed
|
||||
@@ -123,9 +130,10 @@ settings.webdav.port.apply=Apply
|
||||
settings.webdav.prefGvfsScheme.label=WebDAV Scheme
|
||||
settings.debugMode.label=Debug Mode *
|
||||
settings.requiresRestartLabel=* Cryptomator needs to restart
|
||||
settings.volume.label= Mount-Methode *
|
||||
settings.volume.label=Preferred Volume Type
|
||||
settings.volume.webdav=WebDAV
|
||||
settings.volume.fuse=FUSE
|
||||
settings.volume.dokany=Dokany
|
||||
|
||||
# tray icon
|
||||
tray.menu.open=Open
|
||||
|
||||
@@ -47,11 +47,10 @@ changePassword.errorMessage.decryptionFailed = Error en el descifrado
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Bloquear caja fuerte
|
||||
unlocked.moreOptions.reveal = Revelar unidad
|
||||
unlocked.moreOptions.copyUrl = Copiar URL de WebDAV
|
||||
unlocked.label.revealFailed = La orden ha fallado
|
||||
unlocked.label.unmountFailed = Error al expulsar la unidad
|
||||
unlocked.label.statsEncrypted = cifrado
|
||||
unlocked.label.statsDecrypted = descifrado
|
||||
unlocked.label.statsEncrypted = encriptado
|
||||
unlocked.label.statsDecrypted = desencriptado
|
||||
unlocked.ioGraph.yAxis.label = Rendimiento (MiB/s)
|
||||
# settings.fxml
|
||||
settings.version.label = Versión %s
|
||||
@@ -86,31 +85,40 @@ settings.debugMode.label = Modo depuración *
|
||||
upgrade.version3dropBundleExtension.title = Actualizar caja fuerte a la versión 3 (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Actualizar caja fuerte de versión 3 a 4
|
||||
upgrade.version4to5.title = Actualizar caja fuerte de versión 4 a 5
|
||||
upgrade.version4to5.msg = Esta caja fuerte tiene que ser migrada a un formato más moderno.\nLos archivos cifrados se actualizarán.\nAsegúrese de que la sincronización ha terminado antes de iniciar el proceso.\n\nNota\: las fechas de modificación de todos los archivos, se cambiarán a la fecha actual.
|
||||
upgrade.version4to5.msg = Esta caja fuerte tiene que ser migrada a un formato más moderno.\nLos archivos encriptados se actualizarán.\nAsegúrese de que la sincronización ha terminado antes de iniciar el proceso.\n\nNota\: las fechas de modificación de todos los archivos, se cambiarán a la fecha actual.
|
||||
upgrade.version4to5.err.io = Error en la migración debido a una excepción E/S. Consulte el archivo de registro para más información.
|
||||
unlock.label.mountAfterUnlock = Montar unidad
|
||||
unlock.label.revealAfterMount = Revelar unidad
|
||||
unlocked.lock.force.confirmation.title = Error al bloquear %1$s
|
||||
unlocked.lock.force.confirmation.header = ¿Quiere forzar el bloqueo?
|
||||
unlocked.lock.force.confirmation.content = Esto puede ser debido a que otros programas estén todavía accediendo a la caja fuerte o porque se ha producido algún otro problema.\n\nLos programas que estén todavía accediendo a los archivos pueden no funcionar correctamente y se pueden perder los datos pendientes de escribir por estos programas.
|
||||
unlock.label.unlockAfterStartup = Autodesbloqueo al arrancar (experimental)
|
||||
unlock.errorMessage.unlockFailed = Error al desbloquear. Consulte el archivo de registro para más información.
|
||||
unlocked.moreOptions.mount = Montar unidad
|
||||
unlocked.moreOptions.unmount = Expulsar unidad
|
||||
upgrade.version5toX.title = Actualizar la versión de la caja fuerte
|
||||
upgrade.version5toX.msg = Esta caja fuerte debe ser migrada a un formato más moderno.\nAsegúrese de que la sincronización ha terminado antes de iniciar el proceso.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
main.createVault.nonEmptyDir.title = Error en la creación de la bóveda
|
||||
main.createVault.nonEmptyDir.header = El directorio elegido no está vacío
|
||||
main.createVault.nonEmptyDir.content = El directorio seleccionado ya contiene archivos (posiblemente ocultos). Una bóveda sólo puede crearse en un directorio vacío.
|
||||
unlock.label.mountPath = Punto de montaje
|
||||
unlock.label.mountPathButton = Aplicar
|
||||
settings.webdav.port.label = Puerto WebDAV
|
||||
settings.webdav.port.prompt = 0 \= Elige automáticamente
|
||||
settings.webdav.port.apply = Aplicar
|
||||
settings.webdav.prefGvfsScheme.label = Esquema de WebDAV
|
||||
settings.volume.label = Método de montaje *
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = La caja fuerte fue creada exitosamente.
|
||||
unlock.successLabel.passwordChanged = La contraseña ha sido cambiada con éxito.
|
||||
unlock.successLabel.upgraded = Cryptomator fue actualizado exitosamente.
|
||||
unlock.label.useOwnMountPath = Usar Punto de montaje propio
|
||||
welcome.askForUpdateCheck.dialog.title = Buscar actualización
|
||||
welcome.askForUpdateCheck.dialog.header = ¿Habilitar la búsqueda de actualizaciones automática?
|
||||
welcome.askForUpdateCheck.dialog.content = Para buscar actualizaciones, Cryptomator buscará la versión actual en los servidores de Cryptomator y le mostrará una sugerencia si hay una versión más nueva disponible.\n\nRecomendamos habilitar la comprobación de actualización para asegurarse siempre de que tiene instalada la versión más reciente de Cryptomator, con todos los parches de seguridad. Si no habilita la verificación de actualización, puede verificar y descargar la versión actual desde https\://cryptomator.org/downloads/.\n\nPuede cambiar esto en cualquier momento desde dentro de la configuración.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = La ruta individual de montaje no ha sido asignada.
|
||||
main.gracefulShutdown.dialog.title = No fue posible cerrar la(s) caja(s) fuerte(s)
|
||||
main.gracefulShutdown.dialog.header = Caja(s) Fuertes(s) en uso
|
||||
main.gracefulShutdown.dialog.content = Una o más cajas fuertes están siendo utilizadas por otros programas. Por favor ciérrelos para permitir a Cryptomator cerrarse adecuadamente, e intente de nuevo.\n\nSi esto no funciona, Cryptomator puede cerrarse forzosamente, pero esta vía puede provocar pérdida de información y no es recomendada.
|
||||
main.gracefulShutdown.button.tryAgain = Intente de nuevo
|
||||
main.gracefulShutdown.button.forceShutdown = Forzar apagado
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -46,7 +46,6 @@ changePassword.errorMessage.decryptionFailed = Echec du déchiffrement
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Verrouiller le coffre-fort
|
||||
unlocked.moreOptions.reveal = Voir le lecteur
|
||||
unlocked.moreOptions.copyUrl = Copier l'URL WebDAV
|
||||
unlocked.label.revealFailed = Echec de la commande
|
||||
unlocked.label.unmountFailed = Echec de l'éjection du lecteur
|
||||
# Crypter n'existe pas en français.
|
||||
@@ -89,29 +88,38 @@ upgrade.version3to4.title = Mise à jour de la version du coffre-fort (v3 à v4)
|
||||
upgrade.version4to5.title = Mise à jour de la version du coffre-fort (v4 à v5)
|
||||
upgrade.version4to5.msg = Ce coffre-fort doit être migré vers un format plus récent.\nLes fichiers chiffrés seront mis à jour.\nVeuillez vérifier que la synchronisation est terminée avant de commencer.\n\nNote \: la date de modification des fichiers sera mise à jour avec la date courante.
|
||||
upgrade.version4to5.err.io = La migration a échoué à cause d'une erreur d'entrée/sortie. Vérifiez le fichier de log pour plus de détails.
|
||||
unlock.label.mountAfterUnlock = Monter le lecteur
|
||||
unlock.label.revealAfterMount = Voir le lecteur
|
||||
unlocked.lock.force.confirmation.title = Le verrouillage de %1$s a échoué
|
||||
unlocked.lock.force.confirmation.header = Voulez-vous forcer le verrouillage ?
|
||||
unlocked.lock.force.confirmation.content = D'autres programmes sont peut être en train d'accéder à des fichiers dans le coffre-fort ou un autre problème s'est produit.\n\nLes programmes accédant encore aux fichiers pourraient ne pas fonctionner normalement et les données pas encore sauvegardées par ces programmes pourraient être perdues.
|
||||
unlock.label.unlockAfterStartup = Déverouiller automatiquement au démarrage (experimental)
|
||||
unlock.errorMessage.unlockFailed = Le déverouillage a échoué. Référez-vous au fichier log pour plus de détails.
|
||||
unlocked.moreOptions.mount = Monter le disque
|
||||
unlocked.moreOptions.unmount = Ejecter le disque
|
||||
upgrade.version5toX.title = Mise à jour du coffre-fort
|
||||
upgrade.version5toX.msg = Ce coffre-fort doit être converti dans un format plus récent. \nVeuillez-vous assurez que la synchronisation est achevée avant de continuer.
|
||||
main.createVault.nonEmptyDir.title = Echec de création du coffre-fort
|
||||
main.createVault.nonEmptyDir.header = Le répertoire sélectionné n'est pas vide
|
||||
main.createVault.nonEmptyDir.content = Le répertoire sélectionné contient déjà des fichiers (potentiellement cachés). Un coffre-fort ne peut être créé que dans un répertoire vide.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
unlock.label.mountPath = Chemin de montage
|
||||
unlock.label.mountPathButton = Appliquer
|
||||
settings.webdav.port.label = Port de WebDAV
|
||||
settings.webdav.port.prompt = 0 \= choisir automatiquement
|
||||
settings.webdav.port.apply = Appliquer
|
||||
settings.webdav.prefGvfsScheme.label = stratagème webdav
|
||||
settings.volume.label = méthode de montage
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
settings.volume.fuse = limite
|
||||
unlock.successLabel.vaultCreated = Le coffre-fort a été créé avec succès
|
||||
unlock.successLabel.passwordChanged = Le mot de passe a été changé avec succès
|
||||
unlock.successLabel.upgraded = Cryptomator a été mise à jour avec succès
|
||||
unlock.label.useOwnMountPath = Utiliser son propre point de montage
|
||||
welcome.askForUpdateCheck.dialog.title = vérification de la mise à jour
|
||||
welcome.askForUpdateCheck.dialog.header = Activer le contrôle de mise à jour intégré ?
|
||||
welcome.askForUpdateCheck.dialog.content = Pour vérifier les mises à jour, Cryptomator récupère la version actuelle sur les serveurs Cryptomator et vous donne un aperçu si une nouvelle version est disponible.\n\nNous vous recommandons d'activer la vérification de mise à jour pour vous assurer que vous avez toujours la dernière version de Cryptomator, avec tous les correctifs de sécurité, installés. Si vous n'activez pas le contrôle de mise à jour, vous pouvez vérifier et télécharger la version actuelle à partir de https\://cryptomator.org/downloads/.\n\nVous pouvez le modifier à tout moment à partir des paramètres.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Le chemin de montage n'est pas défini.
|
||||
main.gracefulShutdown.dialog.title = Échec en fermant le coffre-fort.
|
||||
main.gracefulShutdown.dialog.header = Coffre-fort est en cours d'utilisation.
|
||||
main.gracefulShutdown.dialog.content = Un ou plusieurs coffre-forts sont en cours d'utilisation par d'autres logiciels. S'il vous plait, fermer-les pour permettre à Cryptomator de finir proprement.\n\nSi ça ne marche pas, Cryptomator peut fermer par force, mais cela peut résulter d'une perte de vos fichiers (non recommandé).
|
||||
main.gracefulShutdown.button.tryAgain = Réessayez
|
||||
main.gracefulShutdown.button.forceShutdown = Arrêt forcé
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = A titkosítás feloldása meghíu
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Széf lezárása
|
||||
unlocked.moreOptions.reveal = Meghajtó felfedése
|
||||
unlocked.moreOptions.copyUrl = WebDAV URL másolása
|
||||
unlocked.label.revealFailed = Parancs meghíusúlt
|
||||
unlocked.label.unmountFailed = Meghajtó leválasztása sikertelen
|
||||
unlocked.label.statsEncrypted = titkosított
|
||||
@@ -75,7 +74,7 @@ upgrade.version3to4.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Ké
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Igen, meggyőződtem a szinkronizáció befejeztéről
|
||||
unlock.label.savePassword = Jelszó mentése
|
||||
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
|
||||
unlock.errorMessage.unauthenticVersionMac = Nem lehet a MAC verziót azonosítani.
|
||||
unlocked.label.mountFailed = Meghajtó csatlakoztatása sikertelen
|
||||
unlock.savePassword.delete.confirmation.title = Mentett jelszó törlése
|
||||
unlock.savePassword.delete.confirmation.header = Biztosan el akarod távolítani a széfhez tartozó mentett jelszót?
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = Széf verziófrissítése 3-ról 4-re
|
||||
upgrade.version4to5.title = Széf verziófrissítése 4-ről 5-re
|
||||
upgrade.version4to5.msg = Ennek a széfnek egy újabb formátumra való migrációja szükséges. A titkosított könyvtárnevek frissítve lesznek. Kérlek, győződj meg a szinkronizáció befejeztéről mielőtt továbblépnél.\n\nMegjegyzés\: A összes fájl módosításának dátuma az aktuális időre fog módosulni
|
||||
upgrade.version4to5.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
unlock.label.revealAfterMount = Meghajtó megnyitása
|
||||
unlocked.lock.force.confirmation.title = Sikertelen lezárás a következőnél\: %1$s
|
||||
unlocked.lock.force.confirmation.header = Szeretné erőltetni a lezárást?
|
||||
unlocked.lock.force.confirmation.content = Ez amiatt lehet, mert más programok még mindig használják a széfben lévő fájlokat vagy valamilyen egyéb probléma lépett fel.\n\nA programok, amik használják ezeket a fájlokat, nem működhetnek megfelelően vagy akár adatvesztés is előfordulhat.
|
||||
unlock.label.unlockAfterStartup = Automatikus feloldás indításnál (kísérleti funkció)
|
||||
unlock.errorMessage.unlockFailed = A feloldás nem sikerült. Nézze meg a naplófájlokat.
|
||||
upgrade.version5toX.title = Széf verziófrissítés
|
||||
upgrade.version5toX.msg = A széf új verzióra történő migrációja szükséges.\nKérlek győződj meg a szinkronizáció befejeztéről, mielőtt más műveletet végeznél.
|
||||
main.createVault.nonEmptyDir.title = A széf létrehozása sikertelen
|
||||
main.createVault.nonEmptyDir.header = A kiválasztott mappa nem üres
|
||||
main.createVault.nonEmptyDir.content = A kiválasztott mappa már tartalmaz fájlokat (valószínűleg rejtett). A széf csak üres mappában hozható létre.
|
||||
unlock.label.mountPath = Elérési út csatlakoztatása
|
||||
unlock.label.mountPathButton = Alkalmaz
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.webdav.port.prompt = 0 \= Automatikus választás
|
||||
settings.webdav.port.apply = Alkalmaz
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV séma
|
||||
settings.volume.label = Csatlakoztatási mód
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = A széf sikeresen létrehozva.
|
||||
unlock.successLabel.passwordChanged = A jelszó sikeresen megváltoztatva.
|
||||
unlock.successLabel.upgraded = A Cryptomator sikeresen frissítésre került.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Próbáld újra
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Decriptaggio fallito
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Blocca vault
|
||||
unlocked.moreOptions.reveal = Apri il disco
|
||||
unlocked.moreOptions.copyUrl = Copia url WebDAV
|
||||
unlocked.label.revealFailed = Comando fallito
|
||||
unlocked.label.unmountFailed = Espulsione disco fallita
|
||||
unlocked.label.statsEncrypted = criptato
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = Aggiornamento Vault da versione 3 a 4
|
||||
upgrade.version4to5.title = Aggiornamento da versione 4 a 5
|
||||
upgrade.version4to5.msg = Questo vault ha bisogno di essere migrato ad un formato piu' recente. Tutti i files criptati saranno aggiornati. Per favore assicurati che la sincronizzazione sia terminata prima di procedere.\n\nNota\: la data di modifica di tutti i files cambiera' alla data/ora attuale del processo.
|
||||
upgrade.version4to5.err.io = Migrazione fallita a causa di una eccezione I/O. Verifica il file di log per i dettagli.
|
||||
unlock.label.mountAfterUnlock = Monta il disco
|
||||
unlock.label.revealAfterMount = Mostra il disco
|
||||
unlocked.lock.force.confirmation.title = Il blocco di %1$s è fallito
|
||||
unlocked.lock.force.confirmation.header = Vuoi forzare il blocco?
|
||||
unlocked.lock.force.confirmation.content = E' accaduto questo perchè altri programmi stanno ancora utilizzando i dati nel vault o perchè è accaduto un altro problema
|
||||
unlock.label.unlockAfterStartup = Blocco automatico all'avvio (Sperimentale)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
unlock.errorMessage.unlockFailed = Sblocco fallito. Guarda il file log per i dettagli.
|
||||
upgrade.version5toX.title = Aggiornamento di versione del Vault
|
||||
upgrade.version5toX.msg = Questo vault deve migrare ad un nuovo formato.\nAssicurati che la sincronizzazione sia terminata prima di procedere.
|
||||
main.createVault.nonEmptyDir.title = Creazione del vaul fallita
|
||||
main.createVault.nonEmptyDir.header = La directory scelta non è vuota
|
||||
main.createVault.nonEmptyDir.content = La directory selezionata contiene già dei file (forse nascosti). Un vault può essere creato solo in una directory vuota.
|
||||
unlock.label.mountPath = Monta il percorso
|
||||
unlock.label.mountPathButton = Applica
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.port.prompt = 0 \= Scelta automatica
|
||||
settings.webdav.port.apply = Applica
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Vaul creato con successo.
|
||||
unlock.successLabel.passwordChanged = Password modificata con successo.
|
||||
unlock.successLabel.upgraded = Cryptomator aggiornato con successo.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = 復号に失敗しました。
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = 金庫の施錠
|
||||
unlocked.moreOptions.reveal = ドライブの表示
|
||||
unlocked.moreOptions.copyUrl = WebDAV URL のコピー
|
||||
unlocked.label.revealFailed = 入力エラー
|
||||
unlocked.label.unmountFailed = ドライブの取り出しに失敗
|
||||
unlocked.label.statsEncrypted = 暗号化済み
|
||||
@@ -86,15 +85,12 @@ upgrade.version3to4.title = 金庫をバージョン 3 から 4 にアップグ
|
||||
upgrade.version4to5.title = 金庫をバージョン 4 から 5 にアップグレード
|
||||
upgrade.version4to5.msg = この金庫は新しいフォーマットに移行する必要があります。\n暗号化されたファイルは更新されます。\n続行する前に同期が完了していることをご確認ください。\n\n注意:すべてのファイルの変更日は、現在の日付・時刻に変わります。
|
||||
upgrade.version4to5.err.io = I/O の例外で移行に失敗しました。詳細はログをご確認ください。
|
||||
unlock.label.mountAfterUnlock = ドライブをマウント
|
||||
unlock.label.revealAfterMount = ドライブの表示
|
||||
unlocked.lock.force.confirmation.title = %1$s の施錠に失敗しました
|
||||
unlocked.lock.force.confirmation.header = 強制的にロックしますか?
|
||||
unlocked.lock.force.confirmation.content = これは恐らく他のプログラムがこの金庫のファイルをまだアクセスしているか、あるいは別の問題が発生したためです。\n\nまだファイルにアクセスしているプログラムが正しく動作しない可能性があり、それらのプログラムによってまだ書き込まれていないデータが失われる可能性があります。
|
||||
unlock.label.unlockAfterStartup = 起動時に解錠 (実験的)
|
||||
unlock.errorMessage.unlockFailed = 施錠に失敗しました。詳細をログファイルで確認してください。
|
||||
unlocked.moreOptions.mount = ドライブのマウント
|
||||
unlocked.moreOptions.unmount = ドライブの取り出し
|
||||
upgrade.version5toX.title = 金庫のバージョンをアップグレード
|
||||
upgrade.version5toX.msg = この金庫を新しいバージョンに移行する必要があります。\n進行する前に同期が完了していることをご確認ください。
|
||||
main.createVault.nonEmptyDir.title = 金庫の作成が失敗しました
|
||||
@@ -109,6 +105,18 @@ settings.webdav.prefGvfsScheme.label = WebDAV スキーム
|
||||
settings.volume.label = マウント方法 *
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = 金庫が正常に作成されました。
|
||||
unlock.successLabel.passwordChanged = パスワードが正常に変更されました。
|
||||
unlock.successLabel.upgraded = Cryptomator が正常にアップグレードされました。
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = 암호화 해제 실패
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = 보관함 잠그기
|
||||
unlocked.moreOptions.reveal = 드라이브 표시
|
||||
unlocked.moreOptions.copyUrl = WebDAV 주소 복사
|
||||
unlocked.label.revealFailed = 명령 실패
|
||||
unlocked.label.unmountFailed = 드라이브 꺼내기 실패
|
||||
unlocked.label.statsEncrypted = 암호화
|
||||
@@ -86,15 +85,12 @@ upgrade.version3to4.title = 보관함 버전 3에서 4로 업그레이드
|
||||
upgrade.version4to5.title = 보관함 버전 4에서 5로 업그레이드
|
||||
upgrade.version4to5.msg = 이 보관함은 새로운 형식으로 이전되어야 합니다.\n암호화된 파일들은 업데이트 될 것입니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.\n\n참고\: 모든 파일의 수정 날짜는 과정 진행 중에 현재 날짜/시간으로 바뀔 것입니다.
|
||||
upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요.
|
||||
unlock.label.mountAfterUnlock = 드라이브 마운트
|
||||
unlock.label.revealAfterMount = 드라이브 공개
|
||||
unlocked.lock.force.confirmation.title = %1$s 잠그기 실패
|
||||
unlocked.lock.force.confirmation.header = 강제로 잠그시겠습니까?
|
||||
unlocked.lock.force.confirmation.content = 이는 다른 프로그램이 보관함 내의 파일을 접근하고 있거나, 다른 문제가 발생했기 때문일 수 있습니다.\n\n파일을 접근하고 있는 프로그램이 제대로 동작하지 않을 수 있으며, 프로그램이 쓰지 않은 데이터는 손실될 수 있습니다.
|
||||
unlock.label.unlockAfterStartup = 시작 시 자동 잠금 해제 (실험적)
|
||||
unlock.errorMessage.unlockFailed = 잠금 해제 실패. 자세한 사항은 로그 파일을 참조하세요.
|
||||
unlocked.moreOptions.mount = 드라이브 마운트
|
||||
unlocked.moreOptions.unmount = 드라이브 꺼내기
|
||||
upgrade.version5toX.title = 보관함 버전 업그레이드
|
||||
upgrade.version5toX.msg = 이 보관함은 새로운 버전으로 이전되어야 합니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.
|
||||
main.createVault.nonEmptyDir.title = 보관함 생성 실패
|
||||
@@ -111,4 +107,16 @@ settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Atšifrēšana neizdevās
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Aizslēgt glabātuvi
|
||||
unlocked.moreOptions.reveal = Atklāt disku
|
||||
unlocked.moreOptions.copyUrl = Kopēt WebDAV saiti
|
||||
unlocked.label.revealFailed = Komunikācija neizdevās
|
||||
unlocked.label.unmountFailed = Diska izgrūšana neizdevās
|
||||
unlocked.label.statsEncrypted = šifrēts
|
||||
@@ -87,29 +86,38 @@ upgrade.version3to4.title = Glabātuves versijas 3 uz 4 atjauninājums
|
||||
upgrade.version4to5.title = Glabātuves versijas 4 uz 5 atjauninājums
|
||||
upgrade.version4to5.msg = Šo glabātuvi nepieciešams migrēt uz jaunāku versiju.\nŠifrētās datnes tiks atjauninātas.\nPirms apstiprini, pārliecinies, ka ir beigusies sinhronizācija.\n\nPiezīme\: Visām datnēm modificēšanas datums tiks izmainīts uz šodienas datumu.
|
||||
upgrade.version4to5.err.io = Migrācijas kļīda dēļ I/O izņēmuma. Sīkāku informāciju skaties žurnālā.
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPath = Mount path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -47,7 +47,6 @@ changePassword.errorMessage.decryptionFailed = Decoderen mislukt
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Vergrendel kluis
|
||||
unlocked.moreOptions.reveal = Maak schijf zichtbaar
|
||||
unlocked.moreOptions.copyUrl = Kopieer WebDAV URL
|
||||
unlocked.label.revealFailed = Opdracht mislukt
|
||||
unlocked.label.unmountFailed = Uitwerpen schijf mislukt
|
||||
unlocked.label.statsEncrypted = versleuteld
|
||||
@@ -88,29 +87,38 @@ upgrade.version3to4.title = Kluis Versie 3 naar 4 Upgrade
|
||||
upgrade.version4to5.title = Kluis Versie 4 naar 5 Upgrade
|
||||
upgrade.version4to5.msg = Deze kluis moet gemigreerd worden naar een nieuw formaat.\nVersleutelde bestanden zullen bijgewerkt worden.\nZorg ervoor dat synchronisatie voltooid is alvorens verder te gaan.\n\nLet op\: Tijdens dit proces zal de wijzigingsdatum van alle bestanden gewijzigd worden naar de huidige datum/tijd.
|
||||
upgrade.version4to5.err.io = Migratie mislukt door een I/O Exception. Bekijk log file voor details.
|
||||
unlock.label.mountAfterUnlock = Schijf mounten
|
||||
unlock.label.revealAfterMount = Maak schijf zichtbaar
|
||||
unlocked.lock.force.confirmation.title = Blokkeren van %1$s is mislukt
|
||||
unlocked.lock.force.confirmation.header = Wil je vergrendelen forceren?
|
||||
unlocked.lock.force.confirmation.content = Dit kan komen omdat er nog andere programma's de bestanden in de kluis gebruik hebben, of door een ander probleem.\n\nProgramma's die de bestanden nog in gebruik hebben werken mogelijk niet goed, en gegevens die nog niet opgeslagen zijn gaan mogelijk verloren.
|
||||
unlock.label.unlockAfterStartup = Auto-ontgrendelen bij starten (Expirimenteel)
|
||||
unlock.errorMessage.unlockFailed = Ontgrendelen mislukt. Zie log file voor details.
|
||||
unlocked.moreOptions.mount = Schijf mounten
|
||||
unlocked.moreOptions.unmount = Schijf uitwerpen
|
||||
upgrade.version5toX.title = Upgraden versie kluis
|
||||
upgrade.version5toX.msg = Deze kluis moet gemigreerd worden naar een nieuwer formaat. Zorg dat de synchronisatie klaar is alvorens verder te gaan.
|
||||
main.createVault.nonEmptyDir.title = Kluis aanmaken mislukt
|
||||
main.createVault.nonEmptyDir.header = De gekozen map is niet leeg
|
||||
main.createVault.nonEmptyDir.content = De geselecteerde map bevat al bestanden (mogelijk verborgen). Een klluis kan alleen worden aangemaakt in een lege map.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
unlock.label.mountPath = Mount pad
|
||||
unlock.label.mountPathButton = Toepassen
|
||||
settings.webdav.port.label = WebDAV Poort
|
||||
settings.webdav.port.prompt = 0 \= Automatisch kiezen
|
||||
settings.webdav.port.apply = Toepassen
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Schema
|
||||
settings.volume.label = Voorkeurs Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
settings.volume.fuse = STOP
|
||||
unlock.successLabel.vaultCreated = Kluis was succesvol gecreeerd
|
||||
unlock.successLabel.passwordChanged = Wachtwoord is succesvol aangepast
|
||||
unlock.successLabel.upgraded = Cryptomator succesvol vernieuwd.
|
||||
unlock.label.useOwnMountPath = Gebruik een eigen koppelpunt
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Geintegreerde update check aanzetten
|
||||
welcome.askForUpdateCheck.dialog.content = Om te controleren op updates haalt Cryptomator het huidige versienummer van de Cryptomatorservers en toont een hint indien een nieuwere versie beschikbaar is.\n\nWe raden aan om de geintegreerde update check aan te zetten om zeker te weten dat je de nieuwste versie van Cryptomator met alle beveiligings aanpassingen hebt geinstalleerd. Indien je deze niet aanzet kun je zelf de versie controleren en downloaden van https\://cryptomatr.org/downloads/.\n\n\nJe kan dit te allen tijden bij instellingen aanpassen.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Eigen koppel pad is niet ingevuld.
|
||||
main.gracefulShutdown.dialog.title = Vergrendelen kluis/kluizen mislukt
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Probeer opnieuw
|
||||
main.gracefulShutdown.button.forceShutdown = Geforceerd afsluiten
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -2,52 +2,51 @@ app.name = Cryptomator
|
||||
# main.fxml
|
||||
main.emptyListInstructions = Kliknij tutaj, aby utworzyć nowy portfel
|
||||
main.directoryList.contextMenu.remove = Usuń z listy
|
||||
main.directoryList.contextMenu.changePassword = Zmień hasło
|
||||
main.addDirectory.contextMenu.new = Stwórz nowy portfel
|
||||
main.directoryList.contextMenu.changePassword = Zmień Hasło
|
||||
main.addDirectory.contextMenu.new = Utwórz Nowy Portfel
|
||||
main.addDirectory.contextMenu.open = Otwórz istniejący portfel
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking = Sprawdzanie aktualizacji...
|
||||
welcome.newVersionMessage = Nowa wersja %1$s jest dostępna do pobrania.\nObecnie używana wersja to %2$s.
|
||||
# initialize.fxml
|
||||
initialize.label.password = Hasło
|
||||
initialize.label.retypePassword = Powtórz hasło
|
||||
initialize.button.ok = Stwórz portfel
|
||||
initialize.label.retypePassword = Powtórz Hasło
|
||||
initialize.button.ok = Utwórz Portfel
|
||||
initialize.messageLabel.alreadyInitialized = Portfel został utworzony
|
||||
initialize.messageLabel.initializationFailed = Nie można utworzyć portfela. Szczegóły błędu znajdziesz w logach.
|
||||
initialize.messageLabel.initializationFailed = Nie można zainicjować portfela. Zobacz plik dziennika, aby poznać szczegóły.
|
||||
# notfound.fxml
|
||||
notfound.label = Nie znaleziono portfela. Może został przeniesiony?
|
||||
# upgrade.fxml
|
||||
upgrade.button = Zaktualizuj portfel
|
||||
upgrade.version3dropBundleExtension.msg = Portfel musi zostać zaktualizowany do nowszego formatu.\n"%1$s" zostanie zmienione na "%2$s".\nZanim rozpoczniesz migracje upewnij się, że synchronizacja plików została ukończona.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = Błąd automatycznej migracji portfela.\n"%s" już istnieje.
|
||||
upgrade.button = Zaktualizuj Portfel
|
||||
upgrade.version3dropBundleExtension.msg = Portfel musi zostać zaktualizowany do nowszego formatu.\n"%1$s" zostanie zmienione na "%2$s".\nPrzed kontynuowaniem upewnij się, że synchronizacja została zakończona.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = Automatyczna migracja nie powiodła się.\n"%s" już istnieje.
|
||||
# unlock.fxml
|
||||
unlock.label.password = Hasło do wolumenu
|
||||
unlock.label.mountName = Nazwa wolumenu
|
||||
unlock.label.winDriveLetter = Litera dysku
|
||||
unlock.label.password = Hasło
|
||||
unlock.label.mountName = Nazwa Napędu
|
||||
unlock.label.winDriveLetter = Litera Napędu
|
||||
unlock.label.downloadsPageLink = Wszystkie wersje Cryptomatora
|
||||
unlock.label.advancedHeading = Opcje zaawansowane
|
||||
unlock.button.unlock = Odblokuj portfel
|
||||
unlock.button.advancedOptions.show = Więcej opcji
|
||||
unlock.button.advancedOptions.hide = Mniej opcji
|
||||
unlock.label.advancedHeading = Opcje Zaawansowane
|
||||
unlock.button.unlock = Odblokuj Portfel
|
||||
unlock.button.advancedOptions.show = Więcej Opcji
|
||||
unlock.button.advancedOptions.hide = Mniej Opcji
|
||||
unlock.choicebox.winDriveLetter.auto = Przydziel automatycznie
|
||||
unlock.errorMessage.wrongPassword = Nieprawidłowe hasło
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Niewspierana wersja portfela. Ten portfel został utworzony przez starszą wersję Cryptomatora.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Niewspierana wersja portfela. Ten portfel został utworzony przez nowszą wersję Cryptomatora.
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Nieobsługiwana wersja portfela. Ten portfel został utworzony przez starszą wersję Cryptomatora.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Nieobsługiwana wersja portfela. Ten portfel został utworzony przez nowszą wersję Cryptomatora.
|
||||
unlock.messageLabel.startServerFailed = Nie udało się uruchomić serwera WebDAV.
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword = Stare hasło
|
||||
changePassword.label.newPassword = Nowe hasło
|
||||
changePassword.label.retypePassword = Powtórz hasło
|
||||
changePassword.label.oldPassword = Stare Hasło
|
||||
changePassword.label.newPassword = Nowe Hasło
|
||||
changePassword.label.retypePassword = Powtórz Hasło
|
||||
changePassword.label.downloadsPageLink = Wszystkie wersje Cryptomatora
|
||||
changePassword.button.change = Zmień hasło
|
||||
changePassword.button.change = Zmień Hasło
|
||||
changePassword.errorMessage.wrongPassword = Nieprawidłowe hasło
|
||||
changePassword.errorMessage.decryptionFailed = Błąd odszyfrowywania
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Zabezpiecz portfel
|
||||
unlocked.moreOptions.reveal = Odkryj wolumen
|
||||
unlocked.moreOptions.copyUrl = Skopiuj URL WebDAV
|
||||
unlocked.label.revealFailed = Błąd odkrywania wolumenu
|
||||
unlocked.label.unmountFailed = Błąd odłączania wolumenu
|
||||
unlocked.button.lock = Blokuj Portfel
|
||||
unlocked.moreOptions.reveal = Odkryj Napęd
|
||||
unlocked.label.revealFailed = Polecenie nie powiodło się
|
||||
unlocked.label.unmountFailed = Wysuwanie napędu nie powiodło się
|
||||
unlocked.label.statsEncrypted = szyfrowane
|
||||
unlocked.label.statsDecrypted = nieszyfrowywane
|
||||
unlocked.ioGraph.yAxis.label = Wydajność (MiB/s)
|
||||
@@ -58,57 +57,66 @@ settings.requiresRestartLabel = * Cryptomator wymaga restartu
|
||||
# tray icon
|
||||
tray.menu.open = Otwórz
|
||||
tray.menu.quit = Wyjdź
|
||||
tray.infoMsg.title = Wciąż działa
|
||||
tray.infoMsg.msg = Cryptomator wciąż jest uruchomiony. Aby go wyłączyć, użyj ikony z obszaru powiadomień.
|
||||
tray.infoMsg.msg.osx = Cryptomator wciąż jest uruchomiony. Aby go wyłączyć, użyj ikony z paska menu.
|
||||
tray.infoMsg.title = Nadal Uruchomiony
|
||||
tray.infoMsg.msg = Cryptomator jest nadal uruchomiony. Zamknij go z ikony z paska zadań.
|
||||
tray.infoMsg.msg.osx = Cryptomator jest nadal uruchomiony. Zamknij go z ikony z paska menu.
|
||||
initialize.messageLabel.passwordStrength.0 = Bardzo słabe
|
||||
initialize.messageLabel.passwordStrength.1 = Słabe
|
||||
initialize.messageLabel.passwordStrength.2 = W porządku
|
||||
initialize.messageLabel.passwordStrength.2 = Dostateczne
|
||||
initialize.messageLabel.passwordStrength.3 = Mocne
|
||||
initialize.messageLabel.passwordStrength.4 = Bardzo mocne
|
||||
initialize.label.doNotForget = WAŻNE\: Jeśli zapomnisz hasło, nie ma żadnej innej możliwości odzyskania Twouch danych.
|
||||
main.directoryList.remove.confirmation.title = Usuń portfel
|
||||
initialize.label.doNotForget = WAŻNE\: Jeśli zapomnisz hasło, nie ma żadnej innej możliwości odzyskania twoich danych.
|
||||
main.directoryList.remove.confirmation.title = Usuń Portfel
|
||||
main.directoryList.remove.confirmation.header = Czy na pewno chcesz usunąć ten portfel?
|
||||
main.directoryList.remove.confirmation.content = Ten portfel zostanie usunięty tylko z listy. Jeśli chcesz trwale go usunąć, usuń pliki portfela z dysku.
|
||||
upgrade.version3to4.msg = Ten portfel wymaga aktualizacji do nowszej wersji. \nZaszyfrowane nazwy folderów zostaną zmienione.\nZanim rozoczniesz migracje upewnij się, że synchronizacja plików została ukończona.
|
||||
upgrade.version3to4.err.io = Błąd aktualizacji z powodu problemów z odczytem/zapisem. Szczegóły błędu znajdziesz w logach.
|
||||
main.directoryList.remove.confirmation.content = Ten portfel zostanie usunięty tylko z listy. Jeśli chcesz trwale go usunąć, usuń pliki portfela ze swojego systemu plików.
|
||||
upgrade.version3to4.msg = Ten portfel wymaga migracji do nowszego formatu.\nZaszyfrowane nazwy folderów zostaną zaktualizowane.\nPrzed kontynuowaniem upewnij się, że synchronizacja została zakończona.
|
||||
upgrade.version3to4.err.io = Migracja nie powiodła się z powodu wyjątku I/O. Zobacz plik dziennika, aby poznać szczegóły.
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Tak, synchronizacja plików na pewno została ukończona.
|
||||
unlock.label.savePassword = Zapisz hasło
|
||||
upgrade.confirmation.label = Tak, upewniłem się że synchronizacja plików została ukończona.
|
||||
unlock.label.savePassword = Zapisz Hasło
|
||||
unlock.errorMessage.unauthenticVersionMac = Nie udało się uwierzytelnić wersji MAC
|
||||
unlocked.label.mountFailed = Błąd podłączanie dysku.
|
||||
unlock.savePassword.delete.confirmation.title = Usuń zapisane hasło
|
||||
unlocked.label.mountFailed = Nie udało się połączyć z napędem
|
||||
unlock.savePassword.delete.confirmation.title = Usuń Zapisane Hasło
|
||||
unlock.savePassword.delete.confirmation.header = Czy na pewno chcesz usunąć zapisane hasło do tego portfela?
|
||||
unlock.savePassword.delete.confirmation.content = Zapisane hasło do tego portfela zostanie natychmiast usunięte z systemowego pęku kluczy. Jeśli chcesz zapisać hasło ponownie, zaloguj się do portfela z zaznaczoną opcją "Zapisz hasło".
|
||||
settings.debugMode.label = Tryb debugowania *
|
||||
unlock.savePassword.delete.confirmation.content = Zapisane hasło do tego portfela zostanie natychmiast usunięte z systemowego pęku kluczy. Jeśli chcesz ponownie zapisać hasło, musisz odblokować portfel z włączoną opcją "Zapisz hasło".
|
||||
settings.debugMode.label = Tryb Debugowania *
|
||||
upgrade.version3dropBundleExtension.title = Aktualizacja portfela do wersji 3 (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Aktualizacja portfela z wersji 3 do 4
|
||||
upgrade.version4to5.title = Aktualizacja portfela z wersji 4 do 5
|
||||
upgrade.version4to5.msg = Ten portfel wymaga aktualizacji do nowszej wersji. \nZaszyfrowane nazwy folderów zostaną zmienione.\nZanim rozpoczniesz migracje, upewnij się, że synchronizacja plików została ukończona.\n\nUwaga\: W procesie aktualizacji data modyfikacji wszystkich plików zmieni się na biezącą datę/czas.
|
||||
upgrade.version4to5.err.io = Błąd aktualizacji z powodu problemów z odczytem/zapisem. Szczegóły błędu znajdziesz w logach.
|
||||
unlock.label.mountAfterUnlock = Zamontuj dysk
|
||||
unlock.label.revealAfterMount = Pokaż dysk
|
||||
upgrade.version4to5.msg = Ten portfel wymaga migracji do nowszego formatu.\nZaszyfrowane pliki zostaną zaktualizowane.\nPrzed kontynuowaniem upewnij się, że synchronizacja została zakończona..\n\nUwaga\: Data modyfikacji wszystkich plików zostanie zmieniona w procesie na bieżącą datę/czas.
|
||||
upgrade.version4to5.err.io = Migracja nie powiodła się z powodu wyjątku I/O. Szczegóły błędu znajdziesz w dzienniku.
|
||||
unlock.label.revealAfterMount = Pokaż Napęd
|
||||
unlocked.lock.force.confirmation.title = Zablokowywanie %1$s nie powiodło się
|
||||
unlocked.lock.force.confirmation.header = Czy chcesz wymusić zablokowanie?
|
||||
unlocked.lock.force.confirmation.content = Może się tak dziać dlatego, że inne programy wciąż korzystają z plików z portfela lub wystąpił inny problem.\n\nProgramy wciąż korzystające z plików mogą przestać działać poprawnie, a nie zapisane przez nie dane mogą zostać utracone.
|
||||
unlock.label.unlockAfterStartup = Auto-odblokowywanie podczas uruchamiania (Eksperymentalne)
|
||||
unlock.errorMessage.unlockFailed = Błąd odblokowywania. Szczegóły błędu znajdziesz w logach.
|
||||
unlocked.moreOptions.mount = Podłącz dysk
|
||||
unlocked.moreOptions.unmount = Odłącz dysk
|
||||
upgrade.version5toX.title = Aktualizacja wersji portfela
|
||||
upgrade.version5toX.msg = Ten portfel wymaga aktualizacji do nowszej wersji.\nZanim rozpoczniesz migracje upewnij się, że synchronizacja plików została ukończona.
|
||||
unlock.errorMessage.unlockFailed = Błąd odblokowywania. Szczegóły błędu znajdziesz w dzienniku.
|
||||
upgrade.version5toX.title = Aktualizacja Wersji Portfela
|
||||
upgrade.version5toX.msg = Ten portfel wymaga migracji do nowszego formatu.\nZanim rozpoczniesz migrację upewnij się, że synchronizacja plików została zakończona.
|
||||
main.createVault.nonEmptyDir.title = Błąd podczas tworzenia portfela
|
||||
main.createVault.nonEmptyDir.header = Wybrany katalog nie jest pusty
|
||||
main.createVault.nonEmptyDir.content = Wybrany katalog aktualnie zawiera pliki (prawdopodobnie ukryte). Portfel mozna utworzyć wyłącznie w puatym katalogu.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
main.createVault.nonEmptyDir.content = Wybrany katalog zawiera już pliki (prawdopodobnie ukryte). Portfel mozna utworzyć wyłącznie w pustym katalogu.
|
||||
unlock.label.mountPath = Zamontuj ścieżkę
|
||||
unlock.label.mountPathButton = Zastosuj
|
||||
settings.webdav.port.label = Port WebDAV
|
||||
settings.webdav.port.prompt = 0 \= Wybierz automatycznie
|
||||
settings.webdav.port.apply = Zastosuj
|
||||
settings.webdav.prefGvfsScheme.label = System WebDAV
|
||||
settings.volume.label = Preferowany Typ Woluminu
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Portfel został pomyślnie utworzony.
|
||||
unlock.successLabel.passwordChanged = Hasło zostało pomyślnie zmienione.
|
||||
unlock.successLabel.upgraded = Cryptomator został pomyślnie zaktualizowany.
|
||||
unlock.label.useOwnMountPath = Użyj indywidualnego punktu montowania
|
||||
welcome.askForUpdateCheck.dialog.title = Sprawdź aktualizację
|
||||
welcome.askForUpdateCheck.dialog.header = Włącz zintegrowane sprawdzenie aktualizacji?
|
||||
welcome.askForUpdateCheck.dialog.content = Aby sprawdzić dostępność aktualizacji, Cryptomator pobierze bieżącą wersję z serwerów Cryptomator i wyświetli podpowiedź, jeśli dostępna będzie nowsza wersja.\n\nZalecamy włączenie sprawdzania aktualizacji, aby zawsze mieć pewność, że zainstalowana jest najnowsza wersja Cryptomatora ze wszystkimi poprawkami zabezpieczeń. Jeśli nie włączysz sprawdzania aktualizacji, możesz sprawdzić i pobrać aktualną wersję z https\://cryptomator.org/downloads/.\n\nMożesz to zmienić w dowolnym momencie, korzystając z ustawień.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Indywidualna ścieżka montażu nie jest ustawiona.
|
||||
main.gracefulShutdown.dialog.title = Nie udało się zablokować porfela(i)
|
||||
main.gracefulShutdown.dialog.header = Portfel(e) w użyciu
|
||||
main.gracefulShutdown.dialog.content = Jedna lub więcej porfelii jest nadal używana przez inne programy. Zamknij je, aby umożliwić prawidłowe zamknięcie Cryptomator, a następnie spróbuj ponownie.\n\nJeśli to nie zadziała, Cryptomator może zamknąć na siłę, ale może to spowodować utratę danych i nie jest zalecane.
|
||||
main.gracefulShutdown.button.tryAgain = Spróbuj ponownie
|
||||
main.gracefulShutdown.button.forceShutdown = Wymuś zamknięcie
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Falha ao descriptografar
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Fechar cofre
|
||||
unlocked.moreOptions.reveal = Mostrar drive
|
||||
unlocked.moreOptions.copyUrl = Copiar URL WebDAV
|
||||
unlocked.label.revealFailed = Falha de comando
|
||||
unlocked.label.unmountFailed = Falha ao ejetar drive
|
||||
unlocked.label.statsEncrypted = Criptografado
|
||||
@@ -74,7 +73,7 @@ upgrade.version3to4.msg = Esse cofre tem que ser migrado a um novo formato. Os n
|
||||
upgrade.version3to4.err.io = Falha na migração devido a um erro de E/S. Veja o arquivo de log para mais detalhes.
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Sim, tenho certeza de que a sincronização foi concluída
|
||||
unlock.label.savePassword = Armazenar senha
|
||||
unlock.label.savePassword = Salvar senha
|
||||
unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a versão do MAC.
|
||||
unlocked.label.mountFailed = Falha ao conectar o drive
|
||||
unlock.savePassword.delete.confirmation.title = Apagar a senha armazenada
|
||||
@@ -86,15 +85,12 @@ upgrade.version3to4.title = Atualização do cofre da versão 3 para 4
|
||||
upgrade.version4to5.title = Atualização do cofre da versão 4 para 5
|
||||
upgrade.version4to5.msg = Este cofre precisa ser migrado a um novo formato.\nOs arquivos criptografados serão atualizados.\nPor favor, assegure que a sincronização do cofre esteja finalizada antes de proceder com a migração para o novo formato.\n\nNota\: A data de modificação de todos os arquivos do cofre será alterada durante o processo para a data e hora corrente.
|
||||
upgrade.version4to5.err.io = A migração falhou devido a uma exceção de I/O. Ver arquivo de log para mais detalhes.
|
||||
unlock.label.mountAfterUnlock = Montar o Drive
|
||||
unlock.label.revealAfterMount = Mostrar o Drive
|
||||
unlocked.lock.force.confirmation.title = O bloqueio do %1$s falhou
|
||||
unlocked.lock.force.confirmation.header = Você quer forçar o bloqueio?
|
||||
unlocked.lock.force.confirmation.content = Isto pode ser causado por outros programas que seguem acessando arquivos no cofre ou porque algum outro problema ocorreu.\n\nProgramas que seguem acessando os arquivos podem não funcionar corretamente e os dados ainda não gravados por estes programas podem ser perdidos.
|
||||
unlock.label.unlockAfterStartup = Auto-desbloqueio ao Iniciar (Experimental)
|
||||
unlock.errorMessage.unlockFailed = O desbloqueio falhou. Veja o log para mais detalhes.
|
||||
unlocked.moreOptions.mount = Montar o Drive
|
||||
unlocked.moreOptions.unmount = Ejetar o Drive
|
||||
upgrade.version5toX.title = Atualização da Versão do Cofre
|
||||
upgrade.version5toX.msg = Este cofre precisa ser migrado a um novo formato. Por favor assegure que a sincronização foi finalizada antes de proceder.
|
||||
main.createVault.nonEmptyDir.title = Falha ao criar o cofre
|
||||
@@ -109,6 +105,18 @@ settings.webdav.prefGvfsScheme.label = WebDAV schema
|
||||
settings.volume.label = Método de Montagem
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Cofre criado com sucesso
|
||||
unlock.successLabel.passwordChanged = Senha modificada com sucesso
|
||||
unlock.successLabel.upgraded = Crytomator atualizado com sucesso
|
||||
unlock.label.useOwnMountPath = Usar Ponto de Montagem Personalizado
|
||||
welcome.askForUpdateCheck.dialog.title = Verificação de atualização
|
||||
welcome.askForUpdateCheck.dialog.header = Habilitar a verificação de atualização integrada?
|
||||
welcome.askForUpdateCheck.dialog.content = Para verificar atualizações, Cryptomator vai buscar a versão atual dos servidores e exibirá uma dica para você se uma nova versão estiver disponível.\n\nNós recomendamos que habilite a verificação de atualização para que sempre tenha certeza de que está usando a última versão do Crytomator, com todos os pacotes de segurança instalados. Se você não habilitar a verificação de atualização, você pode verificar e baixar a versão atual em https\://cryptomator.org/downloads/.\n\nVocê pode mudar isso a qualquer momento através das configurações.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Caminho individual de montagem não está definido.
|
||||
main.gracefulShutdown.dialog.title = Falha no bloqueio do(s) cofre(s)
|
||||
main.gracefulShutdown.dialog.header = Cofre(s) em uso
|
||||
main.gracefulShutdown.dialog.content = Um ou mais cofres ainda estão em uso por outros programas. Por favor, feche-os para permitir que Cryptomator encerre corretamente, em seguida, tente novamente.\n\nSe isso não funcionar, Cryptomator pode forçar o desligamento, mas isso pode causar perda de dados e não é recomendado.
|
||||
main.gracefulShutdown.button.tryAgain = Tente novamente
|
||||
main.gracefulShutdown.button.forceShutdown = Forçar desligamento
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -18,7 +18,7 @@ initialize.messageLabel.initializationFailed = Cofre não inicializado. Veja os
|
||||
notfound.label = Cofre não encontrado. Ele foi movido?
|
||||
# upgrade.fxml
|
||||
upgrade.button = Atualizar Cofre
|
||||
upgrade.version3dropBundleExtension.msg = O Cofre precisa ser migrado para o novo formato.\n%1$s" será renomeado para "%2$s".\nPor favor tenha certeza que a sincronização está finalizada antes de prosseguir.
|
||||
upgrade.version3dropBundleExtension.msg = O Cofre precisa ser migrado para o novo formato.\n%1$s" será renomeado para "%2$s".\nPor favor certifique que a sincronização está finalizada antes de prosseguir.
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = A Migração automática falhou.\n"%s" já existe.
|
||||
# unlock.fxml
|
||||
unlock.label.password = Senha
|
||||
@@ -32,7 +32,7 @@ unlock.button.advancedOptions.hide = Menos Opções
|
||||
unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente
|
||||
unlock.errorMessage.wrongPassword = Senha errada
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não suportado. Esse Cofre foi criado em uma versão antiga do Cryptomator.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse Cofre foi criado em uma versão mais nova do Cryptomator.
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse Cofre foi criado em uma versão mais recente do Cryptomator.
|
||||
unlock.messageLabel.startServerFailed = A inicialização do servidor WebDAV falhou.
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword = Senha antiga
|
||||
@@ -43,9 +43,8 @@ changePassword.button.change = Alterar senha
|
||||
changePassword.errorMessage.wrongPassword = Senha errada
|
||||
changePassword.errorMessage.decryptionFailed = Descriptografia falhou
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Travar Cofre
|
||||
unlocked.button.lock = Trancar Cofre
|
||||
unlocked.moreOptions.reveal = Mostrar volume
|
||||
unlocked.moreOptions.copyUrl = Copiar URL do arquivo de sistema
|
||||
unlocked.label.revealFailed = Falha no comando
|
||||
unlocked.label.unmountFailed = A ejeção do volume falhou
|
||||
unlocked.label.statsEncrypted = criptografado
|
||||
@@ -66,10 +65,10 @@ initialize.messageLabel.passwordStrength.1 = Fraca
|
||||
initialize.messageLabel.passwordStrength.2 = Razoável
|
||||
initialize.messageLabel.passwordStrength.3 = Forte
|
||||
initialize.messageLabel.passwordStrength.4 = Muito forte
|
||||
initialize.label.doNotForget = IMPORTANTE\: Se você perder a sua senha, não haverá maneira alguma de recuperar seus dados.
|
||||
initialize.label.doNotForget = IMPORTANTE\: NÂO existe maneira alguma de recuperar seus dados se você perder a sua senha,
|
||||
main.directoryList.remove.confirmation.title = Remover Cofre
|
||||
main.directoryList.remove.confirmation.header = Você realmente quer remover esse Cofre?
|
||||
main.directoryList.remove.confirmation.content = O Cofre será removido somente da listagem. Para apagá-lo permanentemente, por favor apague o cofre do arquivo de sistemas.
|
||||
main.directoryList.remove.confirmation.content = O Cofre será removido somente da listagem. Para apagá-lo permanentemente é necessario apagá-lo de seu arquivo de sistema.
|
||||
upgrade.version3to4.msg = Esse Cofre precisa ser migrado para o novo formato.\nOs nomes das pastas criptografadas serão atualizados.\nPor favor tenha certeza que a sincronização está finalizada antes de prosseguir.
|
||||
upgrade.version3to4.err.io = A migração falhou devido a uma falha de entrada e saída. Veja o arquivo de log para mais detalhes.
|
||||
# upgrade.fxml
|
||||
@@ -79,24 +78,21 @@ unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a vers
|
||||
unlocked.label.mountFailed = Conexão do volume falhou
|
||||
unlock.savePassword.delete.confirmation.title = Apaga senha salva
|
||||
unlock.savePassword.delete.confirmation.header = Você realmente quer apagar a senha salva para esse Cofre?
|
||||
unlock.savePassword.delete.confirmation.content = A senha salva para esse Cofre será imediatamente apagada do chaveiro do sistema. Se você quiser salvar a senha novamente, é preciso destravar o Cofre com a opção "Salvar senha" ativada.
|
||||
unlock.savePassword.delete.confirmation.content = A senha salva para esse Cofre será imediatamente apagada. Para salvar a senha novamente destrave o Cofre com a opção "Salvar senha" ativada.
|
||||
settings.debugMode.label = Modo Debug *
|
||||
upgrade.version3dropBundleExtension.title = Atualização do Cofre v3 (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Atualização do Cofre v3 para v4
|
||||
upgrade.version4to5.title = Atualização do Cofre v4 para v5
|
||||
upgrade.version4to5.msg = Este Cofre precisa ser migrado para o novo formato.\nOs arquivos criptografados serão atualizados.\nPor favor tenha certeza que a sincronização está finalizada antes de prosseguir. \n\nNota\: A data de modificação de todos os arquivos serão alteradas para a data/hora atual no processo.
|
||||
upgrade.version4to5.err.io = A migração falhou devido a uma falha de entrada e saída. Veja o arquivo de log para mais detalhes.
|
||||
unlock.label.mountAfterUnlock = Montar Volume
|
||||
unlock.label.revealAfterMount = Abrir Volume
|
||||
unlocked.lock.force.confirmation.title = O Travamento para %1$s falhou
|
||||
unlocked.lock.force.confirmation.header = Deseja forçar o travamento?
|
||||
unlocked.lock.force.confirmation.content = Isso pode está ocorrendo porque arquivos no Cofre ainda estão sendo acessados ou algum outro problema ocorreu.\n\nProgramas que ainda estão acessando os arquivos podem não funcionar corretamente e os dados não gravados podem ser perdidos.
|
||||
unlock.label.unlockAfterStartup = Desbloquear ao iniciar (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Desbloqueio falhou. Consulte o arquivo de log para obter mais detalhes.
|
||||
unlocked.moreOptions.mount = Montar Volume
|
||||
unlocked.moreOptions.unmount = Ejetar Volume
|
||||
upgrade.version5toX.title = Atualização da Versão do Cofre
|
||||
upgrade.version5toX.msg = Esse Cofre precisa ser migrado para o novo formato.\nPor favor tenha certeza que a sincronização está finalizada antes de prosseguir.
|
||||
upgrade.version5toX.msg = Esse Cofre precisa ser migrado para o novo formato.\nPor favor certifique que a sincronização está finalizada antes de prosseguir.
|
||||
main.createVault.nonEmptyDir.title = Criação do cofre falhou
|
||||
main.createVault.nonEmptyDir.header = O diretório escolhido não está vazio
|
||||
main.createVault.nonEmptyDir.content = O diretório selecionado já contém arquivos (possivelmente ocultos). Um cofre só pode ser criado em um diretório vazio.
|
||||
@@ -109,6 +105,18 @@ settings.webdav.prefGvfsScheme.label = WebDAV Esquema
|
||||
settings.volume.label = Método de Montagem *
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Cofre foi criado com sucesso.
|
||||
unlock.successLabel.passwordChanged = Senha for trocada com sucesso.
|
||||
unlock.successLabel.upgraded = Cryptomator foi atualizado com sucesso.
|
||||
unlock.label.useOwnMountPath = Usar ponto de montagem individual
|
||||
welcome.askForUpdateCheck.dialog.title = Checar atualizações
|
||||
welcome.askForUpdateCheck.dialog.header = Ativar a checagem por atualizações?
|
||||
welcome.askForUpdateCheck.dialog.content = Para checar as atualizações, Cryptomator irá verificar a versão mais recente em nossos servidores e avisará se existe uma versão disponível.\n\nRecomendamos ativar a checagem por novas atualizações para ter certeza que se tenha a versão mais recente do Cryptomator, com todas as correções de segurança. Se não ativar as atualizações é possivel checar e baixa-las a versão mais recente em https\://cryptomator.org/downloads/.\n\nVocê pode alterar as configurações a qualquer hora.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Caminho para montagem individual não configurado.
|
||||
main.gracefulShutdown.dialog.title = Falha ao trancar o cofre
|
||||
main.gracefulShutdown.dialog.header = Cofre(s) em uso
|
||||
main.gracefulShutdown.dialog.content = Um ou mais cofres ainda estão em uso por outros programas. Por favor feche-os para permitir ao Cryptomator encerrar apropriadamente, então tente novamente.
|
||||
main.gracefulShutdown.button.tryAgain = Tente novamente
|
||||
main.gracefulShutdown.button.forceShutdown = Forçar término da execução
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -11,7 +11,7 @@ welcome.checkForUpdates.label.currentlyChecking = Проверка обновл
|
||||
welcome.newVersionMessage = Версия %1$s доступна для загрузки.\nТекущая версия %2$s.
|
||||
# initialize.fxml
|
||||
initialize.label.password = Пароль
|
||||
initialize.label.retypePassword = Повторите ввод пароля
|
||||
initialize.label.retypePassword = Введите пароль ещё раз
|
||||
initialize.button.ok = Создать хранилище
|
||||
initialize.messageLabel.alreadyInitialized = Хранилище уже инициализировано
|
||||
initialize.messageLabel.initializationFailed = Невозможно инициализировать хранилище. См. подробности в файле журнала.
|
||||
@@ -29,8 +29,8 @@ unlock.label.downloadsPageLink = Все версии Cryptomator
|
||||
# Дополнительные параметры
|
||||
unlock.label.advancedHeading = Дополнительно
|
||||
unlock.button.unlock = Разблокировать хранилище
|
||||
unlock.button.advancedOptions.show = Дополнительные опции
|
||||
unlock.button.advancedOptions.hide = Убрать настройки
|
||||
unlock.button.advancedOptions.show = Больше опций
|
||||
unlock.button.advancedOptions.hide = Меньше опций
|
||||
unlock.choicebox.winDriveLetter.auto = Автоназначение
|
||||
unlock.errorMessage.wrongPassword = Неверный пароль
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Неподдерживаемое хранилище. Оно было создано в более старой версии Cryptomator.
|
||||
@@ -48,7 +48,6 @@ changePassword.errorMessage.decryptionFailed = Ошибка дешифрован
|
||||
unlocked.button.lock = Заблокировать хранилище
|
||||
# Does it mean "open" drive?
|
||||
unlocked.moreOptions.reveal = Открыть диск
|
||||
unlocked.moreOptions.copyUrl = Скопировать URL-адрес WebDAV
|
||||
unlocked.label.revealFailed = Не удалось выполнить команду
|
||||
unlocked.label.unmountFailed = Ошибка извлечения диска
|
||||
unlocked.label.statsEncrypted = зашифровано
|
||||
@@ -61,10 +60,10 @@ settings.requiresRestartLabel = * Требуется перезапуск Crypto
|
||||
# tray icon
|
||||
tray.menu.open = Открыть
|
||||
tray.menu.quit = Выход
|
||||
tray.infoMsg.title = Все еще выполняется
|
||||
tray.infoMsg.title = Всё ещё выполняется
|
||||
# Не нужно использовать жаргонизмы, а также прибегать к вкусовой правке.
|
||||
tray.infoMsg.msg = Cryptomator еще работает. Выйдите при помощи иконки в трее.
|
||||
tray.infoMsg.msg.osx = Cryptomator еще работает. Выйдите при помощи значка в строке меню.
|
||||
tray.infoMsg.msg = Cryptomator всё ещё работает. Выйдите c помощью значка в области уведомлений.
|
||||
tray.infoMsg.msg.osx = Cryptomator всё ещё работает. Выйдите с помощью значка в строке меню.
|
||||
initialize.messageLabel.passwordStrength.0 = Очень слабый
|
||||
initialize.messageLabel.passwordStrength.1 = Слабый
|
||||
initialize.messageLabel.passwordStrength.2 = Приемлемый
|
||||
@@ -82,25 +81,22 @@ unlock.label.savePassword = Сохранить пароль
|
||||
unlock.errorMessage.unauthenticVersionMac = Не удалось проверить подлинность версии MAC.
|
||||
unlocked.label.mountFailed = Ошибка подключения к диску
|
||||
# А как назвать эту правку? Пожалуйста, перестаньте портить перевод.
|
||||
unlock.savePassword.delete.confirmation.title = Удалить сохраненный пароль
|
||||
unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохраненный пароль этого хранилища?
|
||||
unlock.savePassword.delete.confirmation.content = Сохраненный пароль этого хранилища будет немедленно удален из вашей системной связки ключей. Если вы снова захотите сохранить пароль, вам придется разблокировать хранилище с включенным параметром "Сохранить пароль".
|
||||
unlock.savePassword.delete.confirmation.title = Удалить сохранённый пароль
|
||||
unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохранённый пароль этого хранилища?
|
||||
unlock.savePassword.delete.confirmation.content = Сохранённый пароль этого хранилища будет немедленно удалён из вашей системной связки ключей. Если вы снова захотите сохранить пароль, вам придётся разблокировать хранилище с включённым параметром "Сохранить пароль".
|
||||
settings.debugMode.label = Режим отладки *
|
||||
upgrade.version3dropBundleExtension.title = Обновление хранилища версии 3 (расширение пакета)
|
||||
upgrade.version3to4.title = Обновление хранилища с версии 3 на 4
|
||||
upgrade.version4to5.title = Обновление хранилища с версии 4 на 5
|
||||
upgrade.version4to5.msg = Это хранилище нужно преобразовать в более новый формат.\nЗашифрованные файлы будут обновлены.\nПрежде чем продолжить, убедитесь, что завершена синхронизация.\n\nПримечание\: дата и время изменения всех файлов будут изменены на текущие на момент обработки.
|
||||
upgrade.version4to5.err.io = Преобразование не выполнено из-за ошибки ввода-вывода. См. подробности в файле журнала.
|
||||
unlock.label.mountAfterUnlock = Смонтировать диск
|
||||
unlock.label.revealAfterMount = Открыть диск
|
||||
unlocked.lock.force.confirmation.title = Ошибка блокировки %1$s
|
||||
unlocked.lock.force.confirmation.header = Заблокировать принудительно?
|
||||
unlocked.lock.force.confirmation.content = Это может быть вызвано тем, что другие программы по-прежнему обращаются к файлам в хранилище или из-за некоторых других проблем.\n\nТакие программы могут работать неправильно, а данные, которые еще не были записаны могут быть потеряны.
|
||||
unlocked.lock.force.confirmation.content = Возможно, к файлам в хранилище всё ещё обращаются другие программы, либо возникла иная проблема. Такие программы могут работать неправильно, а не записанные ими данные могут быть потеряны.
|
||||
# Авторазблокировка при старте (экспериментально)
|
||||
unlock.label.unlockAfterStartup = Авторазблокировка при запуске (экспериментально)
|
||||
unlock.errorMessage.unlockFailed = Ошибка разблокировки. См. подробности в файле журнала.
|
||||
unlocked.moreOptions.mount = Смонтировать диск
|
||||
unlocked.moreOptions.unmount = Извлечь диск
|
||||
upgrade.version5toX.title = Обновление версии хранилища
|
||||
upgrade.version5toX.msg = Это хранилище нужно преобразовать в новый формат. Прежде чем продолжить, убедитесь, что завершена синхронизация.
|
||||
main.createVault.nonEmptyDir.title = Ошибка создания хранилища
|
||||
@@ -116,6 +112,18 @@ settings.webdav.prefGvfsScheme.label = Схема WebDAV
|
||||
settings.volume.label = Метод монтирования*
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Хранилище успешно создано.
|
||||
unlock.successLabel.passwordChanged = Пароль успешно изменён.
|
||||
unlock.successLabel.upgraded = Обновление Cryptomator успешно выполнено.
|
||||
unlock.label.useOwnMountPath = Своя точка монтирования
|
||||
welcome.askForUpdateCheck.dialog.title = Проверка обновлений
|
||||
welcome.askForUpdateCheck.dialog.header = Включить встроенную проверку обновлений?
|
||||
welcome.askForUpdateCheck.dialog.content = Для проверки наличия обновлений Cryptomator будет получать номер текущей версии со своих серверов и показывать подсказку, что доступна более новая версия.\n\nРекомендуем включить проверку обновлений, чтобы быть уверенным, что у вас всегда новейшая версия программы, содержащая все патчи безопасности. Если вы не хотите включать проверку обновлений, то проверить наличие новой версии и загрузить её можно по адресу https\://cryptomator.org/downloads/\n\nЭтот параметр можно всегда изменить в настройках программы.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Не установлен индивидуальный путь монтирования.
|
||||
main.gracefulShutdown.dialog.title = Ошибка блокировки хранилища
|
||||
main.gracefulShutdown.dialog.header = Используемые хранилища
|
||||
main.gracefulShutdown.dialog.content = Одно или несколько хранилищ всё ещё используются другими программами. Закройте их, чтобы Cryptomator мог корректно завершить работу, и повторите попытку.\n\nЕсли это не поможет, Cryptomator может завершить работу принудительно, но с риском потери данных, и потому это не рекомендуется.
|
||||
main.gracefulShutdown.button.tryAgain = Попробовать снова
|
||||
main.gracefulShutdown.button.forceShutdown = Принудительно завершить работу
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -48,7 +48,6 @@ changePassword.errorMessage.decryptionFailed = Dešifrovanie zlyhalo.
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Zamknúť trezor
|
||||
unlocked.moreOptions.reveal = Odhaliť jednotku
|
||||
unlocked.moreOptions.copyUrl = Kopírovať WebDAV URL
|
||||
unlocked.label.revealFailed = Príkaz zlyhal
|
||||
unlocked.label.unmountFailed = Odpájanie jednotky zlyhalo
|
||||
unlocked.label.statsEncrypted = zašifrované
|
||||
@@ -89,29 +88,38 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPath = Mount path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = การถอดรหัสล
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = ล็อคกล่องข้อมูล
|
||||
unlocked.moreOptions.reveal = โชว์ไดรฟ์
|
||||
unlocked.moreOptions.copyUrl = คัดลอก WebDEV ลิ้งค์
|
||||
unlocked.label.revealFailed = คำสั่งล้มเหลว
|
||||
unlocked.label.unmountFailed = Eject ไดรว์ล้มเหลว
|
||||
unlocked.label.statsEncrypted = เข้ารหัสแล้ว
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = อัพเกรดกล่องข้อมู
|
||||
upgrade.version4to5.title = อัพเกรดกล่องข้อมูลเวอร์ชั่น 4 ไปยัง 5
|
||||
upgrade.version4to5.msg = กล่องข้อมูลนี้ต้องการอัพเกรดเป็นเวอร์ชั่นใหม่\nไฟล์เข้ารหัสจะได้รับการอัพเกรด\nกรุณารอการอัพเกรดให้เสร็จสิ้นก่อนเริ่มใช้งาน\n\nเพิ่มเติม\: วันที่ Modification ของไฟล์จะถูกเปลี่ยนเป็นเวลา ณ ปัจจุบัน
|
||||
upgrade.version4to5.err.io = อัพเกรดล้มเหลวเนื่องจากข้อยกเว้น I/O ดูรายละเอียดได้ใน Log ไฟล์
|
||||
unlock.label.mountAfterUnlock = เมาท์ไดรฟ์
|
||||
unlock.label.revealAfterMount = ไปยังไดรฟ์
|
||||
unlocked.lock.force.confirmation.title = ล็อค %1$s ล้มเหลว
|
||||
unlocked.lock.force.confirmation.header = คุณต้องการล็อคแบบ Force หรือไม่ ?
|
||||
unlocked.lock.force.confirmation.content = เนื่องจากบางโปรแกรมกำลังเรียกใช้ไฟล์ในกล่องข้อมูลอยู่ในขณะนี้ หรือเนื่องจากปัญหาอื่นๆ\n\nโปรแกรมที่เรียกใช้ไฟล์อาจทำงานได้ไม่สมบูรณ์ ข้อมูลอาจสูญหายได้
|
||||
unlock.label.unlockAfterStartup = ปลดล็อคอัตโนมัติตอนเปิดคอม (Experimental)
|
||||
unlock.errorMessage.unlockFailed = ปลดล็อคล้มเหลว ดูรายละเอียดได้ใน Log ไฟล์
|
||||
unlocked.moreOptions.mount = เมาท์ไดรฟ์
|
||||
unlocked.moreOptions.unmount = Eject ไดรฟ์
|
||||
upgrade.version5toX.title = อัพเกรดเวอร์ชั่นกล่องข้อมูล
|
||||
upgrade.version5toX.msg = กล่องข้อมูลต้องการอัพเกรดเป็นเวอร์ชั่นใหม่\nกรุณารอการอัพเกรดให้เสร็จสิ้นก่อนเริ่มใช้งาน
|
||||
main.createVault.nonEmptyDir.title = การสร้างกล่องข้อมูลล้มเหลว
|
||||
main.createVault.nonEmptyDir.header = โฟลเดอร์ที่เลือกมีไฟล์อยู่
|
||||
main.createVault.nonEmptyDir.content = โฟลเดอที่เลือกมีไฟล์อยู่ (อาจจะซ่อนอยู่)\nกล่องข้อมูลสามารถสร้างได้จากโฟลเดอร์เปล่าเท่านั้น
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPath = Mount path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Şifre çözme başarısız
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Kasayı kilitle
|
||||
unlocked.moreOptions.reveal = Sürücüyü göster
|
||||
unlocked.moreOptions.copyUrl = WebDAV URl'sini kopyala
|
||||
unlocked.label.revealFailed = Komut başarısız
|
||||
unlocked.label.unmountFailed = Sürücü çıkarma başarısız
|
||||
unlocked.label.statsEncrypted = şifrelenmiş
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPath = Mount path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Розшифрування нев
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = Заблокувати сховище
|
||||
unlocked.moreOptions.reveal = Відкрити накопичувач
|
||||
unlocked.moreOptions.copyUrl = Копіювати URL-адресу WebDAV
|
||||
unlocked.label.revealFailed = Команда невдала
|
||||
unlocked.label.unmountFailed = Вилучення диска невдале
|
||||
unlocked.label.statsEncrypted = зашифровано
|
||||
@@ -73,42 +72,51 @@ main.directoryList.remove.confirmation.content = Сховище буде вид
|
||||
upgrade.version3to4.msg = Це сховище необхідно перетворити в новий формат. Зашифровані імена папок будуть оновлені. Перш ніж продовжити, виконайте синхронізацію.
|
||||
upgrade.version3to4.err.io = Перетворення невдале через помилку введення-виведення. Дивіться деталі в файлі-звіті.
|
||||
# upgrade.fxml
|
||||
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
|
||||
unlock.label.savePassword = Save Password
|
||||
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = Delete Saved Password
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save Password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
|
||||
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
upgrade.confirmation.label = Так, я переконався, що синхронізація завершена
|
||||
unlock.label.savePassword = Зберегти пароль
|
||||
unlock.errorMessage.unauthenticVersionMac = Неможливо перевірити справжність версії MAC.
|
||||
unlocked.label.mountFailed = Не вдалося підключити диск
|
||||
unlock.savePassword.delete.confirmation.title = Видалити збережений пароль
|
||||
unlock.savePassword.delete.confirmation.header = Ви дійсно хочете видалити збережений пароль цього сховища?
|
||||
unlock.savePassword.delete.confirmation.content = Збережений пароль цього сховища буде негайно видалено з вашого системної в'язки ключів. Якщо ви хочете знову зберегти свій пароль, вам потрібно буде розблокувати свої сховище з опцією "Зберегти пароль".
|
||||
settings.debugMode.label = Режим налагодження *
|
||||
upgrade.version3dropBundleExtension.title = Оновлення 3 версії сховища (Розширення пакету)
|
||||
upgrade.version3to4.title = Оновлення сховища з версії 3 на 4
|
||||
upgrade.version4to5.title = Оновлення сховища з версії 4 на 5
|
||||
upgrade.version4to5.msg = Це сховище потрібно перетворити в більш новий формат. Зашифровані файли будуть оновлені. Будь ласка, переконайтеся, що синхронізація завершена, перш ніж продовжувати.\nПримітка. Дата зміни всіх файлів буде змінена на поточну дату/час в процесі перевторення.
|
||||
upgrade.version4to5.err.io = Перетворення не виконано із-за помилок вводу-виводу. Перегляньте деталі в файлі журналу.
|
||||
unlock.label.revealAfterMount = Відкрити Диск
|
||||
unlocked.lock.force.confirmation.title = Заблокувати %1$s не вдалося
|
||||
unlocked.lock.force.confirmation.header = Ви хочете зупинити блокування?
|
||||
unlocked.lock.force.confirmation.content = Це може бути тому, що інші програми все ще отримують доступ до файлів у сховище або через деяку іншу проблему.\nПрограми, які все ще мають доступ до файлів, можуть працювати некоректно, а дані, які ще не написані цими програмами, можуть бути втрачені.
|
||||
unlock.label.unlockAfterStartup = Авто-розблокування при Запуску (експериментальна)
|
||||
unlock.errorMessage.unlockFailed = Розблокувати не вдалося. Детальніше перегляньте файл журналу.
|
||||
upgrade.version5toX.title = Оновлення версії сховища
|
||||
upgrade.version5toX.msg = Це сховище потрібно перконвертувати в більш новий формат.\nБудь ласка, переконайтеся, що синхронізація завершена, перш ніж продовжувати.
|
||||
main.createVault.nonEmptyDir.title = Створення сховища не вдалося
|
||||
main.createVault.nonEmptyDir.header = Вибраний каталог не порожній
|
||||
main.createVault.nonEmptyDir.content = Вибрана директорія вже містить файли (можливо, приховані). Сховище можна створити лише у порожньому каталозі.
|
||||
unlock.label.mountPath = Шлях монтування
|
||||
unlock.label.mountPathButton = Застосувати
|
||||
settings.webdav.port.label = Порт WebDAV
|
||||
settings.webdav.port.prompt = 0 \= автовибір
|
||||
settings.webdav.port.apply = Застосувати
|
||||
settings.webdav.prefGvfsScheme.label = Схема WebDAV\n
|
||||
settings.volume.label = Метод монтування*
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = Сховище успішно створено.
|
||||
unlock.successLabel.passwordChanged = Пароль успішно змінено.
|
||||
unlock.successLabel.upgraded = Cryptomator був успішно оновлений.
|
||||
unlock.label.useOwnMountPath = Використати Користувацьку Точку Монтування
|
||||
welcome.askForUpdateCheck.dialog.title = Перевірити оновлення
|
||||
welcome.askForUpdateCheck.dialog.header = Включити інтегровану перевірку оновлень?
|
||||
welcome.askForUpdateCheck.dialog.content = Щоб перевірити наявність оновлень, Cryptomator буде завантажувати поточну версію з серверів Cryptomator і показувати підказку, якщо доступна нова версія.\nМи рекомендуємо ввімкнути перевірку оновлень, щоб завжди бути впевненим, що ви встановили найновішу версію Cryptomator з усіма оновленнями безпеки. Якщо ви не ввімкнули перевірку оновлень, ви можете перевірити та завантажити поточну версію за адресою https\://cryptomator.org/downloads/.\nВи можете будь-коли змінити це налаштування.
|
||||
settings.volume.dokany = Віртуальна файлова система
|
||||
unlock.errorMessage.invalidMountPath = Користувацьку опцію монтування не встановлено.
|
||||
main.gracefulShutdown.dialog.title = Блокування сховищ(а) не вдалося
|
||||
main.gracefulShutdown.dialog.header = Сховища(е) використовуються
|
||||
main.gracefulShutdown.dialog.content = Один або декілька сховищ все ще використовуються іншими програмами. Закрийте їх, щоб дозволити Cryptomator безпечно завершити роботу, а потім повторіть спробу.\nЯкщо це не спрацьовує, Cryptomator може примусово завершити роботу, але це може призвести до втрати даних, це нелогічно та не рекомендується.
|
||||
main.gracefulShutdown.button.tryAgain = Спробуйте ще раз
|
||||
main.gracefulShutdown.button.forceShutdown = Примусово завершити роботу
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = 解密失败
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = 锁定资料库
|
||||
unlocked.moreOptions.reveal = 打开驱动器
|
||||
unlocked.moreOptions.copyUrl = 复制 WebDAV 网址
|
||||
unlocked.label.revealFailed = 指令无法执行
|
||||
unlocked.label.unmountFailed = 无法弹出驱动器
|
||||
unlocked.label.statsEncrypted = 已加密
|
||||
@@ -87,29 +86,38 @@ upgrade.version3to4.title = 升级资料库到第四版
|
||||
upgrade.version4to5.title = 升级资料库到第五版
|
||||
upgrade.version4to5.msg = 此资料库需要升级至最新版本,\n已加密的数据将被更新。\n请确保同步完成后再继续操作。
|
||||
upgrade.version4to5.err.io = 升级因 I/O 错误失败。请查看日志来获得详细信息。
|
||||
unlock.label.mountAfterUnlock = 装载驱动器
|
||||
unlock.label.revealAfterMount = 显示驱动器
|
||||
unlocked.lock.force.confirmation.title = 无法锁定 %1$s
|
||||
unlocked.lock.force.confirmation.header = 要强制锁定吗?
|
||||
unlocked.lock.force.confirmation.content = 此错误可能是因为其他应用程序仍在使用此资料库中的文件,或遇到了其他问题。\n\n如强制锁定,正在使用文件的应用程序可能会出错并丢失部分还没有保存的资料。
|
||||
unlock.label.unlockAfterStartup = 启动时自动解锁(试验功能)
|
||||
unlock.errorMessage.unlockFailed = 无法解锁。请查看日志来获得详细信息。
|
||||
unlocked.moreOptions.mount = 装载驱动器
|
||||
unlocked.moreOptions.unmount = 弹出驱动器
|
||||
upgrade.version5toX.title = 资料库版本升级
|
||||
upgrade.version5toX.msg = 此资料库需要升级至最新版本,\n请确保同步完成后再继续操作。
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
main.createVault.nonEmptyDir.title = 创建资料库失败
|
||||
main.createVault.nonEmptyDir.header = 选择的目录不为空
|
||||
main.createVault.nonEmptyDir.content = 选择的目录含有文件(可能是隐藏的)。资料库只能创建在空目录
|
||||
unlock.label.mountPath = 挂载路径
|
||||
unlock.label.mountPathButton = 设定
|
||||
settings.webdav.port.label = webDav端口
|
||||
settings.webdav.port.prompt = 0\=自动选择WebDav端口
|
||||
settings.webdav.port.apply = 设定
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV计划
|
||||
settings.volume.label = 首选卷类型
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = 资料库成功创建
|
||||
unlock.successLabel.passwordChanged = 密码成功更改
|
||||
unlock.successLabel.upgraded = Cryptomator 成功升级
|
||||
unlock.label.useOwnMountPath = 无效的挂载点
|
||||
welcome.askForUpdateCheck.dialog.title = 检查更新
|
||||
welcome.askForUpdateCheck.dialog.header = 启用更新检查?
|
||||
welcome.askForUpdateCheck.dialog.content = 启用检查更新,Cryptomator将从Cryptomator服务器获取当前版本,并在有新版本时提示。\n我们建议您启用更新检查,以确保安装了最新版的Cryptomator,并安装了所有安全补丁。如果您未启用更新检查,则需要您自己到https\://cryptomator.org/downloads/ 检查并下载最新版本。\n你可以随时在设置中更改此设置。
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = 未设置单独的挂载路径
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -1,53 +1,52 @@
|
||||
app.name = Cryptomator
|
||||
# main.fxml
|
||||
main.emptyListInstructions = 按這裡新增檔案庫
|
||||
main.directoryList.contextMenu.remove = 從清單移除
|
||||
main.directoryList.contextMenu.changePassword = 變更密碼
|
||||
main.addDirectory.contextMenu.new = 建立新的檔案庫
|
||||
main.addDirectory.contextMenu.open = 打開現有的檔案庫
|
||||
main.emptyListInstructions = 撳呢度新增檔案夾萬
|
||||
main.directoryList.contextMenu.remove = 由清單移除
|
||||
main.directoryList.contextMenu.changePassword = 改密碼
|
||||
main.addDirectory.contextMenu.new = 建立新嘅檔案夾萬
|
||||
main.addDirectory.contextMenu.open = 開啓現有嘅檔案夾萬
|
||||
# welcome.fxml
|
||||
welcome.checkForUpdates.label.currentlyChecking = 檢查更新...
|
||||
welcome.newVersionMessage = 版本%1$s可下載。這是%2$s。
|
||||
welcome.newVersionMessage = 可以下載版本%1$s。呢個係%2$s。
|
||||
# initialize.fxml
|
||||
initialize.label.password = 密碼
|
||||
initialize.label.retypePassword = 重新輸入密碼
|
||||
initialize.button.ok = 建立檔案庫
|
||||
initialize.messageLabel.alreadyInitialized = 已初始化檔案庫
|
||||
initialize.messageLabel.initializationFailed = 無法初始化檔案庫。取得詳細資訊,請查看紀錄。
|
||||
initialize.button.ok = 建立檔案夾萬
|
||||
initialize.messageLabel.alreadyInitialized = 檔案夾萬已初始化
|
||||
initialize.messageLabel.initializationFailed = 初始化唔到檔案夾萬。詳細資訊請睇記錄檔。
|
||||
# notfound.fxml
|
||||
notfound.label = 無法找到檔案庫。已經移置別的地方?
|
||||
notfound.label = 搵唔到檔案夾萬。係咪轉移咗去其他地方?
|
||||
# upgrade.fxml
|
||||
upgrade.button = 升級檔案庫
|
||||
upgrade.version3dropBundleExtension.msg = 這個檔案庫需要被轉移到新的格式。\n"%1$s"將會重新命名為"%2$s"。\n在進行之前,請確認同步已完成。
|
||||
upgrade.button = 升級檔案夾萬
|
||||
upgrade.version3dropBundleExtension.msg = 這個檔案夾萬要轉換做新格式。\n"%1$s"將會改名為"%2$s"。\n請確認檔案同步完再繼續。
|
||||
upgrade.version3dropBundleExtension.err.alreadyExists = 自動轉移失敗。\n"%s"已存在。
|
||||
# unlock.fxml
|
||||
unlock.label.password = 密碼
|
||||
unlock.label.mountName = 磁碟名稱
|
||||
unlock.label.mountName = 磁碟名
|
||||
unlock.label.winDriveLetter = 磁碟代號
|
||||
unlock.label.downloadsPageLink = 所有的Cryptomator版本
|
||||
unlock.label.downloadsPageLink = 所有Cryptomator版本
|
||||
unlock.label.advancedHeading = 進階選項
|
||||
unlock.button.unlock = 解鎖檔案庫
|
||||
unlock.button.unlock = 解鎖檔案夾萬
|
||||
unlock.button.advancedOptions.show = 更多選項
|
||||
unlock.button.advancedOptions.hide = 更少選項
|
||||
unlock.choicebox.winDriveLetter.auto = 自動指定
|
||||
unlock.errorMessage.wrongPassword = 錯誤的密碼
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 不支援的檔案庫。這個檔案庫是由舊版本的Cryptomator所建立的。
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 不支援的檔案庫。這個檔案庫是由新版本的Cryptomator所建立的。
|
||||
unlock.messageLabel.startServerFailed = 啟動WebDAV的伺服器失敗。
|
||||
unlock.errorMessage.wrongPassword = 密碼錯誤
|
||||
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 呢個檔案夾萬係由舊版Cryptomator創建嘅,並唔支援。
|
||||
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 呢個檔案夾萬係由新版Cryptomator創建嘅,並唔支援。
|
||||
unlock.messageLabel.startServerFailed = 啓動唔到WebDAV嘅伺服器。
|
||||
# change_password.fxml
|
||||
changePassword.label.oldPassword = 舊密碼
|
||||
changePassword.label.newPassword = 新密碼
|
||||
changePassword.label.retypePassword = 重新輸入密碼
|
||||
changePassword.label.downloadsPageLink = 所有的Cryptomator版本
|
||||
changePassword.button.change = 變更密碼
|
||||
changePassword.errorMessage.wrongPassword = 錯誤的密碼
|
||||
changePassword.label.downloadsPageLink = 所有Cryptomator版本
|
||||
changePassword.button.change = 改密碼
|
||||
changePassword.errorMessage.wrongPassword = 密碼錯誤
|
||||
changePassword.errorMessage.decryptionFailed = 解密失敗
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = 鎖住檔案庫
|
||||
unlocked.button.lock = 鎖起檔案夾萬
|
||||
unlocked.moreOptions.reveal = 打開磁碟
|
||||
unlocked.moreOptions.copyUrl = 複製WebDAV的網址
|
||||
unlocked.label.revealFailed = 指令錯誤
|
||||
unlocked.label.unmountFailed = 插入磁碟錯誤
|
||||
unlocked.label.unmountFailed = 移除磁碟錯誤
|
||||
unlocked.label.statsEncrypted = 加密的
|
||||
unlocked.label.statsDecrypted = 解密的
|
||||
unlocked.ioGraph.yAxis.label = 傳輸量(MIB / S)
|
||||
@@ -56,9 +55,9 @@ settings.version.label = 版本%s
|
||||
settings.checkForUpdates.label = 檢查更新
|
||||
settings.requiresRestartLabel = * Cryptomator需要更新
|
||||
# tray icon
|
||||
tray.menu.open = 打開
|
||||
tray.menu.open = 開啓
|
||||
tray.menu.quit = 離開
|
||||
tray.infoMsg.title = 仍然在執行
|
||||
tray.infoMsg.title = 仲運作緊
|
||||
tray.infoMsg.msg = Cryptomator仍然在運作。從工具列的圖示點選離開。
|
||||
tray.infoMsg.msg.osx = Cryptomator仍然在運作。從選單列上點選離開。
|
||||
initialize.messageLabel.passwordStrength.0 = 非常弱的
|
||||
@@ -76,8 +75,8 @@ upgrade.version3to4.err.io = 由於I/O的例外,轉移失敗。取得詳細資
|
||||
upgrade.confirmation.label = 是的,請確認同步已完成。
|
||||
unlock.label.savePassword = 儲存密碼
|
||||
unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。
|
||||
unlocked.label.mountFailed = Connecting drive failed
|
||||
unlock.savePassword.delete.confirmation.title = Delete Saved Password
|
||||
unlocked.label.mountFailed = 連接唔到磁碟
|
||||
unlock.savePassword.delete.confirmation.title = 刪除儲存咗嘅密碼
|
||||
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
|
||||
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save Password" option enabled.
|
||||
settings.debugMode.label = Debug Mode *
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
|
||||
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
|
||||
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
|
||||
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
|
||||
unlock.label.mountAfterUnlock = Mount Drive
|
||||
unlock.label.revealAfterMount = Reveal Drive
|
||||
unlocked.lock.force.confirmation.title = Locking of %1$s failed
|
||||
unlocked.lock.force.confirmation.header = Do you want to force locking?
|
||||
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
|
||||
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
|
||||
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
|
||||
unlocked.moreOptions.mount = Mount Drive
|
||||
unlocked.moreOptions.unmount = Eject Drive
|
||||
upgrade.version5toX.title = Vault Version Upgrade
|
||||
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPath = Mount path
|
||||
unlock.label.mountPathButton = Apply
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.label.useOwnMountPath = Use Custom Mount Point
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = 解密失敗
|
||||
# unlocked.fxml
|
||||
unlocked.button.lock = 鎖住檔案庫
|
||||
unlocked.moreOptions.reveal = 打開磁碟
|
||||
unlocked.moreOptions.copyUrl = 複製 WebDAV 網址
|
||||
unlocked.label.revealFailed = 指令錯誤
|
||||
unlocked.label.unmountFailed = 插入磁碟錯誤
|
||||
unlocked.label.statsEncrypted = 加密的
|
||||
@@ -86,29 +85,38 @@ upgrade.version3to4.title = 檔案庫版本 3 到 4 升級
|
||||
upgrade.version4to5.title = 檔案庫版本 4 到 5 升級
|
||||
upgrade.version4to5.msg = 這個檔案庫需要被遷移到新的格式。\n加密的檔案將會被更新。\n在處理前,請確保同步已經完成。\n\n註記:所有檔案的更改日期將會被變更為目前處理的日期/時間。
|
||||
upgrade.version4to5.err.io = 由於 I/O 異常導致遷移失敗。詳細請見日誌檔。
|
||||
unlock.label.mountAfterUnlock = 掛載磁碟
|
||||
unlock.label.revealAfterMount = 打開磁碟
|
||||
unlocked.lock.force.confirmation.title = %1$s 鎖定失敗
|
||||
unlocked.lock.force.confirmation.header = 你想要強制鎖定?
|
||||
unlocked.lock.force.confirmation.content = 這可能是因為其他軟體仍在存取這個檔案庫,或者發生其他問題。\n\n仍然在存取檔案的軟體可能無法正常運作,而且會造成寫入的資料遺失。
|
||||
unlock.label.unlockAfterStartup = 啟動時,自動解鎖(實驗中)
|
||||
unlock.errorMessage.unlockFailed = 解鎖失敗。詳請查看日誌檔。
|
||||
unlocked.moreOptions.mount = 掛載硬碟
|
||||
unlocked.moreOptions.unmount = 退出硬碟
|
||||
upgrade.version5toX.title = 檔案庫版本升級
|
||||
upgrade.version5toX.msg = 這個檔案庫需要轉移到新的格式。\n進行前,請確認已經完成所有同步。
|
||||
main.createVault.nonEmptyDir.title = Creating vault failed
|
||||
main.createVault.nonEmptyDir.header = Chosen directory is not empty
|
||||
main.createVault.nonEmptyDir.title = 建立vault時發生錯誤
|
||||
main.createVault.nonEmptyDir.header = 選擇的資料夾並不是空的
|
||||
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
|
||||
unlock.label.mountPath = Mount Path
|
||||
unlock.label.mountPathButton = Apply
|
||||
unlock.label.mountPath = 掛載路徑
|
||||
unlock.label.mountPathButton = 套用
|
||||
settings.webdav.port.label = WebDAV Port
|
||||
settings.webdav.port.prompt = 0 \= Choose automatically
|
||||
settings.webdav.port.apply = Apply
|
||||
settings.webdav.port.prompt = 0 \= 自動選擇
|
||||
settings.webdav.port.apply = 套用
|
||||
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
|
||||
settings.volume.label = Mount-Methode *
|
||||
settings.volume.label = Preferred Volume Type
|
||||
settings.volume.webdav = WebDAV
|
||||
settings.volume.fuse = FUSE
|
||||
unlock.successLabel.vaultCreated = Vault was successfully created.
|
||||
unlock.successLabel.passwordChanged = Password was successfully changed.
|
||||
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
|
||||
unlock.successLabel.vaultCreated = 成功建立vault
|
||||
unlock.successLabel.passwordChanged = 密碼變更成功
|
||||
unlock.successLabel.upgraded = Cryptomator成功的更新了
|
||||
unlock.label.useOwnMountPath = 自訂掛載點
|
||||
welcome.askForUpdateCheck.dialog.title = Update check
|
||||
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
|
||||
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
|
||||
settings.volume.dokany = Dokany
|
||||
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
|
||||
main.gracefulShutdown.dialog.title = Locking vault(s) failed
|
||||
main.gracefulShutdown.dialog.header = Vault(s) in use
|
||||
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
|
||||
main.gracefulShutdown.button.tryAgain = Try again
|
||||
main.gracefulShutdown.button.forceShutdown = Force shutdown
|
||||
unlock.pendingMessage.unlocking = Unlocking vault...
|
||||
BIN
main/ui/src/main/resources/tray_icon_unlocked.png
Normal file
BIN
main/ui/src/main/resources/tray_icon_unlocked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 699 B |
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_black.png
Normal file
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 353 B |
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_black@2x.png
Normal file
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_black@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 705 B |
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_white.png
Normal file
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 378 B |
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_white@2x.png
Normal file
BIN
main/ui/src/main/resources/tray_icon_unlocked_mac_white@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 760 B |
@@ -7,15 +7,14 @@ import org.mockito.Mockito;
|
||||
|
||||
public class PasswordStrengthUtilTest {
|
||||
|
||||
@Test
|
||||
public void testLongPasswordsWillBeRatedAsStrong() {
|
||||
@Test(timeout = 5000)
|
||||
public void testLongPasswords() {
|
||||
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(Localization.class));
|
||||
StringBuilder longPwBuilder = new StringBuilder();
|
||||
for (int i = 0; i < 101; i++) {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
longPwBuilder.append('x');
|
||||
}
|
||||
int strength = util.computeRate(longPwBuilder.toString());
|
||||
Assert.assertEquals(4, strength);
|
||||
util.computeRate(longPwBuilder.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user