Compare commits

...
137 Commits
Author SHA1 Message Date
Sebastian Stenzel 5e7cea216d Merge branch 'release/1.4.0-beta1' 2018-04-06 16:54:12 +02:00
Sebastian Stenzel 6d91992102 preparing 1.4.0-beta1 2018-04-06 16:31:08 +02:00
Sebastian Stenzel 5a23ee0be6 updated dependencies 2018-04-06 16:29:40 +02:00
Sebastian Stenzel 31e186dd15 bumped fuse version 2018-04-05 23:24:47 +02:00
Sebastian Stenzel c7beb4a93c Default to FUSE. Use WebDAV as Backup, if FUSE isn't supported 2018-04-03 17:32:26 +02:00
Sebastian Stenzel 6aff94a8f8 Merge tag '1.3.5' into develop
1.3.5

# Conflicts:
#	main/ant-kit/pom.xml
#	main/commons/pom.xml
#	main/jacoco-report/pom.xml
#	main/keychain/pom.xml
#	main/launcher/pom.xml
#	main/pom.xml
#	main/uber-jar/pom.xml
#	main/ui/pom.xml
2018-04-03 10:41:43 +02:00
Sebastian Stenzel 273f6907c9 Merge branch 'hotfix/1.3.5' 2018-04-03 10:41:03 +02:00
Sebastian Stenzel 95df963913 Updated CryptoFS to version 1.5.1, fixing #643 2018-04-03 10:32:40 +02:00
infeo 13c5e2470b UI improvement: adding checkbox before textbox for entering own mountpath is given 2018-03-30 12:43:50 +02:00
Sebastian Stenzel 2341440ed9 Merge tag '1.3.4' into develop
1.3.4

# Conflicts:
#	main/ant-kit/pom.xml
#	main/commons/pom.xml
#	main/jacoco-report/pom.xml
#	main/keychain/pom.xml
#	main/launcher/pom.xml
#	main/pom.xml
#	main/uber-jar/pom.xml
#	main/ui/pom.xml
2018-03-29 13:26:13 +02:00
Sebastian Stenzel 558f4be945 Merge branch 'hotfix/1.3.4' 2018-03-29 13:25:44 +02:00
Sebastian Stenzel d63735df1a bumped version to 1.3.4 2018-03-29 13:24:12 +02:00
Sebastian Stenzel 8be9cbbab7 Merge tag '1.3.4' into develop
1.3.4

# Conflicts:
#	.travis.yml
2018-03-29 12:58:53 +02:00
Sebastian Stenzel 191d7561f0 Merge branch 'hotfix/1.3.4' 2018-03-29 12:58:03 +02:00
Sebastian Stenzel 49a6fe9571 updated api key for github releases 2018-03-29 12:57:18 +02:00
Sebastian Stenzel 8b85fa5928 Merge tag '1.3.4' into develop
1.3.4

# Conflicts:
#	.travis.yml

[ci skip]
2018-03-29 12:42:39 +02:00
Sebastian Stenzel 2695979ae2 Merge branch 'hotfix/1.3.4' 2018-03-29 12:40:11 +02:00
Sebastian Stenzel f2212169be updated api key for github releases 2018-03-29 12:39:32 +02:00
Sebastian Stenzel 5898a4d584 Merge tag '1.3.4' into develop
1.3.4

# Conflicts:
#	main/pom.xml
2018-03-29 12:17:34 +02:00
Sebastian Stenzel 42b5b2663e Merge branch 'hotfix/1.3.4' 2018-03-29 12:16:57 +02:00
Sebastian Stenzel a0a867474b updated dependencies 2018-03-29 12:16:37 +02:00
Sebastian Stenzel c98f7f8574 fixes #645 2018-03-29 12:06:49 +02:00
Sebastian Stenzel fae2e19b96 try to set icon and window title on Linux. Might still be buggy, see https://bugs.openjdk.java.net/browse/JDK-8092837 2018-03-28 17:59:46 +02:00
Sebastian Stenzel 45548a0023 jq is already installed on Travis container environment 2018-03-27 17:48:28 +02:00
Sebastian Stenzel 8edd5326fa fixed if..elif..fi statement 2018-03-27 17:42:57 +02:00
Sebastian Stenzel 1d178674ce updated travis config 2018-03-27 17:39:09 +02:00
Sebastian Stenzel 7593d5cd40 using commit hash instead of timestamp for snapshot versions 2018-03-27 17:26:07 +02:00
Sebastian Stenzel 9e8f88f000 fixed ci build 2018-03-27 16:49:48 +02:00
Sebastian Stenzel e1eafbc838 always delete continuous release from github releases
re-create it if untagged, otherwise create regular release
2018-03-27 16:42:01 +02:00
Sebastian Stenzel f2107954b3 trying to force github releases to overwrite existing continuous release 2018-03-27 14:12:57 +02:00
Sebastian Stenzel db3dabe3c5 clean target dir before re-building for deployment 2018-03-27 14:03:37 +02:00
Sebastian Stenzel 76f69dec34 fixing travis config 2018-03-27 13:53:44 +02:00
Sebastian Stenzel 1b130ab58e updated settings.xml, caching versions-maven-plugin 2018-03-27 13:17:43 +02:00
Sebastian Stenzel a12e2ae6cd attempt to fix use of org.codehaus.mojo:versions-maven-plugin 2018-03-27 12:17:32 +02:00
Sebastian Stenzel 7441f67b03 fixing syntax errors 2018-03-27 11:51:56 +02:00
Sebastian Stenzel d02d521856 fixing syntax errors 2018-03-27 11:46:22 +02:00
Sebastian Stenzel e6dd14d0e5 Enabling continuous releases 2018-03-27 11:34:20 +02:00
infeo e257d8e497 implementing the per-vault mount-directory-creation and just removing the id from the volume name 2018-03-23 17:05:15 +01:00
Tobias Hagemann 2d6d3084b0 updated localizations, added czech [ci skip] 2018-03-23 14:33:46 +01:00
Sebastian Stenzel 4fffc63869 new antkit for upcoming AppImage build (see issue #469) 2018-03-23 12:57:04 +01:00
Sebastian Stenzel ce457ae20e No longer selecting first vault by default, when showing welcome screen after start of application. 2018-03-23 06:51:24 +01:00
Sebastian Stenzel 5b9efcc16f Merge commit 'cc40d05e44780cd52757e8afa0a917dce4f5a377' into develop
fixes #79
2018-03-23 06:47:46 +01:00
Sebastian Stenzel 28001710b3 Merge commit '8ec2b10a4d546b148ec2d6f75b284a636b2b9edf' into develop
# Conflicts:
#	main/ui/src/main/java/org/cryptomator/ui/model/Vault.java

fixes #627
2018-03-23 06:23:04 +01:00
Sebastian Stenzel 32e81796ae Merge commit '68445befeb17cee00c3b7d050edd0404ae3089d2' into develop 2018-03-23 06:16:31 +01:00
infeo 68445befeb simplifying the state enum to prevent illegal states 2018-03-22 17:47:43 +01:00
infeo da31a9d2a0 integrating changes proposed by comments in commit e808db51a5 2018-03-22 15:21:11 +01:00
Sebastian Stenzel 9b3167c886 added dropdown css for mac 2018-03-17 19:11:06 +01:00
Sebastian Stenzel 7c1a0b5fdf Renamed nioAdapterImpl to volumeImpl. 2018-03-17 16:08:58 +01:00
Sebastian Stenzel a666c80ef5 only initialize jetty on demand 2018-03-17 15:54:32 +01:00
Sebastian Stenzel 2610ef4645 Using enum instead of string to choose between FUSE and WebDAV 2018-03-17 15:44:27 +01:00
Sebastian StenzelandGitHub 357f659c8d Update README.md
[ci skip]
2018-03-13 12:13:16 +01:00
Sebastian Stenzel 19225c058d Include logback.xml in antkit, so .deb, .rpm and ppa releases can use it. fixes #650 2018-03-13 11:52:48 +01:00
Sebastian Stenzel f1ee991d07 code format + exception handling 2018-03-06 16:31:08 +01:00
infeo 562daf990f reactivating reveal method 2018-03-06 12:32:23 +01:00
Sebastian Stenzel 19cd0d70e7 Merge branch 'feature/fuse-integration' into develop 2018-03-06 11:46:13 +01:00
Sebastian Stenzel d38b488ee0 using customized maven settings.xml 2018-03-06 11:42:56 +01:00
Sebastian Stenzel 84d6f11be2 Merge branch 'develop' into feature/fuse-integration
# Conflicts:
#	main/commons/pom.xml
#	main/pom.xml
2018-03-06 11:34:41 +01:00
Sebastian Stenzel b3cf7eee16 updated fuse-adapter version 2018-03-06 11:26:53 +01:00
Sebastian Stenzel 9e5e14e462 Merge commit 'bfd8918e6ab3d0a01e9326eb35ce53203876b746' into develop 2018-03-02 12:46:05 +01:00
infeo b165f41c6b fixed test 2018-03-01 23:31:48 +01:00
infeo 41358e6715 fixing issue using an individual mountPath, renaming mountPath-Property, fixing gui issues with mountPath, 2018-03-01 23:27:01 +01:00
infeo c8387c7e3c adding "_ID-" suffix to mount name 2018-03-01 15:27:26 +01:00
infeo 8ace293701 fixing issue in the default vault path (missing leading '/') 2018-03-01 15:24:43 +01:00
infeo f5a08f05c1 fixing visibillity bug in settings of webdav properties shown when fuse is selected 2018-03-01 14:46:37 +01:00
infeo 9707d951d6 fixing a renaming issue 2018-03-01 14:39:12 +01:00
infeo 242b1e92a3 renaming NioAdapter-Interface to Volume to prevent confusing to FUSE-project 2018-03-01 14:35:03 +01:00
infeo 3bc7df9e83 moving the nioAdapterImpl to the commons package 2018-03-01 14:31:49 +01:00
infeo f774829fb1 Pushing FuseEnvironment to other project, using fuseMount now in FuseNioAdapter 2018-02-27 15:38:25 +01:00
Sebastian Stenzel bfd8918e6a updated pom.xml files 2018-02-26 18:33:51 +01:00
Sebastian Stenzel 3989316269 replaced org.apache.httpcomponents:httpclient by jdk.incubator.httpclient (will become official standard in jdk10) 2018-02-23 18:21:38 +01:00
infeo d0d83c6833 removing defaultMountDir from the settings 2018-02-19 23:14:28 +01:00
infeo c957f93ce6 activate reveal-method in vault again 2018-02-05 21:22:35 +01:00
infeo b069a16f0c introduce new FuseEnvironment Interface such that the fuseNioAdapter gets os-dependent information from it 2018-02-05 21:20:29 +01:00
infeo bf637f8361 reactivate reveal()-method of the vault 2018-02-04 00:12:18 +01:00
infeo a2f6a85334 extended settingstest to check new setting-attributes 2018-02-03 22:18:28 +01:00
infeo 8a359704ca removed redundant maven dependency 2018-02-03 22:16:03 +01:00
infeo e3b9601721 fixing a general setting not showing up on Mac OS 2018-02-03 17:42:48 +01:00
infeo d170e87c1b integration of the fuseNioAdapter, including all the gui (controller & fxml) and settings wiring. english localization fitted and enriched for fuse 2018-02-03 17:26:59 +01:00
infeo 39d1d9c561 adapted vault class to nioAdapter Interface (and some other classes) 2018-02-03 17:15:51 +01:00
infeo 2914af5f7b reformatting & removing unused imports 2018-02-03 17:02:05 +01:00
infeo fa10a92fa4 commit of the webDavNioAdapter 2018-02-03 16:44:07 +01:00
infeo 1e7478a89f commit of the nioAdapter Interface, implementation enum and the commandFailedException 2018-02-03 16:43:33 +01:00
Marc Stammerjohann 8ec2b10a4d #627: refactor adding trailing slash to copied WebDAV URL 2018-01-30 20:05:01 +01:00
Marc Stammerjohann 2001e768d4 add trailing slash when WebDAV Url gets copied to the clipboard 2018-01-29 11:23:07 +01:00
Sebastian Stenzel 79fd17250b updated dependency 2018-01-06 08:07:35 +01:00
Sebastian Stenzel b8ee19b395 fixing use of desktop features on headless platform 2017-12-30 21:05:01 +01:00
Sebastian Stenzel 08cfcffa72 updated CI config 2017-12-30 20:49:25 +01:00
Sebastian Stenzel 9e82739c16 fixed dependency version 2017-12-30 20:22:59 +01:00
Sebastian Stenzel 6534242275 updated dependencies and CI config 2017-12-30 20:19:27 +01:00
Marc Stammerjohann cc40d05e44 #79: replace shortcut with CRTL + NUM 2017-12-22 12:53:53 +01:00
Marc Stammerjohann 5fcbe7eff1 #79: add shortcut to navigate through vaults
* CTRL + UP
* CTRL + DOWN
2017-12-21 14:00:51 +01:00
Sebastian Stenzel 4be842aff5 first attempt of building Cryptomator with jdk9 2017-12-20 18:42:16 +01:00
Marc Stammerjohann e808db51a5 #114: show success message
* after creating a vault
* after changing password
* after upgrade
2017-12-20 15:50:31 +01:00
Sebastian Stenzel 8e1bb121bb Merge branch 'release/1.3.3' into develop
[ci skip]
2017-11-28 00:33:08 +01:00
Sebastian Stenzel 355c1934f9 Merge branch 'release/1.3.3' 2017-11-28 00:32:22 +01:00
Sebastian Stenzel b47ced1173 Preparing 1.3.3 2017-11-28 00:04:11 +01:00
Sebastian Stenzel a66e08ee9b No longer using Files.isRegularFile(), fixing "add existing vault located on OneDrive's FoD" 2017-11-27 16:20:35 +01:00
Sebastian Stenzel ad27094d63 Merge branch 'release/1.3.2' into develop
Fixes #554, fixes #542
2017-11-25 17:29:39 +01:00
Sebastian Stenzel 0be97b309b Merge branch 'release/1.3.2' 2017-11-25 17:27:51 +01:00
Sebastian Stenzel b8de68bf3b Preparing 1.3.2 2017-11-25 17:03:24 +01:00
Sebastian Stenzel f9dba09003 more password field focus fixes 2017-11-25 16:37:51 +01:00
Sebastian Stenzel a428e62891 more password field focus fixes 2017-11-24 22:01:31 +01:00
Sebastian Stenzel 424ea8429c focusing password fields on a few more occasions 2017-11-24 21:22:59 +01:00
Sebastian Stenzel a52adc1871 request focus on password field after selecting a vault 2017-11-24 20:16:16 +01:00
Sebastian Stenzel 08d5335b74 unwobblyfied win theme (focus border) 2017-11-24 20:15:07 +01:00
Sebastian Stenzel 8741c64b86 updated dependencies 2017-11-24 20:14:38 +01:00
Sebastian Stenzel b64f7cc7a8 Reverting commit 296848b41e, reopen #542 2017-11-23 12:48:57 +01:00
Sebastian Stenzel f84760746f Updated localizations, added Thai 2017-11-23 12:08:22 +01:00
armin 296848b41e fixes #542 2017-11-21 16:54:08 +01:00
Sebastian Stenzel 51e6ee5be5 fixes #592 2017-11-20 17:45:05 +01:00
armin 9d5609b129 Added highlighting of focused UI elements in windows and linux, for mac it is still missing (see issue #547) 2017-11-20 15:32:24 +01:00
armin e18d62d57f closes #547 2017-11-17 23:54:00 +01:00
Markus Kreusch 9ff710ddf5 Forcing RMI to use sotimeout set by socket factory 2017-11-16 15:29:11 +01:00
Sebastian Stenzel 02f3f5ad53 fixed log message [ci skip] 2017-11-16 14:56:16 +01:00
Sebastian Stenzel 40caba847b Removes ipc port file after shutdown, reduced so timeout for rmi clients 2017-11-16 14:54:54 +01:00
Sebastian Stenzel 467e242df4 Merge branch 'develop' of https://github.com/cryptomator/cryptomator into develop 2017-11-14 18:14:01 +01:00
Sebastian Stenzel a7c42c3d59 Removed use of Files.isRegularFile from UI module, references #592 2017-11-14 18:12:22 +01:00
Markus Kreusch ecdd3bc5ec Fixes #600 2017-11-10 15:04:21 +01:00
armin 46cab2ef9a Merge branch 'develop' of https://github.com/cryptomator/cryptomator into develop 2017-11-06 13:55:42 +01:00
Sebastian Stenzel a7b036d441 fixes #598 2017-11-02 11:16:41 +01:00
armin 17bbd9161f adapted project-files such that project can be used with intellij IDEA IDE 2017-10-24 18:04:19 +02:00
Sebastian Stenzel a850e8b816 Added unit tests for vault format "3 to 4" migration 2017-10-19 13:10:29 +02:00
Sebastian Stenzel 95b8240a21 fixed vault migration version 3 to 4: conflicting .lng files are now properly migrated 2017-10-18 12:35:20 +02:00
Sebastian Stenzel 69d379d03b fixes #583 2017-10-18 12:34:53 +02:00
Sebastian StenzelandGitHub 1b9951e90e Merge pull request #586 from hodyroff/patch-1
Add ownCloud
2017-09-27 16:21:57 +02:00
hodyroffandGitHub e62e9a1dff Add ownCloud
Cryptomator is used by many ownCloud users and the interview and installation guidance was well received.
2017-09-27 15:54:08 +02:00
Sebastian StenzelandGitHub 6d1989bbfe Merge pull request #580 from swiesend/develop
Hide tmp file under Linux
2017-09-12 12:28:27 +02:00
swiesend c41973a8d6 Hide tmp file under Linux 2017-09-12 11:31:31 +02:00
Sebastian Stenzel f84bb4710f Updated webdav-nio-adapter to 1.0.0 2017-08-16 21:06:28 +02:00
Tobias Hagemann d1a9233557 fixed #567: added drag & drop support for password fields 2017-08-07 11:04:44 +02:00
Tobias Hagemann 1a73f84d83 updated issue template [ci skip] 2017-08-03 14:15:39 +02:00
Sebastian Stenzel 36cf3c2283 fixes #546, fixes #557 2017-07-26 16:17:02 +02:00
Marc Stammerjohann 091fab90ee fix english typo [ci skip] 2017-07-25 16:01:02 +08:00
Sebastian StenzelandGitHub d81bf2e301 Update README.md
This is the 1000th commit! 🎉
[ci skip]
2017-07-22 01:29:08 +02:00
Tobias Hagemann cd3cf3da0e updated issue template [ci skip] 2017-07-21 16:11:04 +02:00
Tobias Hagemann 3e961dabdd updated readme [ci skip] 2017-07-21 15:50:27 +02:00
Sebastian Stenzel dde7d263b9 Merge branch 'release/1.3.1' into develop 2017-07-04 15:41:56 +02:00
100 changed files with 2557 additions and 1387 deletions
+4
View File
@@ -17,3 +17,7 @@ test-output/
out/ out/
.idea_modules/ .idea_modules/
*.iws *.iws
*.iml
# Temporary file created by test launcher
main/launcher/.ipcPort.tmp
+56 -13
View File
@@ -1,8 +1,10 @@
language: java language: java
sudo: required sudo: false
dist: trusty
jdk: jdk:
- oraclejdk8 - oraclejdk9
branches:
except:
- continuous # To avoid infinite loops, as this tag is created by this Travis config
cache: cache:
directories: directories:
- $HOME/.m2 - $HOME/.m2
@@ -11,7 +13,11 @@ env:
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" # COVERITY_SCAN_TOKEN - secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" # COVERITY_SCAN_TOKEN
- secure: "lV9OwUbHMrMpLUH1CY+Z4puLDdFXytudyPlG1eGRsesdpuG6KM3uQVz6uAtf6lrU8DRbMM/T7ML+PmvQ4UoPPYLdLxESLLBat2qUPOIVBOhTSlCc7I0DmGy04CSvkeMy8dPaQC0ukgNiR7zwoNzfcpGRN/U9S8tziDruuHoZSrg=" # BINTRAY_API_KEY - secure: "lV9OwUbHMrMpLUH1CY+Z4puLDdFXytudyPlG1eGRsesdpuG6KM3uQVz6uAtf6lrU8DRbMM/T7ML+PmvQ4UoPPYLdLxESLLBat2qUPOIVBOhTSlCc7I0DmGy04CSvkeMy8dPaQC0ukgNiR7zwoNzfcpGRN/U9S8tziDruuHoZSrg=" # BINTRAY_API_KEY
- secure: "oWFgRTVP6lyTa7qVxlvkpm20MtVc3BtmsNXQJS6bfg2A0o/iCQMNx7OD59BaafCLGRKvCcJVESiC8FlSylVMS7CDSyYu0gg70NUiIuHp4NBM5inFWYCy/PdQsCTzr5uvNG+rMFQpMFRaCV0FrfM3tLondcVkhsHL68l93Xoexx4=" # CODACY_PROJECT_TOKEN - secure: "oWFgRTVP6lyTa7qVxlvkpm20MtVc3BtmsNXQJS6bfg2A0o/iCQMNx7OD59BaafCLGRKvCcJVESiC8FlSylVMS7CDSyYu0gg70NUiIuHp4NBM5inFWYCy/PdQsCTzr5uvNG+rMFQpMFRaCV0FrfM3tLondcVkhsHL68l93Xoexx4=" # CODACY_PROJECT_TOKEN
- secure: "zJxgytA2Ks5Xzv+7kUaUq+EBFNQw9Qec63lcMJVuXVWczjL16nKW1EzzV515ag+OWL46z3lEPForDhufw0VtFnNmaX68jkO0mp01eLrHApc1llN2Y/U8GBXfNNazN4+Kom4H+z/AO+wJr8EsKMMUczCdQ3APgd9uVI0hzXw/Z3M=" # GITHUB_API_KEY
addons: addons:
apt:
packages:
- haveged
coverity_scan: coverity_scan:
project: project:
name: "cryptomator/cryptomator" name: "cryptomator/cryptomator"
@@ -19,21 +25,58 @@ addons:
build_command: "mvn -fmain/pom.xml clean test -DskipTests" build_command: "mvn -fmain/pom.xml clean test -DskipTests"
branch_pattern: release.* branch_pattern: release.*
install: install:
# "clean" needed until https://bugs.openjdk.java.net/browse/JDK-8067747 is resolved. - curl -o $HOME/.m2/settings.xml https://gist.githubusercontent.com/cryptobot/cf5fbd909c4782aaeeeb7c7f4a1a43da/raw/e60ee486e34ee0c79f89f947abe2c83b4290c6bb/settings.xml
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Pcoverage - 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
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Prelease
script: script:
- mvn --update-snapshots -fmain/pom.xml clean test jacoco:report verify -Pcoverage - mvn --update-snapshots -fmain/pom.xml clean test jacoco:report 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
before_deploy: before_deploy:
- mvn -fmain/pom.xml -Prelease clean package -DskipTests - 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: deploy:
- provider: releases - provider: releases # CONTINUOUS
prerelease: false prerelease: true
api_key: api-key: $GITHUB_API_KEY
secure: "ZjE1j93v3qbPIe2YbmhS319aCbMdLQw0HuymmluTurxXsZtn9D4t2+eTr99vBVxGRuB5lzzGezPR5zjk5W7iHF7xhwrawXrFzr2rPJWzWFt0aM+Ry2njU1ROTGGXGTbv4anWeBlgMxLEInTAy/9ytOGNJlec83yc0THpOY2wxnk=" tag_name: continuous
overwrite: true
file_glob: true
file: file:
- "main/uber-jar/target/Cryptomator-$TRAVIS_TAG.jar" - "main/uber-jar/target/Cryptomator-*.jar"
- "main/ant-kit/target/antkit.tar.gz" - "main/ant-kit/target/antkit.tar.gz"
skip_cleanup: true
name: Cryptomator continuous build
body: Automatically built on $(date +'%F %T %Z').
on:
repo: cryptomator/cryptomator
branch: develop
condition: $TRAVIS_TAG = ''
- provider: releases # RELEASE
prerelease: false
api_key: $GITHUB_API_KEY
file:
- "main/uber-jar/target/Cryptomator-$TRAVIS_TAG.jar"
- "main/ant-kit/target/antkit.tar.gz"
skip_cleanup: true skip_cleanup: true
on: on:
repo: cryptomator/cryptomator repo: cryptomator/cryptomator
+2 -13
View File
@@ -4,20 +4,9 @@
- Ensure you're running the latest version of Cryptomator. - 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 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 [knowledge base](https://cryptomator.freshdesk.com/support/solutions) and our [Wiki](https://github.com/cryptomator/cryptomator/wiki). - 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).
- If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new). - If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new).
## Do you have questions?
- Ask questions by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new).
- [Contact us](https://cryptomator.org/contact/) directly by writing an email. Wir sprechen auch Deutsch!
- Have a chat with us on [Gitter](https://gitter.im/cryptomator/cryptomator).
## Do you miss a feature?
- Ensure the feature was not [already requested](https://github.com/cryptomator/cryptomator/issues).
- You're welcome to suggest a feature by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new).
## Did you write a patch that fixes a bug? ## Did you write a patch that fixes a bug?
- Open a new pull request with the patch. - Open a new pull request with the patch.
@@ -29,7 +18,7 @@
## Code of Conduct ## Code of Conduct
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/master/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/CODE_OF_CONDUCT.md).
## Above all, thank you for your contributions ## Above all, thank you for your contributions
+9 -16
View File
@@ -1,24 +1,15 @@
To tick a checkbox replace [ ] with [x]. Make sure to replace placeholders (…) accordingly.
## Issue Checklist ## Issue Checklist
Before creating a new issue make sure that you Before creating a new issue make sure that you
- [ ] searched [existing (and closed) issues](https://github.com/cryptomator/cryptomator/issues). - searched existing (and closed) issues: https://github.com/cryptomator/cryptomator/issues
- [ ] searched the [knowledge base](https://cryptomator.freshdesk.com/support/solutions). - searched the knowledge base: https://community.cryptomator.org/c/kb
- [ ] have read the [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md). - have read the support guide: https://github.com/cryptomator/cryptomator/blob/develop/SUPPORT.md
- [ ] have read the [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/master/CODE_OF_CONDUCT.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
## Basic Info ## Basic Info
This is a I'm using Windows / macOS / Linux / … in version: …
- [ ] bug report.
- [ ] feature request.
- [ ] question or something else.
I'm using
- [ ] Windows in version: …
- [ ] macOS in version: …
- [ ] Linux in version: …
I'm running Cryptomator in version: … I'm running Cryptomator in version: …
(You can check the version in the Cryptomator settings.) (You can check the version in the Cryptomator settings.)
@@ -30,7 +21,9 @@ I'm running Cryptomator in version: …
## Attachments (optional) ## Attachments (optional)
If you want to add the log file or screenshots, please add them as attachments. If your log file seems empty and doesn't show any errors, you may enable the [debug mode](https://cryptomator.freshdesk.com/support/solutions/articles/16000046480) first and reproduce the problem to ensure all important information is contained in there. You may use test data or redact sensitive information from the log file. If you want to add the log file or screenshots, please add them as attachments. If your log file seems empty and doesn't show any errors, you may enable the debug mode first. Here is how to do that: https://community.cryptomator.org/t/how-do-i-enable-debug-mode/36
Then reproduce the problem to ensure all important information is contained in there. You may use test data or redact sensitive information from the log file.
You can find the log file You can find the log file
- on Windows: %appdata%/Cryptomator/cryptomator.log - on Windows: %appdata%/Cryptomator/cryptomator.log
+4 -10
View File
@@ -1,11 +1,12 @@
![cryptomator](cryptomator.png) ![cryptomator](cryptomator.png)
[![Build Status](https://travis-ci.org/cryptomator/cryptomator.svg?branch=master)](https://travis-ci.org/cryptomator/cryptomator) [![Build Status](https://travis-ci.org/cryptomator/cryptomator.svg?branch=master)](https://travis-ci.org/cryptomator/cryptomator)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/cryptomator-cryptomator/badge.svg?flat=1)](https://scan.coverity.com/projects/cryptomator-cryptomator) [![Known Vulnerabilities](https://snyk.io/test/github/cryptomator/cryptomator/badge.svg?targetFile=main%2Fpom.xml)](https://snyk.io/test/github/cryptomator/cryptomator?targetFile=main%2Fpom.xml)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&utm_medium=referral&utm_content=cryptomator/cryptomator&utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/app/cryptomator/cryptomator?utm_source=github.com&utm_medium=referral&utm_content=cryptomator/cryptomator&utm_campaign=Badge_Grade)
[![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator) [![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator)
[![POEditor](https://img.shields.io/badge/POEditor-Help%20Translate-blue.svg?style=flat)](https://poeditor.com/join/project/bHwbvJmx0E) [![POEditor](https://img.shields.io/badge/POEditor-Help%20Translate-blue.svg?style=flat)](https://poeditor.com/join/project/bHwbvJmx0E)
[![Latest Release](https://img.shields.io/github/release/cryptomator/cryptomator.svg)](https://github.com/cryptomator/cryptomator/releases/latest) [![Latest Release](https://img.shields.io/github/release/cryptomator/cryptomator.svg)](https://github.com/cryptomator/cryptomator/releases/latest)
[![Community](https://img.shields.io/badge/help-Community-orange.svg)](https://community.cryptomator.org)
Multi-platform transparent client-side encryption of your files in the cloud. Multi-platform transparent client-side encryption of your files in the cloud.
@@ -13,7 +14,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
## Features ## Features
- Works with Dropbox, Google Drive, OneDrive, Nextcloud and any other cloud storage service which synchronizes with a local directory - Works with Dropbox, Google Drive, OneDrive, ownCloud, Nextcloud and any other cloud storage service which synchronizes with a local directory
- Open Source means: No backdoors, control is better than trust - Open Source means: No backdoors, control is better than trust
- Client-side: No accounts, no data shared with any online service - Client-side: No accounts, no data shared with any online service
- Totally transparent: Just work on the virtual drive as if it were a USB flash drive - Totally transparent: Just work on the virtual drive as if it were a USB flash drive
@@ -21,6 +22,7 @@ Download native binaries of Cryptomator on [cryptomator.org](https://cryptomator
- File names get encrypted - File names get encrypted
- Folder structure gets obfuscated - Folder structure gets obfuscated
- Use as many vaults in your Dropbox as you want, each having individual passwords - Use as many vaults in your Dropbox as you want, each having individual passwords
- One thousand commits for the security of your data!! :tada:
### Privacy ### Privacy
@@ -58,14 +60,6 @@ mvn clean install -Prelease
An executable jar file will be created inside `main/uber-jar/target`. An executable jar file will be created inside `main/uber-jar/target`.
## Contributing to Cryptomator
Please read our [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md), if you would like to report a bug, ask a question or help us with coding.
## Code of Conduct
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/master/CODE_OF_CONDUCT.md).
## License ## License
This project is dual-licensed under the GPLv3 for FOSS projects as well as a commercial license for independent software vendors and resellers. If you want to modify this application under different conditions, feel free to contact our support team. This project is dual-licensed under the GPLv3 for FOSS projects as well as a commercial license for independent software vendors and resellers. If you want to modify this application under different conditions, feel free to contact our support team.
+10
View File
@@ -0,0 +1,10 @@
# Support for Cryptomator
For development-related topics, GitHub is the right place.
For _everything else_, please visit our official [Cryptomator Community](https://community.cryptomator.org) (we are there, too :wink:). Amongst others, you will find:
- Installation manuals
- Usage guides
- Help with problems
- Tips & tricks
+3 -2
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id> <id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory> <includeBaseDirectory>false</includeBaseDirectory>
<formats> <formats>
@@ -29,6 +29,7 @@
<directory>target</directory> <directory>target</directory>
<includes> <includes>
<include>build.xml</include> <include>build.xml</include>
<include>logback.xml</include>
</includes> </includes>
<filtered>false</filtered> <filtered>false</filtered>
<outputDirectory>.</outputDirectory> <outputDirectory>.</outputDirectory>
+6 -6
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
</parent> </parent>
<artifactId>ant-kit</artifactId> <artifactId>ant-kit</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
@@ -56,15 +56,15 @@
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<filtering>true</filtering> <filtering>true</filtering>
<excludes> <includes>
<exclude>fixed-binaries/**</exclude> <include>build.xml</include>
</excludes> </includes>
</resource> </resource>
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<filtering>false</filtering> <filtering>false</filtering>
<includes> <includes>
<include>fixed-binaries/**</include> <include>logback.xml</include>
</includes> </includes>
</resource> </resource>
</resources> </resources>
@@ -76,7 +76,7 @@
<!-- create antkit.tar.gz: --> <!-- create antkit.tar.gz: -->
<plugin> <plugin>
<artifactId>maven-assembly-plugin</artifactId> <artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version> <version>3.1.0</version>
<executions> <executions>
<execution> <execution>
<id>make-assembly</id> <id>make-assembly</id>
+9 -35
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project name="Cryptomator" default="create-jar" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant"> <project name="Cryptomator" default="create-jar" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
<taskdef uri="javafx:com.sun.javafx.tools.ant" resource="com/sun/javafx/tools/ant/antlib.xml" classpath="\${java.class.path}:\${java.home}/../lib/ant-javafx.jar:." /> <taskdef uri="javafx:com.sun.javafx.tools.ant" resource="com/sun/javafx/tools/ant/antlib.xml" classpath="\${java.class.path}:\${java.home}/lib/ant-javafx.jar:." />
<!-- Define application to build --> <!-- Define application to build -->
<fx:application id="Cryptomator" name="Cryptomator" version="${project.version}" mainClass="org.cryptomator.launcher.Cryptomator" /> <fx:application id="Cryptomator" name="Cryptomator" version="${project.version}" mainClass="org.cryptomator.launcher.Cryptomator" />
@@ -20,51 +20,25 @@
</fx:manifest> </fx:manifest>
</fx:jar> </fx:jar>
</target> </target>
<!-- Create Debian package --> <!-- Create Image package -->
<target name="deb" depends="create-jar"> <target name="image" depends="create-jar">
<fx:deploy nativeBundles="deb" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true"> <fx:deploy nativeBundles="image" outdir="antbuild" verbose="true">
<fx:application refid="Cryptomator" /> <fx:application refid="Cryptomator" />
<fx:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="MIT" category="Utility"> <fx:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="GPL" category="Utility"/>
<fx:association mimetype="application/x-vnd.cryptomator-vault-metadata" extension="cryptomator" description="Cryptomator Vault Metadata" /> <fx:platform j2se="9.0">
</fx:info>
<fx:platform j2se="8.0">
<fx:property name="logback.configurationFile" value="logback.xml" /> <fx:property name="logback.configurationFile" value="logback.xml" />
<fx:property name="cryptomator.settingsPath" value="~/.Cryptomator/settings.json" /> <fx:property name="cryptomator.settingsPath" value="~/.Cryptomator/settings.json" />
<fx:property name="cryptomator.ipcPortPath" value="~/.Cryptomator/ipcPort.bin" /> <fx:property name="cryptomator.ipcPortPath" value="~/.Cryptomator/ipcPort.bin" />
<fx:jvmarg value="-Xss2m"/> <fx:jvmarg value="-Xss2m"/>
<fx:jvmarg value="-Xmx512m"/> <fx:jvmarg value="-Xmx512m"/>
<fx:jvmarg value="--add-modules"/>
<fx:jvmarg value="jdk.incubator.httpclient"/>
</fx:platform> </fx:platform>
<fx:resources> <fx:resources>
<fx:fileset dir="." type="data" includes="logback.xml" /> <fx:fileset dir="." type="data" includes="logback.xml" />
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" /> <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:fileset dir="libs" type="jar" includes="*.jar" excludes="launcher-${project.version}.jar"/>
<fx:fileset dir="fixed-binaries" type="data" includes="linux-launcher-*" arch=""/>
</fx:resources>
<fx:permissions elevated="false" />
<fx:preferences install="true" />
</fx:deploy>
</target>
<!-- Create Red Hat package -->
<target name="rpm" depends="create-jar">
<fx:deploy nativeBundles="rpm" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true">
<fx:application refid="Cryptomator" />
<fx:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="MIT" category="Utility">
<fx:association mimetype="application/x-vnd.cryptomator-vault-metadata" extension="cryptomator" description="Cryptomator Vault Metadata" />
</fx:info>
<fx:platform j2se="8.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:jvmarg value="-Xss2m"/>
<fx:jvmarg value="-Xmx512m"/>
</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:fileset dir="fixed-binaries" type="data" includes="linux-launcher-*" arch=""/>
</fx:resources> </fx:resources>
<fx:permissions elevated="false" /> <fx:permissions elevated="false" />
<fx:preferences install="true" /> <fx:preferences install="true" />
@@ -1,16 +0,0 @@
Package: APPLICATION_PACKAGE
Version: APPLICATION_VERSION
Section: contrib/utils
Maintainer: Sebastian Stenzel <sebastian.stenzel@gmail.com>
Homepage: https://cryptomator.org
Vcs-Git: https://github.com/totalvoidness/cryptomator.git
Vcs-Browser: https://github.com/totalvoidness/cryptomator
Priority: optional
Architecture: APPLICATION_ARCH
Provides: APPLICATION_PACKAGE
Installed-Size: APPLICATION_INSTALLED_SIZE
Depends: gvfs-bin, gvfs-backends, gvfs-fuse
Description: Multi-platform client-side encryption of your cloud files.
Cryptomator provides free client-side AES encryption for your cloud files.
Create encrypted vaults, which get mounted as virtual volumes. Whatever
you save on one of these volumes will end up encrypted inside your vault.
@@ -1,23 +0,0 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: cryptomator
Source: <https://github.com/totalvoidness/cryptomator>
Copyright: 2015 Sebastian Stenzel <sebastian.stenzel@gmail.com> and contributors.
License: MIT
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,51 +0,0 @@
#!/bin/sh
# postinst script for APPLICATION_NAME
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
echo Adding shortcut to the menu
SECONDARY_LAUNCHERS_INSTALL
APP_CDS_CACHE
mkdir -pm 644 /usr/share/desktop-directories
xdg-desktop-menu install --novendor /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.desktop
FILE_ASSOCIATION_INSTALL
rm /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
if [ $(uname -m) = "x86_64" ]; then
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x64 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
else
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x86 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
@@ -1,54 +0,0 @@
Summary: APPLICATION_SUMMARY
Name: APPLICATION_PACKAGE
Version: APPLICATION_VERSION
Release: 1
License: APPLICATION_LICENSE_TYPE
Vendor: APPLICATION_VENDOR
Prefix: /opt
Provides: APPLICATION_PACKAGE
Requires: ld-linux.so.2 libX11.so.6 libXext.so.6 libXi.so.6 libXrender.so.1 libXtst.so.6 libasound.so.2 libc.so.6 libdl.so.2 libgcc_s.so.1 libm.so.6 libpthread.so.0 libthread_db.so.1
Autoprov: 0
Autoreq: 0
#avoid ARCH subfolder
%define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
#comment line below to enable effective jar compression
#it could easily get your package size from 40 to 15Mb but
#build time will substantially increase and it may require unpack200/system java to install
%define __jar_repack %{nil}
%description
APPLICATION_DESCRIPTION
%prep
%build
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/opt
cp -r %{_sourcedir}/APPLICATION_FS_NAME %{buildroot}/opt
%files
APPLICATION_LICENSE_FILE
/opt/APPLICATION_FS_NAME
%post
SECONDARY_LAUNCHERS_INSTALL
APP_CDS_CACHE
xdg-desktop-menu install --novendor /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.desktop
FILE_ASSOCIATION_INSTALL
rm /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
if [ $(uname -m) = "x86_64" ]; then
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x64 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
else
mv /opt/APPLICATION_FS_NAME/app/linux-launcher-x86 /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME
fi
%preun
SECONDARY_LAUNCHERS_REMOVE
xdg-desktop-menu uninstall --novendor /opt/APPLICATION_FS_NAME/APPLICATION_LAUNCHER_FILENAME.desktop
FILE_ASSOCIATION_REMOVE
%clean
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
</parent> </parent>
<artifactId>commons</artifactId> <artifactId>commons</artifactId>
<name>Cryptomator Commons</name> <name>Cryptomator Commons</name>
@@ -2,7 +2,7 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel * Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved. * All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file. * This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
* *
* Contributors: * Contributors:
* Sebastian Stenzel - initial API and implementation * Sebastian Stenzel - initial API and implementation
******************************************************************************/ ******************************************************************************/
@@ -12,8 +12,10 @@ import java.util.function.Consumer;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@@ -30,6 +32,7 @@ public class Settings {
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3; public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final String DEFAULT_GVFS_SCHEME = "dav"; public static final String DEFAULT_GVFS_SCHEME = "dav";
public static final boolean DEFAULT_DEBUG_MODE = false; public static final boolean DEFAULT_DEBUG_MODE = false;
public static final VolumeImpl DEFAULT_VOLUME_IMPL = VolumeImpl.FUSE;
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables); private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES); private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES);
@@ -37,6 +40,8 @@ public class Settings {
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS); private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
private final StringProperty preferredGvfsScheme = new SimpleStringProperty(DEFAULT_GVFS_SCHEME); private final StringProperty preferredGvfsScheme = new SimpleStringProperty(DEFAULT_GVFS_SCHEME);
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE); private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
private final ObjectProperty<VolumeImpl> volumeImpl = new SimpleObjectProperty<>(DEFAULT_VOLUME_IMPL);
private Consumer<Settings> saveCmd; private Consumer<Settings> saveCmd;
/** /**
@@ -49,6 +54,7 @@ public class Settings {
numTrayNotifications.addListener(this::somethingChanged); numTrayNotifications.addListener(this::somethingChanged);
preferredGvfsScheme.addListener(this::somethingChanged); preferredGvfsScheme.addListener(this::somethingChanged);
debugMode.addListener(this::somethingChanged); debugMode.addListener(this::somethingChanged);
volumeImpl.addListener(this::somethingChanged);
} }
void setSaveCmd(Consumer<Settings> saveCmd) { void setSaveCmd(Consumer<Settings> saveCmd) {
@@ -91,4 +97,8 @@ public class Settings {
return debugMode; return debugMode;
} }
public ObjectProperty<VolumeImpl> volumeImpl() {
return volumeImpl;
}
} }
@@ -33,6 +33,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
out.name("numTrayNotifications").value(value.numTrayNotifications().get()); out.name("numTrayNotifications").value(value.numTrayNotifications().get());
out.name("preferredGvfsScheme").value(value.preferredGvfsScheme().get()); out.name("preferredGvfsScheme").value(value.preferredGvfsScheme().get());
out.name("debugMode").value(value.debugMode().get()); out.name("debugMode").value(value.debugMode().get());
out.name("volumeImpl").value(value.volumeImpl().get().name());
out.endObject(); out.endObject();
} }
@@ -52,27 +53,30 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
while (in.hasNext()) { while (in.hasNext()) {
String name = in.nextName(); String name = in.nextName();
switch (name) { switch (name) {
case "directories": case "directories":
settings.getDirectories().addAll(readVaultSettingsArray(in)); settings.getDirectories().addAll(readVaultSettingsArray(in));
break; break;
case "checkForUpdatesEnabled": case "checkForUpdatesEnabled":
settings.checkForUpdates().set(in.nextBoolean()); settings.checkForUpdates().set(in.nextBoolean());
break; break;
case "port": case "port":
settings.port().set(in.nextInt()); settings.port().set(in.nextInt());
break; break;
case "numTrayNotifications": case "numTrayNotifications":
settings.numTrayNotifications().set(in.nextInt()); settings.numTrayNotifications().set(in.nextInt());
break; break;
case "preferredGvfsScheme": case "preferredGvfsScheme":
settings.preferredGvfsScheme().set(in.nextString()); settings.preferredGvfsScheme().set(in.nextString());
break; break;
case "debugMode": case "debugMode":
settings.debugMode().set(in.nextBoolean()); settings.debugMode().set(in.nextBoolean());
break; break;
default: case "volumeImpl":
LOG.warn("Unsupported vault setting found in JSON: " + name); settings.volumeImpl().set(parseNioAdapterName(in.nextString()));
in.skipValue(); break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
} }
} }
in.endObject(); in.endObject();
@@ -80,6 +84,14 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
return settings; return settings;
} }
private VolumeImpl parseNioAdapterName(String nioAdapterName) {
try {
return VolumeImpl.valueOf(nioAdapterName);
} catch (IllegalArgumentException e) {
return Settings.DEFAULT_VOLUME_IMPL;
}
}
private List<VaultSettings> readVaultSettingsArray(JsonReader in) throws IOException { private List<VaultSettings> readVaultSettingsArray(JsonReader in) throws IOException {
List<VaultSettings> result = new ArrayList<>(); List<VaultSettings> result = new ArrayList<>();
in.beginArray(); in.beginArray();
@@ -28,6 +28,7 @@ public class VaultSettings {
public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false; public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
public static final boolean DEFAULT_MOUNT_AFTER_UNLOCK = true; public static final boolean DEFAULT_MOUNT_AFTER_UNLOCK = true;
public static final boolean DEFAULT_REAVEAL_AFTER_MOUNT = true; public static final boolean DEFAULT_REAVEAL_AFTER_MOUNT = true;
public static final boolean DEFAULT_USES_INDIVIDUAL_MOUNTPATH = false;
private final String id; private final String id;
private final ObjectProperty<Path> path = new SimpleObjectProperty<>(); private final ObjectProperty<Path> path = new SimpleObjectProperty<>();
@@ -36,6 +37,8 @@ public class VaultSettings {
private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP); private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP);
private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty(DEFAULT_MOUNT_AFTER_UNLOCK); private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty(DEFAULT_MOUNT_AFTER_UNLOCK);
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REAVEAL_AFTER_MOUNT); 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();
public VaultSettings(String id) { public VaultSettings(String id) {
this.id = Objects.requireNonNull(id); this.id = Objects.requireNonNull(id);
@@ -44,7 +47,7 @@ public class VaultSettings {
} }
Observable[] observables() { Observable[] observables() {
return new Observable[] {path, mountName, winDriveLetter, unlockAfterStartup, mountAfterUnlock, revealAfterMount}; return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, mountAfterUnlock, revealAfterMount, usesIndividualMountPath, individualMountPath};
} }
private void deriveMountNameFromPath(Path path) { private void deriveMountNameFromPath(Path path) {
@@ -123,6 +126,14 @@ public class VaultSettings {
return revealAfterMount; return revealAfterMount;
} }
public BooleanProperty usesIndividualMountPath() {
return usesIndividualMountPath;
}
public StringProperty individualMountPath() {
return individualMountPath;
}
/* Hashcode/Equals */ /* Hashcode/Equals */
@Override @Override
@@ -27,6 +27,9 @@ class VaultSettingsJsonAdapter {
out.name("unlockAfterStartup").value(value.unlockAfterStartup().get()); out.name("unlockAfterStartup").value(value.unlockAfterStartup().get());
out.name("mountAfterUnlock").value(value.mountAfterUnlock().get()); out.name("mountAfterUnlock").value(value.mountAfterUnlock().get());
out.name("revealAfterMount").value(value.revealAfterMount().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.endObject(); out.endObject();
} }
@@ -34,39 +37,47 @@ class VaultSettingsJsonAdapter {
String id = null; String id = null;
String path = null; String path = null;
String mountName = null; String mountName = null;
String individualMountPath = null;
String winDriveLetter = null; String winDriveLetter = null;
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP; boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
boolean mountAfterUnlock = VaultSettings.DEFAULT_MOUNT_AFTER_UNLOCK; boolean mountAfterUnlock = VaultSettings.DEFAULT_MOUNT_AFTER_UNLOCK;
boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT; boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT;
boolean usesIndividualMountPath = VaultSettings.DEFAULT_USES_INDIVIDUAL_MOUNTPATH;
in.beginObject(); in.beginObject();
while (in.hasNext()) { while (in.hasNext()) {
String name = in.nextName(); String name = in.nextName();
switch (name) { switch (name) {
case "id": case "id":
id = in.nextString(); id = in.nextString();
break; break;
case "path": case "path":
path = in.nextString(); path = in.nextString();
break; break;
case "mountName": case "mountName":
mountName = in.nextString(); mountName = in.nextString();
break; break;
case "winDriveLetter": case "winDriveLetter":
winDriveLetter = in.nextString(); winDriveLetter = in.nextString();
break; break;
case "unlockAfterStartup": case "unlockAfterStartup":
unlockAfterStartup = in.nextBoolean(); unlockAfterStartup = in.nextBoolean();
break; break;
case "mountAfterUnlock": case "mountAfterUnlock":
mountAfterUnlock = in.nextBoolean(); mountAfterUnlock = in.nextBoolean();
break; break;
case "revealAfterMount": case "revealAfterMount":
revealAfterMount = in.nextBoolean(); revealAfterMount = in.nextBoolean();
break; break;
default: case "usesIndividualMountPath":
LOG.warn("Unsupported vault setting found in JSON: " + name); usesIndividualMountPath = in.nextBoolean();
in.skipValue(); break;
case "individualMountPath":
individualMountPath = in.nextString();
break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
} }
} }
in.endObject(); in.endObject();
@@ -78,6 +89,8 @@ class VaultSettingsJsonAdapter {
vaultSettings.unlockAfterStartup().set(unlockAfterStartup); vaultSettings.unlockAfterStartup().set(unlockAfterStartup);
vaultSettings.mountAfterUnlock().set(mountAfterUnlock); vaultSettings.mountAfterUnlock().set(mountAfterUnlock);
vaultSettings.revealAfterMount().set(revealAfterMount); vaultSettings.revealAfterMount().set(revealAfterMount);
vaultSettings.usesIndividualMountPath().set(usesIndividualMountPath);
vaultSettings.individualMountPath().set(individualMountPath);
return vaultSettings; return vaultSettings;
} }
@@ -0,0 +1,33 @@
package org.cryptomator.common.settings;
import java.util.Arrays;
public enum VolumeImpl {
WEBDAV("WebDAV"),
FUSE("FUSE");
private String displayName;
VolumeImpl(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
/**
* Finds a VolumeImpl by display name.
*
* @param displayName Display name of the VolumeImpl
* @return VolumeImpl with the given <code>displayName</code>.
* @throws IllegalArgumentException if not volumeImpl with the given <code>displayName</code> was found.
*/
public static VolumeImpl forDisplayName(String displayName) throws IllegalArgumentException {
return Arrays.stream(values()) //
.filter(impl -> impl.displayName.equals(displayName)) //
.findAny() //
.orElseThrow(IllegalArgumentException::new);
}
}
@@ -21,17 +21,17 @@ public class SettingsJsonAdapterTest {
String json = "{\"directories\": [" + vault1Json + "," + vault2Json + "]," // String json = "{\"directories\": [" + vault1Json + "," + vault2Json + "]," //
+ "\"checkForUpdatesEnabled\": true,"// + "\"checkForUpdatesEnabled\": true,"//
+ "\"port\": 8080,"// + "\"port\": 8080,"//
+ "\"useIpv6\": true,"// + "\"numTrayNotifications\": 42,"//
+ "\"numTrayNotifications\": 42}"; + "\"volumeImpl\": \"FUSE\"}";
Settings settings = adapter.fromJson(json); Settings settings = adapter.fromJson(json);
Assert.assertTrue(settings.checkForUpdates().get()); Assert.assertTrue(settings.checkForUpdates().get());
Assert.assertEquals(2, settings.getDirectories().size()); Assert.assertEquals(2, settings.getDirectories().size());
Assert.assertEquals(8080, settings.port().get()); Assert.assertEquals(8080, settings.port().get());
// Assert.assertTrue(settings.useIpv6().get()); temporarily ignored
Assert.assertEquals(42, settings.numTrayNotifications().get()); Assert.assertEquals(42, settings.numTrayNotifications().get());
Assert.assertEquals("dav", settings.preferredGvfsScheme().get()); Assert.assertEquals("dav", settings.preferredGvfsScheme().get());
Assert.assertEquals(VolumeImpl.FUSE, settings.volumeImpl().get());
} }
} }
@@ -20,7 +20,7 @@ public class VaultSettingsJsonAdapterTest {
@Test @Test
public void testDeserialize() throws IOException { public void testDeserialize() throws IOException {
String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true}"; String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"mountName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true, \"individualMountPath\": \"/home/test/crypto\"}";
JsonReader jsonReader = new JsonReader(new StringReader(json)); JsonReader jsonReader = new JsonReader(new StringReader(json));
VaultSettings vaultSettings = adapter.read(jsonReader); VaultSettings vaultSettings = adapter.read(jsonReader);
@@ -28,6 +28,7 @@ public class VaultSettingsJsonAdapterTest {
Assert.assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get()); Assert.assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get());
Assert.assertEquals("test", vaultSettings.mountName().get()); Assert.assertEquals("test", vaultSettings.mountName().get());
Assert.assertEquals("X", vaultSettings.winDriveLetter().get()); Assert.assertEquals("X", vaultSettings.winDriveLetter().get());
Assert.assertEquals("/home/test/crypto", vaultSettings.individualMountPath().get());
} }
} }
+1 -44
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
</parent> </parent>
<artifactId>jacoco-report</artifactId> <artifactId>jacoco-report</artifactId>
<name>Cryptomator Code Coverage Report</name> <name>Cryptomator Code Coverage Report</name>
@@ -27,27 +27,6 @@
<dependency> <dependency>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>launcher</artifactId> <artifactId>launcher</artifactId>
<exclusions>
<exclusion>
<!-- conflict with codacy-coverage-reporter -->
<groupId>org.apache.logging.log4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- binary dependency used during build -->
<dependency>
<groupId>com.codacy</groupId>
<artifactId>codacy-coverage-reporter</artifactId>
<version>1.0.13</version>
<classifier>assembly</classifier>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
</dependencies> </dependencies>
@@ -66,28 +45,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.codacy.CodacyCoverageReporter</mainClass>
<arguments>
<argument>-l</argument>
<argument>Java</argument>
<argument>-r</argument>
<argument>${project.build.directory}/site/jacoco-aggregate/jacoco.xml</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
</parent> </parent>
<artifactId>keychain</artifactId> <artifactId>keychain</artifactId>
<name>System Keychain Access</name> <name>System Keychain Access</name>
@@ -8,17 +8,27 @@ package org.cryptomator.keychain;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import org.cryptomator.jni.JniModule;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import dagger.multibindings.ElementsIntoSet; import dagger.multibindings.ElementsIntoSet;
import org.cryptomator.jni.JniFunctions;
import org.cryptomator.jni.MacFunctions;
import org.cryptomator.jni.WinFunctions;
@Module(includes = {JniModule.class}) @Module
public class KeychainModule { public class KeychainModule {
@Provides
Optional<MacFunctions> provideOptionalMacFunctions() {
return JniFunctions.macFunctions();
}
@Provides
Optional<WinFunctions> provideOptionalWinFunctions() {
return JniFunctions.winFunctions();
}
@Provides @Provides
@ElementsIntoSet @ElementsIntoSet
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) { Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) {
@@ -15,35 +15,35 @@ import org.cryptomator.jni.MacKeychainAccess;
class MacSystemKeychainAccess implements KeychainAccessStrategy { class MacSystemKeychainAccess implements KeychainAccessStrategy {
private final MacKeychainAccess keychain; private final Optional<MacFunctions> macFunctions;
@Inject @Inject
public MacSystemKeychainAccess(Optional<MacFunctions> macFunctions) { public MacSystemKeychainAccess(Optional<MacFunctions> macFunctions) {
if (macFunctions.isPresent()) { this.macFunctions = macFunctions;
this.keychain = macFunctions.get().keychainAccess(); }
} else {
this.keychain = null; private MacKeychainAccess keychain() {
} return macFunctions.orElseThrow(IllegalStateException::new).keychainAccess();
} }
@Override @Override
public void storePassphrase(String key, CharSequence passphrase) { public void storePassphrase(String key, CharSequence passphrase) {
keychain.storePassword(key, passphrase); keychain().storePassword(key, passphrase);
} }
@Override @Override
public char[] loadPassphrase(String key) { public char[] loadPassphrase(String key) {
return keychain.loadPassword(key); return keychain().loadPassword(key);
} }
@Override @Override
public boolean isSupported() { public boolean isSupported() {
return SystemUtils.IS_OS_MAC_OSX && keychain != null; return SystemUtils.IS_OS_MAC_OSX && macFunctions.isPresent();
} }
@Override @Override
public void deletePassphrase(String key) { public void deletePassphrase(String key) {
keychain.deletePassword(key); keychain().deletePassword(key);
} }
} }
@@ -5,8 +5,6 @@
*******************************************************************************/ *******************************************************************************/
package org.cryptomator.keychain; package org.cryptomator.keychain;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@@ -31,12 +29,6 @@ import java.util.UUID;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.jni.WinDataProtection;
import org.cryptomator.jni.WinFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.BaseEncoding; import com.google.common.io.BaseEncoding;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
@@ -49,6 +41,13 @@ import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer; import com.google.gson.JsonSerializer;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.jni.WinDataProtection;
import org.cryptomator.jni.WinFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.nio.charset.StandardCharsets.UTF_8;
class WindowsProtectedKeychainAccess implements KeychainAccessStrategy { class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
@@ -57,19 +56,15 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
.registerTypeHierarchyAdapter(byte[].class, new ByteArrayJsonAdapter()) // .registerTypeHierarchyAdapter(byte[].class, new ByteArrayJsonAdapter()) //
.disableHtmlEscaping().create(); .disableHtmlEscaping().create();
private final WinDataProtection dataProtection; private final Optional<WinFunctions> winFunctions;
private final Path keychainPath; private final Path keychainPath;
private Map<String, KeychainEntry> keychainEntries; private Map<String, KeychainEntry> keychainEntries;
@Inject @Inject
public WindowsProtectedKeychainAccess(Optional<WinFunctions> winFunctions) { public WindowsProtectedKeychainAccess(Optional<WinFunctions> winFunctions) {
if (winFunctions.isPresent()) { this.winFunctions = winFunctions;
this.dataProtection = winFunctions.get().dataProtection();
} else {
this.dataProtection = null;
}
String keychainPathProperty = System.getProperty("cryptomator.keychainPath"); String keychainPathProperty = System.getProperty("cryptomator.keychainPath");
if (dataProtection != null && keychainPathProperty == null) { if (keychainPathProperty == null) {
LOG.warn("Windows DataProtection module loaded, but no cryptomator.keychainPath property found."); LOG.warn("Windows DataProtection module loaded, but no cryptomator.keychainPath property found.");
} }
if (keychainPathProperty != null) { if (keychainPathProperty != null) {
@@ -82,6 +77,10 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
} }
} }
private WinDataProtection dataProtection() {
return winFunctions.orElseThrow(IllegalStateException::new).dataProtection();
}
@Override @Override
public void storePassphrase(String key, CharSequence passphrase) { public void storePassphrase(String key, CharSequence passphrase) {
loadKeychainEntriesIfNeeded(); loadKeychainEntriesIfNeeded();
@@ -90,7 +89,7 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
buf.get(cleartext); buf.get(cleartext);
KeychainEntry entry = new KeychainEntry(); KeychainEntry entry = new KeychainEntry();
entry.salt = generateSalt(); entry.salt = generateSalt();
entry.ciphertext = dataProtection.protect(cleartext, entry.salt); entry.ciphertext = dataProtection().protect(cleartext, entry.salt);
Arrays.fill(buf.array(), (byte) 0x00); Arrays.fill(buf.array(), (byte) 0x00);
Arrays.fill(cleartext, (byte) 0x00); Arrays.fill(cleartext, (byte) 0x00);
keychainEntries.put(key, entry); keychainEntries.put(key, entry);
@@ -104,7 +103,7 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
if (entry == null) { if (entry == null) {
return null; return null;
} }
byte[] cleartext = dataProtection.unprotect(entry.ciphertext, entry.salt); byte[] cleartext = dataProtection().unprotect(entry.ciphertext, entry.salt);
if (cleartext == null) { if (cleartext == null) {
return null; return null;
} }
@@ -125,7 +124,7 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
@Override @Override
public boolean isSupported() { public boolean isSupported() {
return SystemUtils.IS_OS_WINDOWS && dataProtection != null && keychainPath != null; return SystemUtils.IS_OS_WINDOWS && winFunctions.isPresent() && keychainPath != null;
} }
private byte[] generateSalt() { private byte[] generateSalt() {
@@ -14,9 +14,11 @@ public class KeychainModuleTest {
@Test @Test
public void testGetKeychain() { public void testGetKeychain() {
Optional<KeychainAccess> keychainAccess = DaggerTestKeychainComponent.builder().jniModule(new TestJniModule()).keychainModule(new TestKeychainModule()).build().keychainAccess(); Optional<KeychainAccess> keychainAccess = DaggerTestKeychainComponent.builder().keychainModule(new TestKeychainModule()).build().keychainAccess();
Assert.assertTrue(keychainAccess.isPresent()); Assert.assertTrue(keychainAccess.isPresent());
Assert.assertTrue(keychainAccess.get() instanceof MapKeychainAccess); Assert.assertTrue(keychainAccess.get() instanceof MapKeychainAccess);
keychainAccess.get().storePassphrase("test", "asd");
Assert.assertArrayEquals("asd".toCharArray(), keychainAccess.get().loadPassphrase("test"));
} }
} }
@@ -1,28 +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.keychain;
import java.util.Optional;
import org.cryptomator.jni.JniModule;
import org.cryptomator.jni.MacFunctions;
import org.cryptomator.jni.WinFunctions;
import dagger.Lazy;
public class TestJniModule extends JniModule {
@Override
public Optional<WinFunctions> winFunctions(Lazy<WinFunctions> winFunction) {
return Optional.empty();
}
@Override
public Optional<MacFunctions> macFunctions(Lazy<MacFunctions> winFunction) {
return Optional.empty();
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
</parent> </parent>
<artifactId>launcher</artifactId> <artifactId>launcher</artifactId>
<name>Cryptomator Launcher</name> <name>Cryptomator Launcher</name>
@@ -6,6 +6,7 @@
*******************************************************************************/ *******************************************************************************/
package org.cryptomator.launcher; package org.cryptomator.launcher;
import java.awt.Desktop;
import java.io.File; import java.io.File;
import java.nio.file.FileSystem; import java.nio.file.FileSystem;
import java.nio.file.FileSystems; import java.nio.file.FileSystems;
@@ -13,7 +14,6 @@ import java.nio.file.InvalidPathException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import org.cryptomator.ui.util.EawtApplicationWrapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -24,11 +24,13 @@ class FileOpenRequestHandler {
public FileOpenRequestHandler(BlockingQueue<Path> fileOpenRequests) { public FileOpenRequestHandler(BlockingQueue<Path> fileOpenRequests) {
this.fileOpenRequests = fileOpenRequests; this.fileOpenRequests = fileOpenRequests;
EawtApplicationWrapper.getApplication().ifPresent(app -> { try {
app.setOpenFileHandler(files -> { Desktop.getDesktop().setOpenFileHandler(e -> {
files.stream().map(File::toPath).forEach(fileOpenRequests::add); e.getFiles().stream().map(File::toPath).forEach(fileOpenRequests::add);
}); });
}); } catch (UnsupportedOperationException e) {
LOG.info("Unable to setOpenFileHandler, probably not supported on this OS.");
}
} }
public void handleLaunchArgs(String[] args) { public void handleLaunchArgs(String[] args) {
@@ -9,6 +9,9 @@ import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
@@ -17,6 +20,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.rmi.ConnectException; import java.rmi.ConnectException;
import java.rmi.ConnectIOException;
import java.rmi.NotBoundException; import java.rmi.NotBoundException;
import java.rmi.Remote; import java.rmi.Remote;
import java.rmi.RemoteException; import java.rmi.RemoteException;
@@ -55,22 +59,19 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
// visible for testing // visible for testing
static InterProcessCommunicator start(Path portFilePath, InterProcessCommunicationProtocol endpoint) throws IOException { static InterProcessCommunicator start(Path portFilePath, InterProcessCommunicationProtocol endpoint) throws IOException {
System.setProperty("java.rmi.server.hostname", "localhost"); System.setProperty("java.rmi.server.hostname", "localhost");
// try to connect to existing server:
int port = readPort(portFilePath);
LOG.debug("Connecting to running process on TCP port {}...", port);
try { try {
ClientCommunicator client = new ClientCommunicator(port); // try to connect to existing server:
ClientCommunicator client = new ClientCommunicator(portFilePath);
LOG.trace("Connected to running process."); LOG.trace("Connected to running process.");
return client; return client;
} catch (ConnectException | NotBoundException e) { } catch (ConnectException | ConnectIOException | NotBoundException e) {
LOG.debug("Did not find running process."); LOG.debug("Could not connect to running process.");
// continue // continue
} }
// spawn a new server: // spawn a new server:
LOG.trace("Spawning new server..."); LOG.trace("Spawning new server...");
ServerCommunicator server = new ServerCommunicator(endpoint); ServerCommunicator server = new ServerCommunicator(endpoint, portFilePath);
writePort(portFilePath, server.getPort());
LOG.debug("Server listening on port {}.", server.getPort()); LOG.debug("Server listening on port {}.", server.getPort());
return server; return server;
} }
@@ -79,7 +80,7 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
final String settingsPathProperty = System.getProperty("cryptomator.ipcPortPath"); final String settingsPathProperty = System.getProperty("cryptomator.ipcPortPath");
if (settingsPathProperty == null) { if (settingsPathProperty == null) {
LOG.warn("System property cryptomator.ipcPortPath not set."); LOG.warn("System property cryptomator.ipcPortPath not set.");
return Paths.get("ipcPort.tmp"); return Paths.get(".ipcPort.tmp");
} else { } else {
return Paths.get(replaceHomeDir(settingsPathProperty)); return Paths.get(replaceHomeDir(settingsPathProperty));
} }
@@ -97,12 +98,30 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
private final IpcProtocolRemote remote; private final IpcProtocolRemote remote;
private ClientCommunicator(int port) throws ConnectException, NotBoundException, RemoteException { private ClientCommunicator(Path portFilePath) throws ConnectException, NotBoundException, RemoteException {
if (port == 0) { if (Files.notExists(portFilePath)) {
throw new ConnectException("Can not connect to port 0."); throw new ConnectException("No IPC port file.");
}
try {
int port = ClientCommunicator.readPort(portFilePath);
LOG.debug("Connecting to port {}...", port);
Registry registry = LocateRegistry.getRegistry("localhost", port, new ClientSocketFactory());
this.remote = (IpcProtocolRemote) registry.lookup(RMI_NAME);
} catch (IOException e) {
throw new ConnectException("Error reading IPC port file.");
}
}
private static int readPort(Path portFilePath) throws IOException {
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
try (ReadableByteChannel ch = Files.newByteChannel(portFilePath, StandardOpenOption.READ)) {
if (ch.read(buf) == Integer.BYTES) {
buf.flip();
return buf.getInt();
} else {
throw new IOException("Invalid IPC port file.");
}
} }
Registry registry = LocateRegistry.getRegistry("localhost", port);
this.remote = (IpcProtocolRemote) registry.lookup(RMI_NAME);
} }
@Override @Override
@@ -131,8 +150,9 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
private final ServerSocket socket; private final ServerSocket socket;
private final Registry registry; private final Registry registry;
private final IpcProtocolRemoteImpl remote; private final IpcProtocolRemoteImpl remote;
private final Path portFilePath;
private ServerCommunicator(InterProcessCommunicationProtocol delegate) throws IOException { private ServerCommunicator(InterProcessCommunicationProtocol delegate, Path portFilePath) throws IOException {
this.socket = new ServerSocket(0, Byte.MAX_VALUE, InetAddress.getByName("localhost")); this.socket = new ServerSocket(0, Byte.MAX_VALUE, InetAddress.getByName("localhost"));
RMIClientSocketFactory csf = RMISocketFactory.getDefaultSocketFactory(); RMIClientSocketFactory csf = RMISocketFactory.getDefaultSocketFactory();
SingletonServerSocketFactory ssf = new SingletonServerSocketFactory(socket); SingletonServerSocketFactory ssf = new SingletonServerSocketFactory(socket);
@@ -140,6 +160,20 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
this.remote = new IpcProtocolRemoteImpl(delegate); this.remote = new IpcProtocolRemoteImpl(delegate);
UnicastRemoteObject.exportObject(remote, 0); UnicastRemoteObject.exportObject(remote, 0);
registry.rebind(RMI_NAME, remote); registry.rebind(RMI_NAME, remote);
this.portFilePath = portFilePath;
ServerCommunicator.writePort(portFilePath, socket.getLocalPort());
}
private static void writePort(Path portFilePath, int port) throws IOException {
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
buf.putInt(port);
buf.flip();
MoreFiles.createParentDirectories(portFilePath);
try (WritableByteChannel ch = Files.newByteChannel(portFilePath, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
if (ch.write(buf) != Integer.BYTES) {
throw new IOException("Did not write expected number of bytes.");
}
}
} }
@Override @Override
@@ -162,6 +196,7 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
registry.unbind(RMI_NAME); registry.unbind(RMI_NAME);
UnicastRemoteObject.unexportObject(remote, true); UnicastRemoteObject.unexportObject(remote, true);
socket.close(); socket.close();
Files.deleteIfExists(portFilePath);
LOG.debug("Server shut down."); LOG.debug("Server shut down.");
} catch (NotBoundException | IOException e) { } catch (NotBoundException | IOException e) {
LOG.warn("Failed to close IPC Server.", e); LOG.warn("Failed to close IPC Server.", e);
@@ -210,31 +245,30 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
} }
private static int readPort(Path path) throws IOException { /**
if (Files.notExists(path)) { * Creates client sockets with short timeouts.
return 0; */
} private static class ClientSocketFactory implements RMIClientSocketFactory {
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
try (ReadableByteChannel ch = Files.newByteChannel(path, StandardOpenOption.READ)) { @Override
if (ch.read(buf) == Integer.BYTES) { public Socket createSocket(String host, int port) throws IOException {
buf.flip(); return new SocketWithFixedTimeout(host, port, 1000);
return buf.getInt();
} else {
return 0;
}
} }
} }
private static void writePort(Path path, int port) throws IOException { private static class SocketWithFixedTimeout extends Socket {
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
buf.putInt(port); public SocketWithFixedTimeout(String host, int port, int timeoutInMs) throws UnknownHostException, IOException {
buf.flip(); super(host, port);
MoreFiles.createParentDirectories(path); super.setSoTimeout(timeoutInMs);
try (WritableByteChannel ch = Files.newByteChannel(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
if (ch.write(buf) != Integer.BYTES) {
throw new IOException("Did not write expected number of bytes.");
}
} }
@Override
public synchronized void setSoTimeout(int timeout) throws SocketException {
// do nothing, timeout is fixed
}
} }
} }
@@ -32,7 +32,6 @@ public class FileOpenRequestHandlerTest {
Mockito.when(fs.provider()).thenReturn(provider); Mockito.when(fs.provider()).thenReturn(provider);
Mockito.when(fs.getPath(Mockito.anyString())).thenReturn(p1, p2); Mockito.when(fs.getPath(Mockito.anyString())).thenReturn(p1, p2);
Mockito.when(provider.readAttributes(Mockito.any(), Mockito.eq(BasicFileAttributes.class))).thenReturn(attrs); Mockito.when(provider.readAttributes(Mockito.any(), Mockito.eq(BasicFileAttributes.class))).thenReturn(attrs);
Mockito.when(attrs.isRegularFile()).thenReturn(true);
BlockingQueue<Path> queue = new ArrayBlockingQueue<>(10); BlockingQueue<Path> queue = new ArrayBlockingQueue<>(10);
FileOpenRequestHandler handler = new FileOpenRequestHandler(queue); FileOpenRequestHandler handler = new FileOpenRequestHandler(queue);
+28 -23
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Cryptomator</name> <name>Cryptomator</name>
@@ -24,27 +24,27 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- dependency versions --> <!-- dependency versions -->
<cryptomator.cryptolib.version>1.1.5</cryptomator.cryptolib.version> <cryptomator.cryptolib.version>1.2.0</cryptomator.cryptolib.version>
<cryptomator.cryptofs.version>1.4.1</cryptomator.cryptofs.version> <cryptomator.cryptofs.version>1.5.2</cryptomator.cryptofs.version>
<cryptomator.webdav.version>0.6.2</cryptomator.webdav.version> <cryptomator.webdav.version>1.0.4</cryptomator.webdav.version>
<cryptomator.jni.version>1.0.2</cryptomator.jni.version> <cryptomator.jni.version>2.0.0</cryptomator.jni.version>
<cryptomator.fuse.version>0.1.4</cryptomator.fuse.version>
<commons-io.version>2.5</commons-io.version> <commons-io.version>2.5</commons-io.version>
<commons-lang3.version>3.6</commons-lang3.version> <commons-lang3.version>3.6</commons-lang3.version>
<httpclient.version>4.5.3</httpclient.version>
<easybind.version>1.0.3</easybind.version> <easybind.version>1.0.3</easybind.version>
<guava.version>22.0</guava.version> <guava.version>24.1-jre</guava.version>
<dagger.version>2.11</dagger.version> <dagger.version>2.14.1</dagger.version>
<gson.version>2.8.1</gson.version> <gson.version>2.8.2</gson.version>
<slf4j.version>1.7.25</slf4j.version> <slf4j.version>1.7.25</slf4j.version>
<logback.version>1.2.2</logback.version> <logback.version>1.2.3</logback.version>
<junit.version>4.12</junit.version> <junit.version>4.12</junit.version>
<junit.hierarchicalrunner.version>4.12.1</junit.hierarchicalrunner.version> <junit.hierarchicalrunner.version>4.12.1</junit.hierarchicalrunner.version>
<mockito.version>2.7.21</mockito.version> <mockito.version>2.11.0</mockito.version>
<hamcrest.version>1.3</hamcrest.version> <!-- keep in sync with version required by JUnit --> <hamcrest.version>1.3</hamcrest.version> <!-- keep in sync with version required by JUnit -->
</properties> </properties>
@@ -96,6 +96,11 @@
<artifactId>cryptofs</artifactId> <artifactId>cryptofs</artifactId>
<version>${cryptomator.cryptofs.version}</version> <version>${cryptomator.cryptofs.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>fuse-nio-adapter</artifactId>
<version>${cryptomator.fuse.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId> <artifactId>webdav-nio-adapter</artifactId>
@@ -140,11 +145,6 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version> <version>${commons-lang3.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<!-- EasyBind --> <!-- EasyBind -->
<dependency> <dependency>
@@ -264,7 +264,7 @@
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-dependency-plugin</artifactId> <artifactId>maven-dependency-plugin</artifactId>
<version>3.0.1</version> <version>3.1.0</version>
<executions> <executions>
<execution> <execution>
<id>copy-libs</id> <id>copy-libs</id>
@@ -281,7 +281,7 @@
<plugin> <plugin>
<groupId>org.jacoco</groupId> <groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version> <version>0.8.1</version>
<executions> <executions>
<execution> <execution>
<id>prepare-agent</id> <id>prepare-agent</id>
@@ -302,10 +302,15 @@
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version> <version>3.7.0</version>
<configuration> <configuration>
<source>1.8</source> <source>9</source>
<target>1.8</target> <target>9</target>
<release>9</release>
<compilerArgs>
<arg>--add-modules</arg>
<arg>jdk.incubator.httpclient</arg>
</compilerArgs>
<annotationProcessorPaths> <annotationProcessorPaths>
<path> <path>
<groupId>com.google.dagger</groupId> <groupId>com.google.dagger</groupId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
</parent> </parent>
<artifactId>uber-jar</artifactId> <artifactId>uber-jar</artifactId>
<name>Single über jar with all dependencies</name> <name>Single über jar with all dependencies</name>
+14 -6
View File
@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.3.1</version> <version>1.4.0-beta1</version>
</parent> </parent>
<artifactId>ui</artifactId> <artifactId>ui</artifactId>
<name>Cryptomator GUI</name> <name>Cryptomator GUI</name>
@@ -30,7 +30,11 @@
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>keychain</artifactId> <artifactId>keychain</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>fuse-nio-adapter</artifactId>
</dependency>
<!-- CryptoLib --> <!-- CryptoLib -->
<dependency> <dependency>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
@@ -62,10 +66,6 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- DI --> <!-- DI -->
<dependency> <dependency>
@@ -86,5 +86,13 @@
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- Testing -->
<dependency>
<groupId>com.google.jimfs</groupId>
<artifactId>jimfs</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>
@@ -16,22 +16,20 @@ import java.util.function.Consumer;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import javafx.beans.binding.Binding;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.CommonsModule; import org.cryptomator.common.CommonsModule;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider; import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.frontend.webdav.WebDavServer; import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.jni.JniModule;
import org.cryptomator.keychain.KeychainModule; import org.cryptomator.keychain.KeychainModule;
import org.cryptomator.ui.controllers.ViewControllerModule; import org.cryptomator.ui.controllers.ViewControllerModule;
import org.cryptomator.ui.model.VaultComponent; import org.cryptomator.ui.model.VaultComponent;
import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.EasyBind;
import dagger.Module; @Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class}, subcomponents = {VaultComponent.class})
import dagger.Provides;
import javafx.beans.binding.Binding;
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class, JniModule.class}, subcomponents = {VaultComponent.class})
public class UiModule { public class UiModule {
@Provides @Provides
@@ -119,6 +119,11 @@ public class ChangePasswordController implements ViewController {
return root; return root;
} }
@Override
public void focus() {
oldPasswordField.requestFocus();
}
void setVault(Vault vault) { void setVault(Vault vault) {
this.vault = Objects.requireNonNull(vault); this.vault = Objects.requireNonNull(vault);
// trigger "default" change to refresh key bindings: // trigger "default" change to refresh key bindings:
@@ -10,7 +10,6 @@
package org.cryptomator.ui.controllers; package org.cryptomator.ui.controllers;
import java.io.IOException; import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileAlreadyExistsException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@@ -106,6 +105,11 @@ public class InitializeController implements ViewController {
return root; return root;
} }
@Override
public void focus() {
passwordField.requestFocus();
}
void setVault(Vault vault) { void setVault(Vault vault) {
this.vault = Objects.requireNonNull(vault); this.vault = Objects.requireNonNull(vault);
// trigger "default" change to refresh key bindings: // trigger "default" change to refresh key bindings:
@@ -125,8 +129,6 @@ public class InitializeController implements ViewController {
listener.ifPresent(this::invokeListenerLater); listener.ifPresent(this::invokeListenerLater);
} catch (FileAlreadyExistsException ex) { } catch (FileAlreadyExistsException ex) {
messageLabel.setText(localization.getString("initialize.messageLabel.alreadyInitialized")); messageLabel.setText(localization.getString("initialize.messageLabel.alreadyInitialized"));
} catch (DirectoryNotEmptyException ex) {
messageLabel.setText(localization.getString("initialize.messageLabel.notEmpty"));
} catch (IOException ex) { } catch (IOException ex) {
LOG.error("I/O Exception", ex); LOG.error("I/O Exception", ex);
messageLabel.setText(localization.getString("initialize.messageLabel.initializationFailed")); messageLabel.setText(localization.getString("initialize.messageLabel.initializationFailed"));
@@ -9,6 +9,7 @@
******************************************************************************/ ******************************************************************************/
package org.cryptomator.ui.controllers; package org.cryptomator.ui.controllers;
import java.awt.Desktop;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -20,30 +21,12 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.stream.Stream;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.ExitUtil;
import org.cryptomator.ui.controls.DirectoryListCell;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.AutoUnlocker;
import org.cryptomator.ui.model.UpgradeStrategies;
import org.cryptomator.ui.model.UpgradeStrategy;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.VaultFactory;
import org.cryptomator.ui.model.VaultList;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.cryptomator.ui.util.EawtApplicationWrapper;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.fxmisc.easybind.monadic.MonadicBinding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Binding; import javafx.beans.binding.Binding;
@@ -63,17 +46,40 @@ import javafx.scene.Scene;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
import javafx.scene.control.Cell;
import javafx.scene.control.ContextMenu; import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListCell; import javafx.scene.control.ListCell;
import javafx.scene.control.ListView; import javafx.scene.control.ListView;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.text.Font; import javafx.scene.text.Font;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.ExitUtil;
import org.cryptomator.ui.controls.DirectoryListCell;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.AutoUnlocker;
import org.cryptomator.ui.model.UpgradeStrategies;
import org.cryptomator.ui.model.UpgradeStrategy;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.VaultFactory;
import org.cryptomator.ui.model.VaultList;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.fxmisc.easybind.monadic.MonadicBinding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildErrorDialog;
@Singleton @Singleton
public class MainController implements ViewController { public class MainController implements ViewController {
@@ -122,11 +128,13 @@ public class MainController implements ViewController {
EasyBind.subscribe(areAllVaultsLocked, Platform::setImplicitExit); EasyBind.subscribe(areAllVaultsLocked, Platform::setImplicitExit);
autoUnlocker.unlockAllSilently(); autoUnlocker.unlockAllSilently();
EawtApplicationWrapper.getApplication().ifPresent(app -> { try {
app.setPreferencesHandler(() -> { Desktop.getDesktop().setPreferencesHandler(e -> {
Platform.runLater(this::toggleShowSettings); Platform.runLater(this::toggleShowSettings);
}); });
}); } catch (UnsupportedOperationException e) {
LOG.info("Unable to setPreferencesHandler, probably not supported on this OS.");
}
} }
@FXML @FXML
@@ -162,7 +170,10 @@ public class MainController implements ViewController {
@Override @Override
public void initialize() { public void initialize() {
vaultList.setItems(vaults); vaultList.setItems(vaults);
vaultList.getSelectionModel().clearSelection();
vaultList.setOnKeyReleased(this::didPressKeyOnList);
vaultList.setCellFactory(this::createDirecoryListCell); vaultList.setCellFactory(this::createDirecoryListCell);
root.setOnKeyReleased(this::didPressKeyOnRoot);
activeController.set(viewControllerLoader.load("/fxml/welcome.fxml")); activeController.set(viewControllerLoader.load("/fxml/welcome.fxml"));
selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty()); selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty());
removeVaultButton.disableProperty().bind(canEditSelectedVault.not()); removeVaultButton.disableProperty().bind(canEditSelectedVault.not());
@@ -183,6 +194,7 @@ public class MainController implements ViewController {
public void initStage(Stage stage) { public void initStage(Stage stage) {
stage.setScene(new Scene(getRoot())); stage.setScene(new Scene(getRoot()));
stage.sizeToScene(); stage.sizeToScene();
stage.setTitle(localization.getString("app.name")); // set once before bind to avoid display bugs with Linux window managers
stage.titleProperty().bind(windowTitle()); stage.titleProperty().bind(windowTitle());
stage.setResizable(false); stage.setResizable(false);
loadFont("/css/ionicons.ttf"); loadFont("/css/ionicons.ttf");
@@ -192,9 +204,10 @@ public class MainController implements ViewController {
subs = subs.and(EasyBind.includeWhen(mainWindow.getScene().getRoot().getStyleClass(), INACTIVE_WINDOW_STYLE_CLASS, mainWindow.focusedProperty().not())); subs = subs.and(EasyBind.includeWhen(mainWindow.getScene().getRoot().getStyleClass(), INACTIVE_WINDOW_STYLE_CLASS, mainWindow.focusedProperty().not()));
Application.setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString()); Application.setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString());
} else if (SystemUtils.IS_OS_LINUX) { } else if (SystemUtils.IS_OS_LINUX) {
stage.getIcons().add(new Image(getClass().getResourceAsStream("/window_icon_512.png")));
Application.setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString()); Application.setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString());
} else if (SystemUtils.IS_OS_WINDOWS) { } else if (SystemUtils.IS_OS_WINDOWS) {
stage.getIcons().add(new Image(getClass().getResourceAsStream("/window_icon.png"))); stage.getIcons().add(new Image(getClass().getResourceAsStream("/window_icon_32.png")));
Application.setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString()); Application.setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
} }
exitUtil.initExitHandler(this::gracefulShutdown); exitUtil.initExitHandler(this::gracefulShutdown);
@@ -236,6 +249,7 @@ public class MainController implements ViewController {
private ListCell<Vault> createDirecoryListCell(ListView<Vault> param) { private ListCell<Vault> createDirecoryListCell(ListView<Vault> param) {
final DirectoryListCell cell = new DirectoryListCell(); final DirectoryListCell cell = new DirectoryListCell();
cell.setVaultContextMenu(vaultListCellContextMenu); cell.setVaultContextMenu(vaultListCellContextMenu);
cell.setOnMouseClicked(this::didClickOnListCell);
return cell; return cell;
} }
@@ -261,7 +275,18 @@ public class MainController implements ViewController {
} }
try { try {
final Path vaultDir = file.toPath(); final Path vaultDir = file.toPath();
if (!Files.exists(vaultDir)) { if (Files.exists(vaultDir)) {
try (Stream<Path> stream = Files.list(vaultDir)) {
if (stream.filter(this::isNotHidden).findAny().isPresent()) {
buildErrorDialog( //
localization.getString("main.createVault.nonEmptyDir.title"), //
localization.getString("main.createVault.nonEmptyDir.header"), //
localization.getString("main.createVault.nonEmptyDir.content"), //
ButtonType.OK).show();
return;
}
}
} else {
Files.createDirectory(vaultDir); Files.createDirectory(vaultDir);
} }
addVault(vaultDir, true); addVault(vaultDir, true);
@@ -270,6 +295,10 @@ public class MainController implements ViewController {
} }
} }
private boolean isNotHidden(Path file) {
return !file.getFileName().toString().startsWith(".");
}
@FXML @FXML
private void didClickAddExistingVaults(ActionEvent event) { private void didClickAddExistingVaults(ActionEvent event) {
final FileChooser fileChooser = new FileChooser(); final FileChooser fileChooser = new FileChooser();
@@ -291,7 +320,7 @@ public class MainController implements ViewController {
final Path vaultPath; final Path vaultPath;
if (path != null && Files.isDirectory(path)) { if (path != null && Files.isDirectory(path)) {
vaultPath = path; vaultPath = path;
} else if (path != null && Files.isRegularFile(path)) { } else if (path != null && Files.isReadable(path)) {
vaultPath = path.getParent(); vaultPath = path.getParent();
} else { } else {
LOG.warn("Ignoring attempt to add vault with invalid path: {}", path); LOG.warn("Ignoring attempt to add vault with invalid path: {}", path);
@@ -309,6 +338,7 @@ public class MainController implements ViewController {
} }
if (select) { if (select) {
vaultList.getSelectionModel().select(vault); vaultList.getSelectionModel().select(vault);
activeController.get().focus();
} }
} }
@@ -325,6 +355,8 @@ public class MainController implements ViewController {
vaults.remove(selectedVault.get()); vaults.remove(selectedVault.get());
if (vaults.isEmpty()) { if (vaults.isEmpty()) {
activeController.set(viewControllerLoader.load("/fxml/welcome.fxml")); activeController.set(viewControllerLoader.load("/fxml/welcome.fxml"));
} else {
activeController.get().focus();
} }
} }
} }
@@ -369,12 +401,42 @@ public class MainController implements ViewController {
} else if (newValue.isValidVaultDirectory() && upgradeStrategyForSelectedVault.isPresent()) { } else if (newValue.isValidVaultDirectory() && upgradeStrategyForSelectedVault.isPresent()) {
this.showUpgradeView(); this.showUpgradeView();
} else if (newValue.isValidVaultDirectory()) { } else if (newValue.isValidVaultDirectory()) {
this.showUnlockView(); this.showUnlockView(UnlockController.State.UNLOCKING);
} else { } else {
this.showInitializeView(); this.showInitializeView();
} }
} }
private void didPressKeyOnList(KeyEvent e) {
if (e.getCode() == KeyCode.ENTER || e.getCode() == KeyCode.SPACE) {
activeController.get().focus();
}
}
private void didPressKeyOnRoot(KeyEvent event) {
if ((event.isMetaDown() || event.isControlDown()) && event.getCode().isDigitKey()) {
int digit = Integer.valueOf(event.getText());
switch (digit) {
case 0: {
vaultList.getSelectionModel().clearSelection();
showWelcomeView();
return;
}
default: {
vaultList.getSelectionModel().select(digit - 1);
activeController.get().focus();
return;
}
}
}
}
private void didClickOnListCell(MouseEvent e) {
if (MouseEvent.MOUSE_CLICKED.equals(e.getEventType()) && e.getSource() instanceof Cell && ((Cell<?>) e.getSource()).isSelected()) {
activeController.get().focus();
}
}
// **************************************** // ****************************************
// Public Bindings // Public Bindings
// **************************************** // ****************************************
@@ -407,7 +469,8 @@ public class MainController implements ViewController {
} }
public void didInitialize() { public void didInitialize() {
showUnlockView(); showUnlockView(UnlockController.State.INITIALIZED);
activeController.get().focus();
} }
private void showUpgradeView() { private void showUpgradeView() {
@@ -418,12 +481,13 @@ public class MainController implements ViewController {
} }
public void didUpgrade() { public void didUpgrade() {
showUnlockView(); showUnlockView(UnlockController.State.UPGRADED);
activeController.get().focus();
} }
private void showUnlockView() { private void showUnlockView(UnlockController.State state) {
final UnlockController ctrl = viewControllerLoader.load("/fxml/unlock.fxml"); final UnlockController ctrl = viewControllerLoader.load("/fxml/unlock.fxml");
ctrl.setVault(selectedVault.get()); ctrl.setVault(selectedVault.get(), state);
ctrl.setListener(this::didUnlock); ctrl.setListener(this::didUnlock);
activeController.set(ctrl); activeController.set(ctrl);
} }
@@ -445,7 +509,8 @@ public class MainController implements ViewController {
public void didLock(UnlockedController ctrl) { public void didLock(UnlockedController ctrl) {
unlockedVaults.remove(ctrl.getVault()); unlockedVaults.remove(ctrl.getVault());
showUnlockView(); showUnlockView(UnlockController.State.UNLOCKING);
activeController.get().focus();
} }
private void showChangePasswordView() { private void showChangePasswordView() {
@@ -453,10 +518,12 @@ public class MainController implements ViewController {
ctrl.setVault(selectedVault.get()); ctrl.setVault(selectedVault.get());
ctrl.setListener(this::didChangePassword); ctrl.setListener(this::didChangePassword);
activeController.set(ctrl); activeController.set(ctrl);
Platform.runLater(ctrl::focus);
} }
public void didChangePassword() { public void didChangePassword() {
showUnlockView(); showUnlockView(UnlockController.State.PASSWORD_CHANGED);
activeController.get().focus();
} }
} }
@@ -2,7 +2,7 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel * Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved. * All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file. * This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
* *
* Contributors: * Contributors:
* Sebastian Stenzel - initial API and implementation * Sebastian Stenzel - initial API and implementation
******************************************************************************/ ******************************************************************************/
@@ -14,13 +14,8 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.l10n.Localization;
import com.google.common.base.CharMatcher; import com.google.common.base.CharMatcher;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@@ -31,7 +26,13 @@ import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox; 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.ui.l10n.Localization;
@Singleton @Singleton
public class SettingsController implements ViewController { public class SettingsController implements ViewController {
@@ -52,6 +53,15 @@ public class SettingsController implements ViewController {
@FXML @FXML
private CheckBox checkForUpdatesCheckbox; private CheckBox checkForUpdatesCheckbox;
@FXML
private GridPane webdavVolume;
@FXML
private GridPane fuseVolume;
@FXML
private Label portFieldLabel;
@FXML @FXML
private TextField portField; private TextField portField;
@@ -67,6 +77,12 @@ public class SettingsController implements ViewController {
@FXML @FXML
private ChoiceBox<String> prefGvfsScheme; private ChoiceBox<String> prefGvfsScheme;
@FXML
private Label volumeLabel;
@FXML
private ChoiceBox<VolumeImpl> volume;
@FXML @FXML
private CheckBox debugModeCheckbox; private CheckBox debugModeCheckbox;
@@ -75,25 +91,51 @@ public class SettingsController implements ViewController {
@Override @Override
public void initialize() { public void initialize() {
versionLabel.setText(String.format(localization.getString("settings.version.label"), applicationVersion.orElse("SNAPSHOT")));
checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally()); checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally());
checkForUpdatesCheckbox.setSelected(settings.checkForUpdates().get() && !areUpdatesManagedExternally()); checkForUpdatesCheckbox.setSelected(settings.checkForUpdates().get() && !areUpdatesManagedExternally());
//NIOADAPTER
volume.getItems().addAll(getSupportedAdapters());
volume.setValue(settings.volumeImpl().get());
volume.setVisible(true);
volume.setConverter(new NioAdapterImplStringConverter());
//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());
portField.setText(String.valueOf(settings.port().intValue())); portField.setText(String.valueOf(settings.port().intValue()));
portField.addEventFilter(KeyEvent.KEY_TYPED, this::filterNumericKeyEvents); portField.addEventFilter(KeyEvent.KEY_TYPED, this::filterNumericKeyEvents);
changePortButton.visibleProperty().bind(settings.port().asString().isNotEqualTo(portField.textProperty())); changePortButton.visibleProperty().bind(settings.port().asString().isNotEqualTo(portField.textProperty()));
changePortButton.disableProperty().bind(Bindings.createBooleanBinding(this::isPortValid, portField.textProperty()).not()); changePortButton.disableProperty().bind(Bindings.createBooleanBinding(this::isPortValid, portField.textProperty()).not());
versionLabel.setText(String.format(localization.getString("settings.version.label"), applicationVersion.orElse("SNAPSHOT")));
prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX);
prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX);
prefGvfsScheme.getItems().add("dav"); prefGvfsScheme.getItems().add("dav");
prefGvfsScheme.getItems().add("webdav"); prefGvfsScheme.getItems().add("webdav");
prefGvfsScheme.setValue(settings.preferredGvfsScheme().get()); prefGvfsScheme.setValue(settings.preferredGvfsScheme().get());
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()); debugModeCheckbox.setSelected(settings.debugMode().get());
settings.checkForUpdates().bind(checkForUpdatesCheckbox.selectedProperty()); settings.checkForUpdates().bind(checkForUpdatesCheckbox.selectedProperty());
settings.preferredGvfsScheme().bind(prefGvfsScheme.valueProperty()); settings.preferredGvfsScheme().bind(prefGvfsScheme.valueProperty());
settings.volumeImpl().bind(volume.valueProperty());
settings.debugMode().bind(debugModeCheckbox.selectedProperty()); settings.debugMode().bind(debugModeCheckbox.selectedProperty());
} }
//TODO: how to implement this?
private VolumeImpl[] getSupportedAdapters() {
return new VolumeImpl[]{VolumeImpl.FUSE, VolumeImpl.WEBDAV};
}
@Override @Override
public Parent getRoot() { public Parent getRoot() {
return root; return root;
@@ -133,4 +175,17 @@ public class SettingsController implements ViewController {
return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false")); return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
} }
private static class NioAdapterImplStringConverter extends StringConverter<VolumeImpl> {
@Override
public String toString(VolumeImpl object) {
return object.getDisplayName();
}
@Override
public VolumeImpl fromString(String string) {
return VolumeImpl.forDisplayName(string);
}
}
} }
@@ -2,13 +2,14 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel * Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved. * All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file. * This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
* *
* Contributors: * Contributors:
* Sebastian Stenzel - initial API and implementation * Sebastian Stenzel - initial API and implementation
******************************************************************************/ ******************************************************************************/
package org.cryptomator.ui.controllers; package org.cryptomator.ui.controllers;
import java.io.IOException; import java.io.IOException;
import java.nio.file.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.Objects; import java.util.Objects;
@@ -16,8 +17,12 @@ import java.util.Optional;
import javax.inject.Inject; 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.CharUtils;
import org.apache.commons.lang3.SystemUtils; 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.common.settings.VaultSettings;
import org.cryptomator.cryptolib.api.InvalidPassphraseException; import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException; import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
@@ -72,17 +77,19 @@ public class UnlockController implements ViewController {
private final WindowsDriveLetters driveLetters; private final WindowsDriveLetters driveLetters;
private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange; private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange;
private final Optional<KeychainAccess> keychainAccess; private final Optional<KeychainAccess> keychainAccess;
private final Settings settings;
private Vault vault; private Vault vault;
private Optional<UnlockListener> listener = Optional.empty(); private Optional<UnlockListener> listener = Optional.empty();
private Subscription vaultSubs = Subscription.EMPTY; private Subscription vaultSubs = Subscription.EMPTY;
@Inject @Inject
public UnlockController(Application app, Localization localization, AsyncTaskService asyncTaskService, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess) { public UnlockController(Application app, Localization localization, AsyncTaskService asyncTaskService, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess, Settings settings) {
this.app = app; this.app = app;
this.localization = localization; this.localization = localization;
this.asyncTaskService = asyncTaskService; this.asyncTaskService = asyncTaskService;
this.driveLetters = driveLetters; this.driveLetters = driveLetters;
this.keychainAccess = keychainAccess; this.keychainAccess = keychainAccess;
this.settings = settings;
} }
@FXML @FXML
@@ -94,6 +101,9 @@ public class UnlockController implements ViewController {
@FXML @FXML
private Button unlockButton; private Button unlockButton;
@FXML
private Label successMessage;
@FXML @FXML
private CheckBox savePassword; private CheckBox savePassword;
@@ -112,6 +122,21 @@ public class UnlockController implements ViewController {
@FXML @FXML
private ChoiceBox<Character> winDriveLetter; private ChoiceBox<Character> winDriveLetter;
@FXML
private CheckBox useOwnMountPath;
@FXML
private HBox mountPathBox;
@FXML
private Label mountPathLabel;
@FXML
private TextField mountPath;
@FXML
private Button changeMountPathButton;
@FXML @FXML
private ProgressIndicator progressIndicator; private ProgressIndicator progressIndicator;
@@ -140,14 +165,35 @@ public class UnlockController implements ViewController {
mountName.textProperty().addListener(this::mountNameDidChange); mountName.textProperty().addListener(this::mountNameDidChange);
savePassword.setDisable(!keychainAccess.isPresent()); savePassword.setDisable(!keychainAccess.isPresent());
unlockAfterStartup.disableProperty().bind(savePassword.disabledProperty().or(savePassword.selectedProperty().not())); 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());
if (SystemUtils.IS_OS_WINDOWS) { if (SystemUtils.IS_OS_WINDOWS) {
winDriveLetter.setConverter(new WinDriveLetterLabelConverter()); winDriveLetter.setConverter(new WinDriveLetterLabelConverter());
useOwnMountPath.setVisible(false);
useOwnMountPath.setManaged(false);
mountPathLabel.setManaged(false);
//dirty cheat
mountPathBox.setMouseTransparent(true);
} else { } else {
winDriveLetterLabel.setVisible(false); winDriveLetterLabel.setVisible(false);
winDriveLetterLabel.setManaged(false); winDriveLetterLabel.setManaged(false);
winDriveLetter.setVisible(false); winDriveLetter.setVisible(false);
winDriveLetter.setManaged(false); winDriveLetter.setManaged(false);
if (VolumeImpl.WEBDAV.equals(settings.volumeImpl().get())) {
useOwnMountPath.setVisible(false);
useOwnMountPath.setManaged(false);
mountPathLabel.setManaged(false);
}
} }
changeMountPathButton.disableProperty().bind(Bindings.createBooleanBinding(this::isDirVaild, mountPath.textProperty()).not());
} }
@Override @Override
@@ -155,7 +201,12 @@ public class UnlockController implements ViewController {
return root; return root;
} }
void setVault(Vault vault) { @Override
public void focus() {
passwordField.requestFocus();
}
void setVault(Vault vault, State state) {
vaultSubs.unsubscribe(); vaultSubs.unsubscribe();
vaultSubs = Subscription.EMPTY; vaultSubs = Subscription.EMPTY;
@@ -170,6 +221,8 @@ public class UnlockController implements ViewController {
advancedOptions.setVisible(false); advancedOptions.setVisible(false);
advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.show")); advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.show"));
progressIndicator.setVisible(false); progressIndicator.setVisible(false);
successMessage.setVisible(state.successMessage().isPresent());
state.successMessage().map(localization::getString).ifPresent(successMessage::setText);
if (SystemUtils.IS_OS_WINDOWS) { if (SystemUtils.IS_OS_WINDOWS) {
winDriveLetter.valueProperty().removeListener(driveLetterChangeListener); winDriveLetter.valueProperty().removeListener(driveLetterChangeListener);
winDriveLetter.getItems().clear(); winDriveLetter.getItems().clear();
@@ -195,14 +248,23 @@ public class UnlockController implements ViewController {
Arrays.fill(storedPw, ' '); Arrays.fill(storedPw, ' ');
} }
} }
VaultSettings settings = vault.getVaultSettings(); VaultSettings vaultSettings = vault.getVaultSettings();
unlockAfterStartup.setSelected(savePassword.isSelected() && settings.unlockAfterStartup().get()); unlockAfterStartup.setSelected(savePassword.isSelected() && vaultSettings.unlockAfterStartup().get());
mountAfterUnlock.setSelected(settings.mountAfterUnlock().get()); mountAfterUnlock.setSelected(vaultSettings.mountAfterUnlock().get());
revealAfterMount.setSelected(settings.revealAfterMount().get()); revealAfterMount.setSelected(vaultSettings.revealAfterMount().get());
useOwnMountPath.setSelected(vaultSettings.usesIndividualMountPath().get());
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(unlockAfterStartup.selectedProperty(), settings.unlockAfterStartup()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(mountAfterUnlock.selectedProperty(), settings.mountAfterUnlock()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(revealAfterMount.selectedProperty(), settings.revealAfterMount()::set));
} }
// **************************************** // ****************************************
@@ -220,6 +282,7 @@ public class UnlockController implements ViewController {
@FXML @FXML
private void didClickAdvancedOptionsButton(ActionEvent event) { private void didClickAdvancedOptionsButton(ActionEvent event) {
successMessage.setVisible(false);
advancedOptions.setVisible(!advancedOptions.isVisible()); advancedOptions.setVisible(!advancedOptions.isVisible());
if (advancedOptions.isVisible()) { if (advancedOptions.isVisible()) {
advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.hide")); advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.hide"));
@@ -228,6 +291,28 @@ 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) { private void filterAlphanumericKeyEvents(KeyEvent t) {
if (!Strings.isNullOrEmpty(t.getCharacter()) && !ALPHA_NUMERIC_MATCHER.matchesAllOf(t.getCharacter())) { if (!Strings.isNullOrEmpty(t.getCharacter()) && !ALPHA_NUMERIC_MATCHER.matchesAllOf(t.getCharacter())) {
t.consume(); t.consume();
@@ -392,7 +477,28 @@ public class UnlockController implements ViewController {
@FunctionalInterface @FunctionalInterface
interface UnlockListener { interface UnlockListener {
void didUnlock(Vault vault); void didUnlock(Vault vault);
} }
/* state */
public enum State {
UNLOCKING(null),
INITIALIZED("unlock.successLabel.vaultCreated"),
PASSWORD_CHANGED("unlock.successLabel.passwordChanged"),
UPGRADED("unlock.successLabel.upgraded");
private Optional<String> successMessage;
State(String successMessage) {
this.successMessage = Optional.ofNullable(successMessage);
}
public Optional<String> successMessage() {
return successMessage;
}
}
} }
@@ -244,8 +244,8 @@ public class UnlockedController implements ViewController {
@FXML @FXML
private void didClickCopyUrl(ActionEvent event) { private void didClickCopyUrl(ActionEvent event) {
ClipboardContent clipboardContent = new ClipboardContent(); ClipboardContent clipboardContent = new ClipboardContent();
clipboardContent.putUrl(vault.get().getWebDavUrl()); clipboardContent.putUrl(vault.get().getFilesystemRootUrl());
clipboardContent.putString(vault.get().getWebDavUrl()); clipboardContent.putString(vault.get().getFilesystemRootUrl());
Clipboard.getSystemClipboard().setContent(clipboardContent); Clipboard.getSystemClipboard().setContent(clipboardContent);
} }
@@ -84,6 +84,11 @@ public class UpgradeController implements ViewController {
return root; return root;
} }
@Override
public void focus() {
passwordField.requestFocus();
}
void setVault(Vault vault) { void setVault(Vault vault) {
this.vault = Objects.requireNonNull(vault); this.vault = Objects.requireNonNull(vault);
errorLabel.setText(null); errorLabel.setText(null);
@@ -24,4 +24,8 @@ public interface ViewController extends Initializable {
// no-op // no-op
} }
default void focus() {
// no-op
}
} }
@@ -8,11 +8,10 @@
******************************************************************************/ ******************************************************************************/
package org.cryptomator.ui.controllers; package org.cryptomator.ui.controllers;
import java.io.InputStream; import java.net.URI;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Comparator; import java.util.Comparator;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@@ -22,23 +21,9 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.apache.commons.lang3.SystemUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.util.AsyncTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
@@ -49,6 +34,15 @@ import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator; import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.VBox; 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.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton @Singleton
public class WelcomeController implements ViewController { public class WelcomeController implements ViewController {
@@ -114,31 +108,21 @@ public class WelcomeController implements ViewController {
checkForUpdatesStatus.setText(localization.getString("welcome.checkForUpdates.label.currentlyChecking")); checkForUpdatesStatus.setText(localization.getString("welcome.checkForUpdates.label.currentlyChecking"));
checkForUpdatesIndicator.setVisible(true); checkForUpdatesIndicator.setVisible(true);
asyncTaskService.asyncTaskOf(() -> { asyncTaskService.asyncTaskOf(() -> {
RequestConfig requestConfig = RequestConfig.custom() //
.setConnectTimeout(5000) //
.setConnectionRequestTimeout(5000) //
.setSocketTimeout(5000) //
.build();
String userAgent = String.format("Cryptomator VersionChecker/%s %s %s (%s)", applicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH); String userAgent = String.format("Cryptomator VersionChecker/%s %s %s (%s)", applicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
HttpClientBuilder httpClientBuilder = HttpClients.custom() // HttpClient client = HttpClient.newHttpClient();
.disableCookieManagement() // HttpRequest request = HttpRequest.newBuilder()
.setDefaultRequestConfig(requestConfig) // .GET()
.setUserAgent(userAgent); .uri(new URI("https://api.cryptomator.org/updates/latestVersion.json"))
LOG.debug("Checking for updates..."); .header("User-Agent", userAgent)
try (CloseableHttpClient client = httpClientBuilder.build()) { .timeout(Duration.ofSeconds(5))
HttpGet request = new HttpGet("https://api.cryptomator.org/updates/latestVersion.json"); .build();
try (CloseableHttpResponse response = client.execute(request)) { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandler.asString(StandardCharsets.UTF_8));
if (response.getStatusLine().getStatusCode() == 200 && response.getEntity() != null) { if (response.statusCode() == 200) {
try (InputStream in = response.getEntity().getContent()) { Gson gson = new GsonBuilder().setLenient().create();
Gson gson = new GsonBuilder().setLenient().create(); Map<String, String> map = gson.fromJson(response.body(), new TypeToken<Map<String, String>>() {
Reader utf8Reader = new InputStreamReader(in, StandardCharsets.UTF_8); }.getType());
Map<String, String> map = gson.fromJson(utf8Reader, new TypeToken<Map<String, String>>() { if (map != null) {
}.getType()); this.compareVersions(map);
if (map != null) {
this.compareVersions(map);
}
}
}
} }
} }
}).andFinally(() -> { }).andFinally(() -> {
@@ -11,6 +11,9 @@ package org.cryptomator.ui.controls;
import java.util.Arrays; import java.util.Arrays;
import javafx.scene.control.PasswordField; import javafx.scene.control.PasswordField;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
/** /**
* Compromise in security. While the text can be swiped, any access to the {@link #getText()} method will create a copy of the String in the heap. * Compromise in security. While the text can be swiped, any access to the {@link #getText()} method will create a copy of the String in the heap.
@@ -19,6 +22,27 @@ public class SecPasswordField extends PasswordField {
private static final char SWIPE_CHAR = ' '; private static final char SWIPE_CHAR = ' ';
public SecPasswordField() {
this.onDragOverProperty().set(this::handleDragOver);
this.onDragDroppedProperty().set(this::handleDragDropped);
}
private void handleDragOver(DragEvent event) {
Dragboard dragboard = event.getDragboard();
if (dragboard.hasString() && dragboard.getString() != null) {
event.acceptTransferModes(TransferMode.COPY);
}
event.consume();
}
private void handleDragDropped(DragEvent event) {
Dragboard dragboard = event.getDragboard();
if (dragboard.hasString() && dragboard.getString() != null) {
insertText(getCaretPosition(), dragboard.getString());
}
event.consume();
}
/** /**
* {@link #getContent()} uses a StringBuilder, which in turn is backed by a char[]. * {@link #getContent()} uses a StringBuilder, which in turn is backed by a char[].
* The delete operation of AbstractStringBuilder closes the gap, that forms by deleting chars, by moving up the following chars. * The delete operation of AbstractStringBuilder closes the gap, that forms by deleting chars, by moving up the following chars.
@@ -18,7 +18,6 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.cryptomator.cryptolib.api.CryptoException; import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
import org.cryptomator.keychain.KeychainAccess; import org.cryptomator.keychain.KeychainAccess;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -0,0 +1,17 @@
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,144 @@
package org.cryptomator.ui.model;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
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.EnvironmentVariables;
import org.cryptomator.frontend.fuse.mount.FuseMountFactory;
import org.cryptomator.frontend.fuse.mount.FuseNotSupportedException;
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);
/**
* TODO: dont use fixed Strings and rather set them in some system environment variables in the cryptomator installer and load those!
*/
private static final String DEFAULT_MOUNTROOTPATH_MAC = System.getProperty("user.home") + "/Library/Application Support/Cryptomator";
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) {
this.vaultSettings = vaultSettings;
this.windowsDriveLetters = windowsDriveLetters;
this.extraDirCreated = false;
}
@Override
public void prepare(CryptoFileSystem fs) throws IOException, FuseNotSupportedException {
this.cfs = fs;
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()) {
//specific path given
mountPath = vaultSettings.individualMountPath().get();
} else {
//choose default path & create extra directory
mountPath = createDirIfNotExist(SystemUtils.IS_OS_MAC ? DEFAULT_MOUNTROOTPATH_MAC : DEFAULT_MOUNTROOTPATH_LINUX, vaultSettings.mountName().get());
extraDirCreated = true;
}
this.mountPath = Paths.get(mountPath).toAbsolutePath();
}
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.");
} else {
Files.createDirectory(p);
return p.toString();
}
}
@Override
public void mount() throws CommandFailedException {
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);
}
}
@Override
public void reveal() throws CommandFailedException {
try {
fuseMnt.revealInFileManager();
} catch (org.cryptomator.frontend.fuse.mount.CommandFailedException e) {
LOG.info("Revealing the vault in file manger failed: " + e.getMessage());
throw new CommandFailedException(e);
}
}
@Override
public synchronized void unmount() throws CommandFailedException {
try {
fuseMnt.close();
} catch (org.cryptomator.frontend.fuse.mount.CommandFailedException e) {
throw new CommandFailedException(e);
}
}
@Override
public synchronized void unmountForced() throws CommandFailedException {
unmount();
}
@Override
public void stop() {
if (extraDirCreated) {
try {
Files.delete(mountPath);
} catch (IOException e) {
LOG.warn("Could not delete mounting directory:" + e.getMessage());
}
}
}
@Override
public String getMountUri() {
return "";
}
@Override
public boolean isSupported() {
return FuseMountFactory.isFuseSupported();
}
@Override
public boolean supportsForcedUnmount() {
return false;
}
}
@@ -112,13 +112,8 @@ public abstract class UpgradeStrategy {
public boolean isApplicable(Vault vault) { public boolean isApplicable(Vault vault) {
final Path masterkeyFile = vault.getPath().resolve(MASTERKEY_FILENAME); final Path masterkeyFile = vault.getPath().resolve(MASTERKEY_FILENAME);
try { try {
if (Files.isRegularFile(masterkeyFile)) { byte[] masterkeyFileContents = Files.readAllBytes(masterkeyFile);
byte[] masterkeyFileContents = Files.readAllBytes(masterkeyFile); return KeyFile.parse(masterkeyFileContents).getVersion() == vaultVersionBeforeUpgrade;
return KeyFile.parse(masterkeyFileContents).getVersion() == vaultVersionBeforeUpgrade;
} else {
LOG.warn("Not a file: {}", masterkeyFile);
return false;
}
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Could not determine, whether upgrade is applicable.", e); LOG.warn("Could not determine, whether upgrade is applicable.", e);
return false; return false;
@@ -42,9 +42,10 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion3to4.class); private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion3to4.class);
private static final Pattern LVL1_DIR_PATTERN = Pattern.compile("[A-Z2-7]{2}"); private static final Pattern LVL1_DIR_PATTERN = Pattern.compile("[A-Z2-7]{2}");
private static final Pattern LVL2_DIR_PATTERN = Pattern.compile("[A-Z2-7]{30}"); private static final Pattern LVL2_DIR_PATTERN = Pattern.compile("[A-Z2-7]{30}");
private static final Pattern BASE32_FOLLOWED_BY_UNDERSCORE_PATTERN = Pattern.compile("^(([A-Z2-7]{8})*[A-Z2-7=]{8})_"); private static final Pattern BASE32_PATTERN = Pattern.compile("^(([A-Z2-7]{8})*[A-Z2-7=]{8})");
private static final Pattern BASE32_FOLLOWED_BY_UNDERSCORE_PATTERN = Pattern.compile(BASE32_PATTERN.pattern() + "_");
private static final int FILE_MIN_SIZE = 88; // vault version 3 files have a header of 88 bytes (assuming no chunks at all) private static final int FILE_MIN_SIZE = 88; // vault version 3 files have a header of 88 bytes (assuming no chunks at all)
private static final String LONG_FILENAME_SUFFIX = ".lng"; private static final String LONG_FILENAME_EXT = ".lng";
private static final String OLD_FOLDER_SUFFIX = "_"; private static final String OLD_FOLDER_SUFFIX = "_";
private static final String NEW_FOLDER_PREFIX = "0"; private static final String NEW_FOLDER_PREFIX = "0";
@@ -96,10 +97,12 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String name = file.getFileName().toString(); String name = file.getFileName().toString();
if (name.endsWith(LONG_FILENAME_SUFFIX)) { if (attrs.size() > FILE_MIN_SIZE) {
LOG.trace("Skipping non-directory file {}.", file);
} else if (name.endsWith(LONG_FILENAME_EXT)) {
migrateLong(metadataDir, file); migrateLong(metadataDir, file);
} else { } else {
migrate(file, attrs); migrate(file);
} }
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
} }
@@ -112,14 +115,13 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
LOG.info("Migration finished."); LOG.info("Migration finished.");
} }
private void migrate(Path file, BasicFileAttributes attrs) throws IOException { private void migrate(Path file) throws IOException {
String name = file.getFileName().toString(); String name = file.getFileName().toString();
long size = attrs.size();
Matcher m = BASE32_FOLLOWED_BY_UNDERSCORE_PATTERN.matcher(name); Matcher m = BASE32_FOLLOWED_BY_UNDERSCORE_PATTERN.matcher(name);
if (attrs.isRegularFile() && m.find(0) && size < FILE_MIN_SIZE) { if (m.find(0)) {
String base32 = m.group(1); String base32 = m.group(1);
String suffix = name.substring(m.end()); String suffix = name.substring(m.end());
String renamed = NEW_FOLDER_PREFIX + base32 + (suffix.isEmpty() ? "" : " " + suffix); String renamed = NEW_FOLDER_PREFIX + base32 + suffix;
renameWithoutOverwriting(file, renamed); renameWithoutOverwriting(file, renamed);
} }
} }
@@ -135,22 +137,35 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
private void migrateLong(Path metadataDir, Path path) throws IOException { private void migrateLong(Path metadataDir, Path path) throws IOException {
String oldName = path.getFileName().toString(); String oldName = path.getFileName().toString();
Path oldMetadataFile = metadataDir.resolve(oldName.substring(0, 2)).resolve(oldName.substring(2, 4)).resolve(oldName); assert oldName.endsWith(LONG_FILENAME_EXT);
if (Files.isRegularFile(oldMetadataFile)) { String oldNameBase = StringUtils.removeEnd(oldName, LONG_FILENAME_EXT);
String oldContent = new String(Files.readAllBytes(oldMetadataFile), UTF_8);
if (oldContent.endsWith(OLD_FOLDER_SUFFIX)) { Matcher m = BASE32_PATTERN.matcher(oldNameBase);
String newContent = NEW_FOLDER_PREFIX + StringUtils.removeEnd(oldContent, OLD_FOLDER_SUFFIX); if (m.find(0)) {
String newName = base32.encodeAsString(sha1.digest(newContent.getBytes(UTF_8))) + LONG_FILENAME_SUFFIX; String oldNameBase32 = m.group(1);
String oldNameSuffix = oldNameBase.substring(m.end());
String oldCanonicalName = oldNameBase32 + LONG_FILENAME_EXT;
Path oldMetadataFile = metadataDir.resolve(oldCanonicalName.substring(0, 2)).resolve(oldCanonicalName.substring(2, 4)).resolve(oldCanonicalName);
if (!Files.isReadable(oldMetadataFile)) {
LOG.warn("Found uninflatable long file name. Expected: {}", oldMetadataFile);
return;
}
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 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;
Path newPath = path.resolveSibling(newName); Path newPath = path.resolveSibling(newName);
Path newMetadataFile = metadataDir.resolve(newName.substring(0, 2)).resolve(newName.substring(2, 4)).resolve(newName);
Files.move(path, newPath); Files.move(path, newPath);
Files.createDirectories(newMetadataFile.getParent()); Files.createDirectories(newMetadataFile.getParent());
Files.write(newMetadataFile, newContent.getBytes(UTF_8)); Files.write(newMetadataFile, newLongName.getBytes(UTF_8));
Files.delete(oldMetadataFile); LOG.info("Renaming {} to {}.", path, newName);
LOG.info("Renaming {} to {}\nDeleting {}\nCreating {}", path, newName, oldMetadataFile, newMetadataFile); LOG.info("Creating {}.", newMetadataFile);
} }
} else {
LOG.warn("Found uninflatable long file name. Expected: {}", oldMetadataFile);
} }
} }
@@ -83,7 +83,7 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (attrs.isRegularFile() && BASE32_PATTERN.matcher(file.getFileName().toString()).find() && attrs.size() > cryptor.fileHeaderCryptor().headerSize()) { if (BASE32_PATTERN.matcher(file.getFileName().toString()).find() && attrs.size() > cryptor.fileHeaderCryptor().headerSize()) {
migrate(file, attrs, cryptor); migrate(file, attrs, cryptor);
} else { } else {
LOG.info("Skipping irrelevant file {}.", file); LOG.info("Skipping irrelevant file {}.", file);
@@ -9,25 +9,18 @@
package org.cryptomator.ui.model; package org.cryptomator.ui.model;
import java.io.IOException; import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileSystem;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.LazyInitializer; import org.cryptomator.common.LazyInitializer;
import org.cryptomator.common.Optionals;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem; import org.cryptomator.cryptofs.CryptoFileSystem;
@@ -35,17 +28,7 @@ import org.cryptomator.cryptofs.CryptoFileSystemProperties;
import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptolib.api.CryptoException; import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.cryptolib.api.InvalidPassphraseException; import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.frontend.webdav.ServerLifecycleException;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.frontend.webdav.mount.MountParams;
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
import org.cryptomator.frontend.webdav.mount.Mounter.Mount;
import org.cryptomator.frontend.webdav.mount.Mounter.UnmountOperation;
import org.cryptomator.frontend.webdav.servlet.WebDavServletController;
import org.cryptomator.ui.model.VaultModule.PerVault; import org.cryptomator.ui.model.VaultModule.PerVault;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.Observable; import javafx.beans.Observable;
@@ -53,6 +36,12 @@ import javafx.beans.binding.Binding;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty; 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;
@PerVault @PerVault
public class Vault { public class Vault {
@@ -60,25 +49,24 @@ public class Vault {
public static final Predicate<Vault> NOT_LOCKED = hasState(State.LOCKED).negate(); public static final Predicate<Vault> NOT_LOCKED = hasState(State.LOCKED).negate();
private static final Logger LOG = LoggerFactory.getLogger(Vault.class); private static final Logger LOG = LoggerFactory.getLogger(Vault.class);
private static final String MASTERKEY_FILENAME = "masterkey.cryptomator"; private static final String MASTERKEY_FILENAME = "masterkey.cryptomator";
private static final String LOCALHOST_ALIAS = "cryptomator-vault";
private final Settings settings; private final Settings settings;
private final VaultSettings vaultSettings; private final VaultSettings vaultSettings;
private final WebDavServer server;
private final AtomicReference<CryptoFileSystem> cryptoFileSystem = new AtomicReference<>(); private final AtomicReference<CryptoFileSystem> cryptoFileSystem = new AtomicReference<>();
private final ObjectProperty<State> state = new SimpleObjectProperty<State>(State.LOCKED); private final ObjectProperty<State> state = new SimpleObjectProperty<State>(State.LOCKED);
private WebDavServletController servlet; private Volume volume;
private Mount mount;
public enum State { public enum State {
LOCKED, UNLOCKED, MOUNTING, MOUNTED, UNMOUNTING LOCKED, UNLOCKED, MOUNTING, MOUNTED, UNMOUNTING
}; }
@Inject @Inject
Vault(Settings settings, VaultSettings vaultSettings, WebDavServer server) { Vault(Settings settings, VaultSettings vaultSettings, Volume volume) {
this.settings = settings; this.settings = settings;
this.vaultSettings = vaultSettings; this.vaultSettings = vaultSettings;
this.server = server; this.volume = volume;
} }
// ****************************************************************************** // ******************************************************************************
@@ -99,13 +87,6 @@ public class Vault {
} }
public void create(CharSequence passphrase) throws IOException { public void create(CharSequence passphrase) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(getPath())) {
for (Path file : stream) {
if (!file.getFileName().toString().startsWith(".")) {
throw new DirectoryNotEmptyException(getPath().toString());
}
}
}
if (!isValidVaultDirectory()) { if (!isValidVaultDirectory()) {
CryptoFileSystemProvider.initialize(getPath(), MASTERKEY_FILENAME, passphrase); CryptoFileSystemProvider.initialize(getPath(), MASTERKEY_FILENAME, passphrase);
} else { } else {
@@ -117,66 +98,48 @@ public class Vault {
CryptoFileSystemProvider.changePassphrase(getPath(), MASTERKEY_FILENAME, oldPassphrase, newPassphrase); CryptoFileSystemProvider.changePassphrase(getPath(), MASTERKEY_FILENAME, oldPassphrase, newPassphrase);
} }
public synchronized void unlock(CharSequence passphrase) throws ServerLifecycleException, CryptoException, IOException { public synchronized void unlock(CharSequence passphrase) throws CryptoException, IOException {
FileSystem fs = getCryptoFileSystem(passphrase); CryptoFileSystem fs = getCryptoFileSystem(passphrase);
if (!server.isRunning()) { volume.prepare(fs);
server.start();
}
servlet = server.createWebDavServlet(fs.getPath("/"), vaultSettings.getId() + "/" + vaultSettings.mountName().get());
servlet.start();
Platform.runLater(() -> { Platform.runLater(() -> {
state.set(State.UNLOCKED); state.set(State.UNLOCKED);
}); });
} }
public synchronized void mount() throws CommandFailedException { public synchronized void mount() throws CommandFailedException {
if (servlet == null) {
throw new IllegalStateException("Mounting requires unlocked WebDAV servlet.");
}
MountParams mountParams = MountParams.create() //
.withWindowsDriveLetter(vaultSettings.winDriveLetter().get()) //
.withPreferredGvfsScheme(settings.preferredGvfsScheme().get()) //
.build();
Platform.runLater(() -> { Platform.runLater(() -> {
state.set(State.MOUNTING); state.set(State.MOUNTING);
}); });
mount = servlet.mount(mountParams); // might block this thread for a while volume.mount();
Platform.runLater(() -> { Platform.runLater(() -> {
state.set(State.MOUNTED); state.set(State.MOUNTED);
}); });
} }
public synchronized void unmount() throws CommandFailedException {
unmount(Function.identity());
}
public synchronized void unmountForced() throws CommandFailedException { public synchronized void unmountForced() throws CommandFailedException {
unmount(Optionals.unwrap(Mount::forced)); unmount(true);
} }
private synchronized void unmount(Function<Mount, ? extends UnmountOperation> unmountOperationChooser) throws CommandFailedException { public synchronized void unmount() throws CommandFailedException {
unmount(false);
}
private synchronized void unmount(boolean forced) throws CommandFailedException {
Platform.runLater(() -> { Platform.runLater(() -> {
state.set(State.UNMOUNTING); state.set(State.UNMOUNTING);
}); });
if (mount != null) { if (forced && volume.supportsForcedUnmount()) {
unmountOperationChooser.apply(mount).unmount(); volume.unmountForced();
mount = null; } else {
volume.unmount();
} }
Platform.runLater(() -> { Platform.runLater(() -> {
state.set(State.UNLOCKED); state.set(State.UNLOCKED);
}); });
} }
public boolean supportsForcedUnmount() { public synchronized void lock() throws IOException {
return mount != null && mount.forced().isPresent(); volume.stop();
}
public synchronized void lock() throws ServerLifecycleException, IOException {
if (servlet != null) {
servlet.stop();
}
CryptoFileSystem fs = cryptoFileSystem.getAndSet(null); CryptoFileSystem fs = cryptoFileSystem.getAndSet(null);
if (fs != null) { if (fs != null) {
fs.close(); fs.close();
@@ -193,7 +156,7 @@ public class Vault {
try { try {
unmount(); unmount();
} catch (CommandFailedException e) { } catch (CommandFailedException e) {
if (supportsForcedUnmount()) { if (volume.supportsForcedUnmount()) {
try { try {
unmountForced(); unmountForced();
} catch (CommandFailedException e1) { } catch (CommandFailedException e1) {
@@ -211,9 +174,7 @@ public class Vault {
} }
public void reveal() throws CommandFailedException { public void reveal() throws CommandFailedException {
if (mount != null) { volume.reveal();
mount.reveal();
}
} }
// ****************************************************************************** // ******************************************************************************
@@ -235,17 +196,13 @@ public class Vault {
} }
public Observable[] observables() { public Observable[] observables() {
return new Observable[] {state}; return new Observable[]{state};
} }
public VaultSettings getVaultSettings() { public VaultSettings getVaultSettings() {
return vaultSettings; return vaultSettings;
} }
public synchronized String getWebDavUrl() {
return servlet.getServletRootUri().toString();
}
public Path getPath() { public Path getPath() {
return vaultSettings.path().getValue(); return vaultSettings.path().getValue();
} }
@@ -300,6 +257,14 @@ public class Vault {
return vaultSettings.mountName().get(); return vaultSettings.mountName().get();
} }
public StringProperty getMountPathProperty() {
return vaultSettings.individualMountPath();
}
public void setMountPath(String mountPath) {
vaultSettings.individualMountPath().set(mountPath);
}
public void setMountName(String mountName) throws IllegalArgumentException { public void setMountName(String mountName) throws IllegalArgumentException {
if (StringUtils.isBlank(mountName)) { if (StringUtils.isBlank(mountName)) {
throw new IllegalArgumentException("mount name is empty"); throw new IllegalArgumentException("mount name is empty");
@@ -324,6 +289,10 @@ public class Vault {
} }
} }
public String getFilesystemRootUrl() {
return volume.getMountUri();
}
public String getId() { public String getId() {
return vaultSettings.getId(); return vaultSettings.getId();
} }
@@ -347,4 +316,7 @@ public class Vault {
} }
} }
public boolean supportsForcedUnmount() {
return volume.supportsForcedUnmount();
}
} }
@@ -38,6 +38,11 @@ public class VaultList extends TransformationList<Vault, VaultSettings> {
return index; return index;
} }
@Override
public int getViewIndex(int index) {
return index;
}
@Override @Override
public Vault get(int index) { public Vault get(int index) {
VaultSettings s = source.get(index); VaultSettings s = source.get(index);
@@ -12,6 +12,8 @@ import java.util.Objects;
import javax.inject.Scope; import javax.inject.Scope;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.settings.VaultSettings;
import dagger.Module; import dagger.Module;
@@ -36,6 +38,26 @@ public class VaultModule {
@Documented @Documented
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@interface PerVault { @interface PerVault {
}
@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);
}
} }
} }
@@ -0,0 +1,38 @@
package org.cryptomator.ui.model;
import org.cryptomator.cryptofs.CryptoFileSystem;
import java.io.IOException;
/**
* Takes a Volume and usess it to mount an unlocked vault
*/
public interface Volume {
void prepare(CryptoFileSystem fs) throws IOException;
void mount() throws CommandFailedException;
default void reveal() throws CommandFailedException {
throw new CommandFailedException("Not implemented.");
}
void unmount() throws CommandFailedException;
default void unmountForced() throws CommandFailedException {
throw new CommandFailedException("Operation not supported.");
}
void stop();
String getMountUri();
default boolean isSupported() {
return false;
}
default boolean supportsForcedUnmount() {
return false;
}
}
@@ -0,0 +1,130 @@
package org.cryptomator.ui.model;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.frontend.webdav.mount.MountParams;
import org.cryptomator.frontend.webdav.mount.Mounter;
import org.cryptomator.frontend.webdav.servlet.WebDavServletController;
import javax.inject.Inject;
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";
private final Provider<WebDavServer> serverProvider;
private final VaultSettings vaultSettings;
private final Settings settings;
private WebDavServer server;
private WebDavServletController servlet;
private Mounter.Mount mount;
@Inject
public WebDavVolume(Provider<WebDavServer> serverProvider, VaultSettings vaultSettings, Settings settings) {
this.serverProvider = serverProvider;
this.vaultSettings = vaultSettings;
this.settings = settings;
}
@Override
public void prepare(CryptoFileSystem fs) {
if (server == null) {
server = serverProvider.get();
}
if (!server.isRunning()) {
server.start();
}
servlet = server.createWebDavServlet(fs.getPath("/"), vaultSettings.getId() + "/" + vaultSettings.mountName().get());
servlet.start();
}
@Override
public void mount() throws CommandFailedException {
if (servlet == null) {
throw new IllegalStateException("Mounting requires unlocked WebDAV servlet.");
}
MountParams mountParams = MountParams.create() //
.withWindowsDriveLetter(vaultSettings.winDriveLetter().get()) //
.withPreferredGvfsScheme(settings.preferredGvfsScheme().get())//
.withWebdavHostname(getLocalhostAliasOrNull()) //
.build();
try {
this.mount = servlet.mount(mountParams); // might block this thread for a while
} catch (Mounter.CommandFailedException e) {
e.printStackTrace();
throw new CommandFailedException(e);
}
}
@Override
public void reveal() throws CommandFailedException {
try {
mount.reveal();
} catch (Mounter.CommandFailedException e) {
e.printStackTrace();
throw new CommandFailedException(e);
}
}
@Override
public synchronized void unmount() throws CommandFailedException {
try {
mount.unmount();
} catch (Mounter.CommandFailedException e) {
throw new CommandFailedException(e);
}
}
@Override
public synchronized void unmountForced() {
mount.forced();
}
private String getLocalhostAliasOrNull() {
try {
InetAddress alias = InetAddress.getByName(LOCALHOST_ALIAS);
if (alias.getHostAddress().equals("127.0.0.1")) {
return LOCALHOST_ALIAS;
} else {
return null;
}
} catch (UnknownHostException e) {
return null;
}
}
@Override
public void stop() {
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;
}
public boolean supportsForcedUnmount() {
return mount != null && mount.forced().isPresent();
}
}
@@ -1,127 +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.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.SupplierThrowingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Reflection-based wrapper for com.apple.eawt.Application.
*/
public class EawtApplicationWrapper {
private static final Logger LOG = LoggerFactory.getLogger(EawtApplicationWrapper.class);
private final Class<?> applicationClass;
private final Object application;
private EawtApplicationWrapper() throws ReflectiveOperationException {
this.applicationClass = Class.forName("com.apple.eawt.Application");
this.application = applicationClass.getMethod("getApplication").invoke(null);
}
/**
* @return A wrapper for com.apple.ewat.Application if the current OS is macOS and the class is available in this JVM.
*/
public static Optional<EawtApplicationWrapper> getApplication() {
if (!SystemUtils.IS_OS_MAC_OSX) {
return Optional.empty();
}
try {
return Optional.of(new EawtApplicationWrapper());
} catch (ReflectiveOperationException e) {
return Optional.empty();
}
}
private void setOpenFileHandler(InvocationHandler handler) throws ReflectiveOperationException {
Class<?> handlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
Method setter = applicationClass.getMethod("setOpenFileHandler", handlerClass);
Object proxy = Proxy.newProxyInstance(applicationClass.getClassLoader(), new Class<?>[] {handlerClass}, handler);
setter.invoke(application, proxy);
}
public void setOpenFileHandler(Consumer<List<File>> handler) {
try {
Class<?> openFilesEventClass = Class.forName("com.apple.eawt.AppEvent$OpenFilesEvent");
Method getFiles = openFilesEventClass.getMethod("getFiles");
setOpenFileHandler(methodSpecificInvocationHandler("openFiles", args -> {
Object openFilesEvent = args[0];
assert openFilesEventClass.isInstance(openFilesEvent);
@SuppressWarnings("unchecked")
List<File> files = (List<File>) uncheckedReflectiveOperation(() -> getFiles.invoke(openFilesEvent));
handler.accept(files);
return null;
}));
} catch (ReflectiveOperationException e) {
LOG.error("Exception setting openFileHandler.", e);
}
}
private void setPreferencesHandler(InvocationHandler handler) throws ReflectiveOperationException {
Class<?> handlerClass = Class.forName("com.apple.eawt.PreferencesHandler");
Method setter = applicationClass.getMethod("setPreferencesHandler", handlerClass);
Object proxy = Proxy.newProxyInstance(applicationClass.getClassLoader(), new Class<?>[] {handlerClass}, handler);
setter.invoke(application, proxy);
}
public void setPreferencesHandler(Runnable handler) {
try {
setPreferencesHandler(methodSpecificInvocationHandler("handlePreferences", args -> {
handler.run();
return null;
}));
} catch (ReflectiveOperationException e) {
LOG.error("Exception setting preferencesHandler.", e);
}
}
private static InvocationHandler methodSpecificInvocationHandler(String methodName, Function<Object[], Object> handler) {
return new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals(methodName)) {
return handler.apply(args);
} else {
throw new UnsupportedOperationException("Unexpected invocation " + method.getName() + ", expected " + methodName);
}
}
};
}
/**
* Wraps {@link ReflectiveOperationException}s as {@link UncheckedReflectiveOperationException}.
*
* @param operation Invokation throwing an ReflectiveOperationException
* @return Result returned by <code>operation</code>
* @throws UncheckedReflectiveOperationException in case <code>operation</code> throws an ReflectiveOperationException.
*/
private static <T> T uncheckedReflectiveOperation(SupplierThrowingException<T, ReflectiveOperationException> operation) throws UncheckedReflectiveOperationException {
try {
return operation.get();
} catch (ReflectiveOperationException e) {
throw new UncheckedReflectiveOperationException(e);
}
}
private static class UncheckedReflectiveOperationException extends RuntimeException {
public UncheckedReflectiveOperationException(ReflectiveOperationException cause) {
super(cause);
}
}
}
@@ -14,9 +14,9 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.ui.l10n.Localization; import org.cryptomator.ui.l10n.Localization;
import com.google.common.base.Strings;
import com.nulabinc.zxcvbn.Zxcvbn; import com.nulabinc.zxcvbn.Zxcvbn;
import javafx.geometry.Insets; import javafx.geometry.Insets;
@@ -41,8 +41,10 @@ public class PasswordStrengthUtil {
} }
public int computeRate(String password) { public int computeRate(String password) {
if (StringUtils.isEmpty(password)) { if (Strings.isNullOrEmpty(password)) {
return -1; return -1;
} else if (password.length() > 100) {
return 4; // assume this is strong. zxcvbn memory and runtime depends vastly on the password length
} else { } else {
return zxcvbn.measure(password, sanitizedInputs).getScore(); return zxcvbn.measure(password, sanitizedInputs).getScore();
} }
@@ -108,6 +108,13 @@
-fx-text-fill: COLOR_TEXT_DISABLED; -fx-text-fill: COLOR_TEXT_DISABLED;
} }
.button:focused,
.toggle-button:focused {
-fx-border-color: black;
-fx-border-insets: 2px;
-fx-border-style: dotted inside;
}
/**************************************************************************** /****************************************************************************
* * * *
* Segmented Buttons * * Segmented Buttons *
@@ -157,6 +164,10 @@
-fx-padding: 1; -fx-padding: 1;
} }
.list-view:focused {
-fx-border-style: dotted inside;
}
.list-cell { .list-cell {
-fx-padding: 0.5em; -fx-padding: 0.5em;
-fx-text-fill: COLOR_TEXT; -fx-text-fill: COLOR_TEXT;
@@ -243,6 +254,12 @@
-fx-background-color: COLOR_VGRAD_DARK; -fx-background-color: COLOR_VGRAD_DARK;
} }
.tool-bar.list-related-toolbar .toggle-button:focused,
.tool-bar.list-related-toolbar .button:focused {
-fx-border-style: dotted inside;
-fx-border-color: black;
}
/******************************************************************************* /*******************************************************************************
* * * *
* PopupMenu * * PopupMenu *
@@ -333,6 +350,10 @@
.check-box:selected > .box > .mark { .check-box:selected > .box > .mark {
-fx-background-color: COLOR_TEXT; -fx-background-color: COLOR_TEXT;
} }
/* focused */
.check-box:focused {
-fx-border-style: dotted inside;
}
/* disabled: */ /* disabled: */
.check-box:disabled > .box { .check-box:disabled > .box {
-fx-background-color: COLOR_BORDER, COLOR_BACKGROUND; -fx-background-color: COLOR_BORDER, COLOR_BACKGROUND;
@@ -355,6 +376,10 @@
-fx-text-fill: COLOR_TEXT; -fx-text-fill: COLOR_TEXT;
} }
.choice-box:focused {
-fx-border-style: dotted inside;
}
.choice-box > .open-button > .arrow { .choice-box > .open-button > .arrow {
-fx-background-color: transparent, COLOR_TEXT; -fx-background-color: transparent, COLOR_TEXT;
-fx-background-insets: 0 0 -1 0, 0; -fx-background-insets: 0 0 -1 0, 0;
@@ -434,6 +434,52 @@
-fx-background-color: COLOR_TEXT_DISABLED; -fx-background-color: COLOR_TEXT_DISABLED;
} }
/*******************************************************************************
* *
* ChoiceBox *
* *
******************************************************************************/
.choice-box {
-fx-background-color: COLOR_HGRAD_BTN_BORDER, #FFFFFF;
-fx-background-insets: 0, 1;
-fx-background-radius: 4;
-fx-padding: 0 0 0 0.8em;
-fx-text-fill: COLOR_TEXT;
-fx-alignment: CENTER;
-fx-effect: dropshadow(one-pass-box, #DCDCDC, 0.0, 0.0, 0.0, 1.0);
}
.choice-box > .open-button {
-fx-background-insets: 0, 1 1 1 0;
-fx-background-radius: 0 4 4 0;
-fx-padding: 4 5 4 4;
}
.root.active-window .choice-box > .open-button {
-fx-background-color: COLOR_HGRAD_BTN_DEF_BORDER, COLOR_HGRAD_BTN_DEF_BACKGROUND;
}
.root.inactive-window .choice-box > .open-button {
-fx-background-color: COLOR_HGRAD_BTN_BORDER, #FFFFFF;
}
.choice-box > .open-button > .arrow {
-fx-shape: "M 0 5 L 4 0 L 8 5 L 6 5 L 4 2 L 2 5 Z M 0 8 L 4 13 L 8 8 L 6 8 L 4 11 L 2 8 Z";
-fx-scale-shape: true;
-fx-min-width: 9px;
-fx-min-height: 13px;
}
.root.active-window .choice-box > .open-button > .arrow {
-fx-background-color: #FFFFFF;
}
.root.inactive-window .choice-box > .open-button > .arrow {
-fx-background-color: #444444;
}
.choice-box .context-menu {
-fx-background-color: COLOR_BORDER, #FFF;
-fx-background-insets: 0, 1;
}
/**************************************************************************** /****************************************************************************
* * * *
* ProgressIndicator * * ProgressIndicator *
@@ -157,36 +157,48 @@
.list-view { .list-view {
-fx-background-color: COLOR_BORDER, #FFF; -fx-background-color: COLOR_BORDER, #FFF;
-fx-border-style: dotted inside;
-fx-border-color: transparent;
-fx-background-insets: 0, 1; -fx-background-insets: 0, 1;
-fx-padding: 1; -fx-padding: 1;
} }
.list-view:focused {
-fx-border-color: black;
}
.list-view > .virtual-flow > .scroll-bar:vertical{ .list-view > .virtual-flow > .scroll-bar:vertical{
-fx-background-insets: 0, 0 0 0 1; -fx-background-insets: 0, 0 0 0 1;
-fx-padding: -1 -1 -1 0; -fx-padding: -1 -1 -1 0;
} }
.list-view > .virtual-flow > .scroll-bar:horizontal{ .list-view > .virtual-flow > .scroll-bar:horizontal{
-fx-background-insets: 0, 1 0 0 0; -fx-background-insets: 0, 1 0 0 0;
-fx-padding: 0 -1 -1 -1; -fx-padding: 0 -1 -1 -1;
} }
.list-view > .virtual-flow > .corner { .list-view > .virtual-flow > .corner {
-fx-background-color: COLOR_BORDER, COLOR_CONTROL_BASE; -fx-background-color: COLOR_BORDER, COLOR_CONTROL_BASE;
-fx-background-insets: 0, 1 0 0 1; -fx-background-insets: 0, 1 0 0 1;
} }
.list-cell { .list-cell {
-fx-background-color: #FFF; -fx-background-color: #FFF;
-fx-padding: 0.6em; -fx-padding: 0.6em;
-fx-text-fill: COLOR_TEXT; -fx-text-fill: COLOR_TEXT;
-fx-opacity: 1; -fx-opacity: 1;
} }
.list-view:focused > .virtual-flow > .clipped-container > .sheet > .list-cell:focused { .list-view:focused > .virtual-flow > .clipped-container > .sheet > .list-cell:focused {
-fx-background-color: COLOR_BORDER_FOCUS, #FFF; -fx-background-color: COLOR_BORDER_FOCUS, #FFF;
-fx-background-insets: 0, 1; -fx-background-insets: 0, 1;
} }
.list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected { .list-view > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected {
-fx-background-color: #DEDEDE, #F7F7F7; -fx-background-color: #DEDEDE, #F7F7F7;
-fx-background-insets: 0, 1; -fx-background-insets: 0, 1;
} }
.list-cell:filled:hover { .list-cell:filled:hover {
-fx-background-color: #F7F7F7; -fx-background-color: #F7F7F7;
} }
@@ -364,6 +376,8 @@
.check-box { .check-box {
-fx-label-padding: 0 0 0 6px; -fx-label-padding: 0 0 0 6px;
-fx-text-fill: COLOR_TEXT; -fx-text-fill: COLOR_TEXT;
-fx-border-style: dotted inside;
-fx-border-color: transparent;
} }
.check-box > .box { .check-box > .box {
-fx-padding: 1px; -fx-padding: 1px;
@@ -380,6 +394,10 @@
.check-box:armed > .box { .check-box:armed > .box {
-fx-border-color: COLOR_BORDER_FOCUS; -fx-border-color: COLOR_BORDER_FOCUS;
} }
/* focused */
.check-box:focused {
-fx-border-color: black;
}
/* selected: */ /* selected: */
.check-box:selected > .box > .mark { .check-box:selected > .box > .mark {
-fx-background-color: black; -fx-background-color: black;
@@ -406,6 +424,10 @@
-fx-text-fill: COLOR_TEXT; -fx-text-fill: COLOR_TEXT;
} }
.choice-box:focused {
-fx-border-style: dotted inside;
}
.choice-box > .open-button > .arrow { .choice-box > .open-button > .arrow {
-fx-background-color: transparent, COLOR_TEXT; -fx-background-color: transparent, COLOR_TEXT;
-fx-background-insets: 0 0 -1 0, 0; -fx-background-insets: 0 0 -1 0, 0;
+4 -4
View File
@@ -53,7 +53,7 @@
<VBox prefWidth="200.0" cacheShape="true" cache="true"> <VBox prefWidth="200.0" cacheShape="true" cache="true">
<StackPane VBox.vgrow="ALWAYS" cacheShape="true" cache="true"> <StackPane VBox.vgrow="ALWAYS" cacheShape="true" cache="true">
<ListView fx:id="vaultList" focusTraversable="false" cacheShape="true" cache="true"/> <ListView fx:id="vaultList" focusTraversable="true" cacheShape="true" cache="true"/>
<AnchorPane fx:id="emptyListInstructions" cacheShape="true" cache="true"> <AnchorPane fx:id="emptyListInstructions" cacheShape="true" cache="true">
<HBox AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.bottomAnchor="100.0" alignment="CENTER" cacheShape="true" cache="true"> <HBox AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.bottomAnchor="100.0" alignment="CENTER" cacheShape="true" cache="true">
<Label textAlignment="CENTER" text="%main.emptyListInstructions" wrapText="true" cacheShape="true" cache="true"/> <Label textAlignment="CENTER" text="%main.emptyListInstructions" wrapText="true" cacheShape="true" cache="true"/>
@@ -63,11 +63,11 @@
</StackPane> </StackPane>
<ToolBar VBox.vgrow="NEVER" styleClass="list-related-toolbar" cacheShape="true" cache="true"> <ToolBar VBox.vgrow="NEVER" styleClass="list-related-toolbar" cacheShape="true" cache="true">
<items> <items>
<ToggleButton text="&#xf489;" styleClass="ionicons" fx:id="addVaultButton" onAction="#didClickAddVault" focusTraversable="false" cacheShape="true" cache="true"/> <ToggleButton text="&#xf489;" styleClass="ionicons" fx:id="addVaultButton" onAction="#didClickAddVault" focusTraversable="true" cacheShape="true" cache="true"/>
<Button text="&#xf462;" styleClass="ionicons" fx:id="removeVaultButton" onAction="#didClickRemoveSelectedEntry" focusTraversable="false" cacheShape="true" cache="true"/> <Button text="&#xf462;" styleClass="ionicons" fx:id="removeVaultButton" onAction="#didClickRemoveSelectedEntry" focusTraversable="true" cacheShape="true" cache="true"/>
<Pane HBox.hgrow="ALWAYS" styleClass="spacer" /> <Pane HBox.hgrow="ALWAYS" styleClass="spacer" />
<!-- future use: --> <!-- future use: -->
<ToggleButton text="&#xf43c;" styleClass="ionicons" fx:id="settingsButton" onAction="#didClickShowSettings" focusTraversable="false" cacheShape="true" cache="true"/> <ToggleButton text="&#xf43c;" styleClass="ionicons" fx:id="settingsButton" onAction="#didClickShowSettings" focusTraversable="true" cacheShape="true" cache="true"/>
</items> </items>
</ToolBar> </ToolBar>
</VBox> </VBox>
+24 -14
View File
@@ -35,22 +35,32 @@
<!-- Row 0 --> <!-- Row 0 -->
<Label GridPane.rowIndex="0" GridPane.columnIndex="0" text="%settings.checkForUpdates.label" cacheShape="true" cache="true" /> <Label GridPane.rowIndex="0" GridPane.columnIndex="0" text="%settings.checkForUpdates.label" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="0" GridPane.columnIndex="1" fx:id="checkForUpdatesCheckbox" cacheShape="true" cache="true" /> <CheckBox GridPane.rowIndex="0" GridPane.columnIndex="1" fx:id="checkForUpdatesCheckbox" cacheShape="true" cache="true" />
<!-- Row 1 --> <!-- Row 1 -->
<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%settings.port.label" cacheShape="true" cache="true" /> <Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%settings.debugMode.label" cacheShape="true" cache="true" />
<HBox GridPane.rowIndex="1" GridPane.columnIndex="1" spacing="6.0"> <CheckBox GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="debugModeCheckbox" cacheShape="true" cache="true" />
<TextField fx:id="portField" cacheShape="true" cache="true" promptText="%settings.port.prompt" />
<Button text="%settings.port.apply" fx:id="changePortButton" onAction="#changePort"/>
</HBox>
<!-- Row 2 --> <!-- Row 2 -->
<Label GridPane.rowIndex="2" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.prefGvfsScheme.label" cacheShape="true" cache="true" /> <Label fx:id="volumeLabel" GridPane.rowIndex="2" GridPane.columnIndex="0" text="%settings.volume.label" cacheShape="true" cache="true" />
<ChoiceBox GridPane.rowIndex="2" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" /> <ChoiceBox GridPane.rowIndex="2" GridPane.columnIndex="1" fx:id="volume" cacheShape="true" cache="true" />
<!-- Row 3 --> <!-- Row 3 Alt 1-->
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" text="%settings.debugMode.label" cacheShape="true" cache="true" /> <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">
<CheckBox GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="debugModeCheckbox" 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>
<!-- 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>
</children> </children>
</GridPane> </GridPane>
<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" /> <Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />
+15 -1
View File
@@ -46,6 +46,9 @@
<Button fx:id="unlockButton" text="%unlock.button.unlock" defaultButton="true" prefWidth="150.0" onAction="#didClickUnlockButton" disable="true" 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> </HBox>
<!-- Row 3 -->
<Label fx:id="successMessage" cacheShape="true" cache="true" visible="true" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2"/>
<!-- Row 3 --> <!-- Row 3 -->
<GridPane fx:id="advancedOptions" vgap="12.0" hgap="12.0" prefWidth="400.0" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" visible="false" cacheShape="true" cache="true"> <GridPane fx:id="advancedOptions" vgap="12.0" hgap="12.0" prefWidth="400.0" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" visible="false" cacheShape="true" cache="true">
<padding> <padding>
@@ -83,9 +86,20 @@
<!-- Row 3.5 --> <!-- 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="revealAfterMount" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />
<!-- Row 3.6 --> <!-- Row 3.6 Alt1 -->
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="winDriveLetterLabel" text="%unlock.label.winDriveLetter" cacheShape="true" cache="true" /> <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" /> <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>
</GridPane> </GridPane>
<!-- Row 4 --> <!-- Row 4 -->
@@ -54,8 +54,8 @@
<Label fx:id="messageLabel" cacheShape="true" cache="true" /> <Label fx:id="messageLabel" cacheShape="true" cache="true" />
</Pane> </Pane>
<HBox styleClass="segmented-button-bar" HBox.hgrow="NEVER" alignment="CENTER_RIGHT" cacheShape="true" cache="true"> <HBox styleClass="segmented-button-bar" HBox.hgrow="NEVER" alignment="CENTER_RIGHT" cacheShape="true" cache="true">
<Button text="%unlocked.button.lock" styleClass="first" onAction="#didClickLockVault" focusTraversable="false" cacheShape="true" cache="true"/> <Button text="%unlocked.button.lock" styleClass="first" onAction="#didClickLockVault" focusTraversable="true" cacheShape="true" cache="true"/>
<ToggleButton text="&#xf104;" styleClass="last,ionicons" focusTraversable="false" fx:id="moreOptionsButton" onAction="#didClickMoreOptions" /> <ToggleButton text="&#xf104;" styleClass="last,ionicons" focusTraversable="true" fx:id="moreOptionsButton" onAction="#didClickMoreOptions" />
</HBox> </HBox>
</HBox> </HBox>
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Throughput (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = الاصدار %s settings.version.label = الاصدار %s
settings.checkForUpdates.label = افحص التحديثات settings.checkForUpdates.label = افحص التحديثات
settings.port.label = منفذ ويب داف ( WebDAV )
settings.port.prompt = 0 \= Choose automatically
settings.requiresRestartLabel = * Cryptomator needs to restart settings.requiresRestartLabel = * Cryptomator needs to restart
# tray icon # tray icon
tray.menu.open = فتح tray.menu.open = فتح
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = هل تريد فعلا ازال
main.directoryList.remove.confirmation.content = The vault will only be removed from the list. To permanently delete it, please delete the vault from your filesystem. main.directoryList.remove.confirmation.content = The vault will only be removed from the list. To permanently delete it, please delete the vault from your filesystem.
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding. upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details. upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = المحفظة غير فارغة
unlock.label.savePassword = حفظ كلمة المرور unlock.label.savePassword = حفظ كلمة المرور
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed unlocked.label.mountFailed = Connecting drive failed
@@ -90,7 +86,6 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 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.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. upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
+83 -73
View File
@@ -1,35 +1,35 @@
app.name = Криптоматор app.name = Криптоматор
# main.fxml # main.fxml
main.emptyListInstructions = Натиснете тук за да добавите сейф main.emptyListInstructions = Натиснете тук за добавяне на сейф
main.directoryList.contextMenu.remove = Премахнете от листа main.directoryList.contextMenu.remove = Премахване от листата
main.directoryList.contextMenu.changePassword = Сменете парола main.directoryList.contextMenu.changePassword = Смяна на парола
main.addDirectory.contextMenu.new = Създайте нов сейф main.addDirectory.contextMenu.new = Създаване на нов сейф
main.addDirectory.contextMenu.open = Отворете съществуващ сейф main.addDirectory.contextMenu.open = Отворяне на съществуващ сейф
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Проверете за нови версии welcome.checkForUpdates.label.currentlyChecking = Проверка за обновления...
welcome.newVersionMessage = Version %1$s can be downloaded.\nThis is %2$s. welcome.newVersionMessage = Версия %1$s може да бъде свалена.\nТази е %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password = Парола initialize.label.password = Парола
initialize.label.retypePassword = Повторете Паролата initialize.label.retypePassword = Повторете паролата
initialize.button.ok = Създайте Сейф initialize.button.ok = Създаване на сейф
initialize.messageLabel.alreadyInitialized = Сейфа е вече активен initialize.messageLabel.alreadyInitialized = Сейфа е вече активен
initialize.messageLabel.initializationFailed = Неуспешно активиране на сейф. Проверете лог файловете за повече информация. initialize.messageLabel.initializationFailed = Неуспешно активиране на сейф. Проверете лог файловете за повече информация.
# notfound.fxml # notfound.fxml
notfound.label = Сейфа не може да бъде намерен. Може би е бил преместен? notfound.label = Сейфа не може да бъде намерен. Може би е бил преместен?
# upgrade.fxml # upgrade.fxml
upgrade.button = Обновете версията на Сейф upgrade.button = Обновете сейфа
upgrade.version3dropBundleExtension.msg = This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding. upgrade.version3dropBundleExtension.msg = Този сейф трябва да бъде променен към новия формат.\n"%1$s" ще бъде преименуван в "%2$s".\nМоля, уверете се, че синхронизацията е преключила преди да продължите.
upgrade.version3dropBundleExtension.err.alreadyExists = Автоматичната миграция е неуспешна. "%s" вече съществува. upgrade.version3dropBundleExtension.err.alreadyExists = Автоматичната промяна е неуспешна. "%s" вече съществува.
# unlock.fxml # unlock.fxml
unlock.label.password = Парола unlock.label.password = Парола
unlock.label.mountName = Име на диск unlock.label.mountName = Име на диск
unlock.label.winDriveLetter = Инициали на диск unlock.label.winDriveLetter = Инициали на диск
unlock.label.downloadsPageLink = Покажи всички версии на Криптоматор unlock.label.downloadsPageLink = Всички версии на Криптоматор
unlock.label.advancedHeading = Опции за напреднали unlock.label.advancedHeading = Опции за напреднали
unlock.button.unlock = Отключи Сейф unlock.button.unlock = Отключване на сейф
unlock.button.advancedOptions.show = Покажи повече опции unlock.button.advancedOptions.show = Повече опции
unlock.button.advancedOptions.hide = Покажи по-малко опции unlock.button.advancedOptions.hide = По-малко опции
unlock.choicebox.winDriveLetter.auto = Автоматично наименование на Диска unlock.choicebox.winDriveLetter.auto = Автоматично наименование на диска
unlock.errorMessage.wrongPassword = Неправилна парола unlock.errorMessage.wrongPassword = Неправилна парола
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Неподържана версия. Този сейф е бил създаден със стара версия на Криптоматор. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Неподържана версия. Този сейф е бил създаден със стара версия на Криптоматор.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Неподържана версия. Този сейф е бил създаден с по-нова версия на Криптоматор. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Неподържана версия. Този сейф е бил създаден с по-нова версия на Криптоматор.
@@ -38,67 +38,77 @@ unlock.messageLabel.startServerFailed = Неуспешно стартиране
changePassword.label.oldPassword = Стара парола changePassword.label.oldPassword = Стара парола
changePassword.label.newPassword = Нова парола changePassword.label.newPassword = Нова парола
changePassword.label.retypePassword = Повторете паролата changePassword.label.retypePassword = Повторете паролата
changePassword.label.downloadsPageLink = All Cryptomator versions changePassword.label.downloadsPageLink = Всички версии на Криптоматор
changePassword.button.change = Смени паролата changePassword.button.change = Смени паролата
changePassword.errorMessage.wrongPassword = Неправилна парола changePassword.errorMessage.wrongPassword = Неправилна парола
changePassword.errorMessage.decryptionFailed = Неуспешно декриптиране changePassword.errorMessage.decryptionFailed = Неуспешно декриптиране
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Заключи Сейфа unlocked.button.lock = Заключване на Сейфа
unlocked.moreOptions.reveal = Покажи unlocked.moreOptions.reveal = Покажи диска
unlocked.moreOptions.copyUrl = Copy WebDAV URL unlocked.moreOptions.copyUrl = Копиране адреса на WebDAV
unlocked.label.revealFailed = Командата е неуспешна unlocked.label.revealFailed = Командата е неуспешна
unlocked.label.unmountFailed = Ejecting drive failed unlocked.label.unmountFailed = Изваждането на диска е неуспешно
unlocked.label.statsEncrypted = encrypted unlocked.label.statsEncrypted = криптирано
unlocked.label.statsDecrypted = decrypted unlocked.label.statsDecrypted = декрептирано
unlocked.ioGraph.yAxis.label = Throughput (MiB/s) unlocked.ioGraph.yAxis.label = Скорост (MB/s)
# settings.fxml # settings.fxml
settings.version.label = Version %s settings.version.label = Версия %s
settings.checkForUpdates.label = Check for Updates settings.checkForUpdates.label = Проверка за обновления
settings.port.label = WebDAV Port settings.requiresRestartLabel = * Криптоматор трябва да се рестартира
settings.port.prompt = 0 \= Choose automatically
settings.requiresRestartLabel = * Cryptomator needs to restart
# tray icon # tray icon
tray.menu.open = Open tray.menu.open = Отворяне
tray.menu.quit = Quit tray.menu.quit = Излизане
tray.infoMsg.title = Still Running tray.infoMsg.title = Все още върви
tray.infoMsg.msg = Cryptomator is still alive. Quit it from the tray icon. tray.infoMsg.msg = Криптоматор все още върви. Излезте от иконата в трея.
tray.infoMsg.msg.osx = Cryptomator is still alive. Quit it from the menu bar icon. tray.infoMsg.msg.osx = Криптоматор все още върви. Излезте от иконата в менюто.
initialize.messageLabel.passwordStrength.0 = Very weak initialize.messageLabel.passwordStrength.0 = Прекалено слаба
initialize.messageLabel.passwordStrength.1 = Weak initialize.messageLabel.passwordStrength.1 = Слаба
initialize.messageLabel.passwordStrength.2 = Fair initialize.messageLabel.passwordStrength.2 = Добра
initialize.messageLabel.passwordStrength.3 = Strong initialize.messageLabel.passwordStrength.3 = Силна
initialize.messageLabel.passwordStrength.4 = Very strong initialize.messageLabel.passwordStrength.4 = Много силна
initialize.label.doNotForget = IMPORTANT\: If you forget your password, there is no way to recover your data. initialize.label.doNotForget = ВАЖНО\: Ако забравите паролата, няма начин да възстановите данните.
main.directoryList.remove.confirmation.title = Remove Vault main.directoryList.remove.confirmation.title = Премахване на сейф
main.directoryList.remove.confirmation.header = Do you really want to remove this vault? main.directoryList.remove.confirmation.header = Наистина ли искате да премахнете този сейф?
main.directoryList.remove.confirmation.content = The vault will only be removed from the list. To permanently delete it, please delete the vault from your filesystem. main.directoryList.remove.confirmation.content = Този сейф ще бъде премахнат само от листа. За да го изтриете напълно, моля, изтрийте сейфа от файл системата.
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding. upgrade.version3to4.msg = Този сейф трябва да бъде преместен към по-нов формат.\nКриптираните имена на папки ще бъдат обновени.\nМоля, проверете дали сихронизацията е приключила преди да продължите.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details. upgrade.version3to4.err.io = Преместването е отменено поради грешка в диска. Вижте лог файла за детайли.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Да, сигурен съм, че сихронизацията е приключила
initialize.messageLabel.notEmpty = Vault not empty unlock.label.savePassword = Запазване на парола
unlock.label.savePassword = Save Password unlock.errorMessage.unauthenticVersionMac = Неуспешна оторизация на MAC версията
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlocked.label.mountFailed = Връзката с диска неуспешна
unlocked.label.mountFailed = Connecting drive failed unlock.savePassword.delete.confirmation.title = Изтриване на запазената парола
unlock.savePassword.delete.confirmation.title = Delete Saved Password unlock.savePassword.delete.confirmation.header = Неистина ли искате да изтриете запазената парола за този сейф?
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault? unlock.savePassword.delete.confirmation.content = Запазената парола за този сейф ще бъде незабавно премахната от Вашата система. Ако желаете да запазите паролата отново, трябва да отключите сейса с пусната опция "Запазване на павола".
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 = Режим за отстраняване на грешки *
settings.debugMode.label = Debug Mode * upgrade.version3dropBundleExtension.title = Обновяване до сейф версия 3
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension) upgrade.version3to4.title = Обновяване на сейф от 3-та до 4-та версия
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade upgrade.version4to5.title = Обновяване на сейф от 4-та до 5-та версия
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade upgrade.version4to5.msg = Този сейф трябва да бъде променен към по-нов формат.\nКриптираните файлове ще бъдат обновени.\nМоля, проверете дали сихронизацията е приключила преди да продължите.\n\nЗабележка\: Датата на промяна на всички файлове ще бъде обновена до момента.
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 = Преместването провалено поради грешка в диска. Вижте лог файла за детайли.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details. unlock.label.mountAfterUnlock = Закачане на диска
settings.port.apply = Apply unlock.label.revealAfterMount = Показване на диска
unlock.label.mountAfterUnlock = Mount Drive unlocked.lock.force.confirmation.title = Заключването на %1$s провалено
unlock.label.revealAfterMount = Reveal Drive unlocked.lock.force.confirmation.header = Желаете ли принудително заключване?
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.content = Това е може би защото други програми все още използват файловете в сейфа или защото има някакъв друг проблем.\n\nПрограмите, имащи достъп до файловете, може да не работят правилно и информацията, незаписана от тези програми, може да бъде изгубена.
unlocked.lock.force.confirmation.header = Do you want to force locking? unlock.label.unlockAfterStartup = Автоматично отключване при стартиране (Експериментално)
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.errorMessage.unlockFailed = Грешка при отключване. Вижте лог файла за детайли.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental) unlocked.moreOptions.mount = Закачане на диск
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlocked.moreOptions.unmount = Изваждане на диск
unlocked.moreOptions.mount = Mount Drive upgrade.version5toX.title = Обновяване на версията на сейфа
unlocked.moreOptions.unmount = Eject Drive upgrade.version5toX.msg = Този сейф трябва да бъде обновен до по-нов формат.\nМоля, уверете се, че сихронизацията е приключила, преди да продължите.
upgrade.version5toX.title = Vault Version Upgrade main.createVault.nonEmptyDir.title = Creating vault failed
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. 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 *
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.
@@ -0,0 +1,116 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = Trezor přidáte kliknutím sem
main.directoryList.contextMenu.remove = Odstranit ze seznamu
main.directoryList.contextMenu.changePassword = Změnit heslo
main.addDirectory.contextMenu.new = Vytvořit nový trezor
main.addDirectory.contextMenu.open = Otevřít existující trezor
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Hledání aktualizací...
welcome.newVersionMessage = Ke stažení je verze %1$s.\nNyní je nainstalovaná %2$s.
# initialize.fxml
initialize.label.password = Heslo
initialize.label.retypePassword = Zopakování hesla
initialize.button.ok = Vytvořit trezor
initialize.messageLabel.alreadyInitialized = Trezor je už připravený
initialize.messageLabel.initializationFailed = Trezor se nepodařilo připravit. Podrobnosti naleznete v souboru se záznamem událostí (log).
# notfound.fxml
notfound.label = Trezor nebyl nalezen. Možná byl přesunut?
# upgrade.fxml
upgrade.button = Přechod na novější verzi trezoru
upgrade.version3dropBundleExtension.msg = Tento trezor je třeba aktualizovat na novější formát.\n„%1$s“ bude přejmenováno na „%2$s“.\nNež budete pokračovat ověřte, že synchronizace byla dokončena.
upgrade.version3dropBundleExtension.err.alreadyExists = Automatický převod se nezdařil.\n„%s“ už existuje.
# unlock.fxml
unlock.label.password = Heslo
unlock.label.mountName = Název jednotky
unlock.label.winDriveLetter = Písmeno jednotky
unlock.label.downloadsPageLink = Všechny verze Cryptomator
unlock.label.advancedHeading = Pokročilé volby
unlock.button.unlock = Odemknout trezor
unlock.button.advancedOptions.show = Více možností
unlock.button.advancedOptions.hide = Méně možností
unlock.choicebox.winDriveLetter.auto = Přiřadit automaticky
unlock.errorMessage.wrongPassword = Chybné heslo
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Nepodporovaná verze trezoru. Byl vytvořen ve starším Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Nepodporovaná verze trezoru. Byl vytvořen v novějším Cryptomator.
unlock.messageLabel.startServerFailed = Spuštění WebDAV serveru se nezdařílo.
# change_password.fxml
changePassword.label.oldPassword = Původní heslo
changePassword.label.newPassword = Nové heslo
changePassword.label.retypePassword = Zopakujte heslo
changePassword.label.downloadsPageLink = Všechny verze Cryptomator
changePassword.button.change = Změnit heslo
changePassword.errorMessage.wrongPassword = Chybné heslo
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
unlocked.label.statsDecrypted = rozšifrováno
unlocked.ioGraph.yAxis.label = Propustnost (MiB/s)
# settings.fxml
settings.version.label = Verze %s
settings.checkForUpdates.label = Zjistit případné aktualizace
settings.requiresRestartLabel = * Vyžaduje restart Cryptomator
# tray icon
tray.menu.open = Otevřít
tray.menu.quit = Ukončit
tray.infoMsg.title = Stále ještě spuštěné
tray.infoMsg.msg = Cryptomator je pořád ještě spuštěný. Ukončete ho přes ikonu v oznamovací oblasti.
tray.infoMsg.msg.osx = Cryptomator je pořád ještě spuštěný. Ukončete ho z ikony v liště nabídek.
initialize.messageLabel.passwordStrength.0 = Velmi slabé
initialize.messageLabel.passwordStrength.1 = Slabé
initialize.messageLabel.passwordStrength.2 = Dobré
initialize.messageLabel.passwordStrength.3 = Silné
# Easter egg for Czech users.
initialize.messageLabel.passwordStrength.4 = Velmi silné
initialize.label.doNotForget = DŮLEŽITÉ\: Pokud heslo ztratíte/zapomenete, nenávratně přijdete o přístup k datům\!
main.directoryList.remove.confirmation.title = Odebrat trezor
main.directoryList.remove.confirmation.header = Opravdu chcete tento trezor odebrat?
main.directoryList.remove.confirmation.content = Trezor bude pouze odebrán ze seznamu v Cryptomator. Končené odstranění provedete až smazáním jeho složky na souborovém systému.
upgrade.version3to4.msg = Tento trezor je třeba aktualizovat na novější formát.\nNázvy šifrovaných složek budou aktualizovány.\nNež budete pokračovat ověřte, že byla dokončena synchronizace.
upgrade.version3to4.err.io = Převod se nezdařil kvůli výjimce na vst./výst. Podrobnosti naleznete v souboru se záznamem událostí (log).
# upgrade.fxml
upgrade.confirmation.label = Ano, je ověřeno, že synchronizace byla dokončena
unlock.label.savePassword = Uložit heslo
unlock.errorMessage.unauthenticVersionMac = Nedaří se ověřit MAC funkci verze.
unlocked.label.mountFailed = Připojení jednotky se nezdařilo
unlock.savePassword.delete.confirmation.title = Smazat uložené heslo
unlock.savePassword.delete.confirmation.header = Opravdu chcete smazat uložené heslo pro tento trezor?
unlock.savePassword.delete.confirmation.content = Uložené heslo k tomuto trezoru bude okamžitě vymazáno ze systémové klíčenky. Pokud ho tam budete chtít znovu uložit, bude třeba trezor odemknout se zapnutou volbou „Uložit heslo“.
settings.debugMode.label = Ladící režim *
# Extension of what please? File, protocol, aplication extension for example? And bundle of what with what? Thanks :)
upgrade.version3dropBundleExtension.title = Přechod z verze 3 trezoru na novější (odebrat příp. .cryptomator a registraci bundle v macOS)
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 *
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.
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Throughput (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Version %s settings.version.label = Version %s
settings.checkForUpdates.label = Tjek for opdateringer settings.checkForUpdates.label = Tjek for opdateringer
settings.port.label = WebDAV Port
settings.port.prompt = 0 \= Vælg automatisk
settings.requiresRestartLabel = * Cryptomator skal genstartes settings.requiresRestartLabel = * Cryptomator skal genstartes
# tray icon # tray icon
tray.menu.open = Åbn tray.menu.open = Åbn
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = Er du sikker på at du vil slett
main.directoryList.remove.confirmation.content = Valgte Vault vil kun blive slettet fra listen. For at slette denne permanent, skal du slette filerne fra dit filsystem. main.directoryList.remove.confirmation.content = Valgte Vault vil kun blive slettet fra listen. For at slette denne permanent, skal du slette filerne fra dit filsystem.
upgrade.version3to4.msg = Denne Vault skal migreres til et nyere format.\nDe krypterede foldernavne vil blive opdateret.\nVent venligst til al synkronisering er gennemført, inden du fortsætter. upgrade.version3to4.msg = Denne Vault skal migreres til et nyere format.\nDe krypterede foldernavne vil blive opdateret.\nVent venligst til al synkronisering er gennemført, inden du fortsætter.
upgrade.version3to4.err.io = Migrering fejlede pga. en I/O fejl. Se logfilen for yderligere detaljer. upgrade.version3to4.err.io = Migrering fejlede pga. en I/O fejl. Se logfilen for yderligere detaljer.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Ja, jeg har sikret mig at al synkronisering er gennemført. upgrade.confirmation.label = Ja, jeg har sikret mig at al synkronisering er gennemført.
initialize.messageLabel.notEmpty = Vault er ikke tom
unlock.label.savePassword = Gem adgangskode unlock.label.savePassword = Gem adgangskode
unlock.errorMessage.unauthenticVersionMac = Kunne ikke autentificere versions-MAC unlock.errorMessage.unauthenticVersionMac = Kunne ikke autentificere versions-MAC
unlocked.label.mountFailed = Montering af drev fejlede unlocked.label.mountFailed = Montering af drev fejlede
@@ -90,7 +86,6 @@ upgrade.version3to4.title = Vault Version 3 til 4 Opgradering
upgrade.version4to5.title = Vault Version 4 til 5 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.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. upgrade.version4to5.err.io = Migrering fejlede pga. en I/O fejl. Se logfilen for yderligere detaljer.
settings.port.apply = Gem
unlock.label.mountAfterUnlock = Monter drev unlock.label.mountAfterUnlock = Monter drev
unlock.label.revealAfterMount = Vis drev unlock.label.revealAfterMount = Vis drev
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Durchsatz (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Version %s settings.version.label = Version %s
settings.checkForUpdates.label = Auf Updates prüfen settings.checkForUpdates.label = Auf Updates prüfen
settings.port.label = WebDAV Port *
settings.port.prompt = 0 \= Automatisch wählen
settings.requiresRestartLabel = * benötigt Neustart von Cryptomator settings.requiresRestartLabel = * benötigt Neustart von Cryptomator
# tray icon # tray icon
tray.menu.open = Öffnen tray.menu.open = Öffnen
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = Möchten Sie diesen Tresor wirkl
main.directoryList.remove.confirmation.content = Dieser Tresor wird nur aus der Liste entfernt. Um den Tresor unwiderruflich zu löschen, entfernen Sie bitte den Tresor aus Ihrem Dateisystem. main.directoryList.remove.confirmation.content = Dieser Tresor wird nur aus der Liste entfernt. Um den Tresor unwiderruflich zu löschen, entfernen Sie bitte den Tresor aus Ihrem Dateisystem.
upgrade.version3to4.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nVerschlüsselte Ordnernamen werden dabei aktualisiert.\nStellen Sie bitte sicher, dass derzeit keine Synchronisation stattfindet. upgrade.version3to4.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nVerschlüsselte Ordnernamen werden dabei aktualisiert.\nStellen Sie bitte sicher, dass derzeit keine Synchronisation stattfindet.
upgrade.version3to4.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei. upgrade.version3to4.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.
settings.prefGvfsScheme.label = WebDAV Schema
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Ja, die Synchronisation ist abgeschlossen upgrade.confirmation.label = Ja, die Synchronisation ist abgeschlossen
initialize.messageLabel.notEmpty = Tresor ist nicht leer
unlock.label.savePassword = Passwort speichern unlock.label.savePassword = Passwort speichern
unlock.errorMessage.unauthenticVersionMac = Versions-MAC konnte nicht authentifiziert werden. unlock.errorMessage.unauthenticVersionMac = Versions-MAC konnte nicht authentifiziert werden.
unlocked.label.mountFailed = Verbinden des Laufwerks fehlgeschlagen unlocked.label.mountFailed = Verbinden des Laufwerks fehlgeschlagen
@@ -90,7 +86,6 @@ upgrade.version3to4.title = Upgrade Tresor-Version 3 zu 4
upgrade.version4to5.title = Upgrade Tresor-Version 4 zu 5 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.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. upgrade.version4to5.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.
settings.port.apply = Anwenden
unlock.label.mountAfterUnlock = Laufwerk verbinden unlock.label.mountAfterUnlock = Laufwerk verbinden
unlock.label.revealAfterMount = Laufwerk anzeigen unlock.label.revealAfterMount = Laufwerk anzeigen
unlocked.lock.force.confirmation.title = Sperren von %1$s fehlgeschlagen unlocked.lock.force.confirmation.title = Sperren von %1$s fehlgeschlagen
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Entsperren fehlgeschlagen. Siehe Log-Datei f
unlocked.moreOptions.mount = Laufwerk verbinden unlocked.moreOptions.mount = Laufwerk verbinden
unlocked.moreOptions.unmount = Laufwerk auswerfen unlocked.moreOptions.unmount = Laufwerk auswerfen
upgrade.version5toX.title = Upgrade Tresor-Version 5 zu X 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. 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
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.prompt = 0 \= automatische Auswahl
settings.webdav.port.apply = Anwenden
settings.webdav.prefGvfsScheme.label = WebDAV URL Schema
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.
+18 -7
View File
@@ -16,6 +16,9 @@ main.addDirectory.contextMenu.open=Open Existing Vault
main.directoryList.remove.confirmation.title=Remove Vault main.directoryList.remove.confirmation.title=Remove Vault
main.directoryList.remove.confirmation.header=Do you really want to remove this vault? main.directoryList.remove.confirmation.header=Do you really want to remove this vault?
main.directoryList.remove.confirmation.content=The vault will only be removed from the list. To permanently delete it, please delete the vault from your filesystem. main.directoryList.remove.confirmation.content=The vault will only be removed from the list. To permanently delete it, please delete the vault from your filesystem.
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.
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking=Checking for Updates... welcome.checkForUpdates.label.currentlyChecking=Checking for Updates...
@@ -26,7 +29,6 @@ initialize.label.password=Password
initialize.label.retypePassword=Retype Password initialize.label.retypePassword=Retype Password
initialize.button.ok=Create Vault initialize.button.ok=Create Vault
initialize.messageLabel.alreadyInitialized=Vault already initialized initialize.messageLabel.alreadyInitialized=Vault already initialized
initialize.messageLabel.notEmpty=Vault not empty
initialize.messageLabel.initializationFailed=Could not initialize vault. See log file for details. initialize.messageLabel.initializationFailed=Could not initialize vault. See log file for details.
initialize.messageLabel.passwordStrength.0=Very weak initialize.messageLabel.passwordStrength.0=Very weak
initialize.messageLabel.passwordStrength.1=Weak initialize.messageLabel.passwordStrength.1=Weak
@@ -65,6 +67,9 @@ unlock.label.mountName=Drive Name
unlock.label.unlockAfterStartup=Auto-Unlock on Start (Experimental) unlock.label.unlockAfterStartup=Auto-Unlock on Start (Experimental)
unlock.label.revealAfterMount=Reveal Drive unlock.label.revealAfterMount=Reveal Drive
unlock.label.winDriveLetter=Drive Letter unlock.label.winDriveLetter=Drive Letter
unlock.label.useOwnMountPath=Use own Mount point
unlock.label.mountPath=Mount Path
unlock.label.mountPathButton=Apply
unlock.label.downloadsPageLink=All Cryptomator versions unlock.label.downloadsPageLink=All Cryptomator versions
unlock.label.advancedHeading=Advanced Options unlock.label.advancedHeading=Advanced Options
unlock.button.unlock=Unlock Vault unlock.button.unlock=Unlock Vault
@@ -80,10 +85,13 @@ unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Unsupported vault.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Unsupported vault. This vault has been created with a newer version of Cryptomator. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Unsupported vault. This vault has been created with a newer version of Cryptomator.
unlock.errorMessage.unauthenticVersionMac=Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac=Could not authenticate version MAC.
unlock.messageLabel.startServerFailed=Starting WebDAV server failed. unlock.messageLabel.startServerFailed=Starting WebDAV server failed.
unlock.successLabel.vaultCreated=Vault was successfully created.
unlock.successLabel.passwordChanged=Password was successfully changed.
unlock.successLabel.upgraded=Cryptomator was successfully upgraded.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword=Old Password changePassword.label.oldPassword=Old Password
changePassword.label.newPassword=New Nassword changePassword.label.newPassword=New Password
changePassword.label.retypePassword=Retype Password changePassword.label.retypePassword=Retype Password
changePassword.label.downloadsPageLink=All Cryptomator versions changePassword.label.downloadsPageLink=All Cryptomator versions
changePassword.button.change=Change Password changePassword.button.change=Change Password
@@ -95,7 +103,7 @@ unlocked.button.lock=Lock Vault
unlocked.moreOptions.mount=Mount Drive unlocked.moreOptions.mount=Mount Drive
unlocked.moreOptions.unmount=Eject Drive unlocked.moreOptions.unmount=Eject Drive
unlocked.moreOptions.reveal=Reveal Drive unlocked.moreOptions.reveal=Reveal Drive
unlocked.moreOptions.copyUrl=Copy WebDAV URL unlocked.moreOptions.copyUrl=Copy Filesystem URL
unlocked.label.mountFailed=Connecting drive failed unlocked.label.mountFailed=Connecting drive failed
unlocked.label.revealFailed=Command failed unlocked.label.revealFailed=Command failed
unlocked.label.unmountFailed=Ejecting drive failed unlocked.label.unmountFailed=Ejecting drive failed
@@ -109,12 +117,15 @@ unlocked.lock.force.confirmation.content=This may be because other programs are
# settings.fxml # settings.fxml
settings.version.label=Version %s settings.version.label=Version %s
settings.checkForUpdates.label=Check for Updates settings.checkForUpdates.label=Check for Updates
settings.port.label=WebDAV Port settings.webdav.port.label=WebDAV Port
settings.port.prompt=0 = Choose automatically settings.webdav.port.prompt=0 = Choose automatically
settings.port.apply=Apply settings.webdav.port.apply=Apply
settings.prefGvfsScheme.label=WebDAV Scheme settings.webdav.prefGvfsScheme.label=WebDAV Scheme
settings.debugMode.label=Debug Mode * settings.debugMode.label=Debug Mode *
settings.requiresRestartLabel=* Cryptomator needs to restart settings.requiresRestartLabel=* Cryptomator needs to restart
settings.volume.label= Mount-Methode *
settings.volume.webdav=WebDAV
settings.volume.fuse=FUSE
# tray icon # tray icon
tray.menu.open=Open tray.menu.open=Open
+51 -42
View File
@@ -1,6 +1,6 @@
app.name = Cryptomator app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = Haz clic aquí para añadir una caja fuerte main.emptyListInstructions = Haga clic aquí para añadir una caja fuerte
# should it be imperative? # should it be imperative?
main.directoryList.contextMenu.remove = Eliminar de la lista main.directoryList.contextMenu.remove = Eliminar de la lista
main.directoryList.contextMenu.changePassword = Cambiar la contraseña main.directoryList.contextMenu.changePassword = Cambiar la contraseña
@@ -14,13 +14,13 @@ initialize.label.password = Contraseña
initialize.label.retypePassword = Repetir contraseña initialize.label.retypePassword = Repetir contraseña
initialize.button.ok = Crear caja fuerte initialize.button.ok = Crear caja fuerte
initialize.messageLabel.alreadyInitialized = La caja fuerte ya está inicializada initialize.messageLabel.alreadyInitialized = La caja fuerte ya está inicializada
initialize.messageLabel.initializationFailed = No se pudo inicializar la caja fuerte. Ver archivo de registro para detalles. initialize.messageLabel.initializationFailed = No se ha podido inicializar la caja fuerte. Consulte el archivo de registro para más información.
# notfound.fxml # notfound.fxml
notfound.label = No se pudo encontrar la caja fuerte. Se movió a otro lugar? notfound.label = No se ha encontrado la caja fuerte. ¿Se movió a otro lugar?
# upgrade.fxml # upgrade.fxml
upgrade.button = Actualizar caja fuerte upgrade.button = Actualizar caja fuerte
upgrade.version3dropBundleExtension.msg = Este caja fuerte se debe actualizar a un nuevo formato.\n"%1$s" se renombra a "%2$s".\nPor favor aseguranse que la sincronización ya se terminó antes de continuar. upgrade.version3dropBundleExtension.msg = Este caja fuerte se debe actualizar a un formato más moderno.\n"%1$s" se renombra a "%2$s".\nAsegúrese de que la sincronización ha terminado antes de iniciar el proceso.
upgrade.version3dropBundleExtension.err.alreadyExists = Migración automática ha fallado.\n"%s" ya existe. upgrade.version3dropBundleExtension.err.alreadyExists = Error en la migración automática.\n"%s" ya existe.
# unlock.fxml # unlock.fxml
unlock.label.password = Contraseña unlock.label.password = Contraseña
unlock.label.mountName = Nombre de la unidad unlock.label.mountName = Nombre de la unidad
@@ -32,9 +32,9 @@ unlock.button.advancedOptions.show = Más opciones
unlock.button.advancedOptions.hide = Menos opciones unlock.button.advancedOptions.hide = Menos opciones
unlock.choicebox.winDriveLetter.auto = Asignar automáticamente unlock.choicebox.winDriveLetter.auto = Asignar automáticamente
unlock.errorMessage.wrongPassword = Contraseña incorrecta unlock.errorMessage.wrongPassword = Contraseña incorrecta
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Caja fuerte no soportada. Ésta caja se ha creado con una versión anterior de Cryptomator. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Caja fuerte no soportada. Esta caja se ha creado con una versión anterior de Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Caja fuerte no soportada. Ésta caja se ha creado con una versión nueva de Cryptomator. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Caja fuerte no soportada. Esta caja se ha creado con una versión más moderna de Cryptomator.
unlock.messageLabel.startServerFailed = Iniciación del servidor de WebDAV ha fallado. unlock.messageLabel.startServerFailed = Error al iniciar el servidor de WebDAV.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Contraseña antigua changePassword.label.oldPassword = Contraseña antigua
# Can also use "current password" = "contraseña actual" # Can also use "current password" = "contraseña actual"
@@ -43,65 +43,74 @@ changePassword.label.retypePassword = Repetir contraseña
changePassword.label.downloadsPageLink = Todas las versiones de Cryptomator changePassword.label.downloadsPageLink = Todas las versiones de Cryptomator
changePassword.button.change = Cambiar contraseña changePassword.button.change = Cambiar contraseña
changePassword.errorMessage.wrongPassword = Contraseña incorrecta changePassword.errorMessage.wrongPassword = Contraseña incorrecta
changePassword.errorMessage.decryptionFailed = Decifración ha fallado changePassword.errorMessage.decryptionFailed = Error en el descifrado
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Encerrar caja fuerte unlocked.button.lock = Bloquear caja fuerte
unlocked.moreOptions.reveal = Revelar unidad unlocked.moreOptions.reveal = Revelar unidad
unlocked.moreOptions.copyUrl = Copiar URL de WebDAV unlocked.moreOptions.copyUrl = Copiar URL de WebDAV
unlocked.label.revealFailed = Comando ha fallado unlocked.label.revealFailed = La orden ha fallado
unlocked.label.unmountFailed = Expulsar el disco ha fallado unlocked.label.unmountFailed = Error al expulsar la unidad
unlocked.label.statsEncrypted = cifrado unlocked.label.statsEncrypted = cifrado
unlocked.label.statsDecrypted = decifrado unlocked.label.statsDecrypted = descifrado
unlocked.ioGraph.yAxis.label = Procesamiento (MiB/s) unlocked.ioGraph.yAxis.label = Rendimiento (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Versión %s settings.version.label = Versión %s
settings.checkForUpdates.label = Comprobar actualizaciones settings.checkForUpdates.label = Comprobar actualizaciones
settings.port.label = Puerto WebDAV settings.requiresRestartLabel = * Cryptomator necesita reiniciarse
settings.port.prompt = 0 \= Elegir automáticamente
settings.requiresRestartLabel = * Cryptomator se necesita reiniciar
# tray icon # tray icon
tray.menu.open = Abrir tray.menu.open = Abrir
tray.menu.quit = Salir tray.menu.quit = Salir
tray.infoMsg.title = Todavía en ejecución tray.infoMsg.title = Todavía en ejecución
tray.infoMsg.msg = Cryptomator todavía esta en ejecución. Para salir usa el icono del tray. tray.infoMsg.msg = Cryptomator todavía está en ejecución. Para salir use el icono de la bandeja.
tray.infoMsg.msg.osx = Cryptomator todavía esta en ejecución. Para salir usa el icono de la barra del menú. tray.infoMsg.msg.osx = Cryptomator todavía está en ejecución. Para salir use el icono de la barra del menú.
initialize.messageLabel.passwordStrength.0 = Muy débil initialize.messageLabel.passwordStrength.0 = Muy débil
initialize.messageLabel.passwordStrength.1 = Débil initialize.messageLabel.passwordStrength.1 = Débil
initialize.messageLabel.passwordStrength.2 = Suficiente initialize.messageLabel.passwordStrength.2 = Suficiente
initialize.messageLabel.passwordStrength.3 = Fuerte initialize.messageLabel.passwordStrength.3 = Fuerte
initialize.messageLabel.passwordStrength.4 = Muy fuerte initialize.messageLabel.passwordStrength.4 = Muy fuerte
initialize.label.doNotForget = IMPORTANTE\: Si olivdas tú contraseña, no hay ninguna manera de recuperar tus datos. initialize.label.doNotForget = IMPORTANTE\: Si olvida la contraseña, no habrá ninguna manera de recuperar los datos.
main.directoryList.remove.confirmation.title = Borrar caja fuerte main.directoryList.remove.confirmation.title = Borrar caja fuerte
main.directoryList.remove.confirmation.header = ¿Quieres de verdad borrar esta caja fuerte? main.directoryList.remove.confirmation.header = ¿Quiere de realmente eliminar esta caja fuerte?
main.directoryList.remove.confirmation.content = La caja fuerte solo se borra de la lista. Para eliminarla permanente por favor elimina los datos de sistema de archivos. main.directoryList.remove.confirmation.content = La caja fuerte solo se elimina de la lista. Para borrarla permanente elimine los datos de su sistema de archivos.
upgrade.version3to4.msg = Este caja fuerte se debe migrar a un formato más reciente.\nLos nombres de las carpetas cifradas se actualizan.\nPor favor asegurarse de que la sincronización ha terminado antes de seguir. upgrade.version3to4.msg = Este caja fuerte se debe migrar a un formato más moderno.\nLos nombres de las carpetas cifradas se actualizan.\nAsegúrese de que la sincronización ha terminado antes de continuar.
upgrade.version3to4.err.io = Migración ha fallado por causa de una excepción I/O. Para detalles revisa el archivo de registro. upgrade.version3to4.err.io = Error en la migración debido a una excepción de E/S. Consulte el archivo de registro para más información.
# or esequema WEBDAV but I think sistema sounds better
settings.prefGvfsScheme.label = Esquema WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Sí, me he asegurado de que la sincronización ha terminado upgrade.confirmation.label = Sí, me he asegurado de que la sincronización ha terminado
initialize.messageLabel.notEmpty = Caja fuerte no está vacia
unlock.label.savePassword = Guardar contraseña unlock.label.savePassword = Guardar contraseña
unlock.errorMessage.unauthenticVersionMac = No se pudo autentificar la versión de MAC. unlock.errorMessage.unauthenticVersionMac = No se pudo autentificar la versión de MAC.
unlocked.label.mountFailed = Error al montar la unidad unlocked.label.mountFailed = Error al montar la unidad
unlock.savePassword.delete.confirmation.title = Borrar contraseña guardada unlock.savePassword.delete.confirmation.title = Borrar contraseña guardada
unlock.savePassword.delete.confirmation.header = ¿Quieres borrar la contraseña guardada de esta unidad? unlock.savePassword.delete.confirmation.header = ¿Quiere realmente borrar la contraseña guardada de esta unidad?
unlock.savePassword.delete.confirmation.content = La contraseña guardada de esta caja fuerte, será borrada inmediatamente del sistema de claves. Si quieres guardar tu contraseña de nuevo, tienes que volver a desbloquear la caja fuerte marcando la opción de "Guardar contraseña". unlock.savePassword.delete.confirmation.content = La contraseña guardada de esta caja fuerte, será borrada inmediatamente del sistema de claves. Si quiere guardar su contraseña de nuevo, tiene que volver a desbloquear la caja fuerte marcando la opción de "Guardar contraseña".
settings.debugMode.label = Modo depuración * settings.debugMode.label = Modo depuración *
upgrade.version3dropBundleExtension.title = Actualizar caja fuerte a la versión 3 (Drop Bundle Extension) 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.version3to4.title = Actualizar caja fuerte de versión 3 a 4
upgrade.version4to5.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 nuevo.\nLos archivos encriptados se actualizarán.\nPor favor, asegúrate de que la sincronización ha terminado antes de empezar con 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 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.err.io = La migración ha fallado por una excepción E/S. Consulta el log para ver más detalles. 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.
settings.port.apply = Aplicar
unlock.label.mountAfterUnlock = Montar unidad unlock.label.mountAfterUnlock = Montar unidad
unlock.label.revealAfterMount = Revelar unidad unlock.label.revealAfterMount = Revelar unidad
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Error al bloquear %1$s
unlocked.lock.force.confirmation.header = Do you want to force locking? unlocked.lock.force.confirmation.header = ¿Quiere forzar el bloqueo?
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. 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 = Auto-Unlock on Start (Experimental) unlock.label.unlockAfterStartup = Autodesbloqueo al arrancar (experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlock.errorMessage.unlockFailed = Error al desbloquear. Consulte el archivo de registro para más información.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Montar unidad
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Expulsar unidad
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.title = Actualizar la versión de la caja fuerte
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. 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 *
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.
+58 -48
View File
@@ -1,24 +1,24 @@
app.name = Cryptomator app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = Cliquez ici pour ajouter un coffre main.emptyListInstructions = Cliquer ici pour ajouter un coffre-fort
main.directoryList.contextMenu.remove = Retirer de la liste main.directoryList.contextMenu.remove = Retirer de la liste
main.directoryList.contextMenu.changePassword = Changer le mot de passe main.directoryList.contextMenu.changePassword = Changer le mot de passe
main.addDirectory.contextMenu.new = Créer un nouveau coffre main.addDirectory.contextMenu.new = Créer un nouveau coffre-fort
main.addDirectory.contextMenu.open = Ouvrir un coffre existant main.addDirectory.contextMenu.open = Ouvrir un coffre-fort existant
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Recherche de mise à jour... welcome.checkForUpdates.label.currentlyChecking = Rechercher les mises à jour...
welcome.newVersionMessage = La version %1$s peut-être téléchargée.\nIl s'agit de %2$s. welcome.newVersionMessage = La version %1$s peut-être téléchargée.\nLa version installée est la %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password = Mot de passe initialize.label.password = Mot de passe
initialize.label.retypePassword = Confirmation initialize.label.retypePassword = Confirmation
initialize.button.ok = Créer le coffre initialize.button.ok = Créer le coffre-fort
initialize.messageLabel.alreadyInitialized = Coffre déjà initialisé initialize.messageLabel.alreadyInitialized = Coffre-fort déjà initialisé
initialize.messageLabel.initializationFailed = Impossible d'initialiser le coffre. Voir le fichier de log pour plus de détails. initialize.messageLabel.initializationFailed = Impossible d'initialiser le coffre-fort. Vérifiez le fichier de log pour plus de détails.
# notfound.fxml # notfound.fxml
notfound.label = Coffre introuvable. A-t-il été déplacé? notfound.label = Coffre-fort introuvable. A-t-il été déplacé?
# upgrade.fxml # upgrade.fxml
upgrade.button = Mettre à niveau upgrade.button = Mettre à jour
upgrade.version3dropBundleExtension.msg = Ce coffre doit être converti dans un format plus récent.\n"%1$s" sera renommé en "%2$s".\nAssurez-vous que la synchronisation est terminée avant de continuer. upgrade.version3dropBundleExtension.msg = Ce coffre-fort doit être converti dans un format plus récent.\n"%1$s" sera renommé en "%2$s".\nAssurez-vous que la synchronisation est terminée avant de continuer.
upgrade.version3dropBundleExtension.err.alreadyExists = La conversion automatique a échoué.\n"%s" existe déjà. upgrade.version3dropBundleExtension.err.alreadyExists = La conversion automatique a échoué.\n"%s" existe déjà.
# unlock.fxml # unlock.fxml
unlock.label.password = Mot de passe unlock.label.password = Mot de passe
@@ -26,14 +26,14 @@ unlock.label.mountName = Nom du lecteur
unlock.label.winDriveLetter = Lettre du lecteur unlock.label.winDriveLetter = Lettre du lecteur
unlock.label.downloadsPageLink = Toutes les versions de Cryptomator unlock.label.downloadsPageLink = Toutes les versions de Cryptomator
unlock.label.advancedHeading = Options avancées unlock.label.advancedHeading = Options avancées
unlock.button.unlock = Déverrouiller le coffre unlock.button.unlock = Déverrouiller le coffre-fort
unlock.button.advancedOptions.show = Plus d'options unlock.button.advancedOptions.show = Plus d'options
unlock.button.advancedOptions.hide = Moins d'options unlock.button.advancedOptions.hide = Moins d'options
unlock.choicebox.winDriveLetter.auto = Assigner automatiquement unlock.choicebox.winDriveLetter.auto = Assigner automatiquement
unlock.errorMessage.wrongPassword = Mot de passe incorrect unlock.errorMessage.wrongPassword = Mot de passe incorrect
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Coffre non supporté. Ce coffre a été créé avec une ancienne version de Cryptomator. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Coffre-fort non supporté. Ce coffre a été créé avec une ancienne version de Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Coffre non supporté. Ce coffre a été créé avec une version de Cryptomator plus récente. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Coffre-fort non supporté. Ce coffre a été créé avec une version de Cryptomator plus récente.
unlock.messageLabel.startServerFailed = Le serveur WebDAV n'a pas pu démarrer. unlock.messageLabel.startServerFailed = Echec de démarrage du serveur WebDAV.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Ancien mot de passe changePassword.label.oldPassword = Ancien mot de passe
changePassword.label.newPassword = Nouveau mot de passe changePassword.label.newPassword = Nouveau mot de passe
@@ -44,7 +44,7 @@ changePassword.errorMessage.wrongPassword = Mot de passe incorrect
# En français, on dit déchiffrement lorsque la clé est connue # En français, on dit déchiffrement lorsque la clé est connue
changePassword.errorMessage.decryptionFailed = Echec du déchiffrement changePassword.errorMessage.decryptionFailed = Echec du déchiffrement
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Verrouiller le coffre unlocked.button.lock = Verrouiller le coffre-fort
unlocked.moreOptions.reveal = Voir le lecteur unlocked.moreOptions.reveal = Voir le lecteur
unlocked.moreOptions.copyUrl = Copier l'URL WebDAV unlocked.moreOptions.copyUrl = Copier l'URL WebDAV
unlocked.label.revealFailed = Echec de la commande unlocked.label.revealFailed = Echec de la commande
@@ -56,52 +56,62 @@ unlocked.label.statsDecrypted = déchiffré
unlocked.ioGraph.yAxis.label = Débit (MiB/s) unlocked.ioGraph.yAxis.label = Débit (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Version %s settings.version.label = Version %s
settings.checkForUpdates.label = Vérif. des mises à jour settings.checkForUpdates.label = Vérifier les mises à jour
settings.port.label = Port WebDAV *
settings.port.prompt = 0 \= Choix automatique
settings.requiresRestartLabel = * Redémarrage requis settings.requiresRestartLabel = * Redémarrage requis
# tray icon # tray icon
tray.menu.open = Ouvrir tray.menu.open = Ouvrir
tray.menu.quit = Quitter tray.menu.quit = Quitter
tray.infoMsg.title = Toujours en fonctionnement tray.infoMsg.title = Action en cours
tray.infoMsg.msg = Cryptomator est toujours en fonctionnement. Utiliser l'icône de la barre des tâches pour quitter. tray.infoMsg.msg = Cryptomator est toujours en fonctionnement. Utiliser l'icône de la barre des tâches pour quitter.
tray.infoMsg.msg.osx = Cryptomator est toujours en fonctionnement. Utilisez la barre de menu pour quitter. tray.infoMsg.msg.osx = Cryptomator est toujours en fonctionnement. Utilisez la barre de menu pour quitter.
initialize.messageLabel.passwordStrength.0 = Très faible initialize.messageLabel.passwordStrength.0 = Très faible
initialize.messageLabel.passwordStrength.1 = Faible initialize.messageLabel.passwordStrength.1 = Faible
initialize.messageLabel.passwordStrength.2 = Raisonnable initialize.messageLabel.passwordStrength.2 = Correct
initialize.messageLabel.passwordStrength.3 = Fort initialize.messageLabel.passwordStrength.3 = Fort
initialize.messageLabel.passwordStrength.4 = Très fort initialize.messageLabel.passwordStrength.4 = Très fort
initialize.label.doNotForget = ATTENTION \: Si vous oubliez votre mot de passe, il n'y aura aucun moyen de récupérer vos données. initialize.label.doNotForget = ATTENTION \: Si vous oubliez votre mot de passe, il n'y aura aucun moyen de récupérer vos données.
main.directoryList.remove.confirmation.title = Retirer un coffre main.directoryList.remove.confirmation.title = Supprimer le coffre-fort
main.directoryList.remove.confirmation.header = Voulez-vous vraiment retirer ce coffre ? main.directoryList.remove.confirmation.header = Voulez-vous vraiment supprimer ce coffre-fort ?
main.directoryList.remove.confirmation.content = Le coffre sera seulement retiré de la liste. Pour le supprimer complètement, supprimez les fichiers depuis votre système de fichiers. main.directoryList.remove.confirmation.content = Le coffre-fort sera seulement retiré de la liste. Pour le supprimer complètement, supprimez les fichiers depuis votre système de fichiers.
upgrade.version3to4.msg = Ce coffre doit être converti dans un nouveau format. Les noms de dossiers chiffrés seront mis à jour.\nMerci de vous assurer que la procédure de synchronisation est terminée avant de continuer. upgrade.version3to4.msg = Ce coffre-fort doit être converti dans un nouveau format. \nLes noms des dossiers chiffrés seront mis à jour.\nMerci de vous assurer que la synchronisation est terminée avant de continuer.
upgrade.version3to4.err.io = La migration a échoué à cause d'une erreur d'entrée/sortie. Référez-vous au fichier log pour plus de détails. upgrade.version3to4.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.
settings.prefGvfsScheme.label = Schéma d'URI WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Oui, je suis certain que la synchronisation est terminée upgrade.confirmation.label = Oui, je suis certain que la synchronisation est terminée
initialize.messageLabel.notEmpty = Le coffre n'est pas vide
unlock.label.savePassword = Se souvenir du mot de passe unlock.label.savePassword = Se souvenir du mot de passe
unlock.errorMessage.unauthenticVersionMac = Impossible d'authentifier la version MAC unlock.errorMessage.unauthenticVersionMac = Impossible d'authentifier la version MAC
unlocked.label.mountFailed = Echec de connexion au lecteur unlocked.label.mountFailed = Echec de connexion au lecteur
unlock.savePassword.delete.confirmation.title = supprimer le mot de passe sauvegardé unlock.savePassword.delete.confirmation.title = Supprimer le mot de passe sauvegardé
unlock.savePassword.delete.confirmation.header = voulez vous vraiment supprimer le mot de pase sauvegardé de ce compte ? unlock.savePassword.delete.confirmation.header = Voulez vous vraiment oublier le mot de passe de ce coffre-fort ?
unlock.savePassword.delete.confirmation.content = Le mot de passe de ce coffre sera supprimé immédiatement du trousseau.Si vous voulez le sauvegarder à nouveau, vous devrez cocher la case "retenir le mot de passe" lors du déverrouillage du coffre. unlock.savePassword.delete.confirmation.content = Le mot de passe de ce coffre sera supprimé immédiatement du trousseau. Si vous voulez le sauvegarder à nouveau, vous devrez cocher la case "Se souvenir du mot de passe" lors du déverrouillage du coffre.
settings.debugMode.label = mode debuggage* settings.debugMode.label = Mode bug *
upgrade.version3dropBundleExtension.title = mise à jour vers la version 3 du coffre (extension "drop bundle") upgrade.version3dropBundleExtension.title = Mise à jour du coffre-fort (en version 3 extension "Drop Bundle")
upgrade.version3to4.title = metre à jour le coffre de la version 3 à la version 4 upgrade.version3to4.title = Mise à jour de la version du coffre-fort (v3 à v4)
upgrade.version4to5.title = metre à jour le coffre de la version 4 à la version 5 upgrade.version4to5.title = Mise à jour de la version du coffre-fort (v4 à v5)
upgrade.version4to5.msg = ce coffre doit être mis à jour vers un format plus récent.\nles fichiés 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.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 = Migration échouée due à une erreur de lecture. Lisez les logs pour plus de détails. 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.
settings.port.apply = Appliquer unlock.label.mountAfterUnlock = Monter le lecteur
unlock.label.mountAfterUnlock = Monter un lecteur
unlock.label.revealAfterMount = Voir le lecteur unlock.label.revealAfterMount = Voir le lecteur
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Le verrouillage de %1$s a échoué
unlocked.lock.force.confirmation.header = Do you want to force locking? unlocked.lock.force.confirmation.header = Voulez-vous forcer le verrouillage ?
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. 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 = Auto-Unlock on Start (Experimental) unlock.label.unlockAfterStartup = Déverouiller automatiquement au démarrage (experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlock.errorMessage.unlockFailed = Le déverouillage a échoué. Référez-vous au fichier log pour plus de détails.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Monter le disque
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Ejecter le disque
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.title = Mise à jour du coffre-fort
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. 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 *
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.
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Teljesítmény (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Verzió\: %s settings.version.label = Verzió\: %s
settings.checkForUpdates.label = Frissítések keresése settings.checkForUpdates.label = Frissítések keresése
settings.port.label = WebDAV Port *
settings.port.prompt = 0 \= Automatikus választás
settings.requiresRestartLabel = * Cryptomator újraindítása szükséges settings.requiresRestartLabel = * Cryptomator újraindítása szükséges
# tray icon # tray icon
tray.menu.open = Megnyit tray.menu.open = Megnyit
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = Tényleg törölni akarod ezt a
main.directoryList.remove.confirmation.content = A széf csak a listából lesz eltávolítva. Végleges törléshez kérlek töröld a merevlemezen tárolt fájlokat. main.directoryList.remove.confirmation.content = A széf csak a listából lesz eltávolítva. Végleges törléshez kérlek töröld a merevlemezen tárolt fájlokat.
upgrade.version3to4.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. upgrade.version3to4.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.
upgrade.version3to4.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. upgrade.version3to4.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.
settings.prefGvfsScheme.label = WebDAV séma
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Igen, meggyőződtem a szinkronizáció befejeztéről upgrade.confirmation.label = Igen, meggyőződtem a szinkronizáció befejeztéről
initialize.messageLabel.notEmpty = A széf nem üres
unlock.label.savePassword = Jelszó mentése unlock.label.savePassword = Jelszó mentése
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Meghajtó csatlakoztatása sikertelen unlocked.label.mountFailed = Meghajtó csatlakoztatása sikertelen
@@ -90,7 +86,6 @@ 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.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.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. 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.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Volume dati (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Versione %s settings.version.label = Versione %s
settings.checkForUpdates.label = Verifica aggiornamenti settings.checkForUpdates.label = Verifica aggiornamenti
settings.port.label = WebDAV Port *
settings.port.prompt = 0 \= Scegli automaticamente
settings.requiresRestartLabel = * Cryptomator deve essere riavviato settings.requiresRestartLabel = * Cryptomator deve essere riavviato
# tray icon # tray icon
tray.menu.open = Apri tray.menu.open = Apri
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = Vuoi davvero rimuovere questo va
main.directoryList.remove.confirmation.content = Il vault sarà rimosso solo dalla lista. Per eliminarlo definitivamente, elimina per favore i file dal tuo hard disk. main.directoryList.remove.confirmation.content = Il vault sarà rimosso solo dalla lista. Per eliminarlo definitivamente, elimina per favore i file dal tuo hard disk.
upgrade.version3to4.msg = Il vault deve ha bisogno di essere migrato in un nuovo formato. I nome delle cartelle criptate saranno aggiornati. Per favore assicurati che la sincronizzazione sia terminata prima di procedere. upgrade.version3to4.msg = Il vault deve ha bisogno di essere migrato in un nuovo formato. I nome delle cartelle criptate saranno aggiornati. Per favore assicurati che la sincronizzazione sia terminata prima di procedere.
upgrade.version3to4.err.io = Migrazione fallita a causa di una eccezione I/O. Verificare i file di log per i dettagli. upgrade.version3to4.err.io = Migrazione fallita a causa di una eccezione I/O. Verificare i file di log per i dettagli.
settings.prefGvfsScheme.label = Schema WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Si, sono sicuro che la sincronizzazione e' terminata upgrade.confirmation.label = Si, sono sicuro che la sincronizzazione e' terminata
initialize.messageLabel.notEmpty = Vault non vuoto
unlock.label.savePassword = Salva Password unlock.label.savePassword = Salva Password
unlock.errorMessage.unauthenticVersionMac = Non riesco ad autenticare la versione MAC. unlock.errorMessage.unauthenticVersionMac = Non riesco ad autenticare la versione MAC.
unlocked.label.mountFailed = Tentativo di connessione drive fallito unlocked.label.mountFailed = Tentativo di connessione drive fallito
@@ -90,7 +86,6 @@ upgrade.version3to4.title = Aggiornamento Vault da versione 3 a 4
upgrade.version4to5.title = Aggiornamento da versione 4 a 5 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.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. upgrade.version4to5.err.io = Migrazione fallita a causa di una eccezione I/O. Verifica il file di log per i dettagli.
settings.port.apply = Conferma
unlock.label.mountAfterUnlock = Monta il disco unlock.label.mountAfterUnlock = Monta il disco
unlock.label.revealAfterMount = Mostra il disco unlock.label.revealAfterMount = Mostra il disco
unlocked.lock.force.confirmation.title = Il blocco di %1$s è fallito unlocked.lock.force.confirmation.title = Il blocco di %1$s è fallito
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
+79 -69
View File
@@ -1,104 +1,114 @@
app.name = Cryptomator app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = ここをクリックして金庫を追加する main.emptyListInstructions = ここをクリックして金庫を追加
main.directoryList.contextMenu.remove = リストから削除する main.directoryList.contextMenu.remove = リストから削除
main.directoryList.contextMenu.changePassword = パスワード変更 main.directoryList.contextMenu.changePassword = パスワード変更
main.addDirectory.contextMenu.new = 新しい金庫を作成する main.addDirectory.contextMenu.new = 新しい金庫を作成
main.addDirectory.contextMenu.open = 既存の金庫を開く main.addDirectory.contextMenu.open = 既存の金庫を開く
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = アップデートを確認... welcome.checkForUpdates.label.currentlyChecking = アップデートを確認しています...
welcome.newVersionMessage = バージョン%1$sがダウンロードできます。\n現在のバージョンは%2$sです。 welcome.newVersionMessage = バージョン %1$s がダウンロード可能です。\n現在のバージョンは %2$s です。
# initialize.fxml # initialize.fxml
initialize.label.password = パスワード initialize.label.password = パスワード
initialize.label.retypePassword = パスワード再入力 initialize.label.retypePassword = パスワード再入力
initialize.button.ok = 金庫を作成 initialize.button.ok = 金庫を作成
initialize.messageLabel.alreadyInitialized = 金庫がすでに初期化されています initialize.messageLabel.alreadyInitialized = 金庫は既に初期化されています
initialize.messageLabel.initializationFailed = 金庫の初期化ができませんでした。詳細はログファイルをご覧ください。 initialize.messageLabel.initializationFailed = 金庫の初期化ができませんでした。詳細はログファイルをご覧ください。
# notfound.fxml # notfound.fxml
notfound.label = 金庫が見つかりませんでした。動かされたのですか? notfound.label = 金庫が見つかりません。移動しましたか?
# upgrade.fxml # upgrade.fxml
upgrade.button = 金庫をアップグレードする upgrade.button = 金庫をアップグレード
upgrade.version3dropBundleExtension.msg = この金庫を新しい形式に移行する必要があります。\n"%1$s""%2$s"に変更されます。\n続行する前に同期が完了していることをご確認ください。 upgrade.version3dropBundleExtension.msg = この金庫を新しい形式に移行する必要があります。\n"%1$s""%2$s" に変更されます。\n続行する前に同期が完了していることをご確認ください。
upgrade.version3dropBundleExtension.err.alreadyExists = 自動移行が失敗しました。\n"%s"はすでに存在します。 upgrade.version3dropBundleExtension.err.alreadyExists = 自動移行が失敗しました。\n"%s" はすでに存在します。
# unlock.fxml # unlock.fxml
unlock.label.password = パスワード unlock.label.password = パスワード
unlock.label.mountName = ドライブ名 unlock.label.mountName = ドライブ名
unlock.label.winDriveLetter = ドライブ文字 unlock.label.winDriveLetter = ドライブ文字
unlock.label.downloadsPageLink = てのCryptomatorバージョン unlock.label.downloadsPageLink = すべての Cryptomator バージョン
unlock.label.advancedHeading = 詳細オプション unlock.label.advancedHeading = 詳細オプション
unlock.button.unlock = 金庫を解除する unlock.button.unlock = 金庫を解
unlock.button.advancedOptions.show = その他のオプション unlock.button.advancedOptions.show = オプションを表示
unlock.button.advancedOptions.hide = 基本オプション unlock.button.advancedOptions.hide = オプションを非表示
unlock.choicebox.winDriveLetter.auto = 自動に割り当てる unlock.choicebox.winDriveLetter.auto = 自動に割り当てる
unlock.errorMessage.wrongPassword = 間違ったパスワード unlock.errorMessage.wrongPassword = パスワードが無効です
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = サポートされていない金庫です。この金庫は古いバージョンのCryptomatorから作成されました。 unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = サポートされない金庫です。この金庫は古いバージョンの Cryptomator を使用して作成されました。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = サポートされていない金庫です。この金庫は新しいバージョンのCryptomatorから作成されました。 unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = サポートされない金庫です。この金庫は新しいバージョンの Cryptomator を使用して作成されました。
unlock.messageLabel.startServerFailed = WebDAVサーバーの起動失敗 unlock.messageLabel.startServerFailed = WebDAV サーバーの起動失敗しました。
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = 古いパスワード changePassword.label.oldPassword = 古いパスワード
changePassword.label.newPassword = 新しいパスワード changePassword.label.newPassword = 新しいパスワード
changePassword.label.retypePassword = 二回目のパスワード(確認用) changePassword.label.retypePassword = パスワードの再入力
changePassword.label.downloadsPageLink = てのCryptomatorバージョン changePassword.label.downloadsPageLink = すべての Cryptomator バージョン
changePassword.button.change = パスワードの変更 changePassword.button.change = パスワードの変更
changePassword.errorMessage.wrongPassword = 違うパスワード changePassword.errorMessage.wrongPassword = パスワードが無効です
changePassword.errorMessage.decryptionFailed = 解読不可 changePassword.errorMessage.decryptionFailed = 復号に失敗しました。
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = 金庫の施錠 unlocked.button.lock = 金庫の施錠
unlocked.moreOptions.reveal = 金庫ドライブの表示 unlocked.moreOptions.reveal = ドライブの表示
unlocked.moreOptions.copyUrl = WebDAVURLのコピー unlocked.moreOptions.copyUrl = WebDAV URL のコピー
unlocked.label.revealFailed = 入力エラー unlocked.label.revealFailed = 入力エラー
unlocked.label.unmountFailed = 外部出力の排出エラー unlocked.label.unmountFailed = ドライブの取り出しに失敗
unlocked.label.statsEncrypted = 暗号化 unlocked.label.statsEncrypted = 暗号化済み
unlocked.label.statsDecrypted = 解読 unlocked.label.statsDecrypted = 復号済み
unlocked.ioGraph.yAxis.label = 情報処理量 unlocked.ioGraph.yAxis.label = スループット (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = バージョン%s settings.version.label = バージョン %s
settings.checkForUpdates.label = 最新版のチェック settings.checkForUpdates.label = 最新版のチェック
settings.port.label = WebDAVの移動 settings.requiresRestartLabel = *Cryptomatorの再起動が必要
settings.port.prompt = 0=自動的に選択します
settings.requiresRestartLabel = Cryptomatorの再起動が必要です
# tray icon # tray icon
tray.menu.open = 開く tray.menu.open = 開く
tray.menu.quit = 閉じる tray.menu.quit = 閉じる
tray.infoMsg.title = バックグラウンドで稼働 tray.infoMsg.title = バックグラウンドで実行
tray.infoMsg.msg = Cryptomatorはまだ稼働しています。終了はトレイアイコンからしてください。 tray.infoMsg.msg = まだ Cryptomator は実行中です。トレイアイコンのアイコンから閉じてください。
tray.infoMsg.msg.osx = Cryptomatorはまだ稼働しています。終了はメヌーバーアイコンからてください。 tray.infoMsg.msg.osx = まだ Cryptomator は実行中です。メニューバーアイコンから閉じてください。
initialize.messageLabel.passwordStrength.0 = 非常に弱い initialize.messageLabel.passwordStrength.0 = 非常に弱い
initialize.messageLabel.passwordStrength.1 = 弱い initialize.messageLabel.passwordStrength.1 = 弱い
initialize.messageLabel.passwordStrength.2 = 普通 initialize.messageLabel.passwordStrength.2 = 普通
initialize.messageLabel.passwordStrength.3 = 強い initialize.messageLabel.passwordStrength.3 = 強い
initialize.messageLabel.passwordStrength.4 = 非常に強い initialize.messageLabel.passwordStrength.4 = 非常に強い
initialize.label.doNotForget = 重要パスワードを忘れましたら、あなたのデータ復旧できません。 initialize.label.doNotForget = 重要\: パスワードを忘れると、データ復旧できません。
main.directoryList.remove.confirmation.title = 金庫削除 main.directoryList.remove.confirmation.title = 金庫削除
main.directoryList.remove.confirmation.header = 本当にこの金庫を取り除きたいですか main.directoryList.remove.confirmation.header = この金庫を本当に削除しますか?
main.directoryList.remove.confirmation.content = 金庫はリストのみで削除されます。永久に削除するなら、ファイルシステムからファイルを削除してください。 main.directoryList.remove.confirmation.content = 金庫はリストのみで削除されます。完全に削除するには、ファイルシステムからファイルを削除してください。
upgrade.version3to4.msg = この金庫は新しいフォーマットに移行する必要があります。暗号化されたフォルダの名前は更新されます。行する前に同期が完了していることをご確認ください。 upgrade.version3to4.msg = この金庫は新しいフォーマットに移行する必要があります。\n暗号化されたフォルダの名前は更新されます。\n続行する前に同期が完了していることをご確認ください。
upgrade.version3to4.err.io = I/O例外のため移行失敗しました。詳細はログをご確認ください。 upgrade.version3to4.err.io = I/O の例外で移行失敗しました。詳細はログをご確認ください。
settings.prefGvfsScheme.label = WebDAVスキーム
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = はい、同期が完了していることを確認しました。 upgrade.confirmation.label = はい、同期が完了していることを確認しました。
initialize.messageLabel.notEmpty = 金庫が空いていません。 unlock.label.savePassword = パスワードを保存
unlock.label.savePassword = パスワード保存 unlock.errorMessage.unauthenticVersionMac = MAC バージョンを認証できません。
unlock.errorMessage.unauthenticVersionMac = バージョンMACを認証できません。 unlocked.label.mountFailed = ドライブの接続に失敗
unlocked.label.mountFailed = ドライブの接続に失敗しました。 unlock.savePassword.delete.confirmation.title = 保存済みのパスワードを削除
unlock.savePassword.delete.confirmation.title = 保存されたパスワードを削除 unlock.savePassword.delete.confirmation.header = 本当にこの金庫の保存済みパスワードを削除しますか?
unlock.savePassword.delete.confirmation.header = あなたは本当にこの金庫の保存されたパスワードを削除しますか? unlock.savePassword.delete.confirmation.content = この金庫の保存済みパスワードは、直ちにシステムのキーチェーンから削除されます。もう一度パスワードを保存するには、"Save Password" オプションを有効にして金庫を解錠する必要があります。
unlock.savePassword.delete.confirmation.content = この金庫の保存されたパスワードはあなたのシステムキーチェーンから直ちに削除されます。もしまたパスワードを保存したい際には、”パスワード保存”オプションを有効にした上に金庫を解除する必要があります。 settings.debugMode.label = デバッグモード *
settings.debugMode.label = デバッグモード upgrade.version3dropBundleExtension.title = 金庫をバージョン 3 にアップグレード(Drop Bundle Extension)
upgrade.version3dropBundleExtension.title = 金庫バージョン3アップグレード(Drop Bundle Extension) upgrade.version3to4.title = 金庫バージョン 3 から 4 にアップグレード
upgrade.version3to4.title = 金庫バージョン3から4にアップグレード upgrade.version4to5.title = 金庫バージョン 4 から 5 にアップグレード
upgrade.version4to5.title = 金庫バージョン4から5にアップグレード upgrade.version4to5.msg = この金庫は新しいフォーマットに移行する必要があります。\n暗号化されたファイルは更新されます。\n続行する前に同期が完了していることをご確認ください。\n\n注意:すべてのファイルの変更日は、現在の日付・時刻に変わります。
upgrade.version4to5.msg = この金庫は新しいフォーマットに移行する必要があります。暗号化されたファイルは更新されます。進行する前に同期が完了していることをご確認ください。\n\n注意:すべてのファイルの変更日は、現在の日付・時刻に変わります upgrade.version4to5.err.io = I/O の例外で移行に失敗しました。詳細はログをご確認ください
upgrade.version4to5.err.io = I/O例外のため移行が失敗しました。詳細はログをご確認ください。
settings.port.apply = 適用
unlock.label.mountAfterUnlock = ドライブをマウント unlock.label.mountAfterUnlock = ドライブをマウント
unlock.label.revealAfterMount = ドライブを明らかにする unlock.label.revealAfterMount = ドライブの表示
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = %1$s の施錠に失敗しました
unlocked.lock.force.confirmation.header = Do you want to force locking? unlocked.lock.force.confirmation.header = 強制的にロックしますか?
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. unlocked.lock.force.confirmation.content = これは恐らく他のプログラムがこの金庫のファイルをまだアクセスしているか、あるいは別の問題が発生したためです。\n\nまだファイルにアクセスしているプログラムが正しく動作しない可能性があり、それらのプログラムによってまだ書き込まれていないデータが失われる可能性があります。
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental) unlock.label.unlockAfterStartup = 起動時に解錠 (実験的)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlock.errorMessage.unlockFailed = 施錠に失敗しました。詳細をログファイルで確認してください。
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = ドライブのマウント
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = ドライブの取り出し
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.title = 金庫のバージョンをアップグレード
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. 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 スキーム
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.
+36 -26
View File
@@ -30,7 +30,7 @@ unlock.button.unlock = 보관함 해제
unlock.button.advancedOptions.show = 더 많은 옵션 unlock.button.advancedOptions.show = 더 많은 옵션
unlock.button.advancedOptions.hide = 기본 옵션 unlock.button.advancedOptions.hide = 기본 옵션
unlock.choicebox.winDriveLetter.auto = 자동으로 할당 unlock.choicebox.winDriveLetter.auto = 자동으로 할당
unlock.errorMessage.wrongPassword = 틀린 비밀번호 unlock.errorMessage.wrongPassword = 잘못된 비밀번호
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 지원되지 않는 보관함. 이 보관함은 이전 버전의 Cryptomator에서 생성되었습니다. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 지원되지 않는 보관함. 이 보관함은 이전 버전의 Cryptomator에서 생성되었습니다.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 지원되지 않는 보관함. 이 보관함은 상위 버전의 Cryptomator에서 생성되었습니다. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 지원되지 않는 보관함. 이 보관함은 상위 버전의 Cryptomator에서 생성되었습니다.
unlock.messageLabel.startServerFailed = WedDAV 서버 시작 실패 unlock.messageLabel.startServerFailed = WedDAV 서버 시작 실패
@@ -40,29 +40,27 @@ changePassword.label.newPassword = 새로운 비밀번호
changePassword.label.retypePassword = 비밀번호 재입력 changePassword.label.retypePassword = 비밀번호 재입력
changePassword.label.downloadsPageLink = 모든 Cryptomator 버전 changePassword.label.downloadsPageLink = 모든 Cryptomator 버전
changePassword.button.change = 비밀번호 변경 changePassword.button.change = 비밀번호 변경
changePassword.errorMessage.wrongPassword = 틀린 비밀번호 changePassword.errorMessage.wrongPassword = 잘못된 비밀번호
changePassword.errorMessage.decryptionFailed = 호화 실패 changePassword.errorMessage.decryptionFailed = 호화 해제 실패
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = 보관함 잠그기 unlocked.button.lock = 보관함 잠그기
unlocked.moreOptions.reveal = 드라이브 표시 unlocked.moreOptions.reveal = 드라이브 표시
unlocked.moreOptions.copyUrl = WebDAV 주소 복사 unlocked.moreOptions.copyUrl = WebDAV 주소 복사
unlocked.label.revealFailed = 명령 실패 unlocked.label.revealFailed = 명령 실패
unlocked.label.unmountFailed = 드라이브 추출 실패 unlocked.label.unmountFailed = 드라이브 꺼내기 실패
unlocked.label.statsEncrypted = 암호화 unlocked.label.statsEncrypted = 암호화
unlocked.label.statsDecrypted = 복호화 unlocked.label.statsDecrypted = 복호화
unlocked.ioGraph.yAxis.label = 처리량 (MiB/s) unlocked.ioGraph.yAxis.label = 처리량 (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = 버전 %s settings.version.label = 버전 %s
settings.checkForUpdates.label = 업데이트 확인 settings.checkForUpdates.label = 업데이트 확인
settings.port.label = WebDAV 포트 *
settings.port.prompt = 0 \= 자동으로 선택
settings.requiresRestartLabel = * Cryptomator 재시작 필요 settings.requiresRestartLabel = * Cryptomator 재시작 필요
# tray icon # tray icon
tray.menu.open = 열기 tray.menu.open = 열기
tray.menu.quit = 종료 tray.menu.quit = 종료
tray.infoMsg.title = 계속 실행 중입니다. tray.infoMsg.title = 계속 실행 중입니다.
tray.infoMsg.msg = Cryptomator가 계속 실행 중입니다. 종료하실려면 트레이 아이콘에서 해주세요. tray.infoMsg.msg = Cryptomator가 계속 실행 중입니다. 종료 트레이 아이콘에서 해주세요.
tray.infoMsg.msg.osx = Cryptomator가 계속 실행중입니다. 종료하실려면 메뉴 바 아이콘에서 해주세요. tray.infoMsg.msg.osx = Cryptomator가 계속 실행중입니다. 종료 메뉴바 아이콘에서 해주세요.
initialize.messageLabel.passwordStrength.0 = 매우 약함 initialize.messageLabel.passwordStrength.0 = 매우 약함
initialize.messageLabel.passwordStrength.1 = 약함 initialize.messageLabel.passwordStrength.1 = 약함
initialize.messageLabel.passwordStrength.2 = 괜찮음 initialize.messageLabel.passwordStrength.2 = 괜찮음
@@ -71,34 +69,46 @@ initialize.messageLabel.passwordStrength.4 = 매우 강력함
initialize.label.doNotForget = 중요\: 만약 비밀번호를 잊으셨다면, 여러분의 데이터를 복구할 수 없습니다. initialize.label.doNotForget = 중요\: 만약 비밀번호를 잊으셨다면, 여러분의 데이터를 복구할 수 없습니다.
main.directoryList.remove.confirmation.title = 보관함 삭제 main.directoryList.remove.confirmation.title = 보관함 삭제
main.directoryList.remove.confirmation.header = 정말 이 보관함을 삭제하시겠습니까? main.directoryList.remove.confirmation.header = 정말 이 보관함을 삭제하시겠습니까?
main.directoryList.remove.confirmation.content = 보관함이 목록에서만 제거되었습니다. 데이터를 완전히 제거하시려면, 여러분의 파일시스템이서 제거해 주시기 바랍니다. main.directoryList.remove.confirmation.content = 보관함이 목록에서만 제거되었습니다. 데이터를 완전히 제거하시려면, 사용자의 파일시스템이서 제거해 주시기 바랍니다.
upgrade.version3to4.msg = 이 보관함은 새로운 형식으로 바뀔 필요가 있습니다. 암호화된 폴더 이름이 업데이트 될 것입니다. 진행하기 전에 동기화가 완료되었는지 확인하기 바랍니다. upgrade.version3to4.msg = 이 보관함은 새로운 형식으로 이전되어야 합니다. 암호화된 폴더 이름이 업데이트 될 것입니다. 진행하기 전에 동기화가 완료되었는지 확인하기 바랍니다.
upgrade.version3to4.err.io = 입출력 예외 문제로 마이그레이션이 실패하였습니다. 자세한 사항은 로그 파일을 확인하세요. upgrade.version3to4.err.io = I/O 예외 문제로 마이그레이션이 실패하였습니다. 자세한 사항은 로그 파일을 확인하세요.
settings.prefGvfsScheme.label = WebDAV sceme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = 네. 동기화가 완료되었음을 확인하였습니다. upgrade.confirmation.label = 네. 동기화가 완료되었음을 확인하였습니다.
initialize.messageLabel.notEmpty = 보관함이 비어있지 않음
unlock.label.savePassword = 비밀번호 저장 unlock.label.savePassword = 비밀번호 저장
unlock.errorMessage.unauthenticVersionMac = 인증할 수 없는 버전의 입니다 unlock.errorMessage.unauthenticVersionMac = 인증할 수 없는 버전의 MAC(Message Authentication Code)입니다
unlocked.label.mountFailed = 드라이브 연결 실패 unlocked.label.mountFailed = 드라이브 연결 실패
unlock.savePassword.delete.confirmation.title = 저장된 비밀번호 삭제 unlock.savePassword.delete.confirmation.title = 저장된 비밀번호 삭제
unlock.savePassword.delete.confirmation.header = 정말로 이 보관함의 저장된 비밀번호를 지우시겠습니까? unlock.savePassword.delete.confirmation.header = 정말로 이 보관함의 저장된 비밀번호를 지우시겠습니까?
unlock.savePassword.delete.confirmation.content = 이 보관함의 저장된 비밀번호는 당신의 시스템 키체인에서 즉시 삭제될 것입니다. 다시 비밀번호를 저장하고 싶으시다면, 보관함을 열 때 "비밀번호 저장" 옵션을 활성화해야 합니다 unlock.savePassword.delete.confirmation.content = 이 보관함의 저장된 비밀번호는 당신의 시스템 키체인에서 즉시 삭제될 것입니다. 다시 비밀번호를 저장하고 싶으시다면, 보관함을 열 때 "비밀번호 저장" 옵션을 활성화해야 합니다
settings.debugMode.label = 디버그 모드 settings.debugMode.label = 디버그 모드 *
upgrade.version3dropBundleExtension.title = 버전 3 보관함 업그레이드 (Drop Bundle Extension) upgrade.version3dropBundleExtension.title = 버전 3 보관함 업그레이드 (Drop Bundle Extension)
upgrade.version3to4.title = 보관함 버전 3에서 4로 업그레이드 upgrade.version3to4.title = 보관함 버전 3에서 4로 업그레이드
upgrade.version4to5.title = 보관함 버전 4에서 5로 업그레이드 upgrade.version4to5.title = 보관함 버전 4에서 5로 업그레이드
upgrade.version4to5.msg = 이 보관함은 새로운 포맷으로 이전되어야 합니다.\n암호화된 파일들은 업데이트 될 것입니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.\n\n참고\: 모든 파일의 수정 날짜는 과정 진행 중에 현재 날짜/시간으로 바뀔 것입니다. upgrade.version4to5.msg = 이 보관함은 새로운 형식으로 이전되어야 합니다.\n암호화된 파일들은 업데이트 될 것입니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.\n\n참고\: 모든 파일의 수정 날짜는 과정 진행 중에 현재 날짜/시간으로 바뀔 것입니다.
upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요. upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요.
settings.port.apply = 적용
unlock.label.mountAfterUnlock = 드라이브 마운트 unlock.label.mountAfterUnlock = 드라이브 마운트
unlock.label.revealAfterMount = 드라이브 공개 unlock.label.revealAfterMount = 드라이브 공개
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = %1$s 잠그기 실패
unlocked.lock.force.confirmation.header = Do you want to force locking? unlocked.lock.force.confirmation.header = 강제로 잠그시겠습니까?
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. unlocked.lock.force.confirmation.content = 이는 다른 프로그램이 보관함 내의 파일을 접근하고 있거나, 다른 문제가 발생했기 때문일 수 있습니다.\n\n파일을 접근하고 있는 프로그램이 제대로 동작하지 않을 수 있으며, 프로그램이 쓰지 않은 데이터는 손실될 수 있습니다.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental) unlock.label.unlockAfterStartup = 시작 시 자동 잠금 해제 (실험적)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlock.errorMessage.unlockFailed = 잠금 해제 실패. 자세한 사항은 로그 파일을 참조하세요.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = 드라이브 마운트
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = 드라이브 꺼내기
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.title = 보관함 버전 업그레이드
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. 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 스킴
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.
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Caurlaidība (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Versija %s settings.version.label = Versija %s
settings.checkForUpdates.label = Meklēt atjauninājumus settings.checkForUpdates.label = Meklēt atjauninājumus
settings.port.label = WebDAV Ports *
settings.port.prompt = 0 \= automātiski
settings.requiresRestartLabel = * Cryptomator nepieciešams restarts settings.requiresRestartLabel = * Cryptomator nepieciešams restarts
# tray icon # tray icon
tray.menu.open = Atvērt tray.menu.open = Atvērt
@@ -75,10 +73,8 @@ main.directoryList.remove.confirmation.header = Vai tiešām vēlie noņemt šo
main.directoryList.remove.confirmation.content = Glabātuve tiks noņemta tikai no saraksta. Lai to dzēstu pilnībā, lūdzu nodzēs to no datņu sistēmas. main.directoryList.remove.confirmation.content = Glabātuve tiks noņemta tikai no saraksta. Lai to dzēstu pilnībā, lūdzu nodzēs to no datņu sistēmas.
upgrade.version3to4.msg = Šī glabātuve ir jāmigrē uz jaunāku formāta versiju. Sifrētie mapju nosaukumi tiks atjaunināti. Pirms palaišanas lūdzu pārliecinies, ka ir pabeigusies sinhronizācija. upgrade.version3to4.msg = Šī glabātuve ir jāmigrē uz jaunāku formāta versiju. Sifrētie mapju nosaukumi tiks atjaunināti. Pirms palaišanas lūdzu pārliecinies, ka ir pabeigusies sinhronizācija.
upgrade.version3to4.err.io = Migrācija neizdevās dēļ I/O izņēmuma. Sīkākai informācijai skati žurnālu. upgrade.version3to4.err.io = Migrācija neizdevās dēļ I/O izņēmuma. Sīkākai informācijai skati žurnālu.
settings.prefGvfsScheme.label = WebDAV shēma
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Jā, esmu pārliecinājies, ka sinhronizācija ir pabeigta. upgrade.confirmation.label = Jā, esmu pārliecinājies, ka sinhronizācija ir pabeigta.
initialize.messageLabel.notEmpty = Glabātuve nav tukša
unlock.label.savePassword = Saglabāt paroli unlock.label.savePassword = Saglabāt paroli
unlock.errorMessage.unauthenticVersionMac = Nevar autentificēt versijas MAC unlock.errorMessage.unauthenticVersionMac = Nevar autentificēt versijas MAC
unlocked.label.mountFailed = Diska pievienošana neizdevās unlocked.label.mountFailed = Diska pievienošana neizdevās
@@ -91,7 +87,6 @@ upgrade.version3to4.title = Glabātuves versijas 3 uz 4 atjauninājums
upgrade.version4to5.title = Glabātuves versijas 4 uz 5 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.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ā. upgrade.version4to5.err.io = Migrācijas kļīda dēļ I/O izņēmuma. Sīkāku informāciju skaties žurnālā.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -102,4 +97,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
+26 -16
View File
@@ -56,8 +56,6 @@ unlocked.ioGraph.yAxis.label = Doorvoer (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Versie %s settings.version.label = Versie %s
settings.checkForUpdates.label = Controleer op updates settings.checkForUpdates.label = Controleer op updates
settings.port.label = WebDAV Poort *
settings.port.prompt = 0 \= Kies automatisch
settings.requiresRestartLabel = * Cryptomator dient te worden herstart settings.requiresRestartLabel = * Cryptomator dient te worden herstart
# tray icon # tray icon
tray.menu.open = Open tray.menu.open = Open
@@ -76,10 +74,8 @@ main.directoryList.remove.confirmation.header = Weet je zeker dat je deze kluis
main.directoryList.remove.confirmation.content = De kluis zal alleen van de lijst worden verwijdert. Verwijder de bestanden van het bestandssysteem voor permanente verwijdering. main.directoryList.remove.confirmation.content = De kluis zal alleen van de lijst worden verwijdert. Verwijder de bestanden van het bestandssysteem voor permanente verwijdering.
upgrade.version3to4.msg = Deze kluis dient gemigreerd te worden naar een nieuwer type. \nVersleutelde mapnamen zullen worden geüpdatet. \nZorg ervoor dat de synchronisatie voltooid is alvorens door te gaan. upgrade.version3to4.msg = Deze kluis dient gemigreerd te worden naar een nieuwer type. \nVersleutelde mapnamen zullen worden geüpdatet. \nZorg ervoor dat de synchronisatie voltooid is alvorens door te gaan.
upgrade.version3to4.err.io = I/O Exception\: migratie mislukt. Zie logbestand voor details. upgrade.version3to4.err.io = I/O Exception\: migratie mislukt. Zie logbestand voor details.
settings.prefGvfsScheme.label = WebDAV schema
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Ja, ik heb geverifieerd dat de synchronisatie voltooid is upgrade.confirmation.label = Ja, ik heb geverifieerd dat de synchronisatie voltooid is
initialize.messageLabel.notEmpty = Kluis niet leeg
unlock.label.savePassword = Wachtwoord Opslaan unlock.label.savePassword = Wachtwoord Opslaan
unlock.errorMessage.unauthenticVersionMac = MAC authenticatie mislukt unlock.errorMessage.unauthenticVersionMac = MAC authenticatie mislukt
unlocked.label.mountFailed = Verbinden van schijf mislukt unlocked.label.mountFailed = Verbinden van schijf mislukt
@@ -92,15 +88,29 @@ upgrade.version3to4.title = Kluis Versie 3 naar 4 Upgrade
upgrade.version4to5.title = Kluis Versie 4 naar 5 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.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. upgrade.version4to5.err.io = Migratie mislukt door een I/O Exception. Bekijk log file voor details.
settings.port.apply = Apply unlock.label.mountAfterUnlock = Schijf mounten
unlock.label.mountAfterUnlock = Mount Drive unlock.label.revealAfterMount = Maak schijf zichtbaar
unlock.label.revealAfterMount = Reveal Drive unlocked.lock.force.confirmation.title = Blokkeren van %1$s is mislukt
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.header = Wil je vergrendelen forceren?
unlocked.lock.force.confirmation.header = Do you want to force locking? 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.
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-ontgrendelen bij starten (Expirimenteel)
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental) unlock.errorMessage.unlockFailed = Ontgrendelen mislukt. Zie log file voor details.
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlocked.moreOptions.mount = Schijf mounten
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.unmount = Schijf uitwerpen
unlocked.moreOptions.unmount = Eject Drive upgrade.version5toX.title = Upgraden versie kluis
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.msg = Deze kluis moet gemigreerd worden naar een nieuwer formaat. Zorg dat de synchronisatie klaar is alvorens verder te gaan.
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 = 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 *
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.
+53 -43
View File
@@ -1,38 +1,38 @@
app.name = Cryptomator app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = Kliknij tutaj, aby dodać kryptę main.emptyListInstructions = Kliknij tutaj, aby utworzyć nowy portfel
main.directoryList.contextMenu.remove = Usuń z listy main.directoryList.contextMenu.remove = Usuń z listy
main.directoryList.contextMenu.changePassword = Zmień hasło main.directoryList.contextMenu.changePassword = Zmień hasło
main.addDirectory.contextMenu.new = Stwórz nową kryptę main.addDirectory.contextMenu.new = Stwórz nowy portfel
main.addDirectory.contextMenu.open = Otwórz istniejącą kryptę main.addDirectory.contextMenu.open = Otwórz istniejący portfel
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Sprawdzanie aktualizacji... welcome.checkForUpdates.label.currentlyChecking = Sprawdzanie aktualizacji...
welcome.newVersionMessage = Nowa wersja %1$s jest dostępna do pobrania.\nObecnie używana wersja to %2$s. welcome.newVersionMessage = Nowa wersja %1$s jest dostępna do pobrania.\nObecnie używana wersja to %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password = Hasło initialize.label.password = Hasło
initialize.label.retypePassword = Powtórz hasło initialize.label.retypePassword = Powtórz hasło
initialize.button.ok = Stwórz kryptę initialize.button.ok = Stwórz portfel
initialize.messageLabel.alreadyInitialized = Krypta aktualnie załadowana initialize.messageLabel.alreadyInitialized = Portfel został utworzony
initialize.messageLabel.initializationFailed = Nie można załadować krypty. Szczegóły błędu znajdziesz w logach. initialize.messageLabel.initializationFailed = Nie można utworzyć portfela. Szczegóły błędu znajdziesz w logach.
# notfound.fxml # notfound.fxml
notfound.label = Nie znaleziono krypty. Może została przeniesiona? notfound.label = Nie znaleziono portfela. Może został przeniesiony?
# upgrade.fxml # upgrade.fxml
upgrade.button = Zaktualizuj kryptę upgrade.button = Zaktualizuj portfel
upgrade.version3dropBundleExtension.msg = Krypta musi zostać zaktualizowana do nowszego formatu.\n"%1$s" zostanie zmienione na "%2$s".\nZanim kontynuujesz, upewnij się, że synchronizacja plików została ukończona. 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 aktualizacji krypty.\n"%s" już istnieje. upgrade.version3dropBundleExtension.err.alreadyExists = Błąd automatycznej migracji portfela.\n"%s" już istnieje.
# unlock.fxml # unlock.fxml
unlock.label.password = Hasło unlock.label.password = Hasło do wolumenu
unlock.label.mountName = Nazwa dysku unlock.label.mountName = Nazwa wolumenu
unlock.label.winDriveLetter = Litera dysku unlock.label.winDriveLetter = Litera dysku
unlock.label.downloadsPageLink = Wszystkie wersje Cryptomatora unlock.label.downloadsPageLink = Wszystkie wersje Cryptomatora
unlock.label.advancedHeading = Opcje zaawansowane unlock.label.advancedHeading = Opcje zaawansowane
unlock.button.unlock = Odblokuj kryptę unlock.button.unlock = Odblokuj portfel
unlock.button.advancedOptions.show = Więcej opcji unlock.button.advancedOptions.show = Więcej opcji
unlock.button.advancedOptions.hide = Mniej opcji unlock.button.advancedOptions.hide = Mniej opcji
unlock.choicebox.winDriveLetter.auto = Przydziel automatycznie unlock.choicebox.winDriveLetter.auto = Przydziel automatycznie
unlock.errorMessage.wrongPassword = Nieprawidłowe hasło unlock.errorMessage.wrongPassword = Nieprawidłowe hasło
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Niewspierana wersja krypty. Krypta została utworzona przez starszą wersję Cryptomatora. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Niewspierana wersja portfela. Ten portfel został utworzony przez starszą wersję Cryptomatora.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Niewspierana wersja krypty. Krypta została utworzona przez nowszą wersję Cryptomatora. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Niewspierana wersja portfela. Ten portfel został utworzony przez nowszą wersję Cryptomatora.
unlock.messageLabel.startServerFailed = Nie udało się uruchomić serwera WebDAV. unlock.messageLabel.startServerFailed = Nie udało się uruchomić serwera WebDAV.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Stare hasło changePassword.label.oldPassword = Stare hasło
@@ -43,24 +43,22 @@ changePassword.button.change = Zmień hasło
changePassword.errorMessage.wrongPassword = Nieprawidłowe hasło changePassword.errorMessage.wrongPassword = Nieprawidłowe hasło
changePassword.errorMessage.decryptionFailed = Błąd odszyfrowywania changePassword.errorMessage.decryptionFailed = Błąd odszyfrowywania
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Zablokuj kryptę unlocked.button.lock = Zabezpiecz portfel
unlocked.moreOptions.reveal = Pokaż dysk unlocked.moreOptions.reveal = Odkryj wolumen
unlocked.moreOptions.copyUrl = Skopiuj URL WebDAV unlocked.moreOptions.copyUrl = Skopiuj URL WebDAV
unlocked.label.revealFailed = Błąd pokazywania dysku unlocked.label.revealFailed = Błąd odkrywania wolumenu
unlocked.label.unmountFailed = Błąd odłączania dysku unlocked.label.unmountFailed = Błąd odłączania wolumenu
unlocked.label.statsEncrypted = szyfrowanie unlocked.label.statsEncrypted = szyfrowane
unlocked.label.statsDecrypted = odszyfrowywanie unlocked.label.statsDecrypted = nieszyfrowywane
unlocked.ioGraph.yAxis.label = Wydajność (MiB/s) unlocked.ioGraph.yAxis.label = Wydajność (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Wersja %s settings.version.label = Wersja %s
settings.checkForUpdates.label = Sprawdzaj aktualizacje settings.checkForUpdates.label = Sprawdź aktualizacje
settings.port.label = Port WebDAV
settings.port.prompt = 0 \= Automatycznie
settings.requiresRestartLabel = * Cryptomator wymaga restartu settings.requiresRestartLabel = * Cryptomator wymaga restartu
# tray icon # tray icon
tray.menu.open = Otwórz tray.menu.open = Otwórz
tray.menu.quit = Wyjdź tray.menu.quit = Wyjdź
tray.infoMsg.title = Nadal działa 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 = 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.msg.osx = Cryptomator wciąż jest uruchomiony. Aby go wyłączyć, użyj ikony z paska menu.
initialize.messageLabel.passwordStrength.0 = Bardzo słabe initialize.messageLabel.passwordStrength.0 = Bardzo słabe
@@ -68,37 +66,49 @@ initialize.messageLabel.passwordStrength.1 = Słabe
initialize.messageLabel.passwordStrength.2 = W porządku initialize.messageLabel.passwordStrength.2 = W porządku
initialize.messageLabel.passwordStrength.3 = Mocne initialize.messageLabel.passwordStrength.3 = Mocne
initialize.messageLabel.passwordStrength.4 = Bardzo mocne initialize.messageLabel.passwordStrength.4 = Bardzo mocne
initialize.label.doNotForget = WAŻNE\: Jeśli zapomnisz hasło, nie ma żadnej możliwości odzyskania danych. 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ń kryptę main.directoryList.remove.confirmation.title = Usuń portfel
main.directoryList.remove.confirmation.header = Czy na pewno chcesz usunąć kryptę? main.directoryList.remove.confirmation.header = Czy na pewno chcesz usunąć ten portfel?
main.directoryList.remove.confirmation.content = Krypta zostanie usunięta tylko z listy. Jeśli chcesz trwale usunąć, usuń pliki krypty z dysku. 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 = Krypta wymaga aktualizacji do nowszej wersji. \nZaszyfrowane nazwy folderów zostaną zmienione.\nZanim kontynuujesz, upewnij się, że synchronizacja plików została ukończona. 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. upgrade.version3to4.err.io = Błąd aktualizacji z powodu problemów z odczytem/zapisem. Szczegóły błędu znajdziesz w logach.
settings.prefGvfsScheme.label = Schemat WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Tak, synchronizacja plików na pewno została ukończona. upgrade.confirmation.label = Tak, synchronizacja plików na pewno została ukończona.
initialize.messageLabel.notEmpty = Krypta nie jest pusta
unlock.label.savePassword = Zapisz hasło unlock.label.savePassword = Zapisz hasło
unlock.errorMessage.unauthenticVersionMac = Nie udało się uwierzytelnić wersji MAC unlock.errorMessage.unauthenticVersionMac = Nie udało się uwierzytelnić wersji MAC
unlocked.label.mountFailed = Błąd podłączanie dysku. unlocked.label.mountFailed = Błąd podłączanie dysku.
unlock.savePassword.delete.confirmation.title = Usuń zapisane hasło unlock.savePassword.delete.confirmation.title = Usuń zapisane hasło
unlock.savePassword.delete.confirmation.header = Czy na pewno chcesz usunąć zapisane hasło do tej krypty? 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 tej krypty zostanie natychmiast usunięte z systemowego pęku kluczy. Jeśli chcesz zapisać hasło ponownie, odblokuj kryptę z zaznaczoną opcją "Zapisz hasło". 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 * settings.debugMode.label = Tryb debugowania *
upgrade.version3dropBundleExtension.title = Aktualizacja krypty do wersji 3 (Drop Bundle Extension) upgrade.version3dropBundleExtension.title = Aktualizacja portfela do wersji 3 (Drop Bundle Extension)
upgrade.version3to4.title = Aktualizacja krypty z wersji 3 do 4 upgrade.version3to4.title = Aktualizacja portfela z wersji 3 do 4
upgrade.version4to5.title = Aktualizacja krypty z wersji 4 do 5 upgrade.version4to5.title = Aktualizacja portfela z wersji 4 do 5
upgrade.version4to5.msg = Krypta wymaga aktualizacji do nowszej wersji. \nZaszyfrowane nazwy folderów zostaną zmienione.\nZanim kontynuujesz, upewnij się, że synchronizacja plików została ukończona.\n\nUwaga\: W trakcje aktualizacji zmieni się data modyfikacji wszystkich plików. 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. upgrade.version4to5.err.io = Błąd aktualizacji z powodu problemów z odczytem/zapisem. Szczegóły błędu znajdziesz w logach.
settings.port.apply = Akceptuj unlock.label.mountAfterUnlock = Zamontuj dysk
unlock.label.mountAfterUnlock = Podłącz dysk
unlock.label.revealAfterMount = Pokaż dysk unlock.label.revealAfterMount = Pokaż dysk
unlocked.lock.force.confirmation.title = Zablokowywanie %1$s nie powiodło się 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.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 krypty 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. 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.label.unlockAfterStartup = Auto-odblokowywanie podczas uruchamiania (Eksperymentalne)
unlock.errorMessage.unlockFailed = Błąd odblokowywania. Szczegóły błędu znajdziesz w logach. unlock.errorMessage.unlockFailed = Błąd odblokowywania. Szczegóły błędu znajdziesz w logach.
unlocked.moreOptions.mount = Podłącz dysk unlocked.moreOptions.mount = Podłącz dysk
unlocked.moreOptions.unmount = Odłącz dysk unlocked.moreOptions.unmount = Odłącz dysk
upgrade.version5toX.title = Aktualizacja wersji krypty upgrade.version5toX.title = Aktualizacja wersji portfela
upgrade.version5toX.msg = Krypta wymaga aktualizacji do nowszej wersji.\nZanim kontynuujesz, upewnij się, że synchronizacja plików została ukończona. upgrade.version5toX.msg = Ten portfel wymaga aktualizacji do nowszej wersji.\nZanim rozpoczniesz migracje upewnij się, że synchronizacja plików została ukoń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 *
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.
+40 -30
View File
@@ -18,7 +18,7 @@ initialize.messageLabel.initializationFailed = Não pôde inicializar o cofre. V
notfound.label = O cofre não pode ser encontrado. Pode ter sido movido? notfound.label = O cofre não pode ser encontrado. Pode ter sido movido?
# upgrade.fxml # upgrade.fxml
upgrade.button = Atualizar cofre upgrade.button = Atualizar cofre
upgrade.version3dropBundleExtension.msg = Esse cofre tem que ser migrado paraa um novo formato. "%1$s" será renomeada para "%2$s". Por favor assegure-se de que a sincronização foi finalizada antes de proceder com a migração. upgrade.version3dropBundleExtension.msg = Esse cofre necessita ser migrado para um novo formato. "%1$s" será renomeado para "%2$s". Por favor assegure que a sincronização esta finalizada antes de proceder com a migração.
upgrade.version3dropBundleExtension.err.alreadyExists = A migração automática falhou. "%s" já existe. upgrade.version3dropBundleExtension.err.alreadyExists = A migração automática falhou. "%s" já existe.
# unlock.fxml # unlock.fxml
unlock.label.password = Senha unlock.label.password = Senha
@@ -30,32 +30,30 @@ unlock.button.unlock = Abrir cofre
unlock.button.advancedOptions.show = Mais opções unlock.button.advancedOptions.show = Mais opções
unlock.button.advancedOptions.hide = Menos opções unlock.button.advancedOptions.hide = Menos opções
unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente
unlock.errorMessage.wrongPassword = Senha errada unlock.errorMessage.wrongPassword = Senha incorreta
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não suportado. Esse cofre foi criado por uma versão antiga do Cryptomator. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não suportado. Esse cofre foi criado por uma versão mais antiga do Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse cofre foi criado por uma versão mais nova do Cryptomator. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse cofre foi criado por uma versão mais nova do Cryptomator.
unlock.messageLabel.startServerFailed = Falha ao iniciar servidor WebDAV. unlock.messageLabel.startServerFailed = Falha ao iniciar servidor WebDAV.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Senha atual changePassword.label.oldPassword = Senha antiga
changePassword.label.newPassword = Nova senha changePassword.label.newPassword = Senha Nova
changePassword.label.retypePassword = Re-digitar senha changePassword.label.retypePassword = Redigitar senha
changePassword.label.downloadsPageLink = Todas as versões do Cryptomator changePassword.label.downloadsPageLink = Todas as versões do Cryptomator
changePassword.button.change = Alterar senha changePassword.button.change = Alterar senha
changePassword.errorMessage.wrongPassword = Senha incorreta changePassword.errorMessage.wrongPassword = Senha incorreta
changePassword.errorMessage.decryptionFailed = Falha ao desencriptar changePassword.errorMessage.decryptionFailed = Falha ao descriptografar
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Fechar cofre unlocked.button.lock = Fechar cofre
unlocked.moreOptions.reveal = Mostrar drive unlocked.moreOptions.reveal = Mostrar drive
unlocked.moreOptions.copyUrl = Copiar URL WebDAV unlocked.moreOptions.copyUrl = Copiar URL WebDAV
unlocked.label.revealFailed = Falha ao mostrar drive unlocked.label.revealFailed = Falha de comando
unlocked.label.unmountFailed = Falha ao ejetar drive unlocked.label.unmountFailed = Falha ao ejetar drive
unlocked.label.statsEncrypted = Encriptado unlocked.label.statsEncrypted = Criptografado
unlocked.label.statsDecrypted = Desencriptado unlocked.label.statsDecrypted = Descriptografado
unlocked.ioGraph.yAxis.label = Taxa de transferência (MiB/s) unlocked.ioGraph.yAxis.label = Taxa de transferência (Mbps)
# settings.fxml # settings.fxml
settings.version.label = Versão %s settings.version.label = Versão %s
settings.checkForUpdates.label = Verificar por atualizações settings.checkForUpdates.label = Verificar por atualizações
settings.port.label = Porta WebDAV *
settings.port.prompt = 0 \= Escolher automaticamente
settings.requiresRestartLabel = * Cryptomator precisa ser reiniciado settings.requiresRestartLabel = * Cryptomator precisa ser reiniciado
# tray icon # tray icon
tray.menu.open = Abrir tray.menu.open = Abrir
@@ -72,33 +70,45 @@ initialize.label.doNotForget = IMPORTANTE\: se você esquecer a sua senha, não
main.directoryList.remove.confirmation.title = Remover cofre main.directoryList.remove.confirmation.title = Remover cofre
main.directoryList.remove.confirmation.header = Você realmente quer remover esse cofre? main.directoryList.remove.confirmation.header = Você realmente quer remover esse cofre?
main.directoryList.remove.confirmation.content = O cofre somente será removido da lista. Para apagá-lo permanentemente, por favor apagar os arquivos do seu sistema de arquivos. main.directoryList.remove.confirmation.content = O cofre somente será removido da lista. Para apagá-lo permanentemente, por favor apagar os arquivos do seu sistema de arquivos.
upgrade.version3to4.msg = Esse cofre tem que ser migrado a um novo formato. Os nomes das pastas encriptadas serão atualizados. Por favor, assegure-se de que a sincronização do cofre foi finalizada antes de proceder com a sua migração. upgrade.version3to4.msg = Esse cofre tem que ser migrado a um novo formato. Os nomes das pastas criptografadas serão atualizados. Por favor, assegure que a sincronização do cofre foi finalizada antes de iniciar procedimento de migração.
upgrade.version3to4.err.io = Falha na migração devido a um erro de E/S. Veja o arquivo de log para mais detalhes. upgrade.version3to4.err.io = Falha na migração devido a um erro de E/S. Veja o arquivo de log para mais detalhes.
settings.prefGvfsScheme.label = Esquema WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Sim, tenho certeza de que a sincronização foi concluída upgrade.confirmation.label = Sim, tenho certeza de que a sincronização foi concluída
initialize.messageLabel.notEmpty = Cofre não vazio
unlock.label.savePassword = Armazenar senha unlock.label.savePassword = Armazenar senha
unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a versão do MAC. unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a versão do MAC.
unlocked.label.mountFailed = Falha ao conectar o drive unlocked.label.mountFailed = Falha ao conectar o drive
unlock.savePassword.delete.confirmation.title = Apagar a senha armazenada unlock.savePassword.delete.confirmation.title = Apagar a senha armazenada
unlock.savePassword.delete.confirmation.header = Você realmente quer apagar a senha armazenada deste cofre? unlock.savePassword.delete.confirmation.header = Você realmente quer apagar a senha armazenada deste cofre?
unlock.savePassword.delete.confirmation.content = A senha deste cofre que se encontra armazenada será imediatamente apagada do gestor de senhas do seu sistema. Se você quiser armazenar a sua senha novamente, você terá que abrir o seu cofre com a opção "Armazenar Senha" habilitada. unlock.savePassword.delete.confirmation.content = A senha deste cofre que se encontra armazenada será imediatamente apagada de seu sistema. Se você quiser novamente armazenar sua senha, abra o seu cofre com a opção "Armazenar Senha" habilitada.
settings.debugMode.label = Modo de Debug * settings.debugMode.label = Modo de Debug *
upgrade.version3dropBundleExtension.title = Atualização para a versão 3 do cofre (Drop Bundle Extension) upgrade.version3dropBundleExtension.title = Atualização para a versão 3 do cofre (Drop Bundle Extension)
upgrade.version3to4.title = Atualização do cofre da versão 3 para 4 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.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 encriptados serão atualizados.\nPor favor, assegure-se de que a sincronização do cofre foi finalizada antes de proceder com a sua migração.\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.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. upgrade.version4to5.err.io = A migração falhou devido a uma exceção de I/O. Ver arquivo de log para mais detalhes.
settings.port.apply = Apply unlock.label.mountAfterUnlock = Montar o Drive
unlock.label.mountAfterUnlock = Mount Drive unlock.label.revealAfterMount = Mostrar o Drive
unlock.label.revealAfterMount = Reveal Drive unlocked.lock.force.confirmation.title = O bloqueio do %1$s falhou
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.header = Você quer forçar o bloqueio?
unlocked.lock.force.confirmation.header = Do you want to force locking? 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.
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-desbloqueio ao Iniciar (Experimental)
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental) unlock.errorMessage.unlockFailed = O desbloqueio falhou. Veja o log para mais detalhes.
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlocked.moreOptions.mount = Montar o Drive
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.unmount = Ejetar o Drive
unlocked.moreOptions.unmount = Eject Drive upgrade.version5toX.title = Atualização da Versão do Cofre
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.msg = Este cofre precisa ser migrado a um novo formato. Por favor assegure que a sincronização foi finalizada antes de proceder.
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 = Falha ao criar o cofre
main.createVault.nonEmptyDir.header = O diretório escolhido não se encontra vazio
main.createVault.nonEmptyDir.content = O diretório selecionado contém arquivos (possivelmente ocultos). Um cofre só pode ser criado num diretório vazio.
unlock.label.mountPath = Local da montagem
unlock.label.mountPathButton = Aplicar
settings.webdav.port.label = WebDAV Porta
settings.webdav.port.prompt = 0 \= Escolha Automática
settings.webdav.port.apply = Aplicar
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.
@@ -6,7 +6,7 @@ main.directoryList.contextMenu.changePassword = Mudar senha
main.addDirectory.contextMenu.new = Criar novo cofre main.addDirectory.contextMenu.new = Criar novo cofre
main.addDirectory.contextMenu.open = Abrir um Cofre existente main.addDirectory.contextMenu.open = Abrir um Cofre existente
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Checando atualizações welcome.checkForUpdates.label.currentlyChecking = Verificando Atualizações...
welcome.newVersionMessage = A versão %1$s pode ser baixada.\nVocê está na %2$s. welcome.newVersionMessage = A versão %1$s pode ser baixada.\nVocê está na %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password = Senha initialize.label.password = Senha
@@ -18,7 +18,7 @@ initialize.messageLabel.initializationFailed = Cofre não inicializado. Veja os
notfound.label = Cofre não encontrado. Ele foi movido? notfound.label = Cofre não encontrado. Ele foi movido?
# upgrade.fxml # upgrade.fxml
upgrade.button = Atualizar Cofre 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 tenha terminado antes de começar o procedimento. 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.err.alreadyExists = A Migração automática falhou.\n"%s" já existe. upgrade.version3dropBundleExtension.err.alreadyExists = A Migração automática falhou.\n"%s" já existe.
# unlock.fxml # unlock.fxml
unlock.label.password = Senha unlock.label.password = Senha
@@ -35,34 +35,32 @@ unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não supor
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 nova do Cryptomator.
unlock.messageLabel.startServerFailed = A inicialização do servidor WebDAV falhou. unlock.messageLabel.startServerFailed = A inicialização do servidor WebDAV falhou.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Sua senha antiga changePassword.label.oldPassword = Senha antiga
changePassword.label.newPassword = Nova senha changePassword.label.newPassword = Nova senha
changePassword.label.retypePassword = Repita a senha changePassword.label.retypePassword = Repita a senha
changePassword.label.downloadsPageLink = Todas as versões do Cyptomator changePassword.label.downloadsPageLink = Todas as versões do Cyptomator
changePassword.button.change = Alterar senha changePassword.button.change = Alterar senha
changePassword.errorMessage.wrongPassword = Senha errada changePassword.errorMessage.wrongPassword = Senha errada
changePassword.errorMessage.decryptionFailed = Falha na Desencriptação changePassword.errorMessage.decryptionFailed = Descriptografia falhou
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Travar Cofre unlocked.button.lock = Travar Cofre
unlocked.moreOptions.reveal = Mostrar volume unlocked.moreOptions.reveal = Mostrar volume
unlocked.moreOptions.copyUrl = Copiar endereço do WebDAV unlocked.moreOptions.copyUrl = Copiar URL do arquivo de sistema
unlocked.label.revealFailed = Falha no comando unlocked.label.revealFailed = Falha no comando
unlocked.label.unmountFailed = A ejeção do volume falhou unlocked.label.unmountFailed = A ejeção do volume falhou
unlocked.label.statsEncrypted = Encriptado unlocked.label.statsEncrypted = criptografado
unlocked.label.statsDecrypted = Desencriptado unlocked.label.statsDecrypted = descriptografado
unlocked.ioGraph.yAxis.label = Transferência (MiB/s) unlocked.ioGraph.yAxis.label = Transferência (Mbps)
# settings.fxml # settings.fxml
settings.version.label = Versão %s settings.version.label = Versão %s
settings.checkForUpdates.label = Procurar por atualizações settings.checkForUpdates.label = Procurar por atualizações
settings.port.label = Porta de WebDAV
settings.port.prompt = 0 \= Escolhido automaticamente
settings.requiresRestartLabel = * O Cryptomator precisa ser reiniciado settings.requiresRestartLabel = * O Cryptomator precisa ser reiniciado
# tray icon # tray icon
tray.menu.open = Abrir tray.menu.open = Abrir
tray.menu.quit = Sair tray.menu.quit = Sair
tray.infoMsg.title = Ainda Rodando tray.infoMsg.title = Ainda em Execução
tray.infoMsg.msg = O Cryptomator ainda está ativo. Feche-o através do icone da bandeja. tray.infoMsg.msg = O Cryptomator ainda está ativo. Feche-o através do icone da bandeja.
tray.infoMsg.msg.osx = O Cryptomator ainda está ativo. Feche-o através do menu da barra de icones. tray.infoMsg.msg.osx = O Cryptomator ainda está ativo. Feche-o através do menu da barra de ícones.
initialize.messageLabel.passwordStrength.0 = Muito fraca initialize.messageLabel.passwordStrength.0 = Muito fraca
initialize.messageLabel.passwordStrength.1 = Fraca initialize.messageLabel.passwordStrength.1 = Fraca
initialize.messageLabel.passwordStrength.2 = Razoável initialize.messageLabel.passwordStrength.2 = Razoável
@@ -71,15 +69,13 @@ 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\: Se você perder a sua senha, não haverá maneira alguma de recuperar seus dados.
main.directoryList.remove.confirmation.title = Remover Cofre main.directoryList.remove.confirmation.title = Remover Cofre
main.directoryList.remove.confirmation.header = Você realmente quer remover esse Cofre? main.directoryList.remove.confirmation.header = Você realmente quer remover esse Cofre?
main.directoryList.remove.confirmation.content = O Cofre será somente removido da listagem. Para apagá-lo permanentemente, por favor apague os arquivos. 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.
upgrade.version3to4.msg = Esse Cofre precisa ser migrado para o novo formato.\nA encriptação das pastas foi atualizada.\nPor favor tenha certeza que a sincronização está finalizada ante de começar. 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.version3to4.err.io = A migração falhou devido a uma falha de entrada e saída. Veja o arquivo de log para mais detalhes.
settings.prefGvfsScheme.label = Esquema WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Sim, tenho certeza que a sincronização terminada. upgrade.confirmation.label = Sim, tenho certeza que a sincronização terminou
initialize.messageLabel.notEmpty = Cofre não vazio
unlock.label.savePassword = Salvar senha unlock.label.savePassword = Salvar senha
unlock.errorMessage.unauthenticVersionMac = Não pude autenticar a versão da MAC unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a versão MAC
unlocked.label.mountFailed = Conexão do volume falhou unlocked.label.mountFailed = Conexão do volume falhou
unlock.savePassword.delete.confirmation.title = Apaga senha salva 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.header = Você realmente quer apagar a senha salva para esse Cofre?
@@ -88,17 +84,31 @@ settings.debugMode.label = Modo Debug *
upgrade.version3dropBundleExtension.title = Atualização do Cofre v3 (Drop Bundle Extension) upgrade.version3dropBundleExtension.title = Atualização do Cofre v3 (Drop Bundle Extension)
upgrade.version3to4.title = Atualização do Cofre v3 para v4 upgrade.version3to4.title = Atualização do Cofre v3 para v4
upgrade.version4to5.title = Atualização do Cofre v4 para v5 upgrade.version4to5.title = Atualização do Cofre v4 para v5
upgrade.version4to5.msg = Este Cofre precisa ser migrado para o novo formato.\nOs arquivos encriptados serão atualizados.\nPor favor tenha certeza que a sincronização esteja terminada antes de começar.\n\nNote\: A data de modificação de todos os arquivos serão alterados para a data/hora atual. 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. 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.
settings.port.apply = Aplicar
unlock.label.mountAfterUnlock = Montar Volume unlock.label.mountAfterUnlock = Montar Volume
unlock.label.revealAfterMount = Abrir Volume unlock.label.revealAfterMount = Abrir Volume
unlocked.lock.force.confirmation.title = O Travamento para %1$s falhou 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.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 arquivo podem não funcionar corretamente e os dados não gravados podem serem perdidos. 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 = Destravar ao iniciar unlock.label.unlockAfterStartup = Desbloquear ao iniciar (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlock.errorMessage.unlockFailed = Desbloqueio falhou. Consulte o arquivo de log para obter mais detalhes.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Montar Volume
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Ejetar Volume
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.title = Atualização da Versão do Cofre
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. 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.
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.
unlock.label.mountPath = Caminho da Montagem
unlock.label.mountPathButton = Aplicar
settings.webdav.port.label = WebDAV Porta
settings.webdav.port.prompt = 0 \= Escolher automaticamente
settings.webdav.port.apply = Aplicar
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.
+49 -34
View File
@@ -8,27 +8,28 @@ main.addDirectory.contextMenu.open = Открыть имеющееся хран
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Проверка обновлений... welcome.checkForUpdates.label.currentlyChecking = Проверка обновлений...
# Does the first %s mean the new version number, and the second %s - the current version user has? # Does the first %s mean the new version number, and the second %s - the current version user has?
welcome.newVersionMessage = Доступна версия %1$s.\nУ вас версия %2$s. welcome.newVersionMessage = Версия %1$s доступна для загрузки.\nТекущая версия %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password = Пароль initialize.label.password = Пароль
initialize.label.retypePassword = Введите пароль ещё раз initialize.label.retypePassword = Повторите ввод пароля
initialize.button.ok = Создать хранилище initialize.button.ok = Создать хранилище
initialize.messageLabel.alreadyInitialized = Хранилище уже инициализировано initialize.messageLabel.alreadyInitialized = Хранилище уже инициализировано
initialize.messageLabel.initializationFailed = Невозможно инициализировать хранилище. См. подробности в файле-отчёте. initialize.messageLabel.initializationFailed = Невозможно инициализировать хранилище. См. подробности в файле журнала.
# notfound.fxml # notfound.fxml
notfound.label = Хранилище не найдено. Оно было перемещено? notfound.label = Хранилище не найдено. Оно было перемещено?
# upgrade.fxml # upgrade.fxml
upgrade.button = Обновить хранилище upgrade.button = Обновить хранилище
upgrade.version3dropBundleExtension.msg = Это хранилище нужно преобразовать в новый формат.\n"%1$s" будет переименовано в "%2$s".\nПрежде чем продолжить, выполните синхронизацию. upgrade.version3dropBundleExtension.msg = Это хранилище необходимо преобразовать в новый формат.\n"%1$s" будет переименовано в "%2$s".\nПрежде чем продолжить, убедитесь, что синхронизация завершена.
upgrade.version3dropBundleExtension.err.alreadyExists = Автоматическое преобразование не выполнено.\n"%s" уже существует. upgrade.version3dropBundleExtension.err.alreadyExists = Автоматическое преобразование не выполнено.\n"%s" уже существует.
# unlock.fxml # unlock.fxml
unlock.label.password = Пароль unlock.label.password = Пароль
unlock.label.mountName = Имя диска unlock.label.mountName = Имя диска
unlock.label.winDriveLetter = Буква диска unlock.label.winDriveLetter = Буква диска
unlock.label.downloadsPageLink = Все версии Cryptomator unlock.label.downloadsPageLink = Все версии Cryptomator
# Дополнительные параметры
unlock.label.advancedHeading = Дополнительно unlock.label.advancedHeading = Дополнительно
unlock.button.unlock = Разблокировать хранилище unlock.button.unlock = Разблокировать хранилище
unlock.button.advancedOptions.show = Ещё настройки unlock.button.advancedOptions.show = Дополнительные опции
unlock.button.advancedOptions.hide = Убрать настройки unlock.button.advancedOptions.hide = Убрать настройки
unlock.choicebox.winDriveLetter.auto = Автоназначение unlock.choicebox.winDriveLetter.auto = Автоназначение
unlock.errorMessage.wrongPassword = Неверный пароль unlock.errorMessage.wrongPassword = Неверный пароль
@@ -38,7 +39,7 @@ unlock.messageLabel.startServerFailed = Ошибка запуска сервер
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Старый пароль changePassword.label.oldPassword = Старый пароль
changePassword.label.newPassword = Новый пароль changePassword.label.newPassword = Новый пароль
changePassword.label.retypePassword = Введите пароль ещё раз changePassword.label.retypePassword = Повторите ввод пароля
changePassword.label.downloadsPageLink = Все версии Cryptomator changePassword.label.downloadsPageLink = Все версии Cryptomator
changePassword.button.change = Сменить пароль changePassword.button.change = Сменить пароль
changePassword.errorMessage.wrongPassword = Неверный пароль changePassword.errorMessage.wrongPassword = Неверный пароль
@@ -46,9 +47,9 @@ changePassword.errorMessage.decryptionFailed = Ошибка дешифрован
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Заблокировать хранилище unlocked.button.lock = Заблокировать хранилище
# Does it mean "open" drive? # Does it mean "open" drive?
unlocked.moreOptions.reveal = Открыть накопитель unlocked.moreOptions.reveal = Открыть диск
unlocked.moreOptions.copyUrl = Скопировать URL-адрес WebDAV unlocked.moreOptions.copyUrl = Скопировать URL-адрес WebDAV
unlocked.label.revealFailed = Ошибка команды unlocked.label.revealFailed = Не удалось выполнить команду
unlocked.label.unmountFailed = Ошибка извлечения диска unlocked.label.unmountFailed = Ошибка извлечения диска
unlocked.label.statsEncrypted = зашифровано unlocked.label.statsEncrypted = зашифровано
unlocked.label.statsDecrypted = расшифровано unlocked.label.statsDecrypted = расшифровано
@@ -56,51 +57,65 @@ unlocked.ioGraph.yAxis.label = Пропускная способность (Ми
# settings.fxml # settings.fxml
settings.version.label = Версия %s settings.version.label = Версия %s
settings.checkForUpdates.label = Проверка обновлений settings.checkForUpdates.label = Проверка обновлений
settings.port.label = Порт WebDAV * settings.requiresRestartLabel = * Требуется перезапуск Cryptomator
settings.port.prompt = 0 \= автовыбор
settings.requiresRestartLabel = * Требуется перезагрузка Cryptomator
# tray icon # tray icon
tray.menu.open = Открыть tray.menu.open = Открыть
tray.menu.quit = Выход tray.menu.quit = Выход
tray.infoMsg.title = Всё ещё выполняется tray.infoMsg.title = Все еще выполняется
tray.infoMsg.msg = Cryptomator всё ещё работает. Выйдите c помощью значка в области уведомлений. # Не нужно использовать жаргонизмы, а также прибегать к вкусовой правке.
tray.infoMsg.msg.osx = Cryptomator всё ещё работает. Выйдите с помощью значка в строке меню. tray.infoMsg.msg = Cryptomator еще работает. Выйдите при помощи иконки в трее.
tray.infoMsg.msg.osx = Cryptomator еще работает. Выйдите при помощи значка в строке меню.
initialize.messageLabel.passwordStrength.0 = Очень слабый initialize.messageLabel.passwordStrength.0 = Очень слабый
initialize.messageLabel.passwordStrength.1 = Слабый initialize.messageLabel.passwordStrength.1 = Слабый
initialize.messageLabel.passwordStrength.2 = Приемлемый initialize.messageLabel.passwordStrength.2 = Приемлемый
initialize.messageLabel.passwordStrength.3 = Сильный initialize.messageLabel.passwordStrength.3 = Стойкий
initialize.messageLabel.passwordStrength.4 = Очень сильный initialize.messageLabel.passwordStrength.4 = Очень стойкий
initialize.label.doNotForget = ВАЖНО\: Если вы забудете свой пароль, то восстановить данные будет невозможно. initialize.label.doNotForget = ВАЖНО\: Если вы забудете свой пароль, то восстановить данные будет невозможно.
main.directoryList.remove.confirmation.title = Удаление хранилища main.directoryList.remove.confirmation.title = Удаление хранилища
main.directoryList.remove.confirmation.header = Вы действительно хотите удалить это хранилище? main.directoryList.remove.confirmation.header = Вы действительно хотите удалить это хранилище?
main.directoryList.remove.confirmation.content = Хранилище будет удалено только из списка. Чтобы стереть его окончательно, удалите файлы из файловой системы. main.directoryList.remove.confirmation.content = Хранилище будет удалено только из списка. Чтобы стереть его окончательно, удалите файлы из файловой системы.
upgrade.version3to4.msg = Это хранилище требуется преобразовать в новый формат. Зашифрованные имена папок будут обновлены. Прежде чем продолжить, выполните синхронизацию. upgrade.version3to4.msg = Это хранилище требуется преобразовать в новый формат.\nИмена зашифрованных папок будут обновлены.\nПеред продолжением убедитесь, что синхронизация завершена.
upgrade.version3to4.err.io = Преобразование не выполнено из-за ошибки ввода-вывода. См. подробности в файле-отчёте. upgrade.version3to4.err.io = Преобразование не выполнено из-за ошибки ввода-вывода. См. подробности в файле журнала.
settings.prefGvfsScheme.label = Схема WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Да, синхронизация точно завершена upgrade.confirmation.label = Да, синхронизация завершена
initialize.messageLabel.notEmpty = Хранилище не пусто
unlock.label.savePassword = Сохранить пароль unlock.label.savePassword = Сохранить пароль
unlock.errorMessage.unauthenticVersionMac = Не удалось идентифицировать версию MAC. unlock.errorMessage.unauthenticVersionMac = Не удалось проверить подлинность версии MAC.
unlocked.label.mountFailed = Ошибка подключения к диску unlocked.label.mountFailed = Ошибка подключения к диску
unlock.savePassword.delete.confirmation.title = Удалить сохранённый пароль # А как назвать эту правку? Пожалуйста, перестаньте портить перевод.
unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохранённый пароль для этого хранилища? unlock.savePassword.delete.confirmation.title = Удалить сохраненный пароль
unlock.savePassword.delete.confirmation.content = Сохранённый пароль от этого хранилища будет немедленно удалён из системной связки ключей. Если вы снова захотите сохранить пароль, вам придётся разблокировать хранилище с включённой опцией "Сохранить пароль". unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохраненный пароль этого хранилища?
unlock.savePassword.delete.confirmation.content = Сохраненный пароль этого хранилища будет немедленно удален из вашей системной связки ключей. Если вы снова захотите сохранить пароль, вам придется разблокировать хранилище с включенным параметром "Сохранить пароль".
settings.debugMode.label = Режим отладки * settings.debugMode.label = Режим отладки *
upgrade.version3dropBundleExtension.title = Обновление хранилища версии 3 (Drop Bundle Extension) upgrade.version3dropBundleExtension.title = Обновление хранилища версии 3 (расширение пакета)
upgrade.version3to4.title = Обновление хранилища с версии 3 на 4 upgrade.version3to4.title = Обновление хранилища с версии 3 на 4
upgrade.version4to5.title = Обновление хранилища с версии 4 на 5 upgrade.version4to5.title = Обновление хранилища с версии 4 на 5
upgrade.version4to5.msg = Это хранилище нужно преобразовать в более новый формат.\nЗашифрованные файлы будут обновлены.\nПрежде чем продолжить, убедитесь, что завершена синхронизация.\n\nПримечание\: даты изменения всех файлов будут изменены на текущие дату и время на момент обработки. upgrade.version4to5.msg = Это хранилище нужно преобразовать в более новый формат.\nЗашифрованные файлы будут обновлены.\nПрежде чем продолжить, убедитесь, что завершена синхронизация.\n\nПримечание\: дата и время изменения всех файлов будут изменены на текущие на момент обработки.
upgrade.version4to5.err.io = Преобразование не выполнено из-за исключения ввода-вывода. См. подробности в отчёте. upgrade.version4to5.err.io = Преобразование не выполнено из-за ошибки ввода-вывода. См. подробности в файле журнала.
settings.port.apply = Применить
unlock.label.mountAfterUnlock = Смонтировать диск unlock.label.mountAfterUnlock = Смонтировать диск
unlock.label.revealAfterMount = Открыть диск unlock.label.revealAfterMount = Открыть диск
unlocked.lock.force.confirmation.title = Ошибка блокировки %1$s unlocked.lock.force.confirmation.title = Ошибка блокировки %1$s
unlocked.lock.force.confirmation.header = Заблокировать принудительно? unlocked.lock.force.confirmation.header = Заблокировать принудительно?
unlocked.lock.force.confirmation.content = Возможно, к файлам в хранилище всё ещё обращаются другие программы, либо возникла иная проблема.\n\nТакие программы могут работать неправильно, а не записанные ими данные могут быть потеряны. unlocked.lock.force.confirmation.content = Это может быть вызвано тем, что другие программы по-прежнему обращаются к файлам в хранилище или из-за некоторых других проблем.\n\nТакие программы могут работать неправильно, а данные, которые еще не были записаны могут быть потеряны.
unlock.label.unlockAfterStartup = Автоблокировка при старте (экспериментально) # Авторазблокировка при старте (экспериментально)
unlock.errorMessage.unlockFailed = Ошибка разблокировки. См. подробности в отчёте. unlock.label.unlockAfterStartup = Авторазблокировка при запуске (экспериментально)
unlock.errorMessage.unlockFailed = Ошибка разблокировки. См. подробности в файле журнала.
unlocked.moreOptions.mount = Смонтировать диск unlocked.moreOptions.mount = Смонтировать диск
unlocked.moreOptions.unmount = Извлечь диск unlocked.moreOptions.unmount = Извлечь диск
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.title = Обновление версии хранилища
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. upgrade.version5toX.msg = Это хранилище нужно преобразовать в новый формат. Прежде чем продолжить, убедитесь, что завершена синхронизация.
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
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.
+16 -6
View File
@@ -57,8 +57,6 @@ unlocked.ioGraph.yAxis.label = Priepustnosť (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Verzia %s settings.version.label = Verzia %s
settings.checkForUpdates.label = Skontrolovať aktualizácie settings.checkForUpdates.label = Skontrolovať aktualizácie
settings.port.label = WebDAV Port *
settings.port.prompt = 0 \= Vybrať automaticky
settings.requiresRestartLabel = * Cryptomator vyžaduje reštart settings.requiresRestartLabel = * Cryptomator vyžaduje reštart
# tray icon # tray icon
tray.menu.open = Otvoriť tray.menu.open = Otvoriť
@@ -77,10 +75,8 @@ main.directoryList.remove.confirmation.header = Skutočne chcete odstrániť ten
main.directoryList.remove.confirmation.content = Trezor bude odstránení zo zoznamu. Pre úplné zmazanie vymažte súbor s trezorom. main.directoryList.remove.confirmation.content = Trezor bude odstránení zo zoznamu. Pre úplné zmazanie vymažte súbor s trezorom.
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding. upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migrácia zlyhala kvôli I/O Exception. Skontrolujte log pre viac detailov upgrade.version3to4.err.io = Migrácia zlyhala kvôli I/O Exception. Skontrolujte log pre viac detailov
settings.prefGvfsScheme.label = WebDAV Schéma
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Áno, som si istý že synchronizácia je hotová upgrade.confirmation.label = Áno, som si istý že synchronizácia je hotová
initialize.messageLabel.notEmpty = Trezor nie je prázdny
unlock.label.savePassword = Uložiť heslo unlock.label.savePassword = Uložiť heslo
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed unlocked.label.mountFailed = Connecting drive failed
@@ -93,7 +89,6 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 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.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. upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -104,4 +99,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
@@ -0,0 +1,114 @@
app.name = Cryptomator
# main.fxml
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 พร้อมให้ดาวโหลดแล้ว\nเวอร์ชั่นที่ใช้อยู่คือ %2$s
# initialize.fxml
initialize.label.password = รหัสผ่าน
initialize.label.retypePassword = ยืนยันรหัสผ่าน
initialize.button.ok = สร้างกล่องข้อมูล
initialize.messageLabel.alreadyInitialized = กล่องข้อมูลสร้างเสร็จแล้ว
initialize.messageLabel.initializationFailed = ไม่สามารถสร้างกล่องข้อมูลได้ ดูรายละเอียดได้ใน Log ไฟล์
# notfound.fxml
notfound.label = ไม่พบกล่องข้อมูล กล่องอาจถูกย้าย?
# upgrade.fxml
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.winDriveLetter = เลือกไดรฟ์
unlock.label.downloadsPageLink = เวอร์ชั่น Cryptomator ทั้งหมด
unlock.label.advancedHeading = ตั้งค่าขั้นสูง
unlock.button.unlock = ปลดล็อคกล่องข้อมูล
unlock.button.advancedOptions.show = ตั้งค่าเพิ่มเติม
unlock.button.advancedOptions.hide = ย่อเมนู
unlock.choicebox.winDriveLetter.auto = เลือกไดรฟ์อัตโนมัติ
unlock.errorMessage.wrongPassword = รหัสผ่านไม่ถูกต้อง
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = ไม่รองรับกล่องข้อมูลนี้ อาจเป็นกล่องข้อมูลของเวอชั่นเก่า
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = ไม่รองรับกล่องข้อมูลนี้ อาจเป็นกล่องข้อมูลของเวอชั่นใหม่กว่า
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.errorMessage.decryptionFailed = การถอดรหัสล้มเหลว
# unlocked.fxml
unlocked.button.lock = ล็อคกล่องข้อมูล
unlocked.moreOptions.reveal = โชว์ไดรฟ์
unlocked.moreOptions.copyUrl = คัดลอก WebDEV ลิ้งค์
unlocked.label.revealFailed = คำสั่งล้มเหลว
unlocked.label.unmountFailed = Eject ไดรว์ล้มเหลว
unlocked.label.statsEncrypted = เข้ารหัสแล้ว
unlocked.label.statsDecrypted = ถอดรหัสแล้ว
unlocked.ioGraph.yAxis.label = ความเร็วอ่านเขียน (MiB/s)
# settings.fxml
settings.version.label = เวอร์ชั่น %s
settings.checkForUpdates.label = ค้นหาอัพเดท
settings.requiresRestartLabel = * ต้องรีสตาร์ท Cryptomator ใหม่
# tray icon
tray.menu.open = เปิด
tray.menu.quit = ออก
tray.infoMsg.title = กำลังทำงาน
tray.infoMsg.msg = Cryptomator กำลังทำงาน คลิ้กออกตรง tray icon
tray.infoMsg.msg.osx = Cryptomator กำลังทำงาน คลิ้กออกตรงแถบเมนู
initialize.messageLabel.passwordStrength.0 = คาดเดาง่ายมาก
initialize.messageLabel.passwordStrength.1 = คาดเดาง่าย
initialize.messageLabel.passwordStrength.2 = ปลอดภัย
initialize.messageLabel.passwordStrength.3 = คาดเดายาก
initialize.messageLabel.passwordStrength.4 = คาดเดายากมาก
initialize.label.doNotForget = คำเตือน\!\!\!\: ถ้าคุณลืมรหัสผ่าน คุณจะไม่สามารถเข้าถึงและกู้ข้อมูลได้
main.directoryList.remove.confirmation.title = ลบกล่องข้อมูล
main.directoryList.remove.confirmation.header = คุณต้องการลบกล่องข้อมูลใช่หรือไม่ ?
main.directoryList.remove.confirmation.content = กล่องข้อมูลแค่ถูกลบออกจากรายการ หากต้องการลบข้อมูล ต้องไปลบในที่อยู่ไฟล์ของคุณ
upgrade.version3to4.msg = กล่องข้อมูลต้องการอัพเกรดเป็นเวอร์ชั่นใหม่\nชื่อโฟลเดอร์จะถูกอัพเดท\nกรุณารอการอัพเกรดให้เสร็จสิ้นก่อนเริ่มใช้งาน
upgrade.version3to4.err.io = อัพเกรดล้มเหลวเนื่องจากข้อยกเว้น I/O ดูรายละเอียดได้ใน Log ไฟล์
# upgrade.fxml
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 = รหัสผ่านที่เซฟถูกลบจาก system keychain แล้ว ถ้าคุณต้องการเซฟรหัสผ่านใหม่อีกครั้ง ให้คุณคลิ้กเลือก "เซฟรหัสผ่าน"
settings.debugMode.label = โหมด Debug *
upgrade.version3dropBundleExtension.title = อัพเกรดกล่องข้อมูลเวอร์ชั่น 3 (Drop Bundle Extension)
upgrade.version3to4.title = อัพเกรดกล่องข้อมูลเวอร์ชั่น 3 ไปยัง 4
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.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.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.
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Veri hacmi (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = Sürüm %s settings.version.label = Sürüm %s
settings.checkForUpdates.label = Güncellemeleri denetle settings.checkForUpdates.label = Güncellemeleri denetle
settings.port.label = WebDAV Port *
settings.port.prompt = 0 \= Otomatik seç
settings.requiresRestartLabel = * Cryptomator yeniden başlatılması gerek settings.requiresRestartLabel = * Cryptomator yeniden başlatılması gerek
# tray icon # tray icon
tray.menu.open = Aç tray.menu.open = Aç
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = Kasayı silmek istediğinize emi
main.directoryList.remove.confirmation.content = Kasa yalnızca listeden silinecek. Tamamen silmek için dosya sisteminizden dosyaları elle siliniz. main.directoryList.remove.confirmation.content = Kasa yalnızca listeden silinecek. Tamamen silmek için dosya sisteminizden dosyaları elle siliniz.
upgrade.version3to4.msg = Bu kasanın yeni formata geçirilmesi gerekmekte. Şifreli klasör isimleri güncellenecek. Devam etmeden önce senkronizasyonun bittiğine emin olun. upgrade.version3to4.msg = Bu kasanın yeni formata geçirilmesi gerekmekte. Şifreli klasör isimleri güncellenecek. Devam etmeden önce senkronizasyonun bittiğine emin olun.
upgrade.version3to4.err.io = Format değiştirme işlemi I/O Hatası dolayısı ile başarısız oldu. Detaylar için log dosyasına bakın upgrade.version3to4.err.io = Format değiştirme işlemi I/O Hatası dolayısı ile başarısız oldu. Detaylar için log dosyasına bakın
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save Password unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed unlocked.label.mountFailed = Connecting drive failed
@@ -90,7 +86,6 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 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.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. upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
+16 -6
View File
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = Пропускна спроможність (Мі
# settings.fxml # settings.fxml
settings.version.label = Версія %s settings.version.label = Версія %s
settings.checkForUpdates.label = Перевірити оновлення settings.checkForUpdates.label = Перевірити оновлення
settings.port.label = Порт WebDAV *
settings.port.prompt = 0 \= Обрати автоматично
settings.requiresRestartLabel = * Необхідне перезавантаження Cryptomator settings.requiresRestartLabel = * Необхідне перезавантаження Cryptomator
# tray icon # tray icon
tray.menu.open = Відкрити tray.menu.open = Відкрити
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = Ви дійсно хочете
main.directoryList.remove.confirmation.content = Сховище буде видалене тільки зі списку. Щоб стерти його остаточно, видаліть файли із файлової системи. main.directoryList.remove.confirmation.content = Сховище буде видалене тільки зі списку. Щоб стерти його остаточно, видаліть файли із файлової системи.
upgrade.version3to4.msg = Це сховище необхідно перетворити в новий формат. Зашифровані імена папок будуть оновлені. Перш ніж продовжити, виконайте синхронізацію. upgrade.version3to4.msg = Це сховище необхідно перетворити в новий формат. Зашифровані імена папок будуть оновлені. Перш ніж продовжити, виконайте синхронізацію.
upgrade.version3to4.err.io = Перетворення невдале через помилку введення-виведення. Дивіться деталі в файлі-звіті. upgrade.version3to4.err.io = Перетворення невдале через помилку введення-виведення. Дивіться деталі в файлі-звіті.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save Password unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed unlocked.label.mountFailed = Connecting drive failed
@@ -90,7 +86,6 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 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.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. upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
+84 -75
View File
@@ -1,106 +1,115 @@
app.name = Cryptomator app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = 单击此处添加保管 main.emptyListInstructions = 点按这里添加资料
main.directoryList.contextMenu.remove = 从列表中 main.directoryList.contextMenu.remove = 从列表中
main.directoryList.contextMenu.changePassword = 更密码 main.directoryList.contextMenu.changePassword = 更密码
main.addDirectory.contextMenu.new = 创建新保管 main.addDirectory.contextMenu.new = 新建资料
main.addDirectory.contextMenu.open = 打开现有保管 main.addDirectory.contextMenu.open = 使用现有资料
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = 正在检查更新…… welcome.checkForUpdates.label.currentlyChecking = 检查更新……
welcome.newVersionMessage = 发现新版本版本%1$s\n当前版本%2$s welcome.newVersionMessage = 新版本 %1$s 已发布\n当前版本%2$s
# initialize.fxml # initialize.fxml
initialize.label.password = 密码 initialize.label.password = 密码
initialize.label.retypePassword = 确认密码 initialize.label.retypePassword = 重新输入密码
initialize.button.ok = 创建保管 initialize.button.ok = 新建资料
initialize.messageLabel.alreadyInitialized = 保管库已初始化 initialize.messageLabel.alreadyInitialized = 已新建资料库
initialize.messageLabel.initializationFailed = 无法初始化保管库。 有关详情,请参阅日志文件 initialize.messageLabel.initializationFailed = 无法创建资料库。请查看日志来获得详细信息
# notfound.fxml # notfound.fxml
notfound.label = 找不到保险柜。 是否已移动? notfound.label = 找不到这个资料库,是否已移动到别的地方
# upgrade.fxml # upgrade.fxml
upgrade.button = 升级保险柜 upgrade.button = 升级资料库
upgrade.version3dropBundleExtension.msg = 此保管库需要迁移到较新的格式。\n"%1$s"将重命名为"%2$s"。\n请确保同步完成,然后再继续。 upgrade.version3dropBundleExtension.msg = 此资料库需要升级至最新版本,\n"%1$s" 将重命名为 "%2$s"。\n请确保同步完成后再继续操作
upgrade.version3dropBundleExtension.err.alreadyExists = 自动迁移失败。\n"%s"已存在 upgrade.version3dropBundleExtension.err.alreadyExists = 自动迁移失败。\n%s已存在
# unlock.fxml # unlock.fxml
unlock.label.password = 密码 unlock.label.password = 密码
unlock.label.mountName = 驱动器名称 unlock.label.mountName = 驱动器名称
unlock.label.winDriveLetter = 驱动器号 unlock.label.winDriveLetter = 驱动器号
unlock.label.downloadsPageLink = 所有Cryptomator版本 unlock.label.downloadsPageLink = 所有 Cryptomator 版本
unlock.label.advancedHeading = 高级选项 unlock.label.advancedHeading = 高级选项
unlock.button.unlock = 保险柜解锁 unlock.button.unlock = 解锁资料库
unlock.button.advancedOptions.show = 更多选项 unlock.button.advancedOptions.show = 更多选项
unlock.button.advancedOptions.hide = 更少选项 unlock.button.advancedOptions.hide = 更少选项
unlock.choicebox.winDriveLetter.auto = 自动分配 unlock.choicebox.winDriveLetter.auto = 自动分配
unlock.errorMessage.wrongPassword = 密码错误 unlock.errorMessage.wrongPassword = 密码错误
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 不支持的保管库。 此保管库由旧版本的Cryptomator创建 unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = 此资料库属于过时版本的 Cryptomator,无法在此版本中使用
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 不支持的保管库。 此保管库由较新版本的Cryptomator创建 unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = 此资料库属于较新版本的 Cryptomator,无法在此版本中使用
unlock.messageLabel.startServerFailed = 启动WebDAV服务器失败 unlock.messageLabel.startServerFailed = 无法启动 WebDAV 服务器。
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = 密码 changePassword.label.oldPassword = 密码
changePassword.label.newPassword = 新密码 changePassword.label.newPassword = 新密码
changePassword.label.retypePassword = 确认新密码 changePassword.label.retypePassword = 再次输入新密码
changePassword.label.downloadsPageLink = 所有Cryptomator版本 changePassword.label.downloadsPageLink = 所有 Cryptomator 版本
changePassword.button.change = 更密码 changePassword.button.change = 更密码
changePassword.errorMessage.wrongPassword = 密码错误 changePassword.errorMessage.wrongPassword = 密码错误
changePassword.errorMessage.decryptionFailed = 解密失败 changePassword.errorMessage.decryptionFailed = 解密失败
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = 保险柜上 unlocked.button.lock = 锁定资料库
unlocked.moreOptions.reveal = 显示驱动器 unlocked.moreOptions.reveal = 打开驱动器
unlocked.moreOptions.copyUrl = 复制WebDAV地址(URL) unlocked.moreOptions.copyUrl = 复制 WebDAV 网址
unlocked.label.revealFailed = 命令失败 unlocked.label.revealFailed = 指令无法执行
unlocked.label.unmountFailed = 弹出驱动器失败 unlocked.label.unmountFailed = 无法弹出驱动器
unlocked.label.statsEncrypted = 加密 unlocked.label.statsEncrypted = 加密
unlocked.label.statsDecrypted = 解密 unlocked.label.statsDecrypted = 解密
unlocked.ioGraph.yAxis.label = 吞吐量(Mib/s) unlocked.ioGraph.yAxis.label = 吞吐量 (Mib/s)
# settings.fxml # settings.fxml
settings.version.label = 版本%s settings.version.label = 版本 %s
settings.checkForUpdates.label = 检查更新 settings.checkForUpdates.label = 检查更新
# What's the "*" mean? settings.requiresRestartLabel = * Cryptomator 需要重启
settings.port.label = WebDAV 端口 *
settings.port.prompt = 0 \=自动选择
settings.requiresRestartLabel = * Cryptomator需要重新启动
# tray icon # tray icon
tray.menu.open = 打开 tray.menu.open = 打开
tray.menu.quit = 退出 tray.menu.quit = 退出
tray.infoMsg.title = 仍在运行 tray.infoMsg.title = 仍在运行
tray.infoMsg.msg = Cryptomator仍在运行。 从托盘图标中退出。 tray.infoMsg.msg = Cryptomator 仍在运行。 从托盘图标中退出。
tray.infoMsg.msg.osx = Cryptomator仍在运行。 从菜单栏图标中退出。 tray.infoMsg.msg.osx = Cryptomator 仍在运行。 从菜单栏图标中退出。
initialize.messageLabel.passwordStrength.0 = 非常简单 initialize.messageLabel.passwordStrength.0 = 非常
initialize.messageLabel.passwordStrength.1 = 简单 initialize.messageLabel.passwordStrength.1 = 略弱
initialize.messageLabel.passwordStrength.2 = 平均水平 initialize.messageLabel.passwordStrength.2 = 可接受
initialize.messageLabel.passwordStrength.3 = 强 initialize.messageLabel.passwordStrength.3 =
initialize.messageLabel.passwordStrength.4 = 非常强 initialize.messageLabel.passwordStrength.4 = 非常强
initialize.label.doNotForget = 重要信息:如果您忘记密码,将无法恢复您的数据 initialize.label.doNotForget = 重要:若忘记密码,数据将无法找回
main.directoryList.remove.confirmation.title = 移除保险柜 main.directoryList.remove.confirmation.title = 移除资料库
main.directoryList.remove.confirmation.header = 确定要除此保管库吗? main.directoryList.remove.confirmation.header = 确定要除此资料库吗?
main.directoryList.remove.confirmation.content = 文件库将仅从列表中删除。 要永久删除,请从文件系统中删除这些文件。 main.directoryList.remove.confirmation.content = 资料库将仅从列表中移除,如需永久删除,请从文件系统中删除这些文件。
upgrade.version3to4.msg = 此保管库需要迁移到较新的格式。\n加密的文件夹名称将更新。\n请确保同步完成,然后再继续。 upgrade.version3to4.msg = 此资料库需要升级至最新版本,\n加密的文件夹名称将更新。\n请确保同步完成后再继续操作
upgrade.version3to4.err.io = 由于I/O异常,迁移失败。有关详情,请参阅日志文件 upgrade.version3to4.err.io = 由于 I/O 异常,迁移失败。请查看日志来获得详细信息
settings.prefGvfsScheme.label = WebDAV方案
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = 是的,我确保同步已完成 upgrade.confirmation.label = 没错,同步已完成
initialize.messageLabel.notEmpty = 保险柜非空
unlock.label.savePassword = 保存密码 unlock.label.savePassword = 保存密码
# This Mac means Mac(Apple) or Mac address? # This Mac means Mac(Apple) or Mac address?
unlock.errorMessage.unauthenticVersionMac = 无法验证消息验证代码的版本。 unlock.errorMessage.unauthenticVersionMac = 无法确认消息认证码版本。
unlocked.label.mountFailed = 连接设备失败 unlocked.label.mountFailed = 无法连接到驱动器
unlock.savePassword.delete.confirmation.title = 删除已存的密码 unlock.savePassword.delete.confirmation.title = 删除已存的密码
unlock.savePassword.delete.confirmation.header = 真的要删除此密码库已保存的密码吗? unlock.savePassword.delete.confirmation.header = 真的要删除为此资料库储存的密码吗?
unlock.savePassword.delete.confirmation.content = 此密码库保存的密码将立即从系统钥匙串中删除。如果您想再次保存密码,则必须通过启用“保存密码”选项启用您的密码库。 unlock.savePassword.delete.confirmation.content = 此资料库储存的密码将立即从系统钥匙串中删除。如果您想再次保存密码,则必须通过启用“保存密码”选项启用您的密码库。
settings.debugMode.label = 调试模式 * settings.debugMode.label = 调试模式 *
upgrade.version3dropBundleExtension.title = 升级Vault版本3Drop Bundle Extension upgrade.version3dropBundleExtension.title = 升级资料库到第三版(移除 Bundle Extension
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade upgrade.version3to4.title = 升级资料库到第四版
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade upgrade.version4to5.title = 升级资料库到第五版
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.msg = 此资料库需要升级至最新版本,\n已加密的数据将被更新。\n请确保同步完成后再继续操作。
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details. upgrade.version4to5.err.io = 升级因 I/O 错误失败。请查看日志来获得详细信息。
settings.port.apply = Apply unlock.label.mountAfterUnlock = 装载驱动器
unlock.label.mountAfterUnlock = Mount Drive unlock.label.revealAfterMount = 显示驱动器
unlock.label.revealAfterMount = Reveal Drive unlocked.lock.force.confirmation.title = 无法锁定 %1$s
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.header = 要强制锁定吗?
unlocked.lock.force.confirmation.header = Do you want to force locking? unlocked.lock.force.confirmation.content = 此错误可能是因为其他应用程序仍在使用此资料库中的文件,或遇到了其他问题。\n\n如强制锁定,正在使用文件的应用程序可能会出错并丢失部分还没有保存的资料。
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 = 启动时自动解锁(试验功能)
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental) unlock.errorMessage.unlockFailed = 无法解锁。请查看日志来获得详细信息。
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlocked.moreOptions.mount = 装载驱动器
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.unmount = 弹出驱动器
unlocked.moreOptions.unmount = Eject Drive upgrade.version5toX.title = 资料库版本升级
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.msg = 此资料库需要升级至最新版本,\n请确保同步完成后再继续操作。
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 *
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.
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = 傳輸量(MIB / S
# settings.fxml # settings.fxml
settings.version.label = 版本%s settings.version.label = 版本%s
settings.checkForUpdates.label = 檢查更新 settings.checkForUpdates.label = 檢查更新
settings.port.label = WebDAV的埠號*
settings.port.prompt = 0 \=自動選擇
settings.requiresRestartLabel = * Cryptomator需要更新 settings.requiresRestartLabel = * Cryptomator需要更新
# tray icon # tray icon
tray.menu.open = 打開 tray.menu.open = 打開
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = 你真的想要移除這個檔
main.directoryList.remove.confirmation.content = 這個檔案庫只會從清單中移除。如果要永久刪除,請從檔案系統中刪除。 main.directoryList.remove.confirmation.content = 這個檔案庫只會從清單中移除。如果要永久刪除,請從檔案系統中刪除。
upgrade.version3to4.msg = 這個檔案庫需要被轉移到新的格式。\n加密的資料夾名稱將會被更新。\n在進行之前,請確認同步已完成。 upgrade.version3to4.msg = 這個檔案庫需要被轉移到新的格式。\n加密的資料夾名稱將會被更新。\n在進行之前,請確認同步已完成。
upgrade.version3to4.err.io = 由於I/O的例外,轉移失敗。取得詳細資訊,請查看紀錄。 upgrade.version3to4.err.io = 由於I/O的例外,轉移失敗。取得詳細資訊,請查看紀錄。
settings.prefGvfsScheme.label = WebDAV的格式
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = 是的,請確認同步已完成。 upgrade.confirmation.label = 是的,請確認同步已完成。
initialize.messageLabel.notEmpty = 檔案庫不是空的
unlock.label.savePassword = 儲存密碼 unlock.label.savePassword = 儲存密碼
unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。 unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。
unlocked.label.mountFailed = Connecting drive failed unlocked.label.mountFailed = Connecting drive failed
@@ -90,7 +86,6 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 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.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. upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed unlocked.lock.force.confirmation.title = Locking of %1$s failed
@@ -101,4 +96,19 @@ unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade 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. 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 *
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.
@@ -54,8 +54,6 @@ unlocked.ioGraph.yAxis.label = 傳輸量 (MiB/s)
# settings.fxml # settings.fxml
settings.version.label = 版本 %s settings.version.label = 版本 %s
settings.checkForUpdates.label = 檢查更新 settings.checkForUpdates.label = 檢查更新
settings.port.label = WebDAV 埠號 *
settings.port.prompt = 0 \= 自動選擇
settings.requiresRestartLabel = * Cryptomator 需要更新 settings.requiresRestartLabel = * Cryptomator 需要更新
# tray icon # tray icon
tray.menu.open = 打開 tray.menu.open = 打開
@@ -74,10 +72,8 @@ main.directoryList.remove.confirmation.header = 你真的想要移除這個檔
main.directoryList.remove.confirmation.content = 這個檔案庫只會從清單中移除。如果要永久刪除,請從檔案系統中刪除。 main.directoryList.remove.confirmation.content = 這個檔案庫只會從清單中移除。如果要永久刪除,請從檔案系統中刪除。
upgrade.version3to4.msg = 這個檔案庫需要被轉移到新的格式。\n加密的資料夾名稱將會被更新。\n在進行之前,請確認同步已完成。 upgrade.version3to4.msg = 這個檔案庫需要被轉移到新的格式。\n加密的資料夾名稱將會被更新。\n在進行之前,請確認同步已完成。
upgrade.version3to4.err.io = 由於 I/O 的例外,轉移失敗。取得詳細資訊,請查看日誌檔。 upgrade.version3to4.err.io = 由於 I/O 的例外,轉移失敗。取得詳細資訊,請查看日誌檔。
settings.prefGvfsScheme.label = WebDAV 格式
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = 是的,請確認同步已完成。 upgrade.confirmation.label = 是的,請確認同步已完成。
initialize.messageLabel.notEmpty = 檔案庫不是空的
unlock.label.savePassword = 儲存密碼 unlock.label.savePassword = 儲存密碼
unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。 unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。
unlocked.label.mountFailed = 連線到磁碟失敗 unlocked.label.mountFailed = 連線到磁碟失敗
@@ -90,15 +86,29 @@ upgrade.version3to4.title = 檔案庫版本 3 到 4 升級
upgrade.version4to5.title = 檔案庫版本 4 到 5 升級 upgrade.version4to5.title = 檔案庫版本 4 到 5 升級
upgrade.version4to5.msg = 這個檔案庫需要被遷移到新的格式。\n加密的檔案將會被更新。\n在處理前,請確保同步已經完成。\n\n註記:所有檔案的更改日期將會被變更為目前處理的日期/時間。 upgrade.version4to5.msg = 這個檔案庫需要被遷移到新的格式。\n加密的檔案將會被更新。\n在處理前,請確保同步已經完成。\n\n註記:所有檔案的更改日期將會被變更為目前處理的日期/時間。
upgrade.version4to5.err.io = 由於 I/O 異常導致遷移失敗。詳細請見日誌檔。 upgrade.version4to5.err.io = 由於 I/O 異常導致遷移失敗。詳細請見日誌檔。
settings.port.apply = 套用
unlock.label.mountAfterUnlock = 掛載磁碟 unlock.label.mountAfterUnlock = 掛載磁碟
unlock.label.revealAfterMount = 打開磁碟 unlock.label.revealAfterMount = 打開磁碟
unlocked.lock.force.confirmation.title = %1$s 鎖定失敗 unlocked.lock.force.confirmation.title = %1$s 鎖定失敗
unlocked.lock.force.confirmation.header = 你想要強制鎖定? unlocked.lock.force.confirmation.header = 你想要強制鎖定?
unlocked.lock.force.confirmation.content = 這可能是因為其他軟體仍在存取這個檔案庫,或者發生其他問題。\n\n仍然在存取檔案的軟體可能無法正常運作,而且會造成寫入的資料遺失。 unlocked.lock.force.confirmation.content = 這可能是因為其他軟體仍在存取這個檔案庫,或者發生其他問題。\n\n仍然在存取檔案的軟體可能無法正常運作,而且會造成寫入的資料遺失。
unlock.label.unlockAfterStartup = 啟動時,自動解鎖(實驗中) unlock.label.unlockAfterStartup = 啟動時,自動解鎖(實驗中)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details. unlock.errorMessage.unlockFailed = 解鎖失敗。詳請查看日誌檔。
unlocked.moreOptions.mount = Mount Drive unlocked.moreOptions.mount = 掛載硬碟
unlocked.moreOptions.unmount = Eject Drive unlocked.moreOptions.unmount = 退出硬碟
upgrade.version5toX.title = Vault Version Upgrade upgrade.version5toX.title = 檔案庫版本升級
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding. 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 *
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.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

@@ -0,0 +1,10 @@
package org.cryptomator.ui.l10n;
public class LocalizationMock extends Localization {
@Override
public String handleGetObject(String key) {
return key;
}
}
@@ -31,8 +31,8 @@ public class LocalizationTest {
private static final Logger LOG = LoggerFactory.getLogger(LocalizationTest.class); private static final Logger LOG = LoggerFactory.getLogger(LocalizationTest.class);
private static final String RESOURCE_FOLDER_PATH = "/localization/"; private static final String RESOURCE_FOLDER_PATH = "/localization/";
private static final String REF_FILE_NAME = "en.txt"; private static final String REF_FILE_NAME = "en.txt";
private static final String[] LANG_FILE_NAMES = {"ar.txt", "bg.txt", "da.txt", "de.txt", "es.txt", "fr.txt", "hu.txt", "it.txt", "ja.txt", // private static final String[] LANG_FILE_NAMES = {"ar.txt", "bg.txt", "cs.txt", "da.txt", "de.txt", "es.txt", "fr.txt", "hu.txt", "it.txt", "ja.txt", //
"ko.txt", "lv.txt", "nl.txt", "pl.txt", "pt.txt", "pt_BR.txt", "ru.txt", "sk.txt", "tr.txt", "uk.txt", "zh_HK.txt", "zh_TW.txt", "zh.txt"}; "ko.txt", "lv.txt", "nl.txt", "pl.txt", "pt.txt", "pt_BR.txt", "ru.txt", "sk.txt", "th.txt", "tr.txt", "uk.txt", "zh_HK.txt", "zh_TW.txt", "zh.txt"};
/* /*
* @see Formatter * @see Formatter
@@ -0,0 +1,164 @@
package org.cryptomator.ui.model;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.l10n.LocalizationMock;
import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
public class UpgradeVersion3to4Test {
private static final Localization L10N = new LocalizationMock();
private static final String NULL_KEY_CONTENTS = "{" //
+ " \"version\": 3," //
+ " \"scryptSalt\": \"AAAAAAAAAAA=\"," //
+ " \"scryptCostParam\": 16384," //
+ " \"scryptBlockSize\": 8," //
+ " \"primaryMasterKey\": \"BJPIq5pvhN24iDtPJLMFPLaVJWdGog9k4n0P03j4ru+ivbWY9OaRGQ==\"," //
+ " \"hmacMasterKey\": \"BJPIq5pvhN24iDtPJLMFPLaVJWdGog9k4n0P03j4ru+ivbWY9OaRGQ==\"," //
+ " \"versionMac\": \"iUmRRHITuyJsJbVNqGNw+82YQ4A3Rma7j/y1v0DCVLA=\"" //
+ "}";
@Rule
public final ExpectedException thrown = ExpectedException.none();
private final UpgradeStrategy upgradeStrategy = new UpgradeVersion3to4(L10N);
private FileSystem fs;
private Path fsRoot;
private Vault vault;
private Path dataDir;
private Path metadataDir;
@Before
public void setup() throws IOException {
fs = Jimfs.newFileSystem(Configuration.unix());
fsRoot = fs.getPath("/");
dataDir = fsRoot.resolve("d");
metadataDir = fsRoot.resolve("m");
vault = Mockito.mock(Vault.class);
Mockito.when(vault.getPath()).thenReturn(fsRoot);
Files.write(fsRoot.resolve("masterkey.cryptomator"), NULL_KEY_CONTENTS.getBytes(StandardCharsets.US_ASCII));
}
@After
public void teardown() throws IOException {
fs.close();
}
@Test
public void upgradeFailsWithWrongPassword() throws UpgradeFailedException {
thrown.expect(UpgradeFailedException.class);
thrown.expectMessage("unlock.errorMessage.wrongPassword");
upgradeStrategy.upgrade(vault, "asdd");
}
@Test
public void upgradeCreatesBackup() throws UpgradeFailedException {
upgradeStrategy.upgrade(vault, "asd");
Assert.assertTrue(Files.exists(fsRoot.resolve("masterkey.cryptomator.bkup")));
}
@Test
public void upgradeRenamesSimpleDirFile() throws IOException, UpgradeFailedException {
Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
Files.createDirectories(lvl2Dir);
Path oldFile = lvl2Dir.resolve("ABCDEFGH_");
Files.createFile(oldFile);
upgradeStrategy.upgrade(vault, "asd");
Path newFile = lvl2Dir.resolve("0ABCDEFGH");
Assert.assertTrue(Files.exists(newFile));
Assert.assertTrue(Files.notExists(oldFile));
}
@Test
public void upgradeRenamesConflictingDirFile() throws IOException, UpgradeFailedException {
Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
Files.createDirectories(lvl2Dir);
Path oldFile = lvl2Dir.resolve("ABCDEFGH_ (1)");
Files.createFile(oldFile);
upgradeStrategy.upgrade(vault, "asd");
Path newFile = lvl2Dir.resolve("0ABCDEFGH (1)");
Assert.assertTrue(Files.exists(newFile));
Assert.assertTrue(Files.notExists(oldFile));
}
@Test
public void upgradeDontRenameNonDirFile() throws IOException, UpgradeFailedException {
Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
Files.createDirectories(lvl2Dir);
Path oldFile = lvl2Dir.resolve("ABCDEFGH");
Files.createFile(oldFile);
upgradeStrategy.upgrade(vault, "asd");
Assert.assertTrue(Files.exists(oldFile));
}
@Test
public void upgradeRenameSimpleLongDirFile() throws IOException, UpgradeFailedException {
Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
Files.createDirectories(lvl2Dir);
Path oldFile = lvl2Dir.resolve("ABCDEFGH.lng");
Files.createFile(oldFile);
Path oldMetadataFile = metadataDir.resolve("AB/CD/ABCDEFGH.lng");
Files.createDirectories(oldMetadataFile.getParent());
Files.write(oldMetadataFile, "OPQRSTUVWXYZ====_".getBytes(StandardCharsets.UTF_8));
upgradeStrategy.upgrade(vault, "asd");
// hex2base32(sha1("0OPQRSTUVWXYZ====")) = DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G
Path newMetadataFile = metadataDir.resolve("DD/LC/DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G.lng");
Path newFile = lvl2Dir.resolve("DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G.lng");
Assert.assertTrue(Files.exists(newFile));
Assert.assertTrue(Files.exists(newMetadataFile));
Assert.assertTrue(Files.notExists(oldFile));
}
@Test
public void upgradeRenameConflictingLongDirFile() throws IOException, UpgradeFailedException {
Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
Files.createDirectories(lvl2Dir);
Path oldFile = lvl2Dir.resolve("ABCDEFGH (1).lng");
Files.createFile(oldFile);
Path oldMetadataFile = metadataDir.resolve("AB/CD/ABCDEFGH.lng");
Files.createDirectories(oldMetadataFile.getParent());
Files.write(oldMetadataFile, "OPQRSTUVWXYZ====_".getBytes(StandardCharsets.UTF_8));
upgradeStrategy.upgrade(vault, "asd");
// hex2base32(sha1("0OPQRSTUVWXYZ====")) = DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G
Path newMetadataFile = metadataDir.resolve("DD/LC/DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G.lng");
Path newFile = lvl2Dir.resolve("DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G (1).lng");
Assert.assertTrue(Files.exists(newFile));
Assert.assertTrue(Files.exists(newMetadataFile));
Assert.assertTrue(Files.notExists(oldFile));
}
@Test
public void upgradeDontRenameLongNonDirFile() throws IOException, UpgradeFailedException {
Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
Files.createDirectories(lvl2Dir);
Path oldFile = lvl2Dir.resolve("ABCDEFGH.lng");
Files.createFile(oldFile);
Path oldMetadataFile = metadataDir.resolve("AB/CD/ABCDEFGH.lng");
Files.createDirectories(oldMetadataFile.getParent());
Files.write(oldMetadataFile, "OPQRSTUVWXYZ====".getBytes(StandardCharsets.UTF_8));
upgradeStrategy.upgrade(vault, "asd");
Assert.assertTrue(Files.exists(oldFile));
}
}
@@ -0,0 +1,21 @@
package org.cryptomator.ui.util;
import org.cryptomator.ui.l10n.Localization;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
public class PasswordStrengthUtilTest {
@Test
public void testLongPasswordsWillBeRatedAsStrong() {
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(Localization.class));
StringBuilder longPwBuilder = new StringBuilder();
for (int i = 0; i < 101; i++) {
longPwBuilder.append('x');
}
int strength = util.computeRate(longPwBuilder.toString());
Assert.assertEquals(4, strength);
}
}