Compare commits

..

203 Commits
1.3.2 ... 1.4.1

Author SHA1 Message Date
Tobias Hagemann
ee5505362c Merge branch 'release/1.4.1' 2019-01-16 16:50:44 +01:00
Tobias Hagemann
82f388d420 Preparing 1.4.1 2019-01-16 16:38:37 +01:00
Tobias Hagemann
70e733f341 Updated localizations 2019-01-16 16:27:00 +01:00
Tobias Hagemann
3af5d5f267 Repositioned messageText in unlock, updated "unlock.pendingMessage.unlocking" copy 2019-01-16 16:23:03 +01:00
Sebastian Stenzel
28bf9e2ab1 fixes #732 2019-01-16 16:10:11 +01:00
Sebastian Stenzel
2f3a576de9 Renewed BINTRAY_API_KEY [ci skip] 2019-01-16 16:02:52 +01:00
Armin Schrenk
bbe1ef3dbc Feature/custom mount point generalizing (#797)
* changing naming of individual mout path property

* adding input/output for the new custom mount points

* ui integration of custom mount point

* removing unused variable

* Improving UX

* Simplify mountPathProperty and implement its usage

* reverting renaming of Properties concerning the usage of own mount point (rescheduled for 1.5.0)

* changing displayed message when no mount path given

* fixing ui error

* applying suggestion of comment 7338fda418 (r248254180)
2019-01-16 15:08:00 +01:00
Tobias Hagemann
078a127182 Shortened "welcome.askForUpdateCheck.dialog.content" copy 2019-01-16 14:15:26 +01:00
Tobias Hagemann
240bf122dd Hide "check for updates" indicator by default 2019-01-16 14:00:32 +01:00
Sebastian Stenzel
f2f8f9b28c added intellij project configuration 2019-01-15 13:15:38 +01:00
Sebastian Stenzel
af03e0d73d updated dagger [ci skip] 2019-01-15 13:07:39 +01:00
Sebastian Stenzel
7844078203 Merge pull request #784 from jellemdekker/bugfix/771_abort_graceful_shutdown_dialog
Added a Cancel button to the graceful shutdown-dialog
2019-01-14 13:05:40 +01:00
Armin Schrenk
da62a22faf fixes #750 2019-01-09 17:59:41 +01:00
Armin Schrenk
c36a1a4aef closes #711 2019-01-09 17:58:23 +01:00
Armin Schrenk
f760347d9d fixes #787 2019-01-09 15:28:05 +01:00
Armin Schrenk
8fc647eb2b Updating Apache Commons libraries 2019-01-09 15:26:02 +01:00
jellemdekker
69b1bf5a26 Added a Cancel button to the graceful shutdown-dialog. Fixes issue #771. 2018-12-22 12:53:42 +01:00
Sebastian Stenzel
6951edac96 fixes #770 2018-12-05 18:22:48 +01:00
Sebastian Stenzel
76c84b34e9 bumped version 2018-11-05 10:46:39 +01:00
Sebastian Stenzel
1362720011 Merge branch 'master' into develop
[ci skip]
2018-10-31 16:21:48 +01:00
Sebastian Stenzel
3f15352ebf Merge branch 'release/1.4.0-rc1' 2018-10-31 16:21:09 +01:00
Sebastian Stenzel
fdedee49d3 Preparing 1.4.0-rc1 2018-10-31 16:20:42 +01:00
Sebastian Stenzel
b506493c13 updated localization 2018-10-31 16:17:20 +01:00
Sebastian Stenzel
bc09f28120 updating dependencies
fixes #742, fixes #705
2018-10-31 16:03:37 +01:00
Sebastian Stenzel
eba0935900 attempting to downgrade to oracle jdk 9 because of stupid jdk 10 deprecation 2018-10-31 15:56:18 +01:00
Armin Schrenk
050a6e6a57 use jdk 10 for 1.4.0 release 2018-10-31 15:22:00 +01:00
Armin Schrenk
dbcb407a7c updating travis config 2018-10-31 14:41:30 +01:00
Armin Schrenk
b1acdf9e61 fixex #738 2018-10-31 14:13:03 +01:00
Armin Schrenk
9c6a0b3e0c readjust columns in settings dialogue 2018-10-31 13:36:52 +01:00
Sebastian Stenzel
f6df442948 Merge branch 'master' into develop
[ci skip]
2018-10-15 14:37:05 +02:00
Sebastian Stenzel
29038a679f Merge branch 'release/1.4.0-beta3' 2018-10-15 14:36:27 +02:00
Sebastian Stenzel
2e042423d0 Preparing 1.4.0-beta3 2018-10-15 14:35:34 +02:00
Sebastian Stenzel
e08c2b7dc3 updated dependencies 2018-10-11 00:31:22 +02:00
infeo
d5d0589dec changing description of own mount point usage 2018-10-10 12:34:23 +02:00
infeo
a760edcab9 fixing settings bug under linux 2018-10-05 18:31:38 +02:00
infeo
a759455473 removing testsetting 2018-10-05 17:53:10 +02:00
Armin Schrenk
50d2f16f71 fixing ui bug: setting fields did not disappeared with mount adapter change 2018-10-05 17:42:35 +02:00
infeo
8afa09007b aligning webdav port number textfield 2018-10-04 16:12:07 +02:00
infeo
194f373c08 changes spelling of the word dokany 2018-10-01 23:12:51 +02:00
Sebastian Stenzel
5f11e1aa8b Next attempt to provide a solution for #656. 2018-09-17 22:39:46 +02:00
Sebastian Stenzel
0ac1b406b7 tmp fix from https://github.com/cryptomator/cryptomator/pull/29 apparently no longer needed with latest JDK. 2018-09-17 22:38:35 +02:00
Sebastian Stenzel
ade2db7cc0 attempt to correctly size the UI (#656) 2018-09-16 14:46:50 +02:00
Sebastian Stenzel
eb911aeb6c Merge pull request #690 from jellemdekker/feature/230-graceful-quit
Implemented graceful shutdown confirmation dialog, fixes #230.
2018-08-21 18:15:02 +02:00
jellemdekker
a58259d4f0 As per feedback on PR #690: refactored if-statement. 2018-08-21 15:27:32 +02:00
jellemdekker
963a731202 As per feedback on PR #690: redid line wrapping, refactored signature for dialog builder method to include a default button, and the default button for the graceful shutdown dialog is now 'Force shutdown'. 2018-08-21 15:26:10 +02:00
Tobias Hagemann
5ea0fc4b6f updated localizations [ci skip] 2018-08-08 23:42:54 +02:00
Sebastian Stenzel
4becdf7e1e now publishing ant-kit to bintray instead of github releases 2018-07-23 23:21:10 +02:00
Sebastian Stenzel
8ab8798381 jdk_switcher no longer needed, since codacy-coverage-reporter should now support jdk 10 (see https://github.com/codacy/codacy-coverage-reporter/issues/83) 2018-07-23 21:01:43 +02:00
Sebastian Stenzel
c3f8fa1662 code refinements 2018-07-19 18:13:19 +02:00
infeo
59d019f34a fixes #700 2018-07-19 15:40:45 +02:00
infeo
ee99e9994e closes #695 2018-07-17 18:36:30 +02:00
infeo
019b7ac643 refactoring inconsistent method in vault class 2018-07-17 18:18:23 +02:00
infeo
7392a99da5 small ui fix: text for using individual mount path is not shown completely 2018-07-17 18:17:27 +02:00
Sebastian Stenzel
e909269ae0 Merge tag '1.4.0-beta2' into develop
1.4.0-beta2
2018-07-12 15:22:42 +02:00
Sebastian Stenzel
45ad496f41 Merge branch 'release/1.4.0-beta2' 2018-07-12 15:21:50 +02:00
Sebastian Stenzel
a272bf2614 preparing 1.4.0-beta2 2018-07-12 15:14:36 +02:00
infeo
119e0724d5 fixing broken option "reveal after mount" 2018-07-12 14:58:34 +02:00
Sebastian Stenzel
76a9cb9a06 using different threadpools for normal ExecutorService (will spawn threads on demand) and ScheduledExecutorService (limited to 4 scheduler threads) 2018-07-12 14:53:27 +02:00
infeo
acb8d4cd0c fixing display issue when locking a vault and changign to another vault during the lock process 2018-07-12 11:53:44 +02:00
Sebastian Stenzel
ffe8887114 no longer using jdk.incubator.httpclient, because windows app doesn't start with --add-modules arg in cfg file 2018-07-12 11:03:35 +02:00
Sebastian Stenzel
d8c8c2380a trying to move coverage report to end of build to workaround https://github.com/travis-ci/travis-cookbooks/issues/989 2018-07-11 16:12:07 +02:00
Sebastian Stenzel
fe5ce79802 updated mockito (restoring jdk 10 compatibility) 2018-07-11 15:52:07 +02:00
Sebastian Stenzel
bf7a8686a6 fix build 2018-07-11 15:45:05 +02:00
Sebastian Stenzel
143070d02d Updated to JDK 10 2018-07-11 15:40:28 +02:00
Sebastian Stenzel
06827a7466 changed ant-kit format to zip (because windows..) 2018-07-10 22:57:33 +02:00
Sebastian Stenzel
5add862ce8 updated ant-kit 2018-07-10 17:44:22 +02:00
Sebastian Stenzel
2b8d7c6c3b linux logback configuration moved to https://github.com/cryptomator/cryptomator-linux
[ci skip]
2018-07-10 17:05:45 +02:00
Sebastian Stenzel
f5da13d3b4 Updated ant-kit. To be used by Windows and Mac build as well 2018-07-10 16:59:07 +02:00
Sebastian Stenzel
03dfd3e887 Replaced AsyncTaskService by new Tasks utility using javafx.concurrent API 2018-07-10 14:51:33 +02:00
infeo
8241559362 Merge branch 'develop' of https://github.com/cryptomator/cryptomator into develop 2018-07-09 18:43:51 +02:00
infeo
c289040624 fixes a display error where a vault appeared unlocked even when a wrong password was given 2018-07-09 18:43:45 +02:00
Sebastian Stenzel
767acbd922 Merge pull request #689 from jellemdekker/feature/296-status-indicator-in-system-tray
[Help needed] Different system tray icon is shown when one or more vaults are unlocked

fixes #296
2018-07-09 17:54:47 +02:00
Tobias Hagemann
ccd4cedb08 Unlocked tray icons for macOS 2018-07-09 17:37:16 +02:00
jellemdekker
0ddd6d767d Implemented confirmation dialog when graceful shutdown of Cryptomator fails, so that the user can try again or opt to shutdown forcefully. 2018-07-09 16:42:53 +02:00
jellemdekker
6a5a1e5bae Replaced spaces in indentation with tabs. 2018-07-09 14:56:22 +02:00
jellemdekker
b3d76bb394 Created the unlocked version of the tray icon for every operating system except macOS. Uses the free-for-commercial-use 'Lock, open icon' from the Hawcons icon set by Yannick Lung over at Iconfinder.com: https://www.iconfinder.com/icons/314694/lock_open_icon 2018-07-06 17:43:43 +02:00
jellemdekker
1924a7dec9 Implemented that a different system tray icon is shown to indicate when one or more vaults are unlocked. The unlocked icons are placeholders and will updated visually in following commits. 2018-07-06 17:34:39 +02:00
Sebastian Stenzel
b65da30899 Merge pull request #688 from Gregvh/fix-broken-links
Fix broken links in CONTRIBUTING.md
[ci skip]
2018-07-06 17:33:56 +02:00
Sebastian Stenzel
7de8b3da02 Merge pull request #686 from jellemdekker/bugfix/update-readme.md-build-dependency-java
Updated minimum required version of Java Development Kit
[ci skip]
2018-07-06 17:33:02 +02:00
Gregvh
48ac8da1a7 Fix broken links in CONTRIBUTING.md 2018-07-06 14:13:15 +02:00
jellemdekker
86ae35c7eb Updated minimum required version of Java Development Kit, because this has changed since Cryptomator version 1.4.0. Source: https://community.cryptomator.org/t/how-to-run-cryptomator-1-4-0-beta1-jar/1599/4 . Skipping over Java 9, because its support has already ended. Also, JCE unlimited strength policy files are now included in the JDK by default, so they no longer need to be mentioned separately. 2018-07-06 03:52:04 +02:00
infeo
8421a8fc7b updating version of dokany-nio-adapter 2018-07-05 16:44:13 +02:00
infeo
b579e03bc8 workaround for the combination of windows + dokany + (automatic drive letter selection) 2018-06-28 16:55:00 +02:00
infeo
9217b11e61 adding automatic drive letter selection to dokany volume 2018-06-28 16:02:11 +02:00
Tobias Hagemann
e16bd7373c updated dokany version [ci skip] 2018-06-22 17:00:48 +02:00
Sebastian Stenzel
ef53561bf0 Improvements suggested in #598 2018-06-21 17:47:47 +02:00
Sebastian Stenzel
3165c4ba86 Add GPG signature for antkit.tar.gz, fixes #522 2018-06-17 23:22:48 +02:00
Sebastian Stenzel
f1bf157cac Update stale.yml
[ci skip]
2018-06-17 16:20:00 +02:00
Sebastian Stenzel
9c75dd48dd Create no-response.yml
[ci skip]
2018-06-17 15:55:09 +02:00
Sebastian Stenzel
74d4b4ea47 Rename style.yml to stale.yml
[ci skip]
2018-06-17 15:49:19 +02:00
Sebastian Stenzel
6f66f4cbf1 Create style.yml
[ci skip]
2018-06-17 15:48:59 +02:00
Sebastian Stenzel
874c5506a7 Added Dokany to volume type setting.
Restart no longer required, when changing preferred volume type.
References #207
2018-06-17 14:19:22 +02:00
Sebastian Stenzel
aed35c17c8 Added Dokany Support
fixes #207
2018-06-17 13:59:28 +02:00
Sebastian Stenzel
873e438759 merging jacoco reports via codacy, subproject no longer needed 2018-06-17 11:58:26 +02:00
Sebastian Stenzel
5b45893c7b Renamed CommandFailedException to VolumeException 2018-06-15 09:48:46 +02:00
Sebastian Stenzel
5515258af1 updated FUSE, fixed reveal after unlock 2018-06-14 17:37:32 +02:00
Sebastian Stenzel
dd5d52d25a updated dependencies 2018-05-24 14:19:59 +02:00
Sebastian Stenzel
24236f3844 Merge commit '458866f7d6460e688897b851248c8a2c22dc80d1' into develop 2018-05-24 14:14:44 +02:00
Markus Kreusch
458866f7d6 Asking user once before enabling update check 2018-05-22 11:36:00 +02:00
Sebastian Stenzel
525b0a7982 updated dependencies 2018-05-14 21:38:22 +02:00
Sebastian Stenzel
d53af61b58 Removed "Mount after unlock" option. Mounting/unmounting no longer visible to the user, but merged with unlocking/locking. 2018-05-14 21:37:38 +02:00
Sebastian Stenzel
b0ab46b7b6 Removed copy WebDAV URL button 2018-05-14 21:04:00 +02:00
infeo
9107d296c3 fixes partially #660 2018-04-09 18:07:04 +02:00
Sebastian Stenzel
6be95963a1 moved issue templates to .github directory
[ci skip]
2018-04-07 00:42:08 +02:00
Sebastian Stenzel
09c9361e94 Merge branch 'release/1.4.0-beta1' into develop
[ci skip]
2018-04-06 16:55:22 +02:00
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 Stenzel
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
114 changed files with 2834 additions and 2001 deletions

View File

@@ -4,7 +4,7 @@
- Ensure you're running the latest version of Cryptomator.
- Ensure the bug is related to the desktop version of Cryptomator. Bugs concerning the Cryptomator iOS and Android app can be reported on the [Cryptomator for iOS issues list](https://github.com/cryptomator/cryptomator-ios/issues) and [Cryptomator for Android issues list](https://github.com/cryptomator/cryptomator-android/issues) respectively.
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/faq).
- Ensure the bug was not [already reported](https://github.com/cryptomator/cryptomator/issues). You can also check out our [FAQ](https://community.cryptomator.org/c/kb/faq).
- If you're unable to find an open issue addressing the problem, [submit a new one](https://github.com/cryptomator/cryptomator/issues/new).
## Did you write a patch that fixes a bug?
@@ -18,7 +18,7 @@
## Code of Conduct
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/CODE_OF_CONDUCT.md).
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md).
## Above all, thank you for your contributions

View File

@@ -4,8 +4,8 @@ Before creating a new issue make sure that you
- searched existing (and closed) issues: https://github.com/cryptomator/cryptomator/issues
- searched the knowledge base: https://community.cryptomator.org/c/kb
- have read the support guide: https://github.com/cryptomator/cryptomator/blob/develop/SUPPORT.md
- have read the contribution guide: https://github.com/cryptomator/cryptomator/blob/develop/CONTRIBUTING.md
- have read the code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/CODE_OF_CONDUCT.md
- have read the contribution guide: https://github.com/cryptomator/cryptomator/blob/develop/.github/CONTRIBUTING.md
- have read the code of conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
## Basic Info

View File

@@ -0,0 +1,15 @@
## 1.4.0 Beta Issue Checklist
- Existing 1.4.0 Beta Issues: https://github.com/cryptomator/cryptomator/milestone/27
- Contribution Guide: https://github.com/cryptomator/cryptomator/blob/develop/.github/CONTRIBUTING.md
- Code of Conduct: https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md
## Software Used During the Test
- Cryptomator 1.4.0 Beta 1
- Ubuntu 16.04 / macOS 10.11.6 / etc
- Linux Kernel x.y.z
- Gnome x.y.z
- OpenOffice x.y.z
- ...
## Description
What doesn't work? What did you do? How can the bug be reproduced?

13
.github/no-response.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
# Configuration for probot-no-response - https://github.com/probot/no-response
# Number of days of inactivity before an Issue is closed for lack of response
daysUntilClose: 14
# Label requiring a response
responseRequiredLabel: state:awaiting-response
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
closeComment: >
This issue has been automatically closed because there has been no response
to our request for more information from the original author. With only the
information that is currently in the issue, we don't have enough information
to take action. Please reach out if you have or find the answers we need so
that we can investigate further.

19
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- type:security-issue # never close automatically
- state:awaiting-response # handled by different bot
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
# Label to use when marking an issue as stale
staleLabel: state:stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

18
.gitignore vendored
View File

@@ -9,15 +9,13 @@
.settings
.project
.classpath
# Maven #
target/
test-output/
# IntelliJ Settings Files #
.idea/
out/
.idea_modules/
*.iws
*.iml
# Temporary file created by test launcher
main/launcher/.ipcPort.tmp
# IntelliJ Settings Files (https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems) #
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/libraries/
*.iml

1
.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
Cryptomator

51
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,51 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="USE_TAB_CHARACTER" value="true" />
</value>
</option>
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="RIGHT_MARGIN" value="220" />
<option name="FORMATTER_TAGS_ENABLED" value="true" />
<JavaCodeStyleSettings>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="30" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="10" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
</JavaCodeStyleSettings>
<codeStyleSettings language="Groovy">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="HTML">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_LINE_BREAKS" value="false" />
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

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

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="commons" />
<module name="keychain" />
<module name="launcher" />
<module name="ui" />
</profile>
</annotationProcessing>
</component>
</project>

10
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/main" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/commons" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/keychain" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/launcher" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/main/ui" charset="UTF-8" />
</component>
</project>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/main/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_10" project-jdk-name="10" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,50 +1,73 @@
language: java
sudo: required
dist: trusty
sudo: false
jdk:
- oraclejdk8
- oraclejdk9
cache:
directories:
- $HOME/.m2
env:
global:
- secure: "IfYURwZaDWuBDvyn47n0k1Zod/IQw1FF+CS5nnV08Q+NfC3vGGJMwV8m59XnbfwnWGxwvCaAbk4qP6s6+ijgZNKkvgfFMo3rfTok5zt43bIqgaFOANYV+OC/1c59gYD6ZUxhW5iNgMgU3qdsRtJuwSmfkVv/jKyLGfAbS4kN8BA=" # COVERITY_SCAN_TOKEN
- secure: "lV9OwUbHMrMpLUH1CY+Z4puLDdFXytudyPlG1eGRsesdpuG6KM3uQVz6uAtf6lrU8DRbMM/T7ML+PmvQ4UoPPYLdLxESLLBat2qUPOIVBOhTSlCc7I0DmGy04CSvkeMy8dPaQC0ukgNiR7zwoNzfcpGRN/U9S8tziDruuHoZSrg=" # BINTRAY_API_KEY
- secure: "HftEaabMmWn5GwKFKksUkOcelc3Mn7xazwAEy+4d4gL1+F8VhID/6DCK7nas+afUymWnxTano8Rv4Ci5MWryNkNkTH+FUPWmF3xWezc3hajSyS7RB92IZ8VPetl4Fo8UI1WwM5apDEaugalPxkIf8a7N+lpG5X/Gpumwzo3Be3w=" # BINTRAY_API_KEY
- secure: "oWFgRTVP6lyTa7qVxlvkpm20MtVc3BtmsNXQJS6bfg2A0o/iCQMNx7OD59BaafCLGRKvCcJVESiC8FlSylVMS7CDSyYu0gg70NUiIuHp4NBM5inFWYCy/PdQsCTzr5uvNG+rMFQpMFRaCV0FrfM3tLondcVkhsHL68l93Xoexx4=" # CODACY_PROJECT_TOKEN
- secure: "zJxgytA2Ks5Xzv+7kUaUq+EBFNQw9Qec63lcMJVuXVWczjL16nKW1EzzV515ag+OWL46z3lEPForDhufw0VtFnNmaX68jkO0mp01eLrHApc1llN2Y/U8GBXfNNazN4+Kom4H+z/AO+wJr8EsKMMUczCdQ3APgd9uVI0hzXw/Z3M=" # GITHUB_API_KEY
addons:
coverity_scan:
project:
name: "cryptomator/cryptomator"
notification_email: sebastian.stenzel@cryptomator.org
build_command: "mvn -fmain/pom.xml clean test -DskipTests"
branch_pattern: release.*
apt:
packages:
- haveged
install:
# "clean" needed until https://bugs.openjdk.java.net/browse/JDK-8067747 is resolved.
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Pcoverage
- mvn -fmain/pom.xml clean package -DskipTests dependency:go-offline -Prelease
- curl -o $HOME/.m2/settings.xml https://gist.githubusercontent.com/cryptobot/cf5fbd909c4782aaeeeb7c7f4a1a43da/raw/e60ee486e34ee0c79f89f947abe2c83b4290c6bb/settings.xml
- mvn -fmain/pom.xml clean install -DskipTests org.codehaus.mojo:versions-maven-plugin:help dependency:go-offline -Pcoverage,release # "clean install" needed until we can exclude artifacts currently in the reactor, see https://maven.apache.org/plugins/maven-dependency-plugin/go-offline-mojo.html#excludeReactor and https://issues.apache.org/jira/browse/MDEP-568
script:
- mvn --update-snapshots -fmain/pom.xml clean test jacoco:report verify -Pcoverage
- mvn --update-snapshots -fmain/pom.xml clean test verify -Pcoverage
after_success:
- curl -o ~/codacy-coverage-reporter.jar https://oss.sonatype.org/service/local/repositories/releases/content/com/codacy/codacy-coverage-reporter/4.0.2/codacy-coverage-reporter-4.0.2-assembly.jar
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/commons/target/site/jacoco/jacoco.xml --partial
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/keychain/target/site/jacoco/jacoco.xml --partial
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/ui/target/site/jacoco/jacoco.xml --partial
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar report -l Java -r main/launcher/target/site/jacoco/jacoco.xml --partial
- $JAVA_HOME/bin/java -jar ~/codacy-coverage-reporter.jar final
before_deploy:
- mvn -fmain/pom.xml -Prelease clean package -DskipTests
- |
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)
fi
- mvn -fmain/pom.xml clean package -Prelease -DskipTests
deploy:
- provider: releases
- provider: script # SNAPSHOTS
skip_cleanup: true
script: >-
curl -T main/ant-kit/target/antkit.zip
-u cryptobot:${BINTRAY_API_KEY}
-H "X-Bintray-Package:ant-kit"
-H "X-Bintray-Version:continuous"
-H "X-Bintray-Override:1"
-H "X-Bintray-Publish:1"
https://api.bintray.com/content/cryptomator/cryptomator/antkit-continuous.zip
on:
repo: cryptomator/cryptomator
branch: develop
condition: $TRAVIS_TAG = ''
- provider: releases # RELEASE
prerelease: false
api_key:
secure: "ZjE1j93v3qbPIe2YbmhS319aCbMdLQw0HuymmluTurxXsZtn9D4t2+eTr99vBVxGRuB5lzzGezPR5zjk5W7iHF7xhwrawXrFzr2rPJWzWFt0aM+Ry2njU1ROTGGXGTbv4anWeBlgMxLEInTAy/9ytOGNJlec83yc0THpOY2wxnk="
api_key: $GITHUB_API_KEY
file:
- "main/uber-jar/target/Cryptomator-$TRAVIS_TAG.jar"
- "main/ant-kit/target/antkit.tar.gz"
- "main/uber-jar/target/Cryptomator-$TRAVIS_TAG.jar"
skip_cleanup: true
on:
repo: cryptomator/cryptomator
tags: true
- provider: script
script: "curl -X POST -u cryptobot:${BINTRAY_API_KEY} -H 'Content-Type: application/json' -d '{\"name\": \"${TRAVIS_TAG}\", \"vcs_tag\": \"${TRAVIS_TAG}\"}' https://api.bintray.com/packages/cryptomator/cryptomator/cryptomator-win/versions"
on:
repo: cryptomator/cryptomator
tags: true
- provider: script
script: "curl -X POST -u cryptobot:${BINTRAY_API_KEY} -H 'Content-Type: application/json' -d '{\"name\": \"${TRAVIS_TAG}\", \"vcs_tag\": \"${TRAVIS_TAG}\"}' https://api.bintray.com/packages/cryptomator/cryptomator/cryptomator-osx/versions"
skip_cleanup: true
script: >-
curl -T main/ant-kit/target/antkit.zip
-u cryptobot:${BINTRAY_API_KEY}
-H "X-Bintray-Package:ant-kit"
-H "X-Bintray-Version:${TRAVIS_TAG}"
-H "X-Bintray-Override:1"
-H "X-Bintray-Publish:1"
https://api.bintray.com/content/cryptomator/cryptomator/antkit-${TRAVIS_TAG}.zip
on:
repo: cryptomator/cryptomator
tags: true

View File

@@ -1,7 +1,7 @@
![cryptomator](cryptomator.png)
[![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&amp;utm_medium=referral&amp;utm_content=cryptomator/cryptomator&amp;utm_campaign=Badge_Grade)
[![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)
@@ -46,8 +46,7 @@ For more information on the security details visit [cryptomator.org](https://cry
### Dependencies
* Java 8 (min. 8u51, we recommend to use the current version)
* [JCE unlimited strength policy files](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) (needed for 256-bit keys)
* Java 10 (min. 10.0.1, we recommend to use the current version)
* Maven 3
* Optional: OS-dependent build tools for native packaging (see [Windows](https://github.com/cryptomator/cryptomator-win), [OS X](https://github.com/cryptomator/cryptomator-osx), [Linux](https://github.com/cryptomator/builder-containers))

View File

@@ -1,10 +1,10 @@
<?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"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<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/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>tarball</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>tar.gz</format>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
@@ -29,6 +29,7 @@
<directory>target</directory>
<includes>
<include>build.xml</include>
<include>logback.xml</include>
</includes>
<filtered>false</filtered>
<outputDirectory>.</outputDirectory>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
<version>1.4.1</version>
</parent>
<artifactId>ant-kit</artifactId>
<packaging>pom</packaging>
@@ -56,15 +56,15 @@
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>fixed-binaries/**</exclude>
</excludes>
<includes>
<include>build.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>fixed-binaries/**</include>
<include>logback.xml</include>
</includes>
</resource>
</resources>
@@ -73,10 +73,10 @@
</executions>
</plugin>
<!-- create antkit.tar.gz: -->
<!-- create antkit.zip: -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<version>3.1.0</version>
<executions>
<execution>
<id>make-assembly</id>

View File

@@ -1,12 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 -->
<fx:application id="Cryptomator" name="Cryptomator" version="${project.version}" mainClass="org.cryptomator.launcher.Cryptomator" />
<!-- Print build environment properties -->
<target name="check-env">
<echoproperties/>
</target>
<!-- Create main application jar -->
<target name="create-jar">
<target name="create-jar" depends="check-env">
<fx:jar destfile="antbuild/Cryptomator-${project.version}.jar">
<fx:application refid="Cryptomator" />
<fx:fileset dir="libs" includes="launcher-${project.version}.jar" />
@@ -20,54 +25,27 @@
</fx:manifest>
</fx:jar>
</target>
<!-- Create Debian package -->
<target name="deb" depends="create-jar">
<fx:deploy nativeBundles="deb" outdir="antbuild" outfile="Cryptomator-${project.version}" verbose="true">
<!-- Create Image -->
<target name="image" depends="create-jar">
<fx:deploy nativeBundles="image" outdir="antbuild" verbose="true">
<fx:application refid="Cryptomator" />
<fx:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="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:info title="Cryptomator" vendor="cryptomator.org" copyright="cryptomator.org" license="GPL" category="Utility"/>
<fx:platform j2se="10">
<fx:property name="logback.configurationFile" value="\${antbuild.logback.configurationFile}" />
<fx:property name="cryptomator.settingsPath" value="\${antbuild.cryptomator.settingsPath}" />
<fx:property name="cryptomator.ipcPortPath" value="\${antbuild.cryptomator.ipcPortPath}" />
<fx:property name="cryptomator.keychainPath" value="\${antbuild.cryptomator.keychainPath}"/>
<fx:jvmarg value="-Xss2m"/>
<fx:jvmarg value="-Xmx512m"/>
</fx: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: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:permissions elevated="false" />
<fx:preferences install="true" />
<fx:bundleArgument arg="dropinResourcesRoot" value="\${antbuild.dropinResourcesRoot}"/>
</fx:deploy>
</target>

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xml>
<configuration scan="true" debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${user.home}/.Cryptomator/cryptomator.log</file>
<append>false</append>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${user.home}/.Cryptomator/cryptomator%i.log</fileNamePattern>
<minIndex>0</minIndex>
<maxIndex>9</maxIndex>
</rollingPolicy>
<triggeringPolicy class="org.cryptomator.logging.LaunchBasedTriggeringPolicy" />
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="UPGRADE_FILE" class="ch.qos.logback.core.FileAppender">
<file>${user.home}/.Cryptomator/upgrade.log</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.cryptomator" level="INFO" />
<logger name="org.eclipse.jetty.server.HttpChannel" level="INFO" />
<logger name="org.cryptomator.ui.model" level="INFO">
<appender-ref ref="UPGRADE_FILE" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
<version>1.4.1</version>
</parent>
<artifactId>commons</artifactId>
<name>Cryptomator Commons</name>
@@ -34,15 +34,6 @@
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
</dependency>
<!-- Logging -->
<dependency>

View File

@@ -2,41 +2,41 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
******************************************************************************/
package org.cryptomator.common.settings;
import java.util.function.Consumer;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import java.util.function.Consumer;
public class Settings {
public static final int MIN_PORT = 1024;
public static final int MAX_PORT = 65535;
public static final boolean DEFAULT_CHECK_FOR_UDPATES = true;
public static final boolean DEFAULT_ASKED_FOR_UPDATE_CHECK = false;
public static final boolean DEFAULT_CHECK_FOR_UDPATES = false;
public static final int DEFAULT_PORT = 42427;
public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final String DEFAULT_GVFS_SCHEME = "dav";
public static final boolean DEFAULT_DEBUG_MODE = false;
public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = System.getProperty("os.name").toLowerCase().contains("windows") ? VolumeImpl.DOKANY : VolumeImpl.FUSE;
private final ObservableList<VaultSettings> directories = FXCollections.observableArrayList(VaultSettings::observables);
private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK);
private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES);
private final IntegerProperty port = new SimpleIntegerProperty(DEFAULT_PORT);
private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS);
private final StringProperty preferredGvfsScheme = new SimpleStringProperty(DEFAULT_GVFS_SCHEME);
private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE);
private final ObjectProperty<VolumeImpl> preferredVolumeImpl = new SimpleObjectProperty<>(DEFAULT_PREFERRED_VOLUME_IMPL);
private Consumer<Settings> saveCmd;
/**
@@ -44,11 +44,13 @@ public class Settings {
*/
Settings() {
directories.addListener((ListChangeListener.Change<? extends VaultSettings> change) -> this.save());
askedForUpdateCheck.addListener(this::somethingChanged);
checkForUpdates.addListener(this::somethingChanged);
port.addListener(this::somethingChanged);
numTrayNotifications.addListener(this::somethingChanged);
preferredGvfsScheme.addListener(this::somethingChanged);
debugMode.addListener(this::somethingChanged);
preferredVolumeImpl.addListener(this::somethingChanged);
}
void setSaveCmd(Consumer<Settings> saveCmd) {
@@ -71,6 +73,10 @@ public class Settings {
return directories;
}
public BooleanProperty askedForUpdateCheck() {
return askedForUpdateCheck;
}
public BooleanProperty checkForUpdates() {
return checkForUpdates;
}
@@ -91,4 +97,8 @@ public class Settings {
return debugMode;
}
public ObjectProperty<VolumeImpl> preferredVolumeImpl() {
return preferredVolumeImpl;
}
}

View File

@@ -5,17 +5,16 @@
*******************************************************************************/
package org.cryptomator.common.settings;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class SettingsJsonAdapter extends TypeAdapter<Settings> {
@@ -28,11 +27,13 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
out.beginObject();
out.name("directories");
writeVaultSettingsArray(out, value.getDirectories());
out.name("askedForUpdateCheck").value(value.askedForUpdateCheck().get());
out.name("checkForUpdatesEnabled").value(value.checkForUpdates().get());
out.name("port").value(value.port().get());
out.name("numTrayNotifications").value(value.numTrayNotifications().get());
out.name("preferredGvfsScheme").value(value.preferredGvfsScheme().get());
out.name("debugMode").value(value.debugMode().get());
out.name("preferredVolumeImpl").value(value.preferredVolumeImpl().get().name());
out.endObject();
}
@@ -52,27 +53,33 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
while (in.hasNext()) {
String name = in.nextName();
switch (name) {
case "directories":
settings.getDirectories().addAll(readVaultSettingsArray(in));
break;
case "checkForUpdatesEnabled":
settings.checkForUpdates().set(in.nextBoolean());
break;
case "port":
settings.port().set(in.nextInt());
break;
case "numTrayNotifications":
settings.numTrayNotifications().set(in.nextInt());
break;
case "preferredGvfsScheme":
settings.preferredGvfsScheme().set(in.nextString());
break;
case "debugMode":
settings.debugMode().set(in.nextBoolean());
break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
case "directories":
settings.getDirectories().addAll(readVaultSettingsArray(in));
break;
case "askedForUpdateCheck":
settings.askedForUpdateCheck().set(in.nextBoolean());
break;
case "checkForUpdatesEnabled":
settings.checkForUpdates().set(in.nextBoolean());
break;
case "port":
settings.port().set(in.nextInt());
break;
case "numTrayNotifications":
settings.numTrayNotifications().set(in.nextInt());
break;
case "preferredGvfsScheme":
settings.preferredGvfsScheme().set(in.nextString());
break;
case "debugMode":
settings.debugMode().set(in.nextBoolean());
break;
case "preferredVolumeImpl":
settings.preferredVolumeImpl().set(parsePreferredVolumeImplName(in.nextString()));
break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
}
}
in.endObject();
@@ -80,6 +87,14 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
return settings;
}
private VolumeImpl parsePreferredVolumeImplName(String nioAdapterName) {
try {
return VolumeImpl.valueOf(nioAdapterName);
} catch (IllegalArgumentException e) {
return Settings.DEFAULT_PREFERRED_VOLUME_IMPL;
}
}
private List<VaultSettings> readVaultSettingsArray(JsonReader in) throws IOException {
List<VaultSettings> result = new ArrayList<>();
in.beginArray();

View File

@@ -5,16 +5,6 @@
*******************************************************************************/
package org.cryptomator.common.settings;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Base64;
import java.util.Objects;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.fxmisc.easybind.EasyBind;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
@@ -22,20 +12,34 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.apache.commons.lang3.StringUtils;
import org.fxmisc.easybind.EasyBind;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Base64;
import java.util.Objects;
import java.util.UUID;
/**
* The settings specific to a single vault.
* TODO: Change the name of individualMountPath and its derivatives to customMountPath
*/
public class VaultSettings {
public static final boolean DEFAULT_UNLOCK_AFTER_STARTUP = false;
public static final boolean DEFAULT_MOUNT_AFTER_UNLOCK = true;
public static final boolean DEFAULT_REAVEAL_AFTER_MOUNT = true;
public static final boolean DEFAULT_USES_INDIVIDUAL_MOUNTPATH = false;
private final String id;
private final ObjectProperty<Path> path = new SimpleObjectProperty<>();
private final StringProperty mountName = new SimpleStringProperty();
private final StringProperty winDriveLetter = new SimpleStringProperty();
private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP);
private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty(DEFAULT_MOUNT_AFTER_UNLOCK);
private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REAVEAL_AFTER_MOUNT);
private final BooleanProperty usesIndividualMountPath = new SimpleBooleanProperty(DEFAULT_USES_INDIVIDUAL_MOUNTPATH);
private final StringProperty individualMountPath = new SimpleStringProperty();
public VaultSettings(String id) {
this.id = Objects.requireNonNull(id);
@@ -44,7 +48,7 @@ public class VaultSettings {
}
Observable[] observables() {
return new Observable[] {path, mountName, winDriveLetter, unlockAfterStartup, mountAfterUnlock, revealAfterMount};
return new Observable[]{path, mountName, winDriveLetter, unlockAfterStartup, revealAfterMount, usesIndividualMountPath, individualMountPath};
}
private void deriveMountNameFromPath(Path path) {
@@ -115,14 +119,18 @@ public class VaultSettings {
return unlockAfterStartup;
}
public BooleanProperty mountAfterUnlock() {
return mountAfterUnlock;
}
public BooleanProperty revealAfterMount() {
return revealAfterMount;
}
public BooleanProperty usesIndividualMountPath() {
return usesIndividualMountPath;
}
public StringProperty individualMountPath() {
return individualMountPath;
}
/* Hashcode/Equals */
@Override

View File

@@ -5,14 +5,13 @@
*******************************************************************************/
package org.cryptomator.common.settings;
import java.io.IOException;
import java.nio.file.Paths;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.nio.file.Paths;
class VaultSettingsJsonAdapter {
@@ -25,8 +24,9 @@ class VaultSettingsJsonAdapter {
out.name("mountName").value(value.mountName().get());
out.name("winDriveLetter").value(value.winDriveLetter().get());
out.name("unlockAfterStartup").value(value.unlockAfterStartup().get());
out.name("mountAfterUnlock").value(value.mountAfterUnlock().get());
out.name("revealAfterMount").value(value.revealAfterMount().get());
out.name("usesIndividualMountPath").value(value.usesIndividualMountPath().get());
out.name("individualMountPath").value(value.individualMountPath().get()); //TODO: should this always be written? ( because it could contain metadata, which the user may not want to save!)
out.endObject();
}
@@ -34,39 +34,43 @@ class VaultSettingsJsonAdapter {
String id = null;
String path = null;
String mountName = null;
String individualMountPath = null;
String winDriveLetter = null;
boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP;
boolean mountAfterUnlock = VaultSettings.DEFAULT_MOUNT_AFTER_UNLOCK;
boolean revealAfterMount = VaultSettings.DEFAULT_REAVEAL_AFTER_MOUNT;
boolean usesIndividualMountPath = VaultSettings.DEFAULT_USES_INDIVIDUAL_MOUNTPATH;
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
switch (name) {
case "id":
id = in.nextString();
break;
case "path":
path = in.nextString();
break;
case "mountName":
mountName = in.nextString();
break;
case "winDriveLetter":
winDriveLetter = in.nextString();
break;
case "unlockAfterStartup":
unlockAfterStartup = in.nextBoolean();
break;
case "mountAfterUnlock":
mountAfterUnlock = in.nextBoolean();
break;
case "revealAfterMount":
revealAfterMount = in.nextBoolean();
break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
case "id":
id = in.nextString();
break;
case "path":
path = in.nextString();
break;
case "mountName":
mountName = in.nextString();
break;
case "winDriveLetter":
winDriveLetter = in.nextString();
break;
case "unlockAfterStartup":
unlockAfterStartup = in.nextBoolean();
break;
case "revealAfterMount":
revealAfterMount = in.nextBoolean();
break;
case "usesIndividualMountPath":
usesIndividualMountPath = in.nextBoolean();
break;
case "individualMountPath":
individualMountPath = in.nextString();
break;
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
}
}
in.endObject();
@@ -76,8 +80,9 @@ class VaultSettingsJsonAdapter {
vaultSettings.path().set(Paths.get(path));
vaultSettings.winDriveLetter().set(winDriveLetter);
vaultSettings.unlockAfterStartup().set(unlockAfterStartup);
vaultSettings.mountAfterUnlock().set(mountAfterUnlock);
vaultSettings.revealAfterMount().set(revealAfterMount);
vaultSettings.usesIndividualMountPath().set(usesIndividualMountPath);
vaultSettings.individualMountPath().set(individualMountPath);
return vaultSettings;
}

View File

@@ -0,0 +1,34 @@
package org.cryptomator.common.settings;
import java.util.Arrays;
public enum VolumeImpl {
WEBDAV("WebDAV"),
FUSE("FUSE"),
DOKANY("Dokany");
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);
}
}

View File

@@ -21,17 +21,17 @@ public class SettingsJsonAdapterTest {
String json = "{\"directories\": [" + vault1Json + "," + vault2Json + "]," //
+ "\"checkForUpdatesEnabled\": true,"//
+ "\"port\": 8080,"//
+ "\"useIpv6\": true,"//
+ "\"numTrayNotifications\": 42}";
+ "\"numTrayNotifications\": 42,"//
+ "\"preferredVolumeImpl\": \"FUSE\"}";
Settings settings = adapter.fromJson(json);
Assert.assertTrue(settings.checkForUpdates().get());
Assert.assertEquals(2, settings.getDirectories().size());
Assert.assertEquals(8080, settings.port().get());
// Assert.assertTrue(settings.useIpv6().get()); temporarily ignored
Assert.assertEquals(42, settings.numTrayNotifications().get());
Assert.assertEquals("dav", settings.preferredGvfsScheme().get());
Assert.assertEquals(VolumeImpl.FUSE, settings.preferredVolumeImpl().get());
}
}

View File

@@ -20,7 +20,7 @@ public class VaultSettingsJsonAdapterTest {
@Test
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));
VaultSettings vaultSettings = adapter.read(jsonReader);
@@ -28,6 +28,7 @@ public class VaultSettingsJsonAdapterTest {
Assert.assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get());
Assert.assertEquals("test", vaultSettings.mountName().get());
Assert.assertEquals("X", vaultSettings.winDriveLetter().get());
Assert.assertEquals("/home/test/crypto", vaultSettings.individualMountPath().get());
}
}

View File

@@ -1 +0,0 @@
/target/

View File

@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
</parent>
<artifactId>jacoco-report</artifactId>
<name>Cryptomator Code Coverage Report</name>
<packaging>pom</packaging>
<dependencies>
<!-- all modules containing unit tests: -->
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>commons</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>keychain</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>ui</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>launcher</artifactId>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>report-aggregate</id>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
<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>
</build>
</project>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
<version>1.4.1</version>
</parent>
<artifactId>keychain</artifactId>
<name>System Keychain Access</name>
@@ -34,10 +34,6 @@
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
</dependency>
<!-- Logging -->
<dependency>

View File

@@ -8,17 +8,27 @@ package org.cryptomator.keychain;
import java.util.Optional;
import java.util.Set;
import org.cryptomator.jni.JniModule;
import com.google.common.collect.Sets;
import dagger.Module;
import dagger.Provides;
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 {
@Provides
Optional<MacFunctions> provideOptionalMacFunctions() {
return JniFunctions.macFunctions();
}
@Provides
Optional<WinFunctions> provideOptionalWinFunctions() {
return JniFunctions.winFunctions();
}
@Provides
@ElementsIntoSet
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) {

View File

@@ -15,35 +15,35 @@ import org.cryptomator.jni.MacKeychainAccess;
class MacSystemKeychainAccess implements KeychainAccessStrategy {
private final MacKeychainAccess keychain;
private final Optional<MacFunctions> macFunctions;
@Inject
public MacSystemKeychainAccess(Optional<MacFunctions> macFunctions) {
if (macFunctions.isPresent()) {
this.keychain = macFunctions.get().keychainAccess();
} else {
this.keychain = null;
}
this.macFunctions = macFunctions;
}
private MacKeychainAccess keychain() {
return macFunctions.orElseThrow(IllegalStateException::new).keychainAccess();
}
@Override
public void storePassphrase(String key, CharSequence passphrase) {
keychain.storePassword(key, passphrase);
keychain().storePassword(key, passphrase);
}
@Override
public char[] loadPassphrase(String key) {
return keychain.loadPassword(key);
return keychain().loadPassword(key);
}
@Override
public boolean isSupported() {
return SystemUtils.IS_OS_MAC_OSX && keychain != null;
return SystemUtils.IS_OS_MAC_OSX && macFunctions.isPresent();
}
@Override
public void deletePassphrase(String key) {
keychain.deletePassword(key);
keychain().deletePassword(key);
}
}

View File

@@ -5,8 +5,6 @@
*******************************************************************************/
package org.cryptomator.keychain;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -31,12 +29,6 @@ import java.util.UUID;
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.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -49,6 +41,13 @@ import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.annotations.SerializedName;
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 {
@@ -57,19 +56,15 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
.registerTypeHierarchyAdapter(byte[].class, new ByteArrayJsonAdapter()) //
.disableHtmlEscaping().create();
private final WinDataProtection dataProtection;
private final Optional<WinFunctions> winFunctions;
private final Path keychainPath;
private Map<String, KeychainEntry> keychainEntries;
@Inject
public WindowsProtectedKeychainAccess(Optional<WinFunctions> winFunctions) {
if (winFunctions.isPresent()) {
this.dataProtection = winFunctions.get().dataProtection();
} else {
this.dataProtection = null;
}
this.winFunctions = winFunctions;
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.");
}
if (keychainPathProperty != null) {
@@ -82,6 +77,10 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
}
}
private WinDataProtection dataProtection() {
return winFunctions.orElseThrow(IllegalStateException::new).dataProtection();
}
@Override
public void storePassphrase(String key, CharSequence passphrase) {
loadKeychainEntriesIfNeeded();
@@ -90,7 +89,7 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
buf.get(cleartext);
KeychainEntry entry = new KeychainEntry();
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(cleartext, (byte) 0x00);
keychainEntries.put(key, entry);
@@ -104,7 +103,7 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
if (entry == null) {
return null;
}
byte[] cleartext = dataProtection.unprotect(entry.ciphertext, entry.salt);
byte[] cleartext = dataProtection().unprotect(entry.ciphertext, entry.salt);
if (cleartext == null) {
return null;
}
@@ -125,7 +124,7 @@ class WindowsProtectedKeychainAccess implements KeychainAccessStrategy {
@Override
public boolean isSupported() {
return SystemUtils.IS_OS_WINDOWS && dataProtection != null && keychainPath != null;
return SystemUtils.IS_OS_WINDOWS && winFunctions.isPresent() && keychainPath != null;
}
private byte[] generateSalt() {

View File

@@ -14,9 +14,11 @@ public class KeychainModuleTest {
@Test
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.get() instanceof MapKeychainAccess);
keychainAccess.get().storePassphrase("test", "asd");
Assert.assertArrayEquals("asd".toCharArray(), keychainAccess.get().loadPassphrase("test"));
}
}

View File

@@ -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();
}
}

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
<version>1.4.1</version>
</parent>
<artifactId>launcher</artifactId>
<name>Cryptomator Launcher</name>
@@ -34,10 +34,6 @@
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
</dependency>
<!-- Logging -->
<dependency>

View File

@@ -37,6 +37,8 @@ public class Cryptomator {
}
} catch (IOException e) {
LOG.error("Failed to initiate inter-process communication.", e);
} catch (Throwable e) {
LOG.error("Error during startup", e);
}
System.exit(0); // end remaining non-daemon threads.
}

View File

@@ -6,6 +6,7 @@
*******************************************************************************/
package org.cryptomator.launcher;
import java.awt.Desktop;
import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
@@ -13,7 +14,6 @@ import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.concurrent.BlockingQueue;
import org.cryptomator.ui.util.EawtApplicationWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -24,11 +24,13 @@ class FileOpenRequestHandler {
public FileOpenRequestHandler(BlockingQueue<Path> fileOpenRequests) {
this.fileOpenRequests = fileOpenRequests;
EawtApplicationWrapper.getApplication().ifPresent(app -> {
app.setOpenFileHandler(files -> {
files.stream().map(File::toPath).forEach(fileOpenRequests::add);
try {
Desktop.getDesktop().setOpenFileHandler(e -> {
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) {

View File

@@ -5,25 +5,23 @@
*******************************************************************************/
package org.cryptomator.launcher;
import javafx.application.Application;
import javafx.stage.Stage;
import org.cryptomator.ui.controllers.MainController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
public class MainApplication extends Application {
private static final Logger LOG = LoggerFactory.getLogger(MainApplication.class);
private Stage primaryStage;
@Override
public void start(Stage primaryStage) throws Exception {
public void start(Stage primaryStage) {
LOG.info("JavaFX application started.");
this.primaryStage = primaryStage;
setupFXMLClassLoader();
primaryStage.setMinWidth(652.0);
primaryStage.setMinHeight(440.0);
LauncherModule launcherModule = new LauncherModule(this, primaryStage);
LauncherComponent launcherComponent = DaggerLauncherComponent.builder() //
@@ -34,30 +32,14 @@ public class MainApplication extends Application {
MainController mainCtrl = launcherComponent.fxmlLoader().load("/fxml/main.fxml");
mainCtrl.initStage(primaryStage);
primaryStage.show();
}
@Override
public void stop() throws Exception {
public void stop() {
assert primaryStage != null;
primaryStage.hide();
LOG.info("JavaFX application stopped.");
}
// fix discussed in https://github.com/cryptomator/cryptomator/pull/29
private void setupFXMLClassLoader() {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
FXMLLoader.setDefaultClassLoader(contextClassLoader);
Platform.runLater(() -> {
/*
* This fixes a bug on OSX where the magic file open handler leads to no context class loader being set in the AppKit (event)
* thread if the application is not started opening a file.
*/
if (Thread.currentThread().getContextClassLoader() == null) {
Thread.currentThread().setContextClassLoader(contextClassLoader);
}
});
}
}

View File

@@ -32,7 +32,6 @@ public class FileOpenRequestHandlerTest {
Mockito.when(fs.provider()).thenReturn(provider);
Mockito.when(fs.getPath(Mockito.anyString())).thenReturn(p1, p2);
Mockito.when(provider.readAttributes(Mockito.any(), Mockito.eq(BasicFileAttributes.class))).thenReturn(attrs);
Mockito.when(attrs.isRegularFile()).thenReturn(true);
BlockingQueue<Path> queue = new ArrayBlockingQueue<>(10);
FileOpenRequestHandler handler = new FileOpenRequestHandler(queue);

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
<version>1.4.1</version>
<packaging>pom</packaging>
<name>Cryptomator</name>
@@ -24,27 +24,28 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- dependency versions -->
<cryptomator.cryptolib.version>1.1.7</cryptomator.cryptolib.version>
<cryptomator.cryptofs.version>1.4.5</cryptomator.cryptofs.version>
<cryptomator.webdav.version>1.0.3</cryptomator.webdav.version>
<cryptomator.jni.version>1.0.2</cryptomator.jni.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang3.version>3.6</commons-lang3.version>
<httpclient.version>4.5.3</httpclient.version>
<cryptomator.cryptolib.version>1.2.1</cryptomator.cryptolib.version>
<cryptomator.cryptofs.version>1.6.2</cryptomator.cryptofs.version>
<cryptomator.jni.version>2.0.0</cryptomator.jni.version>
<cryptomator.fuse.version>1.0.3</cryptomator.fuse.version>
<cryptomator.dokany.version>1.1.1</cryptomator.dokany.version>
<cryptomator.webdav.version>1.0.5</cryptomator.webdav.version>
<commons-io.version>2.6</commons-io.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<easybind.version>1.0.3</easybind.version>
<guava.version>23.5-jre</guava.version>
<dagger.version>2.11</dagger.version>
<gson.version>2.8.2</gson.version>
<guava.version>27.0-jre</guava.version>
<dagger.version>2.20</dagger.version>
<gson.version>2.8.5</gson.version>
<slf4j.version>1.7.25</slf4j.version>
<logback.version>1.2.3</logback.version>
<junit.version>4.12</junit.version>
<junit.hierarchicalrunner.version>4.12.1</junit.hierarchicalrunner.version>
<mockito.version>2.11.0</mockito.version>
<mockito.version>2.23.0</mockito.version>
<hamcrest.version>1.3</hamcrest.version> <!-- keep in sync with version required by JUnit -->
</properties>
@@ -59,6 +60,10 @@
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>jcenter</id>
<url>http://jcenter.bintray.com</url>
</repository>
</repositories>
<dependencyManagement>
@@ -96,6 +101,16 @@
<artifactId>cryptofs</artifactId>
<version>${cryptomator.cryptofs.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>fuse-nio-adapter</artifactId>
<version>${cryptomator.fuse.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>dokany-nio-adapter</artifactId>
<version>${cryptomator.dokany.version}</version>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId>
@@ -140,11 +155,6 @@
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<!-- EasyBind -->
<dependency>
@@ -164,12 +174,6 @@
<artifactId>dagger</artifactId>
<version>${dagger.version}</version>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>${dagger.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
@@ -251,9 +255,6 @@
</profile>
<profile>
<id>coverage</id>
<modules>
<module>jacoco-report</module>
</modules>
<build>
<plugins>
<plugin>
@@ -270,7 +271,7 @@
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-libs</id>
@@ -287,7 +288,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
<version>0.8.2</version>
<executions>
<execution>
<id>prepare-agent</id>
@@ -295,6 +296,12 @@
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
@@ -308,10 +315,16 @@
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<release>9</release>
<annotationProcessorPaths>
<path>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
<version>${dagger.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
<version>1.4.1</version>
</parent>
<artifactId>uber-jar</artifactId>
<name>Single über jar with all dependencies</name>

View File

@@ -4,33 +4,42 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.3.2</version>
<version>1.4.1</version>
</parent>
<artifactId>ui</artifactId>
<name>Cryptomator GUI</name>
<dependencies>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>keychain</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>commons</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>cryptofs</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>jni</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>keychain</artifactId>
<artifactId>fuse-nio-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>dokany-nio-adapter</artifactId>
</dependency>
<dependency>
<groupId>org.cryptomator</groupId>
<artifactId>webdav-nio-adapter</artifactId>
</dependency>
<!-- CryptoLib -->
<dependency>
<groupId>org.cryptomator</groupId>
@@ -62,20 +71,12 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- DI -->
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger</artifactId>
</dependency>
<dependency>
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
</dependency>
<!-- Zxcvbn -->
<dependency>

View File

@@ -53,6 +53,7 @@ public class ExitUtil {
private final Localization localization;
private final Settings settings;
private final Optional<MacFunctions> macFunctions;
private TrayIcon trayIcon;
@Inject
public ExitUtil(@Named("mainWindow") Stage mainWindow, Localization localization, Settings settings, Optional<MacFunctions> macFunctions) {
@@ -82,7 +83,7 @@ public class ExitUtil {
}
private void initTrayIconExitHandler(Runnable exitCommand) {
final TrayIcon trayIcon = createTrayIcon(exitCommand);
trayIcon = createTrayIcon(exitCommand);
try {
// double clicking tray icon should open Cryptomator
if (SystemUtils.IS_OS_WINDOWS) {
@@ -118,14 +119,7 @@ public class ExitUtil {
exitItem.addActionListener(e -> exitCommand.run());
popup.add(exitItem);
final Image image;
if (SystemUtils.IS_OS_MAC_OSX && isMacMenuBarDarkMode()) {
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/tray_icon_mac_white.png"));
} else if (SystemUtils.IS_OS_MAC_OSX) {
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/tray_icon_mac_black.png"));
} else {
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/tray_icon.png"));
}
final Image image = getAppropriateTrayIconImage(true);
return new TrayIcon(image, localization.getString("app.name"), popup);
}
@@ -202,4 +196,23 @@ public class ExitUtil {
});
}
public void updateTrayIcon(boolean areAllVaultsLocked) {
if (trayIcon != null) {
Image image = getAppropriateTrayIconImage(areAllVaultsLocked);
trayIcon.setImage(image);
}
}
private Image getAppropriateTrayIconImage(boolean areAllVaultsLocked) {
String resourceName;
if (SystemUtils.IS_OS_MAC_OSX && isMacMenuBarDarkMode()) {
resourceName = areAllVaultsLocked ? "/tray_icon_mac_white.png" : "/tray_icon_unlocked_mac_white.png";
} else if (SystemUtils.IS_OS_MAC_OSX) {
resourceName = areAllVaultsLocked ? "/tray_icon_mac_black.png" : "/tray_icon_unlocked_mac_black.png";
} else {
resourceName = areAllVaultsLocked ? "/tray_icon.png" : "/tray_icon_unlocked.png";
}
return Toolkit.getDefaultToolkit().getImage(getClass().getResource(resourceName));
}
}

View File

@@ -11,39 +11,61 @@ package org.cryptomator.ui;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import javafx.beans.binding.Binding;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.CommonsModule;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.jni.JniModule;
import org.cryptomator.keychain.KeychainModule;
import org.cryptomator.ui.controllers.ViewControllerModule;
import org.cryptomator.ui.model.VaultComponent;
import org.fxmisc.easybind.EasyBind;
import dagger.Module;
import dagger.Provides;
import javafx.beans.binding.Binding;
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class, JniModule.class}, subcomponents = {VaultComponent.class})
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class}, subcomponents = {VaultComponent.class})
public class UiModule {
private static final int NUM_SCHEDULER_THREADS = 4;
@Provides
@Singleton
Settings provideSettings(SettingsProvider settingsProvider) {
return settingsProvider.get();
}
@Provides
@Singleton
ScheduledExecutorService provideScheduledExecutorService(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
final AtomicInteger threadNumber = new AtomicInteger(1);
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(NUM_SCHEDULER_THREADS, r -> {
Thread t = new Thread(r);
t.setName("Scheduler Thread " + threadNumber.getAndIncrement());
t.setDaemon(true);
return t;
});
shutdownTaskScheduler.accept(executorService::shutdown);
return executorService;
}
@Provides
@Singleton
ExecutorService provideExecutorService(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
ExecutorService executorService = Executors.newCachedThreadPool();
final AtomicInteger threadNumber = new AtomicInteger(1);
ExecutorService executorService = Executors.newCachedThreadPool(r -> {
Thread t = new Thread(r);
t.setName("Background Thread " + threadNumber.getAndIncrement());
t.setDaemon(true);
return t;
});
shutdownTaskScheduler.accept(executorService::shutdown);
return executorService;
}

View File

@@ -2,15 +2,14 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
* Jean-Noël Charon - confirmation dialog on vault removal
******************************************************************************/
package org.cryptomator.ui.controllers;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildErrorDialog;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -28,25 +27,6 @@ import javax.inject.Inject;
import javax.inject.Named;
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.Platform;
import javafx.beans.binding.Binding;
@@ -81,6 +61,25 @@ import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
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
public class MainController implements ViewController {
@@ -111,7 +110,7 @@ public class MainController implements ViewController {
@Inject
public MainController(@Named("mainWindow") Stage mainWindow, ExecutorService executorService, @Named("fileOpenRequests") BlockingQueue<Path> fileOpenRequests, ExitUtil exitUtil, Localization localization,
VaultFactory vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, VaultList vaults, AutoUnlocker autoUnlocker) {
VaultFactory vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, VaultList vaults, AutoUnlocker autoUnlocker) {
this.mainWindow = mainWindow;
this.executorService = executorService;
this.fileOpenRequests = fileOpenRequests;
@@ -126,14 +125,17 @@ public class MainController implements ViewController {
this.upgradeStrategyForSelectedVault = EasyBind.monadic(selectedVault).map(upgradeStrategies::getUpgradeStrategy);
this.areAllVaultsLocked = Bindings.isEmpty(FXCollections.observableList(vaults, Vault::observables).filtered(Vault.NOT_LOCKED));
EasyBind.subscribe(areAllVaultsLocked, exitUtil::updateTrayIcon);
EasyBind.subscribe(areAllVaultsLocked, Platform::setImplicitExit);
autoUnlocker.unlockAllSilently();
EawtApplicationWrapper.getApplication().ifPresent(app -> {
app.setPreferencesHandler(() -> {
try {
Desktop.getDesktop().setPreferencesHandler(e -> {
Platform.runLater(this::toggleShowSettings);
});
});
} catch (UnsupportedOperationException e) {
LOG.info("Unable to setPreferencesHandler, probably not supported on this OS.");
}
}
@FXML
@@ -169,8 +171,10 @@ public class MainController implements ViewController {
@Override
public void initialize() {
vaultList.setItems(vaults);
vaultList.getSelectionModel().clearSelection();
vaultList.setOnKeyReleased(this::didPressKeyOnList);
vaultList.setCellFactory(this::createDirecoryListCell);
root.setOnKeyReleased(this::didPressKeyOnRoot);
activeController.set(viewControllerLoader.load("/fxml/welcome.fxml"));
selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty());
removeVaultButton.disableProperty().bind(canEditSelectedVault.not());
@@ -191,6 +195,7 @@ public class MainController implements ViewController {
public void initStage(Stage stage) {
stage.setScene(new Scene(getRoot()));
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.setResizable(false);
loadFont("/css/ionicons.ttf");
@@ -200,9 +205,10 @@ public class MainController implements ViewController {
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());
} 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());
} 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());
}
exitUtil.initExitHandler(this::gracefulShutdown);
@@ -211,7 +217,26 @@ public class MainController implements ViewController {
private void gracefulShutdown() {
vaults.filtered(Vault.NOT_LOCKED).forEach(Vault::prepareForShutdown);
Platform.runLater(Platform::exit);
if (!vaults.filtered(Vault.NOT_LOCKED).isEmpty()) {
ButtonType tryAgainButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.tryAgain"));
ButtonType forceShutdownButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.forceShutdown"));
Alert gracefulShutdownDialog = DialogBuilderUtil.buildGracefulShutdownDialog(
localization.getString("main.gracefulShutdown.dialog.title"), localization.getString("main.gracefulShutdown.dialog.header"), localization.getString("main.gracefulShutdown.dialog.content"),
forceShutdownButtonType, ButtonType.CANCEL, forceShutdownButtonType, tryAgainButtonType);
Optional<ButtonType> choice = gracefulShutdownDialog.showAndWait();
choice.ifPresent(btnType -> {
if (tryAgainButtonType.equals(btnType)) {
gracefulShutdown();
} else if (forceShutdownButtonType.equals(btnType)) {
Platform.runLater(Platform::exit);
} else {
return;
}
});
} else {
Platform.runLater(Platform::exit);
}
}
private void loadFont(String resourcePath) {
@@ -308,14 +333,14 @@ public class MainController implements ViewController {
/**
* adds the given directory or selects it if it is already in the list of directories.
*
*
* @param path to a vault directory or masterkey file
*/
public void addVault(final Path path, boolean select) {
final Path vaultPath;
if (path != null && Files.isDirectory(path)) {
vaultPath = path;
} else if (path != null && Files.isRegularFile(path)) {
} else if (path != null && Files.isReadable(path)) {
vaultPath = path.getParent();
} else {
LOG.warn("Ignoring attempt to add vault with invalid path: {}", path);
@@ -390,13 +415,13 @@ public class MainController implements ViewController {
return;
}
if (newValue.getState() != Vault.State.LOCKED) {
this.showUnlockedView(newValue);
this.showUnlockedView(newValue, false);
} else if (!newValue.doesVaultDirectoryExist()) {
this.showNotFoundView();
} else if (newValue.isValidVaultDirectory() && upgradeStrategyForSelectedVault.isPresent()) {
this.showUpgradeView();
} else if (newValue.isValidVaultDirectory()) {
this.showUnlockView();
this.showUnlockView(UnlockController.State.UNLOCKING);
} else {
this.showInitializeView();
}
@@ -408,6 +433,30 @@ public class MainController implements ViewController {
}
}
private void didPressKeyOnRoot(KeyEvent event) {
boolean triggered;
if (SystemUtils.IS_OS_MAC) {
triggered = event.isMetaDown();
} else {
triggered = event.isControlDown() && !event.isAltDown();
}
if (triggered && event.getCode().isDigitKey()) {
int digit = Integer.valueOf(event.getText());
switch (digit) {
case 0: {
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();
@@ -446,7 +495,7 @@ public class MainController implements ViewController {
}
public void didInitialize() {
showUnlockView();
showUnlockView(UnlockController.State.INITIALIZED);
activeController.get().focus();
}
@@ -458,35 +507,38 @@ public class MainController implements ViewController {
}
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");
ctrl.setVault(selectedVault.get());
ctrl.setVault(selectedVault.get(), state);
ctrl.setListener(this::didUnlock);
activeController.set(ctrl);
}
public void didUnlock(Vault vault) {
if (vault.equals(selectedVault.getValue())) {
this.showUnlockedView(vault);
this.showUnlockedView(vault, vault.getVaultSettings().revealAfterMount().getValue());
}
}
private void showUnlockedView(Vault vault) {
final UnlockedController ctrl = unlockedVaults.computeIfAbsent(vault, k -> {
return viewControllerLoader.load("/fxml/unlocked.fxml");
});
private void showUnlockedView(Vault vault, boolean reveal) {
final UnlockedController ctrl = unlockedVaults.computeIfAbsent(vault, k -> viewControllerLoader.load("/fxml/unlocked.fxml"));
ctrl.setVault(vault);
ctrl.setListener(this::didLock);
if (reveal) {
ctrl.revealVault(vault);
}
activeController.set(ctrl);
}
public void didLock(UnlockedController ctrl) {
unlockedVaults.remove(ctrl.getVault());
showUnlockView();
if (ctrl.getVault().getId() == selectedVault.get().getId()) {
showUnlockView(UnlockController.State.UNLOCKING);
}
activeController.get().focus();
}
@@ -499,7 +551,7 @@ public class MainController implements ViewController {
}
public void didChangePassword() {
showUnlockView();
showUnlockView(UnlockController.State.PASSWORD_CHANGED);
activeController.get().focus();
}

View File

@@ -2,28 +2,19 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
******************************************************************************/
package org.cryptomator.ui.controllers;
import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Named;
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.Strings;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
@@ -32,6 +23,17 @@ import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.util.StringConverter;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Volume;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Optional;
@Singleton
public class SettingsController implements ViewController {
@@ -47,11 +49,17 @@ public class SettingsController implements ViewController {
this.localization = localization;
this.settings = settings;
this.applicationVersion = applicationVersion;
this.webdavSettings = new Group();
}
@FXML
private CheckBox checkForUpdatesCheckbox;
private Group webdavSettings;
@FXML
private Label portFieldLabel;
@FXML
private TextField portField;
@@ -67,6 +75,9 @@ public class SettingsController implements ViewController {
@FXML
private ChoiceBox<String> prefGvfsScheme;
@FXML
private ChoiceBox<VolumeImpl> volume;
@FXML
private CheckBox debugModeCheckbox;
@@ -75,22 +86,41 @@ public class SettingsController implements ViewController {
@Override
public void initialize() {
versionLabel.setText(String.format(localization.getString("settings.version.label"), applicationVersion.orElse("SNAPSHOT")));
checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally());
checkForUpdatesCheckbox.setSelected(settings.checkForUpdates().get() && !areUpdatesManagedExternally());
//NIOADAPTER
volume.getItems().addAll(Volume.getCurrentSupportedAdapters());
volume.setValue(settings.preferredVolumeImpl().get());
volume.setConverter(new NioAdapterImplStringConverter());
volume.valueProperty().addListener(this::setVisibilityGvfsElements);
//WEBDAV
webdavSettings.visibleProperty().bind(volume.valueProperty().isEqualTo(VolumeImpl.WEBDAV));
webdavSettings.managedProperty().bind(webdavSettings.visibleProperty());
prefGvfsScheme.managedProperty().bind(webdavSettings.visibleProperty());
prefGvfsSchemeLabel.managedProperty().bind(webdavSettings.visibleProperty());
portFieldLabel.managedProperty().bind(webdavSettings.visibleProperty());
portFieldLabel.visibleProperty().bind(webdavSettings.visibleProperty());
changePortButton.managedProperty().bind(webdavSettings.visibleProperty());
portField.managedProperty().bind(webdavSettings.visibleProperty());
portField.visibleProperty().bind(webdavSettings.visibleProperty());
portField.setText(String.valueOf(settings.port().intValue()));
portField.addEventFilter(KeyEvent.KEY_TYPED, this::filterNumericKeyEvents);
changePortButton.visibleProperty().bind(settings.port().asString().isNotEqualTo(portField.textProperty()));
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("webdav");
prefGvfsScheme.setValue(settings.preferredGvfsScheme().get());
prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX);
prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX);
debugModeCheckbox.setSelected(settings.debugMode().get());
settings.checkForUpdates().bind(checkForUpdatesCheckbox.selectedProperty());
settings.preferredGvfsScheme().bind(prefGvfsScheme.valueProperty());
settings.preferredVolumeImpl().bind(volume.valueProperty());
settings.debugMode().bind(debugModeCheckbox.selectedProperty());
}
@@ -129,8 +159,26 @@ public class SettingsController implements ViewController {
}
}
private void setVisibilityGvfsElements(Observable obs, Object oldValue, Object newValue) {
prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
}
private boolean areUpdatesManagedExternally() {
return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
}
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);
}
}
}

View File

@@ -2,41 +2,14 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
******************************************************************************/
package org.cryptomator.ui.controllers;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
import org.cryptomator.frontend.webdav.ServerLifecycleException;
import org.cryptomator.keychain.KeychainAccess;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.WindowsDriveLetters;
import org.cryptomator.ui.util.AsyncTaskService;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
@@ -56,6 +29,33 @@ import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
import javafx.util.StringConverter;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
import org.cryptomator.frontend.webdav.ServerLifecycleException;
import org.cryptomator.keychain.KeychainAccess;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.InvalidSettingsException;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.WindowsDriveLetters;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.cryptomator.ui.util.Tasks;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
public class UnlockController implements ViewController {
@@ -68,21 +68,23 @@ public class UnlockController implements ViewController {
private final Application app;
private final Localization localization;
private final AsyncTaskService asyncTaskService;
private final WindowsDriveLetters driveLetters;
private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange;
private final Optional<KeychainAccess> keychainAccess;
private final Settings settings;
private final ExecutorService executor;
private Vault vault;
private Optional<UnlockListener> listener = Optional.empty();
private Subscription vaultSubs = Subscription.EMPTY;
@Inject
public UnlockController(Application app, Localization localization, AsyncTaskService asyncTaskService, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess) {
public UnlockController(Application app, Localization localization, WindowsDriveLetters driveLetters, Optional<KeychainAccess> keychainAccess, Settings settings, ExecutorService executor) {
this.app = app;
this.localization = localization;
this.asyncTaskService = asyncTaskService;
this.driveLetters = driveLetters;
this.keychainAccess = keychainAccess;
this.settings = settings;
this.executor = executor;
}
@FXML
@@ -95,10 +97,10 @@ public class UnlockController implements ViewController {
private Button unlockButton;
@FXML
private CheckBox savePassword;
private Label successMessage;
@FXML
private CheckBox mountAfterUnlock;
private CheckBox savePassword;
@FXML
private TextField mountName;
@@ -112,6 +114,15 @@ public class UnlockController implements ViewController {
@FXML
private ChoiceBox<Character> winDriveLetter;
@FXML
private CheckBox useCustomMountPath;
@FXML
private Label customMountPathLabel;
@FXML
private TextField customMountPathField;
@FXML
private ProgressIndicator progressIndicator;
@@ -134,22 +145,41 @@ public class UnlockController implements ViewController {
public void initialize() {
advancedOptions.managedProperty().bind(advancedOptions.visibleProperty());
unlockButton.disableProperty().bind(passwordField.textProperty().isEmpty());
mountName.disableProperty().bind(mountAfterUnlock.selectedProperty().not());
revealAfterMount.disableProperty().bind(mountAfterUnlock.selectedProperty().not());
mountName.addEventFilter(KeyEvent.KEY_TYPED, this::filterAlphanumericKeyEvents);
mountName.textProperty().addListener(this::mountNameDidChange);
savePassword.setDisable(!keychainAccess.isPresent());
unlockAfterStartup.disableProperty().bind(savePassword.disabledProperty().or(savePassword.selectedProperty().not()));
if (SystemUtils.IS_OS_WINDOWS) {
winDriveLetter.setConverter(new WinDriveLetterLabelConverter());
} else {
customMountPathLabel.visibleProperty().bind(useCustomMountPath.selectedProperty());
customMountPathLabel.managedProperty().bind(useCustomMountPath.selectedProperty());
customMountPathField.visibleProperty().bind(useCustomMountPath.selectedProperty());
customMountPathField.managedProperty().bind(useCustomMountPath.selectedProperty());
customMountPathField.textProperty().addListener(this::mountPathDidChange);
winDriveLetter.setConverter(new WinDriveLetterLabelConverter());
if (!SystemUtils.IS_OS_WINDOWS) {
winDriveLetterLabel.setVisible(false);
winDriveLetterLabel.setManaged(false);
winDriveLetter.setVisible(false);
winDriveLetter.setManaged(false);
}
if (VolumeImpl.WEBDAV.equals(settings.preferredVolumeImpl().get())) {
useCustomMountPath.setVisible(false);
useCustomMountPath.setManaged(false);
customMountPathField.setMouseTransparent(true);
} else {
useCustomMountPath.setVisible(true);
if (SystemUtils.IS_OS_WINDOWS) {
winDriveLetter.visibleProperty().bind(useCustomMountPath.selectedProperty().not());
winDriveLetter.managedProperty().bind(useCustomMountPath.selectedProperty().not());
winDriveLetterLabel.visibleProperty().bind(useCustomMountPath.selectedProperty().not());
winDriveLetterLabel.managedProperty().bind(useCustomMountPath.selectedProperty().not());
}
}
}
@Override
public Parent getRoot() {
return root;
@@ -160,7 +190,7 @@ public class UnlockController implements ViewController {
passwordField.requestFocus();
}
void setVault(Vault vault) {
void setVault(Vault vault, State state) {
vaultSubs.unsubscribe();
vaultSubs = Subscription.EMPTY;
@@ -175,6 +205,8 @@ public class UnlockController implements ViewController {
advancedOptions.setVisible(false);
advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.show"));
progressIndicator.setVisible(false);
successMessage.setVisible(state.successMessage().isPresent());
state.successMessage().map(localization::getString).ifPresent(successMessage::setText);
if (SystemUtils.IS_OS_WINDOWS) {
winDriveLetter.valueProperty().removeListener(driveLetterChangeListener);
winDriveLetter.getItems().clear();
@@ -182,13 +214,11 @@ public class UnlockController implements ViewController {
winDriveLetter.getItems().addAll(driveLetters.getAvailableDriveLetters());
winDriveLetter.getItems().sort(new WinDriveLetterComparator());
winDriveLetter.valueProperty().addListener(driveLetterChangeListener);
chooseSelectedDriveLetter();
}
downloadsPageLink.setVisible(false);
messageText.setText(null);
mountName.setText(vault.getMountName());
if (SystemUtils.IS_OS_WINDOWS) {
chooseSelectedDriveLetter();
}
savePassword.setSelected(false);
// auto-fill pw from keychain:
if (keychainAccess.isPresent()) {
@@ -200,14 +230,19 @@ public class UnlockController implements ViewController {
Arrays.fill(storedPw, ' ');
}
}
VaultSettings settings = vault.getVaultSettings();
unlockAfterStartup.setSelected(savePassword.isSelected() && settings.unlockAfterStartup().get());
mountAfterUnlock.setSelected(settings.mountAfterUnlock().get());
revealAfterMount.setSelected(settings.revealAfterMount().get());
VaultSettings vaultSettings = vault.getVaultSettings();
unlockAfterStartup.setSelected(savePassword.isSelected() && vaultSettings.unlockAfterStartup().get());
revealAfterMount.setSelected(vaultSettings.revealAfterMount().get());
if (!settings.preferredVolumeImpl().get().equals(VolumeImpl.WEBDAV)) {
useCustomMountPath.setSelected(vaultSettings.usesIndividualMountPath().get());
customMountPathField.textProperty().setValue(vaultSettings.individualMountPath().getValueSafe());
}
vaultSubs = vaultSubs.and(EasyBind.subscribe(unlockAfterStartup.selectedProperty(), vaultSettings.unlockAfterStartup()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(revealAfterMount.selectedProperty(), vaultSettings.revealAfterMount()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(useCustomMountPath.selectedProperty(), vaultSettings.usesIndividualMountPath()::set));
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));
}
// ****************************************
@@ -225,6 +260,7 @@ public class UnlockController implements ViewController {
@FXML
private void didClickAdvancedOptionsButton(ActionEvent event) {
successMessage.setVisible(false);
advancedOptions.setVisible(!advancedOptions.isVisible());
if (advancedOptions.isVisible()) {
advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.hide"));
@@ -248,6 +284,10 @@ public class UnlockController implements ViewController {
}
}
private void mountPathDidChange(ObservableValue<? extends String> property, String oldValue, String newValue) {
vault.setCustomMountPath(newValue);
}
/**
* Converts 'C' to "C:" to translate between model and GUI.
*/
@@ -347,10 +387,12 @@ public class UnlockController implements ViewController {
@FXML
private void didClickUnlockButton(ActionEvent event) {
advancedOptions.setDisable(true);
advancedOptions.setVisible(false);
progressIndicator.setVisible(true);
CharSequence password = passwordField.getCharacters();
asyncTaskService.asyncTaskOf(() -> {
Tasks.create(() -> {
messageText.setText(localization.getString("unlock.pendingMessage.unlocking"));
vault.unlock(password);
if (keychainAccess.isPresent() && savePassword.isSelected()) {
keychainAccess.get().storePassphrase(vault.getId(), password);
@@ -359,6 +401,10 @@ public class UnlockController implements ViewController {
messageText.setText(null);
downloadsPageLink.setVisible(false);
listener.ifPresent(lstnr -> lstnr.didUnlock(vault));
}).onError(InvalidSettingsException.class, e -> {
messageText.setText(localization.getString("unlock.errorMessage.invalidMountPath"));
advancedOptions.setVisible(true);
customMountPathField.setStyle("-fx-border-color: red;");
}).onError(InvalidPassphraseException.class, e -> {
messageText.setText(localization.getString("unlock.errorMessage.wrongPassword"));
passwordField.selectAll();
@@ -377,7 +423,7 @@ public class UnlockController implements ViewController {
}).onError(ServerLifecycleException.class, e -> {
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
}).onError(IOException.class, e -> {
}).onError(Exception.class, e -> {
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
}).andFinally(() -> {
@@ -386,7 +432,10 @@ public class UnlockController implements ViewController {
}
advancedOptions.setDisable(false);
progressIndicator.setVisible(false);
}).run();
if (advancedOptions.isVisible()) { //dirty programming, but otherwise the focus is wrong
customMountPathField.requestFocus();
}
}).runOnce(executor);
}
/* callback */
@@ -397,7 +446,28 @@ public class UnlockController implements ViewController {
@FunctionalInterface
interface UnlockListener {
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;
}
}
}

View File

@@ -8,29 +8,13 @@
******************************************************************************/
package org.cryptomator.ui.controllers;
import static java.lang.String.format;
import java.io.IOException;
import java.util.Optional;
import javax.inject.Inject;
import org.cryptomator.frontend.webdav.ServerLifecycleException;
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.util.AsyncTaskService;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.util.concurrent.Runnables;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.binding.ObjectExpression;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
@@ -46,13 +30,19 @@ import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ToggleButton;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.VBox;
import javafx.stage.PopupWindow.AnchorLocation;
import javafx.util.Duration;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.cryptomator.ui.util.Tasks;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.lang.String.format;
public class UnlockedController implements ViewController {
@@ -62,9 +52,8 @@ public class UnlockedController implements ViewController {
private static final double IO_SAMPLING_INTERVAL = 0.25;
private final Localization localization;
private final AsyncTaskService asyncTaskService;
private final ExecutorService executor;
private final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
private final ObjectExpression<Vault.State> vaultState = ObjectExpression.objectExpression(EasyBind.select(vault).selectObject(Vault::stateProperty));
private Optional<LockListener> listener = Optional.empty();
private Timeline ioAnimation;
@@ -83,30 +72,17 @@ public class UnlockedController implements ViewController {
@FXML
private ContextMenu moreOptionsMenu;
@FXML
private MenuItem mountVaultMenuItem;
@FXML
private MenuItem unmountVaultMenuItem;
@FXML
private MenuItem revealVaultMenuItem;
@FXML
private VBox root;
@Inject
public UnlockedController(Localization localization, AsyncTaskService asyncTaskService) {
public UnlockedController(Localization localization, ExecutorService executor) {
this.localization = localization;
this.asyncTaskService = asyncTaskService;
this.executor = executor;
}
@Override
public void initialize() {
mountVaultMenuItem.disableProperty().bind(vaultState.isEqualTo(Vault.State.UNLOCKED).not()); // enable when unlocked
unmountVaultMenuItem.disableProperty().bind(vaultState.isEqualTo(Vault.State.MOUNTED).not()); // enable when mounted
revealVaultMenuItem.disableProperty().bind(vaultState.isEqualTo(Vault.State.MOUNTED).not()); // enable when mounted
EasyBind.subscribe(vault, this::vaultChanged);
EasyBind.subscribe(moreOptionsMenu.showingProperty(), moreOptionsButton::setSelected);
}
@@ -121,10 +97,6 @@ public class UnlockedController implements ViewController {
return;
}
if (newVault.getState() == Vault.State.UNLOCKED && newVault.getVaultSettings().mountAfterUnlock().get()) {
mountVault(newVault);
}
// (re)start throughput statistics:
stopIoSampling();
startIoSampling();
@@ -132,75 +104,22 @@ public class UnlockedController implements ViewController {
@FXML
private void didClickLockVault(ActionEvent event) {
regularUnmountVault(this::lockVault);
regularLockVault(this::lockVaultSucceeded);
}
private void lockVault() {
try {
vault.get().lock();
} catch (ServerLifecycleException | IOException e) {
LOG.error("Lock failed", e);
}
private void lockVaultSucceeded() {
listener.ifPresent(listener -> listener.didLock(this));
}
@FXML
private void didClickMoreOptions(ActionEvent event) {
if (moreOptionsMenu.isShowing()) {
moreOptionsMenu.hide();
} else {
moreOptionsMenu.setAnchorLocation(AnchorLocation.CONTENT_TOP_RIGHT);
moreOptionsMenu.show(moreOptionsButton, Side.BOTTOM, moreOptionsButton.getWidth(), 0.0);
}
}
@FXML
public void didClickMountVault(ActionEvent event) {
mountVault(vault.get());
}
private void mountVault(Vault vault) {
asyncTaskService.asyncTaskOf(() -> {
vault.mount();
}).onSuccess(() -> {
LOG.trace("Mount succeeded.");
messageLabel.setText(null);
if (vault.getVaultSettings().revealAfterMount().get()) {
revealVault(vault);
}
}).onError(CommandFailedException.class, e -> {
LOG.error("Mount failed.", e);
// TODO Markus Kreusch #393: hyperlink auf FAQ oder sowas?
messageLabel.setText(localization.getString("unlocked.label.mountFailed"));
}).run();
}
@FXML
public void didClickUnmountVault(ActionEvent event) {
regularUnmountVault(Runnables.doNothing());
}
private void regularUnmountVault(Runnable onSuccess) {
asyncTaskService.asyncTaskOf(() -> {
vault.get().unmount();
private void regularLockVault(Runnable onSuccess) {
Tasks.create(() -> {
vault.get().lock(false);
}).onSuccess(() -> {
LOG.trace("Regular unmount succeeded.");
onSuccess.run();
}).onError(Exception.class, e -> {
onRegularUnmountVaultFailed(e, onSuccess);
}).run();
}
private void forcedUnmountVault(Runnable onSuccess) {
asyncTaskService.asyncTaskOf(() -> {
vault.get().unmountForced();
}).onSuccess(() -> {
LOG.trace("Forced unmount succeeded.");
onSuccess.run();
}).onError(Exception.class, e -> {
LOG.error("Forced unmount failed.", e);
messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
}).run();
}).runOnce(executor);
}
private void onRegularUnmountVaultFailed(Exception e, Runnable onSuccess) {
@@ -214,7 +133,7 @@ public class UnlockedController implements ViewController {
Optional<ButtonType> choice = confirmDialog.showAndWait();
if (ButtonType.YES.equals(choice.get())) {
forcedUnmountVault(onSuccess);
forcedLockVault(onSuccess);
} else {
LOG.trace("Unmount cancelled.", e);
}
@@ -224,29 +143,43 @@ public class UnlockedController implements ViewController {
}
}
private void forcedLockVault(Runnable onSuccess) {
Tasks.create(() -> {
vault.get().lock(true);
}).onSuccess(() -> {
LOG.trace("Forced unmount succeeded.");
onSuccess.run();
}).onError(Exception.class, e -> {
LOG.error("Forced unmount failed.", e);
messageLabel.setText(localization.getString("unlocked.label.unmountFailed"));
}).runOnce(executor);
}
@FXML
private void didClickMoreOptions(ActionEvent event) {
if (moreOptionsMenu.isShowing()) {
moreOptionsMenu.hide();
} else {
moreOptionsMenu.setAnchorLocation(AnchorLocation.CONTENT_TOP_RIGHT);
moreOptionsMenu.show(moreOptionsButton, Side.BOTTOM, moreOptionsButton.getWidth(), 0.0);
}
}
@FXML
private void didClickRevealVault(ActionEvent event) {
revealVault(vault.get());
}
private void revealVault(Vault vault) {
asyncTaskService.asyncTaskOf(() -> {
void revealVault(Vault vault) {
Tasks.create(() -> {
vault.reveal();
}).onSuccess(() -> {
LOG.trace("Reveal succeeded.");
messageLabel.setText(null);
}).onError(CommandFailedException.class, e -> {
}).onError(Exception.class, e -> {
LOG.error("Reveal failed.", e);
messageLabel.setText(localization.getString("unlocked.label.revealFailed"));
}).run();
}
@FXML
private void didClickCopyUrl(ActionEvent event) {
ClipboardContent clipboardContent = new ClipboardContent();
clipboardContent.putUrl(vault.get().getWebDavUrl());
clipboardContent.putString(vault.get().getWebDavUrl());
Clipboard.getSystemClipboard().setContent(clipboardContent);
}).runOnce(executor);
}
// ****************************************

View File

@@ -5,19 +5,10 @@
*******************************************************************************/
package org.cryptomator.ui.controllers;
import javax.inject.Inject;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.UpgradeStrategies;
import org.cryptomator.ui.model.UpgradeStrategy;
import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.util.AsyncTaskService;
import org.fxmisc.easybind.EasyBind;
import java.util.concurrent.ExecutorService;
import javafx.beans.binding.BooleanExpression;
import javafx.beans.property.ObjectProperty;
@@ -30,19 +21,26 @@ import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.GridPane;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.model.UpgradeStrategies;
import org.cryptomator.ui.model.UpgradeStrategy;
import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.util.Tasks;
import org.fxmisc.easybind.EasyBind;
public class UpgradeController implements ViewController {
private final ObjectProperty<UpgradeStrategy> strategy = new SimpleObjectProperty<>();
private final UpgradeStrategies strategies;
private final AsyncTaskService asyncTaskService;
private final ExecutorService executor;
private Optional<UpgradeListener> listener = Optional.empty();
private Vault vault;
@Inject
public UpgradeController(Localization localization, UpgradeStrategies strategies, AsyncTaskService asyncTaskService) {
public UpgradeController(UpgradeStrategies strategies, ExecutorService executor) {
this.strategies = strategies;
this.asyncTaskService = asyncTaskService;
this.executor = executor;
}
@FXML
@@ -122,8 +120,8 @@ public class UpgradeController implements ViewController {
private void upgrade(UpgradeStrategy instruction) {
passwordField.setDisable(true);
progressIndicator.setVisible(true);
asyncTaskService //
.asyncTaskOf(() -> {
Tasks //
.create(() -> {
if (!instruction.isApplicable(vault)) {
throw new IllegalStateException("No ugprade needed for " + vault.getPath());
}
@@ -137,7 +135,7 @@ public class UpgradeController implements ViewController {
progressIndicator.setVisible(false);
passwordField.setDisable(false);
passwordField.swipe();
}).run();
}).runOnce(executor);
}
private void showNextUpgrade() {

View File

@@ -2,53 +2,50 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
******************************************************************************/
package org.cryptomator.ui.controllers;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import 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 java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.VBox;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.util.Tasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildYesNoDialog;
@Singleton
public class WelcomeController implements ViewController {
@@ -60,17 +57,17 @@ public class WelcomeController implements ViewController {
private final Localization localization;
private final Settings settings;
private final Comparator<String> semVerComparator;
private final AsyncTaskService asyncTaskService;
private final ScheduledExecutorService executor;
@Inject
public WelcomeController(Application app, @Named("applicationVersion") Optional<String> applicationVersion, Localization localization, Settings settings, @Named("SemVer") Comparator<String> semVerComparator,
AsyncTaskService asyncTaskService) {
ScheduledExecutorService executor) {
this.app = app;
this.applicationVersion = applicationVersion;
this.localization = localization;
this.settings = settings;
this.semVerComparator = semVerComparator;
this.asyncTaskService = asyncTaskService;
this.executor = executor;
}
@FXML
@@ -92,6 +89,8 @@ public class WelcomeController implements ViewController {
public void initialize(URL location, ResourceBundle resources) {
if (areUpdatesManagedExternally()) {
checkForUpdatesContainer.setVisible(false);
} else if (!settings.askedForUpdateCheck().get()) {
this.askForUpdateCheck();
} else if (settings.checkForUpdates().get()) {
this.checkForUpdates();
}
@@ -110,44 +109,63 @@ public class WelcomeController implements ViewController {
return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false"));
}
private void askForUpdateCheck() {
Tasks.create(() -> {}).onSuccess(() -> {
Optional<ButtonType> result = buildYesNoDialog(
localization.getString("welcome.askForUpdateCheck.dialog.title"),
localization.getString("welcome.askForUpdateCheck.dialog.header"),
localization.getString("welcome.askForUpdateCheck.dialog.content"),
ButtonType.YES).showAndWait();
if (result.isPresent()) {
settings.askedForUpdateCheck().set(true);
settings.checkForUpdates().set(result.get().equals(ButtonType.YES));
}
if (settings.checkForUpdates().get()) {
this.checkForUpdates();
}
}).scheduleOnce(executor, 1, TimeUnit.SECONDS);
}
private void checkForUpdates() {
checkForUpdatesStatus.setText(localization.getString("welcome.checkForUpdates.label.currentlyChecking"));
checkForUpdatesIndicator.setVisible(true);
asyncTaskService.asyncTaskOf(() -> {
RequestConfig requestConfig = RequestConfig.custom() //
.setConnectTimeout(5000) //
.setConnectionRequestTimeout(5000) //
.setSocketTimeout(5000) //
.build();
Tasks.create(() -> {
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() //
.disableCookieManagement() //
.setDefaultRequestConfig(requestConfig) //
.setUserAgent(userAgent);
LOG.debug("Checking for updates...");
try (CloseableHttpClient client = httpClientBuilder.build()) {
HttpGet request = new HttpGet("https://api.cryptomator.org/updates/latestVersion.json");
try (CloseableHttpResponse response = client.execute(request)) {
if (response.getStatusLine().getStatusCode() == 200 && response.getEntity() != null) {
try (InputStream in = response.getEntity().getContent()) {
Gson gson = new GsonBuilder().setLenient().create();
Reader utf8Reader = new InputStreamReader(in, StandardCharsets.UTF_8);
Map<String, String> map = gson.fromJson(utf8Reader, new TypeToken<Map<String, String>>() {
}.getType());
if (map != null) {
this.compareVersions(map);
}
}
}
URL url = URI.create("https://api.cryptomator.org/updates/latestVersion.json").toURL();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.addRequestProperty("User-Agent", userAgent);
conn.connect();
try {
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
return Optional.<byte[]>empty();
}
try (InputStream in = conn.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
in.transferTo(out);
return Optional.of(out.toByteArray());
}
} finally {
conn.disconnect();
}
}).onSuccess(response -> {
response.ifPresent(bytes -> {
Gson gson = new GsonBuilder().setLenient().create();
String json = new String(bytes, StandardCharsets.UTF_8);
Map<String, String> map = gson.fromJson(json, new TypeToken<Map<String, String>>() {
}.getType());
if (map != null) {
this.compareVersions(map);
}
});
}).onError(Exception.class, e -> {
LOG.warn("Error checking for updates", e);
}).andFinally(() -> {
checkForUpdatesStatus.setText("");
checkForUpdatesIndicator.setVisible(false);
}).run();
}).runOnce(executor);
}
private void compareVersions(final Map<String, String> latestVersions) {
assert Platform.isFxApplicationThread();
final String latestVersion;
if (SystemUtils.IS_OS_MAC_OSX) {
latestVersion = latestVersions.get("mac");
@@ -163,11 +181,9 @@ public class WelcomeController implements ViewController {
LOG.info("Current version: {}, lastest version: {}", currentVersion, latestVersion);
if (currentVersion != null && semVerComparator.compare(currentVersion, latestVersion) < 0) {
final String msg = String.format(localization.getString("welcome.newVersionMessage"), latestVersion, currentVersion);
Platform.runLater(() -> {
this.updateLink.setText(msg);
this.updateLink.setVisible(true);
this.updateLink.setDisable(false);
});
this.updateLink.setText(msg);
this.updateLink.setVisible(true);
this.updateLink.setDisable(false);
}
}

View File

@@ -68,9 +68,7 @@ public class DirectoryListCell extends DraggableListCell<Vault> {
}
switch (state) {
case UNLOCKED:
case MOUNTED:
case MOUNTING:
case UNMOUNTING:
case PROCESSING:
return "\uf09c";
case LOCKED:
default:
@@ -84,9 +82,7 @@ public class DirectoryListCell extends DraggableListCell<Vault> {
}
switch (state) {
case UNLOCKED:
case MOUNTED:
case MOUNTING:
case UNMOUNTING:
case PROCESSING:
return UNLOCKED_ICON_COLOR;
case LOCKED:
default:

View File

@@ -18,7 +18,6 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
import org.cryptomator.keychain.KeychainAccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,33 +73,21 @@ public class AutoUnlocker {
}
try {
vault.unlock(CharBuffer.wrap(storedPw));
mountSilently(vault);
} catch (IOException | CryptoException e) {
revealSilently(vault);
} catch (IOException | CryptoException | Volume.VolumeException e) {
LOG.error("Auto unlock failed.", e);
} finally {
Arrays.fill(storedPw, ' ');
}
}
private void mountSilently(Vault unlockedVault) {
if (!unlockedVault.getVaultSettings().mountAfterUnlock().get()) {
return;
}
try {
unlockedVault.mount();
revealSilently(unlockedVault);
} catch (CommandFailedException e) {
LOG.error("Auto unlock succeded, but mounting the drive failed.", e);
}
}
private void revealSilently(Vault mountedVault) {
if (!mountedVault.getVaultSettings().revealAfterMount().get()) {
return;
}
try {
mountedVault.reveal();
} catch (CommandFailedException e) {
} catch (Volume.VolumeException e) {
LOG.error("Auto unlock succeded, but revealing the drive failed.", e);
}
}

View File

@@ -0,0 +1,80 @@
package org.cryptomator.ui.model;
import com.google.common.base.Strings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.frontend.dokany.Mount;
import org.cryptomator.frontend.dokany.MountFactory;
import org.cryptomator.frontend.dokany.MountFailedException;
import javax.inject.Inject;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
public class DokanyVolume implements Volume {
private static final String FS_TYPE_NAME = "Cryptomator File System";
private final VaultSettings vaultSettings;
private final MountFactory mountFactory;
private final WindowsDriveLetters windowsDriveLetters;
private Mount mount;
@Inject
public DokanyVolume(VaultSettings vaultSettings, ExecutorService executorService, WindowsDriveLetters windowsDriveLetters) {
this.vaultSettings = vaultSettings;
this.mountFactory = new MountFactory(executorService);
this.windowsDriveLetters = windowsDriveLetters;
}
@Override
public boolean isSupported() {
return DokanyVolume.isSupportedStatic();
}
@Override
public void mount(CryptoFileSystem fs) throws VolumeException {
Path mountPath = Paths.get(getMountPathString());
String mountName = vaultSettings.mountName().get();
try {
this.mount = mountFactory.mount(fs.getPath("/"), mountPath, mountName, FS_TYPE_NAME);
} catch (MountFailedException e) {
throw new VolumeException("Unable to mount Filesystem", e);
}
}
private String getMountPathString() throws VolumeException {
if (vaultSettings.usesIndividualMountPath().get()) {
return vaultSettings.individualMountPath().get();
} else if (!Strings.isNullOrEmpty(vaultSettings.winDriveLetter().get())) {
return vaultSettings.winDriveLetter().get().charAt(0) + ":\\";
} else {
//auto assign drive letter
if (!windowsDriveLetters.getAvailableDriveLetters().isEmpty()) {
return windowsDriveLetters.getAvailableDriveLetters().iterator().next() + ":\\";
} else {
throw new VolumeException("No free drive letter available.");
}
}
}
@Override
public void reveal() throws VolumeException {
boolean success = mount.reveal();
if (!success) {
throw new VolumeException("Reveal failed.");
}
}
@Override
public void unmount() {
mount.close();
}
public static boolean isSupportedStatic() {
return MountFactory.isApplicable();
}
}

View File

@@ -0,0 +1,128 @@
package org.cryptomator.ui.model;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.inject.Inject;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.frontend.fuse.mount.CommandFailedException;
import org.cryptomator.frontend.fuse.mount.EnvironmentVariables;
import org.cryptomator.frontend.fuse.mount.FuseMountFactory;
import org.cryptomator.frontend.fuse.mount.FuseNotSupportedException;
import org.cryptomator.frontend.fuse.mount.Mount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 Mount fuseMnt;
private Path mountPath;
private boolean extraDirCreated;
@Inject
public FuseVolume(VaultSettings vaultSettings) {
this.vaultSettings = vaultSettings;
this.extraDirCreated = false;
}
@Override
public void mount(CryptoFileSystem fs) throws IOException, FuseNotSupportedException, VolumeException {
String mountPath;
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();
mount(fs.getPath("/"));
}
private String createDirIfNotExist(String prefix, String dirName) throws IOException {
Path p = Paths.get(prefix, dirName + vaultSettings.getId());
if (Files.isDirectory(p)) {
try (DirectoryStream<Path> emptyCheck = Files.newDirectoryStream(p)) {
if (emptyCheck.iterator().hasNext()) {
throw new DirectoryNotEmptyException("Mount point is not empty.");
} else {
LOG.info("Directory already exists and is empty. Using it as mount point.");
return p.toString();
}
}
} else {
Files.createDirectory(p);
return p.toString();
}
}
private void mount(Path root) throws VolumeException {
try {
EnvironmentVariables envVars = EnvironmentVariables.create()
.withMountName(vaultSettings.mountName().getValue())
.withMountPath(mountPath)
.build();
this.fuseMnt = FuseMountFactory.getMounter().mount(root, envVars);
} catch (CommandFailedException e) {
throw new VolumeException("Unable to mount Filesystem", e);
}
}
@Override
public void reveal() throws VolumeException {
try {
fuseMnt.revealInFileManager();
} catch (CommandFailedException e) {
LOG.info("Revealing the vault in file manger failed: " + e.getMessage());
throw new VolumeException(e);
}
}
@Override
public synchronized void unmount() throws VolumeException {
try {
fuseMnt.close();
} catch (CommandFailedException e) {
throw new VolumeException(e);
}
cleanup();
}
private void cleanup() {
if (extraDirCreated) {
try {
Files.delete(mountPath);
} catch (IOException e) {
LOG.warn("Could not delete mounting directory:" + e.getMessage());
}
}
}
@Override
public boolean isSupported() {
return FuseVolume.isSupportedStatic();
}
public static boolean isSupportedStatic() {
return (SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_LINUX) && FuseMountFactory.isFuseSupported();
}
}

View File

@@ -0,0 +1,5 @@
package org.cryptomator.ui.model;
public class InvalidSettingsException extends RuntimeException {
}

View File

@@ -5,8 +5,8 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import static java.nio.charset.StandardCharsets.UTF_8;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
@@ -19,11 +19,7 @@ import java.util.EnumSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.BaseNCodec;
import com.google.common.io.BaseEncoding;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
@@ -32,6 +28,8 @@ import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Contains the collective knowledge of all creatures who were alive during the development of vault format 3.
* This class uses no external classes from the crypto or shortening layer by purpose, so we don't need legacy code inside these.
@@ -50,7 +48,7 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
private static final String NEW_FOLDER_PREFIX = "0";
private final MessageDigest sha1 = MessageDigestSupplier.SHA1.get();
private final BaseNCodec base32 = new Base32();
private final BaseEncoding base32 = BaseEncoding.base32();
@Inject
public UpgradeVersion3to4(Localization localization) {
@@ -155,7 +153,7 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
String oldLongName = new String(Files.readAllBytes(oldMetadataFile), UTF_8);
if (oldLongName.endsWith(OLD_FOLDER_SUFFIX)) {
String newLongName = NEW_FOLDER_PREFIX + StringUtils.removeEnd(oldLongName, OLD_FOLDER_SUFFIX);
String newCanonicalBase32 = base32.encodeAsString(sha1.digest(newLongName.getBytes(UTF_8)));
String newCanonicalBase32 = base32.encode(sha1.digest(newLongName.getBytes(UTF_8)));
String newCanonicalName = newCanonicalBase32 + LONG_FILENAME_EXT;
Path newMetadataFile = metadataDir.resolve(newCanonicalName.substring(0, 2)).resolve(newCanonicalName.substring(2, 4)).resolve(newCanonicalName);
String newName = newCanonicalBase32 + oldNameSuffix + LONG_FILENAME_EXT;

View File

@@ -8,26 +8,15 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.inject.Inject;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.binding.Binding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.LazyInitializer;
import org.cryptomator.common.Optionals;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
@@ -35,24 +24,22 @@ import org.cryptomator.cryptofs.CryptoFileSystemProperties;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptolib.api.CryptoException;
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.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.binding.Binding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javax.inject.Inject;
import javax.inject.Provider;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
@PerVault
public class Vault {
@@ -64,22 +51,21 @@ public class Vault {
private final Settings settings;
private final VaultSettings vaultSettings;
private final WebDavServer server;
private final Provider<Volume> volumeProvider;
private final AtomicReference<CryptoFileSystem> cryptoFileSystem = new AtomicReference<>();
private final ObjectProperty<State> state = new SimpleObjectProperty<State>(State.LOCKED);
private WebDavServletController servlet;
private Mount mount;
private Volume volume;
public enum State {
LOCKED, UNLOCKED, MOUNTING, MOUNTED, UNMOUNTING
};
LOCKED, PROCESSING, UNLOCKED
}
@Inject
Vault(Settings settings, VaultSettings vaultSettings, WebDavServer server) {
Vault(Settings settings, VaultSettings vaultSettings, Provider<Volume> volumeProvider) {
this.settings = settings;
this.vaultSettings = vaultSettings;
this.server = server;
this.volumeProvider = volumeProvider;
}
// ******************************************************************************
@@ -111,83 +97,40 @@ public class Vault {
CryptoFileSystemProvider.changePassphrase(getPath(), MASTERKEY_FILENAME, oldPassphrase, newPassphrase);
}
public synchronized void unlock(CharSequence passphrase) throws ServerLifecycleException, CryptoException, IOException {
FileSystem fs = getCryptoFileSystem(passphrase);
if (!server.isRunning()) {
server.start();
}
servlet = server.createWebDavServlet(fs.getPath("/"), vaultSettings.getId() + "/" + vaultSettings.mountName().get());
servlet.start();
Platform.runLater(() -> {
state.set(State.UNLOCKED);
});
}
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()) //
.withWebdavHostname(getLocalhostAliasOrNull()) //
.build();
Platform.runLater(() -> {
state.set(State.MOUNTING);
});
mount = servlet.mount(mountParams); // might block this thread for a while
Platform.runLater(() -> {
state.set(State.MOUNTED);
});
}
private String getLocalhostAliasOrNull() {
public synchronized void unlock(CharSequence passphrase) throws InvalidSettingsException, CryptoException, IOException, Volume.VolumeException {
Platform.runLater(() -> state.set(State.PROCESSING));
try {
InetAddress alias = InetAddress.getByName(LOCALHOST_ALIAS);
if (alias.getHostAddress().equals("127.0.0.1")) {
return LOCALHOST_ALIAS;
} else {
return null;
if (vaultSettings.usesIndividualMountPath().and(vaultSettings.individualMountPath().isEmpty()).get()) {
throw new InvalidSettingsException();
}
} catch (UnknownHostException e) {
return null;
CryptoFileSystem fs = getCryptoFileSystem(passphrase);
volume = volumeProvider.get();
volume.mount(fs);
Platform.runLater(() -> {
state.set(State.UNLOCKED);
});
} catch (Exception e) {
Platform.runLater(() -> state.set(State.LOCKED));
throw e;
}
}
public synchronized void unmount() throws CommandFailedException {
unmount(Function.identity());
}
public synchronized void unmountForced() throws CommandFailedException {
unmount(Optionals.unwrap(Mount::forced));
}
private synchronized void unmount(Function<Mount, ? extends UnmountOperation> unmountOperationChooser) throws CommandFailedException {
public synchronized void lock(boolean forced) throws Volume.VolumeException {
Platform.runLater(() -> {
state.set(State.UNMOUNTING);
state.set(State.PROCESSING);
});
if (mount != null) {
unmountOperationChooser.apply(mount).unmount();
mount = null;
}
Platform.runLater(() -> {
state.set(State.UNLOCKED);
});
}
public boolean supportsForcedUnmount() {
return mount != null && mount.forced().isPresent();
}
public synchronized void lock() throws ServerLifecycleException, IOException {
if (servlet != null) {
servlet.stop();
if (forced && volume.supportsForcedUnmount()) {
volume.unmountForced();
} else {
volume.unmount();
}
CryptoFileSystem fs = cryptoFileSystem.getAndSet(null);
if (fs != null) {
fs.close();
try {
fs.close();
} catch (IOException e) {
LOG.error("Error closing file system.", e);
}
}
Platform.runLater(() -> {
state.set(State.LOCKED);
@@ -199,29 +142,22 @@ public class Vault {
*/
public void prepareForShutdown() {
try {
unmount();
} catch (CommandFailedException e) {
if (supportsForcedUnmount()) {
lock(false);
} catch (Volume.VolumeException e) {
if (volume.supportsForcedUnmount()) {
try {
unmountForced();
} catch (CommandFailedException e1) {
LOG.warn("Failed to force unmount vault.");
lock(true);
} catch (Volume.VolumeException e1) {
LOG.warn("Failed to force lock vault.", e1);
}
} else {
LOG.warn("Failed to gracefully unmount vault.");
LOG.warn("Failed to gracefully lock vault.", e);
}
}
try {
lock();
} catch (Exception e) {
LOG.warn("Failed to lock vault.");
}
}
public void reveal() throws CommandFailedException {
if (mount != null) {
mount.reveal();
}
public void reveal() throws Volume.VolumeException {
volume.reveal();
}
// ******************************************************************************
@@ -243,17 +179,13 @@ public class Vault {
}
public Observable[] observables() {
return new Observable[] {state};
return new Observable[]{state};
}
public VaultSettings getVaultSettings() {
return vaultSettings;
}
public synchronized String getWebDavUrl() {
return servlet.getServletRootUri().toString();
}
public Path getPath() {
return vaultSettings.path().getValue();
}
@@ -308,6 +240,14 @@ public class Vault {
return vaultSettings.mountName().get();
}
public String getCustomMountPath() {
return vaultSettings.individualMountPath().getValueSafe();
}
public void setCustomMountPath(String mountPath) {
vaultSettings.individualMountPath().set(mountPath);
}
public void setMountName(String mountName) throws IllegalArgumentException {
if (StringUtils.isBlank(mountName)) {
throw new IllegalArgumentException("mount name is empty");
@@ -355,4 +295,7 @@ public class Vault {
}
}
public boolean supportsForcedUnmount() {
return volume.supportsForcedUnmount();
}
}

View File

@@ -38,6 +38,11 @@ public class VaultList extends TransformationList<Vault, VaultSettings> {
return index;
}
@Override
public int getViewIndex(int index) {
return index;
}
@Override
public Vault get(int index) {
VaultSettings s = source.get(index);

View File

@@ -12,14 +12,19 @@ import java.util.Objects;
import javax.inject.Scope;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import dagger.Module;
import dagger.Provides;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Module
public class VaultModule {
private static final Logger LOG = LoggerFactory.getLogger(VaultModule.class);
private final VaultSettings vaultSettings;
public VaultModule(VaultSettings vaultSettings) {
@@ -36,6 +41,23 @@ public class VaultModule {
@Documented
@Retention(RetentionPolicy.RUNTIME)
@interface PerVault {
}
@Provides
public Volume provideVolume(Settings settings, WebDavVolume webDavVolume, FuseVolume fuseVolume, DokanyVolume dokanyVolume) {
VolumeImpl preferredImpl = settings.preferredVolumeImpl().get();
if (VolumeImpl.DOKANY == preferredImpl && dokanyVolume.isSupported()) {
return dokanyVolume;
} else if (VolumeImpl.FUSE == preferredImpl && fuseVolume.isSupported()) {
return fuseVolume;
} else {
if (VolumeImpl.WEBDAV != preferredImpl) {
LOG.warn("Using WebDAV, because {} is not supported.", preferredImpl.getDisplayName());
}
assert webDavVolume.isSupported();
return webDavVolume;
}
}
}

View File

@@ -0,0 +1,75 @@
package org.cryptomator.ui.model;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.cryptofs.CryptoFileSystem;
import java.io.IOException;
import java.util.stream.Stream;
/**
* Takes a Volume and usess it to mount an unlocked vault
*/
public interface Volume {
/**
* Checks in constant time whether this volume type is supported on the system running Cryptomator.
*
* @return true if this volume can be mounted
*/
boolean isSupported();
/**
* @param fs
* @throws IOException
*/
void mount(CryptoFileSystem fs) throws IOException, VolumeException;
void reveal() throws VolumeException;
void unmount() throws VolumeException;
// optional forced unmounting:
default boolean supportsForcedUnmount() {
return false;
}
default void unmountForced() throws VolumeException {
throw new VolumeException("Operation not supported.");
}
static VolumeImpl[] getCurrentSupportedAdapters() {
return Stream.of(VolumeImpl.values()).filter(impl -> {
switch (impl) {
case WEBDAV:
return WebDavVolume.isSupportedStatic();
case DOKANY:
return DokanyVolume.isSupportedStatic();
case FUSE:
return FuseVolume.isSupportedStatic();
default:
return false;//throw new IllegalStateException("Adapter not implemented.");
}
}).toArray(VolumeImpl[]::new);
}
/**
* Exception thrown when a volume-specific command such as mount/unmount/reveal failed.
*/
class VolumeException extends Exception {
public VolumeException(String message) {
super(message);
}
public VolumeException(Throwable cause) {
super(cause);
}
public VolumeException(String message, Throwable cause) {
super(message, cause);
}
}
}

View File

@@ -0,0 +1,131 @@
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;
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 mount(CryptoFileSystem fs) throws VolumeException {
if (server == null) {
server = serverProvider.get();
}
if (!server.isRunning()) {
server.start();
}
servlet = server.createWebDavServlet(fs.getPath("/"), vaultSettings.getId() + "/" + vaultSettings.mountName().get());
servlet.start();
mount();
}
private void mount() throws VolumeException {
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 VolumeException(e);
}
}
@Override
public void reveal() throws VolumeException {
try {
mount.reveal();
} catch (Mounter.CommandFailedException e) {
e.printStackTrace();
throw new VolumeException(e);
}
}
@Override
public synchronized void unmount() throws VolumeException {
try {
mount.unmount();
} catch (Mounter.CommandFailedException e) {
throw new VolumeException(e);
}
cleanup();
}
@Override
public synchronized void unmountForced() throws VolumeException {
try {
mount.forced().orElseThrow(IllegalStateException::new).unmount();
} catch (Mounter.CommandFailedException e) {
throw new VolumeException(e);
}
cleanup();
}
private String getLocalhostAliasOrNull() {
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;
}
}
private void cleanup() {
if (servlet != null) {
servlet.stop();
}
}
@Override
public boolean isSupported() {
return WebDavVolume.isSupportedStatic();
}
@Override
public boolean supportsForcedUnmount() {
return mount != null && mount.forced().isPresent();
}
public static boolean isSupportedStatic() {
return true;
}
}

View File

@@ -1,219 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.ui.util;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.common.ConsumerThrowingException;
import org.cryptomator.common.RunnableThrowingException;
import org.cryptomator.common.SupplierThrowingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform;
@Singleton
public class AsyncTaskService {
private static final Logger LOG = LoggerFactory.getLogger(AsyncTaskService.class);
private final ExecutorService executor;
@Inject
public AsyncTaskService(ExecutorService executor) {
this.executor = executor;
}
/**
* Creates a new async task
*
* @param task Tasks to be invoked in a background thread.
* @return The async task
*/
public AsyncTaskWithoutSuccessHandler<Void> asyncTaskOf(RunnableThrowingException<?> task) {
return new AsyncTaskImpl<>(() -> {
task.run();
return null;
});
}
/**
* Creates a new async task
*
* @param task Tasks to be invoked in a background thread.
* @return The async task
*/
public <ResultType> AsyncTaskWithoutSuccessHandler<ResultType> asyncTaskOf(SupplierThrowingException<ResultType, ?> task) {
return new AsyncTaskImpl<>(task);
}
private class AsyncTaskImpl<ResultType> implements AsyncTaskWithoutSuccessHandler<ResultType> {
private final SupplierThrowingException<ResultType, ?> task;
private ConsumerThrowingException<ResultType, ?> successHandler = value -> {
};
private final List<ErrorHandler<Throwable>> errorHandlers = new ArrayList<>();
private RunnableThrowingException<?> finallyHandler = () -> {
};
public AsyncTaskImpl(SupplierThrowingException<ResultType, ?> task) {
this.task = task;
}
@Override
public AsyncTaskWithoutErrorHandler onSuccess(ConsumerThrowingException<ResultType, ?> handler) {
successHandler = handler;
return this;
}
@Override
public AsyncTaskWithoutErrorHandler onSuccess(RunnableThrowingException<?> handler) {
return onSuccess(result -> handler.run());
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public <ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, ConsumerThrowingException<ErrorType, ?> handler) {
errorHandlers.add((ErrorHandler) new ErrorHandler<>(type, handler));
return this;
}
@Override
public <ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, RunnableThrowingException<?> handler) {
return onError(type, error -> handler.run());
}
@Override
public AsyncTask andFinally(RunnableThrowingException<?> handler) {
finallyHandler = handler;
return this;
}
@Override
public void run() {
errorHandlers.add(ErrorHandler.LOGGING_HANDLER);
executor.execute(() -> logExceptions(() -> {
try {
ResultType result = task.get();
Platform.runLater(() -> {
try {
successHandler.accept(result);
} catch (Throwable e) {
LOG.error("Uncaught exception", e);
}
});
} catch (Throwable e) {
ErrorHandler<Throwable> errorHandler = errorHandlerFor(e);
Platform.runLater(toRunnableLoggingException(() -> errorHandler.accept(e)));
} finally {
Platform.runLater(toRunnableLoggingException(finallyHandler));
}
}));
}
private ErrorHandler<Throwable> errorHandlerFor(Throwable e) {
return errorHandlers.stream().filter(handler -> handler.handles(e)).findFirst().get();
}
}
private static Runnable toRunnableLoggingException(RunnableThrowingException<?> delegate) {
return () -> logExceptions(delegate);
}
private static void logExceptions(RunnableThrowingException<?> delegate) {
try {
delegate.run();
} catch (Throwable e) {
LOG.error("Uncaught exception", e);
}
}
private static class ErrorHandler<ErrorType> implements ConsumerThrowingException<ErrorType, Throwable> {
public static final ErrorHandler<Throwable> LOGGING_HANDLER = new ErrorHandler<Throwable>(Throwable.class, error -> {
LOG.error("Uncaught exception", error);
});
private final Class<ErrorType> type;
private final ConsumerThrowingException<ErrorType, ?> delegate;
public ErrorHandler(Class<ErrorType> type, ConsumerThrowingException<ErrorType, ?> delegate) {
this.type = type;
this.delegate = delegate;
}
public boolean handles(Throwable error) {
return type.isInstance(error);
}
@Override
public void accept(ErrorType error) throws Throwable {
delegate.accept(error);
}
}
public interface AsyncTaskWithoutSuccessHandler<ResultType> extends AsyncTaskWithoutErrorHandler {
/**
* @param handler Tasks to be invoked on the JavaFX application thread.
* @return The async task
*/
AsyncTaskWithoutErrorHandler onSuccess(ConsumerThrowingException<ResultType, ?> handler);
/**
* @param handler Tasks to be invoked on the JavaFX application thread.
* @return The async task
*/
AsyncTaskWithoutErrorHandler onSuccess(RunnableThrowingException<?> handler);
}
public interface AsyncTaskWithoutErrorHandler extends AsyncTaskWithoutFinallyHandler {
/**
* @param type Exception type to catch
* @param handler Tasks to be invoked on the JavaFX application thread.
* @return The async task
*/
<ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, ConsumerThrowingException<ErrorType, ?> handler);
/**
* @param type Exception type to catch
* @param handler Tasks to be invoked on the JavaFX application thread.
* @return The async task
*/
<ErrorType extends Throwable> AsyncTaskWithoutErrorHandler onError(Class<ErrorType> type, RunnableThrowingException<?> handler);
}
public interface AsyncTaskWithoutFinallyHandler extends AsyncTask {
/**
* @param handler Tasks to be invoked on the JavaFX application thread.
* @return The async task
*/
AsyncTask andFinally(RunnableThrowingException<?> handler);
}
public interface AsyncTask extends Runnable {
/**
* Starts the async task.
*/
@Override
void run();
}
}

View File

@@ -38,6 +38,10 @@ public class DialogBuilderUtil {
return buildDialog(title, header, content, Alert.AlertType.CONFIRMATION, defaultButton, ButtonType.YES, ButtonType.NO);
}
public static Alert buildGracefulShutdownDialog(String title, String header, String content, ButtonType defaultButton, ButtonType... buttons) {
return buildDialog(title, header, content, Alert.AlertType.WARNING, defaultButton, buttons);
}
private static Alert buildDialog(String title, String header, String content, Alert.AlertType type, ButtonType defaultButton, ButtonType... buttons) {
Text contentText = new Text(content);
contentText.setWrappingWidth(360.0);

View File

@@ -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);
}
}
}

View File

@@ -28,6 +28,8 @@ import javafx.scene.paint.Color;
@Singleton
public class PasswordStrengthUtil {
private static final int PW_TRUNC_LEN = 100; // truncate very long passwords, since zxcvbn memory and runtime depends vastly on the length
private final Zxcvbn zxcvbn;
private final List<String> sanitizedInputs;
private final Localization localization;
@@ -43,10 +45,9 @@ public class PasswordStrengthUtil {
public int computeRate(String password) {
if (Strings.isNullOrEmpty(password)) {
return -1;
} else if (password.length() > 100) {
return 4; // assume this is strong. zxcvbn memory and runtime depends vastly on the password length
} else {
return zxcvbn.measure(password, sanitizedInputs).getScore();
int numCharsToRate = Math.min(PW_TRUNC_LEN, password.length());
return zxcvbn.measure(password.substring(0, numCharsToRate), sanitizedInputs).getScore();
}
}

View File

@@ -0,0 +1,192 @@
/*******************************************************************************
* Copyright (c) 2018 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.ui.util;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
import javafx.application.Platform;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tasks {
private static final Logger LOG = LoggerFactory.getLogger(Tasks.class);
public static <T> TaskBuilder<T> create(Callable<T> callable) {
return new TaskBuilder<>(callable);
}
public static TaskBuilder<Void> create(VoidCallable callable) {
return create(() -> {
callable.call();
return null;
});
}
public static class TaskBuilder<T> {
private final Callable<T> callable;
private Consumer<T> successHandler = x -> {
};
private List<ErrorHandler<?>> errorHandlers = new ArrayList<>();
private Runnable finallyHandler = () -> {};
TaskBuilder(Callable<T> callable) {
this.callable = callable;
}
public TaskBuilder<T> onSuccess(Runnable successHandler) {
this.successHandler = x -> {
successHandler.run();
};
return this;
}
public TaskBuilder<T> onSuccess(Consumer<T> successHandler) {
this.successHandler = successHandler;
return this;
}
public <E extends Throwable> TaskBuilder<T> onError(Class<E> type, Consumer<E> exceptionHandler) {
errorHandlers.add(new ErrorHandler<>(type, exceptionHandler));
return this;
}
public TaskBuilder<T> andFinally(Runnable finallyHandler) {
this.finallyHandler = finallyHandler;
return this;
}
private Task<T> build() {
return new TaskImpl<>(callable, successHandler, errorHandlers, finallyHandler);
}
public Task<T> runOnce(ExecutorService executorService) {
Task<T> task = build();
executorService.submit(task);
return task;
}
public Task<T> scheduleOnce(ScheduledExecutorService executorService, long delay, TimeUnit unit) {
Task<T> task = build();
executorService.schedule(task, delay, unit);
return task;
}
public ScheduledService<T> schedulePeriodically(ExecutorService executorService, Duration initialDelay, Duration period) {
ScheduledService<T> service = new RestartingService<>(this::build);
service.setExecutor(executorService);
service.setDelay(initialDelay);
service.setPeriod(period);
Platform.runLater(service::start);
return service;
}
}
private static class ErrorHandler<ErrorType extends Throwable> {
private final Class<ErrorType> type;
private final Consumer<ErrorType> errorHandler;
public ErrorHandler(Class<ErrorType> type, Consumer<ErrorType> errorHandler) {
this.type = type;
this.errorHandler = errorHandler;
}
public boolean handles(Throwable error) {
return type.isInstance(error);
}
public void handle(Throwable error) throws ClassCastException {
ErrorType typedError = type.cast(error);
errorHandler.accept(typedError);
}
}
/**
* Adapter between java.util.function.* and javafx.concurrent.*
*/
private static class TaskImpl<T> extends Task<T> {
private final Callable<T> callable;
private final Consumer<T> successHandler;
private List<ErrorHandler<?>> errorHandlers;
private final Runnable finallyHandler;
TaskImpl(Callable<T> callable, Consumer<T> successHandler, List<ErrorHandler<?>> errorHandlers, Runnable finallyHandler) {
this.callable = callable;
this.successHandler = successHandler;
this.errorHandlers = errorHandlers;
this.finallyHandler = finallyHandler;
}
@Override
protected T call() throws Exception {
return callable.call();
}
@Override
protected void succeeded() {
try {
successHandler.accept(getValue());
} finally {
finallyHandler.run();
}
}
@Override
protected void failed() {
try {
Throwable exception = getException();
errorHandlers.stream().filter(handler -> handler.handles(exception)).findFirst().ifPresentOrElse(exceptionHandler -> {
exceptionHandler.handle(exception);
}, () -> {
LOG.error("Unhandled exception", exception);
});
} finally {
finallyHandler.run();
}
}
}
/**
* A service that keeps executing the next task long as tasks are succeeding.
*/
private static class RestartingService<T> extends ScheduledService<T> {
private final Supplier<Task<T>> taskFactory;
RestartingService(Supplier<Task<T>> taskFactory) {
this.taskFactory = taskFactory;
}
@Override
protected Task<T> createTask() {
return taskFactory.get();
}
}
public interface VoidCallable {
void call() throws Exception;
}
}

View File

@@ -434,6 +434,52 @@
-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 *

View File

@@ -7,7 +7,6 @@
Contributors:
Sebastian Stenzel - initial API and implementation
-->
<?import java.net.URL?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.ColumnConstraints?>
@@ -27,30 +26,34 @@
</padding>
<columnConstraints>
<ColumnConstraints percentWidth="38.2"/>
<ColumnConstraints percentWidth="61.8"/>
<ColumnConstraints percentWidth="45.00"/>
<ColumnConstraints percentWidth="55.00"/>
</columnConstraints>
<children>
<!-- Row 0 -->
<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" />
<!-- Row 1 -->
<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%settings.port.label" cacheShape="true" cache="true" />
<HBox GridPane.rowIndex="1" GridPane.columnIndex="1" spacing="6.0">
<TextField fx:id="portField" cacheShape="true" cache="true" promptText="%settings.port.prompt" />
<Button text="%settings.port.apply" fx:id="changePortButton" onAction="#changePort"/>
</HBox>
<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%settings.debugMode.label" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="debugModeCheckbox" cacheShape="true" cache="true" />
<!-- Row 2 -->
<Label GridPane.rowIndex="2" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.prefGvfsScheme.label" cacheShape="true" cache="true" />
<ChoiceBox GridPane.rowIndex="2" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
<!-- Row 3 -->
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" text="%settings.debugMode.label" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="debugModeCheckbox" 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="volume" cacheShape="true" cache="true" />
<!-- Row 3 Alt 1-->
<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" />
</children>
</GridPane>
<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />

View File

@@ -7,8 +7,6 @@
Contributors:
Sebastian Stenzel - initial API and implementation
-->
<?import java.net.URL?>
<?import java.lang.String?>
<?import org.cryptomator.ui.controls.SecPasswordField?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressIndicator?>
@@ -24,12 +22,13 @@
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.layout.VBox?>
<GridPane fx:controller="org.cryptomator.ui.controllers.UnlockController" fx:id="root" vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
<padding>
<Insets top="24.0" right="12.0" bottom="24.0" left="12.0" />
</padding>
<columnConstraints>
<ColumnConstraints percentWidth="38.2"/>
<ColumnConstraints percentWidth="61.8"/>
@@ -45,18 +44,21 @@
<Button fx:id="advancedOptionsButton" text="%unlock.button.advancedOptions.show" prefWidth="150.0" onAction="#didClickAdvancedOptionsButton" cacheShape="true" cache="true" />
<Button fx:id="unlockButton" text="%unlock.button.unlock" defaultButton="true" prefWidth="150.0" onAction="#didClickUnlockButton" disable="true" cacheShape="true" cache="true" />
</HBox>
<!-- Row 3 -->
<Label fx:id="successMessage" cacheShape="true" cache="true" visible="true" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2"/>
<!-- 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">
<padding>
<Insets top="24.0" />
</padding>
<columnConstraints>
<ColumnConstraints percentWidth="38.2"/>
<ColumnConstraints percentWidth="61.8"/>
</columnConstraints>
<!-- Row 3.0 -->
<Separator GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true"/>
<HBox alignment="CENTER" prefWidth="400.0" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
@@ -66,42 +68,47 @@
</padding>
</Label>
</HBox>
<!-- Row 3.1 -->
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="savePassword" text="%unlock.label.savePassword" onAction="#didClickSavePasswordCheckbox" cacheShape="true" cache="true" />
<!-- Row 3.2 -->
<CheckBox GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="unlockAfterStartup" text="%unlock.label.unlockAfterStartup" cacheShape="true" cache="true" />
<!-- Row 3.3 -->
<CheckBox GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="mountAfterUnlock" text="%unlock.label.mountAfterUnlock" cacheShape="true" cache="true" />
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />
<TextField GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="mountName" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
<!-- Row 3.4 -->
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />
<TextField GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="mountName" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="revealAfterMount" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />
<!-- Row 3.5 -->
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="revealAfterMount" text="%unlock.label.revealAfterMount" cacheShape="true" cache="true" />
<!-- Row 3.6 -->
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="useCustomMountPath" text="%unlock.label.useOwnMountPath" cacheShape="true" cache="true" />
<!-- Row 3.6 Alt1 -->
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="winDriveLetterLabel" text="%unlock.label.winDriveLetter" cacheShape="true" cache="true" />
<ChoiceBox GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="winDriveLetter" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
<!-- Row 3.6 Alt2 -->
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="customMountPathLabel" text="%unlock.label.mountPath" cacheShape="true" cache="true" />
<TextField GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="customMountPathField" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
</GridPane>
<!-- Row 4 -->
<TextFlow GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
<GridPane.margin>
<Insets top="24.0"/>
</GridPane.margin>
<children>
<Text fx:id="messageText" cache="true" />
<Hyperlink fx:id="downloadsPageLink" text="%unlock.label.downloadsPageLink" visible="false" onAction="#didClickDownloadsLink" cacheShape="true" cache="true" />
</children>
</TextFlow>
<!-- Row 5-->
<ProgressIndicator progress="-1" fx:id="progressIndicator" GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" cacheShape="true" cache="true" cacheHint="SPEED" />
<!-- Row 5 -->
<VBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" spacing="12.0" alignment="CENTER" cacheShape="true" cache="true">
<ProgressIndicator progress="-1" fx:id="progressIndicator" cacheShape="true" cache="true" cacheHint="SPEED" />
<Text fx:id="messageText" cache="true" />
</VBox>
</children>
</GridPane>

View File

@@ -28,18 +28,9 @@
<fx:define>
<ContextMenu fx:id="moreOptionsMenu">
<items>
<MenuItem fx:id="mountVaultMenuItem" text="%unlocked.moreOptions.mount" onAction="#didClickMountVault">
<graphic><Label text="&#xf139;" styleClass="ionicons"/></graphic>
</MenuItem>
<MenuItem fx:id="unmountVaultMenuItem" text="%unlocked.moreOptions.unmount" onAction="#didClickUnmountVault">
<graphic><Label text="&#xf131;" styleClass="ionicons"/></graphic>
</MenuItem>
<MenuItem fx:id="revealVaultMenuItem" text="%unlocked.moreOptions.reveal" onAction="#didClickRevealVault">
<graphic><Label text="&#xf133;" styleClass="ionicons"/></graphic>
</MenuItem>
<MenuItem text="%unlocked.moreOptions.copyUrl" onAction="#didClickCopyUrl">
<graphic><Label text="&#xf376;" styleClass="ionicons"/></graphic>
</MenuItem>
</items>
</ContextMenu>
</fx:define>

View File

@@ -7,31 +7,28 @@
Contributors:
Sebastian Stenzel - initial API and implementation
-->
<?import java.net.URL?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.control.Button?>
<VBox fx:controller="org.cryptomator.ui.controllers.WelcomeController" fx:id="root" prefWidth="400.0" prefHeight="400.0" spacing="24.0" alignment="CENTER" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
<VBox fx:id="checkForUpdatesContainer" spacing="6.0" alignment="CENTER" cacheShape="true" cache="true" prefHeight="64.0">
<HBox alignment="CENTER" spacing="5.0" cacheShape="true" cache="true">
<Label fx:id="checkForUpdatesStatus" cacheShape="true" cache="true" />
<ProgressIndicator fx:id="checkForUpdatesIndicator" progress="-1" prefWidth="15.0" prefHeight="15.0" cacheShape="true" cache="true" cacheHint="SPEED" />
<ProgressIndicator fx:id="checkForUpdatesIndicator" progress="-1" prefWidth="15.0" prefHeight="15.0" visible="false" cacheShape="true" cache="true" cacheHint="SPEED" />
</HBox>
<Hyperlink wrapText="true" textAlignment="CENTER" fx:id="updateLink" onAction="#didClickUpdateLink" cacheShape="true" cache="true" disable="true" />
</VBox>
<ImageView fitHeight="200.0" preserveRatio="true" smooth="true" cache="true" style="-fx-background-color: green;">
<Image url="/bot_welcome.png"/>
</ImageView>
<VBox prefHeight="64.0"/>
</VBox>

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = فشل فك التشفير
# unlocked.fxml
unlocked.button.lock = اغلاق المحفظة
unlocked.moreOptions.reveal = Reveal Drive
unlocked.moreOptions.copyUrl = نسخ رابط ويب داف ( WebDAV )
unlocked.label.revealFailed = Command failed
unlocked.label.unmountFailed = Ejecting drive failed
unlocked.label.statsEncrypted = مشفر
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = Throughput (MiB/s)
# settings.fxml
settings.version.label = الاصدار %s
settings.checkForUpdates.label = افحص التحديثات
settings.port.label = منفذ ويب داف ( WebDAV )
settings.port.prompt = 0 \= Choose automatically
settings.requiresRestartLabel = * Cryptomator needs to restart
# tray icon
tray.menu.open = فتح
@@ -74,7 +71,6 @@ 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.
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.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
unlock.label.savePassword = حفظ كلمة المرور
@@ -89,18 +85,38 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
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 = Preferred Volume Type
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Vault was successfully created.
unlock.successLabel.passwordChanged = Password was successfully changed.
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Неуспешно декрипт
# unlocked.fxml
unlocked.button.lock = Заключване на Сейфа
unlocked.moreOptions.reveal = Покажи диска
unlocked.moreOptions.copyUrl = Копиране адреса на WebDAV
unlocked.label.revealFailed = Командата е неуспешна
unlocked.label.unmountFailed = Изваждането на диска е неуспешно
unlocked.label.statsEncrypted = криптирано
@@ -54,12 +53,10 @@ unlocked.ioGraph.yAxis.label = Скорост (MB/s)
# settings.fxml
settings.version.label = Версия %s
settings.checkForUpdates.label = Проверка за обновления
settings.port.label = WebDAV порт
settings.port.prompt = 0 \= Автоматично затваряне
settings.requiresRestartLabel = * Криптоматор трябва да се рестартира
# tray icon
tray.menu.open = Отворяне
tray.menu.quit = Излизане
tray.menu.quit = Изход
tray.infoMsg.title = Все още върви
tray.infoMsg.msg = Криптоматор все още върви. Излезте от иконата в трея.
tray.infoMsg.msg.osx = Криптоматор все още върви. Излезте от иконата в менюто.
@@ -74,7 +71,6 @@ main.directoryList.remove.confirmation.header = Наистина ли искат
main.directoryList.remove.confirmation.content = Този сейф ще бъде премахнат само от листа. За да го изтриете напълно, моля, изтрийте сейфа от файл системата.
upgrade.version3to4.msg = Този сейф трябва да бъде преместен към по-нов формат.\nКриптираните имена на папки ще бъдат обновени.\nМоля, проверете дали сихронизацията е приключила преди да продължите.
upgrade.version3to4.err.io = Преместването е отменено поради грешка в диска. Вижте лог файла за детайли.
settings.prefGvfsScheme.label = WebDAV схема
# upgrade.fxml
upgrade.confirmation.label = Да, сигурен съм, че сихронизацията е приключила
unlock.label.savePassword = Запазване на парола
@@ -89,18 +85,38 @@ upgrade.version3to4.title = Обновяване на сейф от 3-та до
upgrade.version4to5.title = Обновяване на сейф от 4-та до 5-та версия
upgrade.version4to5.msg = Този сейф трябва да бъде променен към по-нов формат.\nКриптираните файлове ще бъдат обновени.\nМоля, проверете дали сихронизацията е приключила преди да продължите.\n\nЗабележка\: Датата на промяна на всички файлове ще бъде обновена до момента.
upgrade.version4to5.err.io = Преместването провалено поради грешка в диска. Вижте лог файла за детайли.
settings.port.apply = Прилагане
unlock.label.mountAfterUnlock = Закачане на диска
unlock.label.revealAfterMount = Показване на диска
unlocked.lock.force.confirmation.title = Заключването на %1$s провалено
unlocked.lock.force.confirmation.header = Желаете ли принудително заключване?
unlocked.lock.force.confirmation.content = Това е може би защото други програми все още използват файловете в сейфа или защото има някакъв друг проблем.\n\nПрограмите, имащи достъп до файловете, може да не работят правилно и информацията, незаписана от тези програми, може да бъде изгубена.
unlock.label.unlockAfterStartup = Автоматично отключване при стартиране (Експериментално)
unlock.errorMessage.unlockFailed = Грешка при отключване. Вижте лог файла за детайли.
unlocked.moreOptions.mount = Закачане на диск
unlocked.moreOptions.unmount = Изваждане на диск
upgrade.version5toX.title = Обновяване на версията на сейфа
upgrade.version5toX.msg = Този сейф трябва да бъде обновен до по-нов формат.\nМоля, уверете се, че сихронизацията е приключила, преди да продължите.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
main.createVault.nonEmptyDir.title = Неуспешно създаване на сейф
main.createVault.nonEmptyDir.header = Избраната директория не е празна
main.createVault.nonEmptyDir.content = Избраната директория съдържа файлове /може би скрити/. Сейфът може да бъде създаден само в празна директория
unlock.label.mountPath = Път за монтиране
unlock.label.mountPathButton = Приложи
settings.webdav.port.label = WebCAM порт
settings.webdav.port.prompt = 0 \= Автоматично избиране
settings.webdav.port.apply = Приложи
settings.webdav.prefGvfsScheme.label = WebDAV схема
settings.volume.label = Метод за точка
settings.volume.webdav = WebDAV
settings.volume.fuse = Предпазител
unlock.successLabel.vaultCreated = Сейфът беше създаден успешно
unlock.successLabel.passwordChanged = Паролата беше сменена успешно
unlock.successLabel.upgraded = Криптоматор беше обновен
unlock.label.useOwnMountPath = Използвайте собствена точка за монтиране
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -0,0 +1,124 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = Trezor přidáte kliknutím zde\n
main.directoryList.contextMenu.remove = Odstranit ze seznamu
main.directoryList.contextMenu.changePassword = Změnit heslo
main.addDirectory.contextMenu.new = Vytvořit nový trezor
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.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.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).
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 = Popis umístění přípojného bodu
unlock.label.mountPathButton = Použít
settings.webdav.port.label = Port WebDAV
settings.webdav.port.prompt = 0 \= zvolit automaticky
settings.webdav.port.apply = Použít
settings.webdav.prefGvfsScheme.label = WebDAV schéma
settings.volume.label = Způsob připojení (mount)
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Trezor byl úspěšně vytvořen.
unlock.successLabel.passwordChanged = Heslo bylo úspěšně změněno.
unlock.successLabel.upgraded = Cryptomator byl úspěšně povýšen na novou verzi.
unlock.label.useOwnMountPath = Použít vlastní přípojný bod
welcome.askForUpdateCheck.dialog.title = Zjišťování aktualizací
welcome.askForUpdateCheck.dialog.header = Zjišťovat automaticky nové verze?
welcome.askForUpdateCheck.dialog.content = Ke zjištění aktualizací, Cryptomator stáhne aktuální verzi z instalačních serverů a zobrazí nápovědu, když je k dispozici novější verze, než je nainstalovaná.\n\nDoporučujeme zapnout zjišťování aktualizací a zajistit tak, že vždy budete mít nejnovější verzi Cryptomator, se všemi opravami zabezpečení nainstalovanými. Pokud automatické zjišťování nezapnete, je možné ručně stahovat nejnovější verzi z https\://cryptomator.org/downloads/.\n\nToto nastavení je možné kdykoli změnit v nastavení aplikace.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Individuální přípojný bod není nastaven
main.gracefulShutdown.dialog.title = Zamčení trezorů se nezdařilo
main.gracefulShutdown.dialog.header = Trezory v používání
main.gracefulShutdown.dialog.content = Jeden nebo více trezorů je stále v používání ostatními programy. Ukončete je aby se Cryptomator mohl správně vypnout a zkuste to znovu.\n\nPokud to nezabere, Cryptomator je možné vypnout vynuceně, ale to může vést ke ztrátě dat a není proto doporučeno.
main.gracefulShutdown.button.tryAgain = Zkusit znovu
main.gracefulShutdown.button.forceShutdown = Vynutit vypnutí
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Dekryptering fejlede
# unlocked.fxml
unlocked.button.lock = Lås Vault
unlocked.moreOptions.reveal = Vis drev
unlocked.moreOptions.copyUrl = Kopier WebDAV URL
unlocked.label.revealFailed = Kommando fejlede
unlocked.label.unmountFailed = Afmontering af drev fejlede
unlocked.label.statsEncrypted = Krypteret
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = Throughput (MiB/s)
# settings.fxml
settings.version.label = Version %s
settings.checkForUpdates.label = Tjek for opdateringer
settings.port.label = WebDAV Port
settings.port.prompt = 0 \= Vælg automatisk
settings.requiresRestartLabel = * Cryptomator skal genstartes
# tray icon
tray.menu.open = Åbn
@@ -74,7 +71,6 @@ 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.
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.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Ja, jeg har sikret mig at al synkronisering er gennemført.
unlock.label.savePassword = Gem adgangskode
@@ -89,18 +85,38 @@ upgrade.version3to4.title = Vault Version 3 til 4 Opgradering
upgrade.version4to5.title = Vault Version 4 til 5 Opgradering
upgrade.version4to5.msg = Denne Vault skal migreres til et nyere format.\nDe krypterede filer vil blive opdateret.\nVent venligst til al synkronisering er gennemført, inden du fortsætter.\n\nNote\: Denne proces vil påvirke ændringsdato og -tidspunkt for samtlige filer.
upgrade.version4to5.err.io = Migrering fejlede pga. en I/O fejl. Se logfilen for yderligere detaljer.
settings.port.apply = Gem
unlock.label.mountAfterUnlock = Monter drev
unlock.label.revealAfterMount = Vis drev
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
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 = Preferred Volume Type
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Vault was successfully created.
unlock.successLabel.passwordChanged = Password was successfully changed.
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -7,7 +7,7 @@ main.addDirectory.contextMenu.new = Tresor erstellen
main.addDirectory.contextMenu.open = Tresor öffnen
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Prüfe auf Updates...
welcome.newVersionMessage = Version %1$s kann heruntergeladen werden.\nMomentane Version %2$s.
welcome.newVersionMessage = Version %1$s kann heruntergeladen werden.\nInstallierte Version %2$s.
# initialize.fxml
initialize.label.password = Passwort
initialize.label.retypePassword = Passwort bestätigen
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Entschlüsselung fehlgeschlagen
# unlocked.fxml
unlocked.button.lock = Tresor sperren
unlocked.moreOptions.reveal = Laufwerk anzeigen
unlocked.moreOptions.copyUrl = WebDAV-URL kopieren
unlocked.label.revealFailed = Befehl fehlgeschlagen
unlocked.label.unmountFailed = Trennen des Laufwerks fehlgeschlagen
unlocked.label.statsEncrypted = verschlüsselt
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = Durchsatz (MiB/s)
# settings.fxml
settings.version.label = Version %s
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
# tray icon
tray.menu.open = Öffnen
@@ -74,7 +71,6 @@ 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.
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.
settings.prefGvfsScheme.label = WebDAV Schema
# upgrade.fxml
upgrade.confirmation.label = Ja, die Synchronisation ist abgeschlossen
unlock.label.savePassword = Passwort speichern
@@ -89,18 +85,38 @@ upgrade.version3to4.title = Upgrade Tresor-Version 3 zu 4
upgrade.version4to5.title = Upgrade Tresor-Version 4 zu 5
upgrade.version4to5.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nVerschlüsselte Dateien werden dabei aktualisiert.\nStellen Sie sicher, dass keine Synchronisation stattfindet, bevor Sie fortfahren.\n\nHinweis\: Beim Upgrade wird das Änderungsdatum aller Dateien auf das aktuelle Datum geändert.
upgrade.version4to5.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.
settings.port.apply = Anwenden
unlock.label.mountAfterUnlock = Laufwerk verbinden
unlock.label.revealAfterMount = Laufwerk anzeigen
unlocked.lock.force.confirmation.title = Sperren von %1$s fehlgeschlagen
unlocked.lock.force.confirmation.header = Möchten Sie das Sperren erzwingen?
unlocked.lock.force.confirmation.content = Dies kann passieren, wenn andere Programme weiterhin auf Dateien im Tresor zugreifen. Oder es ist ein anderes Problem aufgetreten.\n\nProgramme, die weiterhin auf die Dateien zugreifen, könnten nicht mehr richtig funktionieren, oder Daten, die durch diese Programme noch nicht geschrieben wurden, könnten verloren gehen.
unlock.label.unlockAfterStartup = Automatisch entsperren beim Start (Experimentell)
unlock.errorMessage.unlockFailed = Entsperren fehlgeschlagen. Siehe Log-Datei für Details.
unlocked.moreOptions.mount = Laufwerk verbinden
unlocked.moreOptions.unmount = Laufwerk auswerfen
upgrade.version5toX.title = Upgrade Tresor-Version 5 zu X
upgrade.version5toX.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nStellen Sie sicher, dass keine Synchronisation stattfindet, bevor Sie fortfahren.
main.createVault.nonEmptyDir.title = Erstellung des Tresors fehlgeschlagen
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.
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 = Der Tresor wurde erfolgreich erstellt.
unlock.successLabel.passwordChanged = Das Passwort wurde erfolgreich geändert.
unlock.successLabel.upgraded = Das Cryptomator Upgrade wurde erfolgreich abgeschlossen.
unlock.label.useOwnMountPath = Eigenes Laufwerksverzeichnis nutzen
welcome.askForUpdateCheck.dialog.title = Auf Updates prüfen
welcome.askForUpdateCheck.dialog.header = Eingebaute Update-Prüfung aktivieren?
welcome.askForUpdateCheck.dialog.content = Empfehlung\: Aktivieren Sie die Update-Prüfung, um sicherzustellen, dass Sie stets die neueste Cryptomator-Version mit allen Sicherheits-Patches verwenden.\n\nDiese Einstellung können Sie jederzeit im Einstellungs-Menü ändern.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Individueller Mount-Punkt ist nicht gesetzt.
main.gracefulShutdown.dialog.title = Sperren des Tresors gescheitert
main.gracefulShutdown.dialog.header = Tresor in Gebrauch
main.gracefulShutdown.dialog.content = Ein oder mehrere Tresore werden noch von anderen Programmen genutzt. Bitte schliessen Sie die Programme um es Cryptomator zu ermöglichen richtig herunter zu fahren. Versuchen Sie es danach erneut.\n\nFalls dies nicht klappt, kann Cryptomator das Beenden erzwingen. Dies kann zu einem Datenverlust führen und ist nicht empfohlen.
main.gracefulShutdown.button.tryAgain = Versuchen Sie es erneut
main.gracefulShutdown.button.forceShutdown = Herunterfahren erzwingen
unlock.pendingMessage.unlocking = Entsperre Tresor...

View File

@@ -19,10 +19,18 @@ main.directoryList.remove.confirmation.content=The vault will only be removed fr
main.createVault.nonEmptyDir.title=Creating vault failed
main.createVault.nonEmptyDir.header=Chosen directory is not empty
main.createVault.nonEmptyDir.content=The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
main.gracefulShutdown.dialog.title=Locking vault(s) failed
main.gracefulShutdown.dialog.header=Vault(s) in use
main.gracefulShutdown.dialog.content=One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain=Try again
main.gracefulShutdown.button.forceShutdown=Force shutdown
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking=Checking for Updates...
welcome.newVersionMessage=Version %1$s can be downloaded.\nThis is %2$s.
welcome.askForUpdateCheck.dialog.title=Update check
welcome.askForUpdateCheck.dialog.header=Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content=Recommended: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
# initialize.fxml
initialize.label.password=Password
@@ -62,11 +70,13 @@ upgrade.version5toX.msg=This vault needs to be migrated to a newer format.\nPlea
# unlock.fxml
unlock.label.password=Password
unlock.label.savePassword=Save Password
unlock.label.mountAfterUnlock=Mount Drive
unlock.label.mountName=Drive Name
unlock.label.unlockAfterStartup=Auto-Unlock on Start (Experimental)
unlock.label.revealAfterMount=Reveal Drive
unlock.label.winDriveLetter=Drive Letter
unlock.label.useOwnMountPath=Use Custom Mount Point
unlock.label.mountPath=Mount path
unlock.label.mountPathButton=Apply
unlock.label.downloadsPageLink=All Cryptomator versions
unlock.label.advancedHeading=Advanced Options
unlock.button.unlock=Unlock Vault
@@ -76,12 +86,18 @@ unlock.savePassword.delete.confirmation.title=Delete Saved Password
unlock.savePassword.delete.confirmation.header=Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content=The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save Password" option enabled.
unlock.choicebox.winDriveLetter.auto=Assign automatically
unlock.pendingMessage.unlocking=Unlocking vault...
unlock.errorMessage.wrongPassword=Wrong password
unlock.errorMessage.wrongPassword=Wrong Password
unlock.errorMessage.invalidMountPath=Use of custom mount path selected, but no path given.
unlock.errorMessage.unlockFailed=Unlock failed. See log file for details.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Unsupported vault. This vault has been created with an older version of Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Unsupported vault. This vault has been created with a newer version of Cryptomator.
unlock.errorMessage.unauthenticVersionMac=Could not authenticate version MAC.
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
changePassword.label.oldPassword=Old Password
@@ -94,10 +110,7 @@ changePassword.errorMessage.decryptionFailed=Decryption failed
# unlocked.fxml
unlocked.button.lock=Lock Vault
unlocked.moreOptions.mount=Mount Drive
unlocked.moreOptions.unmount=Eject Drive
unlocked.moreOptions.reveal=Reveal Drive
unlocked.moreOptions.copyUrl=Copy WebDAV URL
unlocked.label.mountFailed=Connecting drive failed
unlocked.label.revealFailed=Command failed
unlocked.label.unmountFailed=Ejecting drive failed
@@ -111,12 +124,16 @@ unlocked.lock.force.confirmation.content=This may be because other programs are
# settings.fxml
settings.version.label=Version %s
settings.checkForUpdates.label=Check for Updates
settings.port.label=WebDAV Port
settings.port.prompt=0 = Choose automatically
settings.port.apply=Apply
settings.prefGvfsScheme.label=WebDAV Scheme
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.debugMode.label=Debug Mode *
settings.requiresRestartLabel=* Cryptomator needs to restart
settings.volume.label=Preferred Volume Type
settings.volume.webdav=WebDAV
settings.volume.fuse=FUSE
settings.volume.dokany=Dokany
# tray icon
tray.menu.open=Open

View File

@@ -47,17 +47,14 @@ changePassword.errorMessage.decryptionFailed = Error en el descifrado
# unlocked.fxml
unlocked.button.lock = Bloquear caja fuerte
unlocked.moreOptions.reveal = Revelar unidad
unlocked.moreOptions.copyUrl = Copiar URL de WebDAV
unlocked.label.revealFailed = La orden ha fallado
unlocked.label.unmountFailed = Error al expulsar la unidad
unlocked.label.statsEncrypted = cifrado
unlocked.label.statsDecrypted = descifrado
unlocked.label.statsEncrypted = encriptado
unlocked.label.statsDecrypted = desencriptado
unlocked.ioGraph.yAxis.label = Rendimiento (MiB/s)
# settings.fxml
settings.version.label = Versión %s
settings.checkForUpdates.label = Comprobar actualizaciones
settings.port.label = Puerto WebDAV
settings.port.prompt = 0 \= Elegir automáticamente
settings.requiresRestartLabel = * Cryptomator necesita reiniciarse
# tray icon
tray.menu.open = Abrir
@@ -76,8 +73,6 @@ main.directoryList.remove.confirmation.header = ¿Quiere de realmente eliminar e
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 moderno.\nLos nombres de las carpetas cifradas se actualizarán.\nAsegúrese de que la sincronización ha terminado antes de continuar.
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 de WebDAV
# upgrade.fxml
upgrade.confirmation.label = Sí, me he asegurado de que la sincronización ha terminado
unlock.label.savePassword = Guardar contraseña
@@ -90,20 +85,40 @@ settings.debugMode.label = Modo depuración *
upgrade.version3dropBundleExtension.title = Actualizar caja fuerte a la versión 3 (Drop Bundle Extension)
upgrade.version3to4.title = Actualizar caja fuerte de versión 3 a 4
upgrade.version4to5.title = Actualizar caja fuerte de versión 4 a 5
upgrade.version4to5.msg = Esta caja fuerte tiene que ser migrada a un formato más moderno.\nLos archivos cifrados se actualizarán.\nAsegúrese de que la sincronización ha terminado antes de iniciar el proceso.\n\nNota\: las fechas de modificación de todos los archivos, se cambiarán a la fecha actual.
upgrade.version4to5.msg = Esta caja fuerte tiene que ser migrada a un formato más moderno.\nLos archivos encriptados se actualizarán.\nAsegúrese de que la sincronización ha terminado antes de iniciar el proceso.\n\nNota\: las fechas de modificación de todos los archivos, se cambiarán a la fecha actual.
upgrade.version4to5.err.io = Error en la migración debido a una excepción E/S. Consulte el archivo de registro para más información.
settings.port.apply = Aplicar
unlock.label.mountAfterUnlock = Montar unidad
unlock.label.revealAfterMount = Revelar unidad
unlocked.lock.force.confirmation.title = Error al bloquear %1$s
unlocked.lock.force.confirmation.header = ¿Quiere forzar el bloqueo?
unlocked.lock.force.confirmation.content = Esto puede ser debido a que otros programas estén todavía accediendo a la caja fuerte o porque se ha producido algún otro problema.\n\nLos programas que estén todavía accediendo a los archivos pueden no funcionar correctamente y se pueden perder los datos pendientes de escribir por estos programas.
unlock.label.unlockAfterStartup = Autodesbloqueo al arrancar (experimental)
unlock.errorMessage.unlockFailed = Error al desbloquear. Consulte el archivo de registro para más información.
unlocked.moreOptions.mount = Montar unidad
unlocked.moreOptions.unmount = Expulsar unidad
upgrade.version5toX.title = Actualizar la versión de la caja fuerte
upgrade.version5toX.msg = Esta caja fuerte debe ser migrada a un formato más moderno.\nAsegúrese de que la sincronización ha terminado antes de iniciar el proceso.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
main.createVault.nonEmptyDir.title = Error en la creación de la bóveda
main.createVault.nonEmptyDir.header = El directorio elegido no está vacío
main.createVault.nonEmptyDir.content = El directorio seleccionado ya contiene archivos (posiblemente ocultos). Una bóveda sólo puede crearse en un directorio vacío.
unlock.label.mountPath = Punto de montaje
unlock.label.mountPathButton = Aplicar
settings.webdav.port.label = Puerto WebDAV
settings.webdav.port.prompt = 0 \= Elige automáticamente
settings.webdav.port.apply = Aplicar
settings.webdav.prefGvfsScheme.label = Esquema de WebDAV
settings.volume.label = Método de montaje *
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = La caja fuerte fue creada exitosamente.
unlock.successLabel.passwordChanged = La contraseña ha sido cambiada con éxito.
unlock.successLabel.upgraded = Cryptomator fue actualizado exitosamente.
unlock.label.useOwnMountPath = Usar Punto de montaje propio
welcome.askForUpdateCheck.dialog.title = Buscar actualización
welcome.askForUpdateCheck.dialog.header = ¿Habilitar la búsqueda de actualizaciones automática?
welcome.askForUpdateCheck.dialog.content = Para buscar actualizaciones, Cryptomator buscará la versión actual en los servidores de Cryptomator y le mostrará una sugerencia si hay una versión más nueva disponible.\n\nRecomendamos habilitar la comprobación de actualización para asegurarse siempre de que tiene instalada la versión más reciente de Cryptomator, con todos los parches de seguridad. Si no habilita la verificación de actualización, puede verificar y descargar la versión actual desde https\://cryptomator.org/downloads/.\n\nPuede cambiar esto en cualquier momento desde dentro de la configuración.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = La ruta individual de montaje no ha sido asignada.
main.gracefulShutdown.dialog.title = No fue posible cerrar la(s) caja(s) fuerte(s)
main.gracefulShutdown.dialog.header = Caja(s) Fuertes(s) en uso
main.gracefulShutdown.dialog.content = Una o más cajas fuertes están siendo utilizadas por otros programas. Por favor ciérrelos para permitir a Cryptomator cerrarse adecuadamente, e intente de nuevo.\n\nSi esto no funciona, Cryptomator puede cerrarse forzosamente, pero esta vía puede provocar pérdida de información y no es recomendada.
main.gracefulShutdown.button.tryAgain = Intente de nuevo
main.gracefulShutdown.button.forceShutdown = Forzar apagado
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -1,24 +1,24 @@
app.name = Cryptomator
# 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.changePassword = Changer le mot de passe
main.addDirectory.contextMenu.new = Créer un nouveau coffre
main.addDirectory.contextMenu.open = Ouvrir un coffre existant
main.addDirectory.contextMenu.new = Créer un nouveau coffre-fort
main.addDirectory.contextMenu.open = Ouvrir un coffre-fort existant
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Recherche de mise à jour...
welcome.newVersionMessage = La version %1$s peut-être téléchargée.\nIl s'agit de %2$s.
welcome.checkForUpdates.label.currentlyChecking = Rechercher les mises à jour...
welcome.newVersionMessage = La version %1$s peut-être téléchargée.\nLa version installée est la %2$s.
# initialize.fxml
initialize.label.password = Mot de passe
initialize.label.retypePassword = Confirmation
initialize.button.ok = Créer le coffre
initialize.messageLabel.alreadyInitialized = Coffre déjà initialisé
initialize.messageLabel.initializationFailed = Impossible d'initialiser le coffre. Voir le fichier de log pour plus de détails.
initialize.button.ok = Créer le coffre-fort
initialize.messageLabel.alreadyInitialized = Coffre-fort déjà initialisé
initialize.messageLabel.initializationFailed = Impossible d'initialiser le coffre-fort. Vérifiez le fichier de log pour plus de détails.
# 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.button = Mettre à niveau
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.button = Mettre à jour
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à.
# unlock.fxml
unlock.label.password = Mot de passe
@@ -26,14 +26,14 @@ unlock.label.mountName = Nom du lecteur
unlock.label.winDriveLetter = Lettre du lecteur
unlock.label.downloadsPageLink = Toutes les versions de Cryptomator
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.hide = Moins d'options
unlock.choicebox.winDriveLetter.auto = Assigner automatiquement
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.softwareOlderThanVault = Coffre 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.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Coffre-fort non supporté. Ce coffre a été créé avec une ancienne version de Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Coffre-fort non supporté. Ce coffre a été créé avec une version de Cryptomator plus récente.
unlock.messageLabel.startServerFailed = Echec de démarrage du serveur WebDAV.
# change_password.fxml
changePassword.label.oldPassword = Ancien mot de passe
changePassword.label.newPassword = Nouveau mot de passe
@@ -44,9 +44,8 @@ changePassword.errorMessage.wrongPassword = Mot de passe incorrect
# En français, on dit déchiffrement lorsque la clé est connue
changePassword.errorMessage.decryptionFailed = Echec du déchiffrement
# unlocked.fxml
unlocked.button.lock = Verrouiller le coffre
unlocked.button.lock = Verrouiller le coffre-fort
unlocked.moreOptions.reveal = Voir le lecteur
unlocked.moreOptions.copyUrl = Copier l'URL WebDAV
unlocked.label.revealFailed = Echec de la commande
unlocked.label.unmountFailed = Echec de l'éjection du lecteur
# Crypter n'existe pas en français.
@@ -56,54 +55,71 @@ unlocked.label.statsDecrypted = déchiffré
unlocked.ioGraph.yAxis.label = Débit (MiB/s)
# settings.fxml
settings.version.label = Version %s
settings.checkForUpdates.label = Vérif. des mises à jour
settings.port.label = Port WebDAV *
settings.port.prompt = 0 \= Choix automatique
settings.checkForUpdates.label = Vérifier les mises à jour
settings.requiresRestartLabel = * Redémarrage requis
# tray icon
tray.menu.open = Ouvrir
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.osx = Cryptomator est toujours en fonctionnement. Utilisez la barre de menu pour quitter.
initialize.messageLabel.passwordStrength.0 = Très faible
initialize.messageLabel.passwordStrength.1 = Faible
initialize.messageLabel.passwordStrength.2 = Raisonnable
initialize.messageLabel.passwordStrength.2 = Correct
initialize.messageLabel.passwordStrength.3 = 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.
main.directoryList.remove.confirmation.title = Retirer un coffre
main.directoryList.remove.confirmation.header = Voulez-vous vraiment retirer ce coffre ?
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.
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.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.
settings.prefGvfsScheme.label = Schéma d'URI WebDAV
main.directoryList.remove.confirmation.title = Supprimer le coffre-fort
main.directoryList.remove.confirmation.header = Voulez-vous vraiment supprimer ce coffre-fort ?
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-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. Vérifiez le fichier de log pour plus de détails.
# upgrade.fxml
upgrade.confirmation.label = Oui, je suis certain que la synchronisation est terminée
unlock.label.savePassword = Se souvenir du mot de passe
unlock.errorMessage.unauthenticVersionMac = Impossible d'authentifier la version MAC
unlocked.label.mountFailed = Echec de connexion au lecteur
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.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.
settings.debugMode.label = mode debuggage*
upgrade.version3dropBundleExtension.title = mise à jour vers la version 3 du coffre (extension "drop bundle")
upgrade.version3to4.title = metre à jour le coffre de la version 3 à la version 4
upgrade.version4to5.title = metre à jour le coffre de la version 4 à la version 5
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.err.io = Migration échouée due à une erreur de lecture. Lisez les logs pour plus de détails.
settings.port.apply = Appliquer
unlock.label.mountAfterUnlock = Monter un lecteur
unlock.savePassword.delete.confirmation.title = Supprimer le mot de passe sauvegardé
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 "Se souvenir du mot de passe" lors du déverrouillage du coffre.
settings.debugMode.label = Mode bug *
upgrade.version3dropBundleExtension.title = Mise à jour du coffre-fort (en version 3 extension "Drop Bundle")
upgrade.version3to4.title = Mise à jour de la version du coffre-fort (v3 à v4)
upgrade.version4to5.title = Mise à jour de la version du coffre-fort (v4 à v5)
upgrade.version4to5.msg = Ce coffre-fort doit être migré vers un format plus récent.\nLes fichiers chiffrés seront mis à jour.\nVeuillez vérifier que la synchronisation est terminée avant de commencer.\n\nNote \: la date de modification des fichiers sera mise à jour avec la date courante.
upgrade.version4to5.err.io = La migration a échoué à cause d'une erreur d'entrée/sortie. Vérifiez le fichier de log pour plus de détails.
unlock.label.revealAfterMount = Voir le lecteur
unlocked.lock.force.confirmation.title = Le vérouillage de %1$s a ćhoué
unlocked.lock.force.confirmation.header = Voulez-vous forcer le vérouillage ?
unlocked.lock.force.confirmation.content = Cela peut être car d'autres programmes sont entrain d'accéder à des fichiers dans le coffre ou car d'autres problème se sont produits.\n\nLes programmes accédant aux fichiers pourraient ne pas fonctionner normalement et les données pas encore sauvegardées par ces programmes pourraient être perdues.
unlock.label.unlockAfterStartup = Déverouiller automatiquement au démarrage (Experimental)
unlock.errorMessage.unlockFailed = Le déverouillage a échoué. Regarder les logs pour plus d'informations.
unlocked.moreOptions.mount = Monter le disque
unlocked.moreOptions.unmount = Ejecter le disque
upgrade.version5toX.title = Mise à niveau de la version du coffre
upgrade.version5toX.msg = Ce coffre doit être converti dans un format plus récent. Veuillez-vous assurez que la synchronisation est finie avant de continuer.
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.
unlocked.lock.force.confirmation.title = Le verrouillage de %1$s a échoué
unlocked.lock.force.confirmation.header = Voulez-vous forcer le verrouillage ?
unlocked.lock.force.confirmation.content = D'autres programmes sont peut être en train d'accéder à des fichiers dans le coffre-fort ou un autre problème s'est produit.\n\nLes programmes accédant encore aux fichiers pourraient ne pas fonctionner normalement et les données pas encore sauvegardées par ces programmes pourraient être perdues.
unlock.label.unlockAfterStartup = Déverouiller automatiquement au démarrage (experimental)
unlock.errorMessage.unlockFailed = Le déverouillage a échoué. Référez-vous au fichier log pour plus de détails.
upgrade.version5toX.title = Mise à jour du coffre-fort
upgrade.version5toX.msg = Ce coffre-fort doit être converti dans un format plus récent. \nVeuillez-vous assurez que la synchronisation est achevée avant de continuer.
main.createVault.nonEmptyDir.title = Echec de création du coffre-fort
main.createVault.nonEmptyDir.header = Le répertoire sélectionné n'est pas vide
main.createVault.nonEmptyDir.content = Le répertoire sélectionné contient déjà des fichiers (potentiellement cachés). Un coffre-fort ne peut être créé que dans un répertoire vide.
unlock.label.mountPath = Chemin de montage
unlock.label.mountPathButton = Appliquer
settings.webdav.port.label = Port de WebDAV
settings.webdav.port.prompt = 0 \= choisir automatiquement
settings.webdav.port.apply = Appliquer
settings.webdav.prefGvfsScheme.label = stratagème webdav
settings.volume.label = méthode de montage
settings.volume.webdav = WebDAV
settings.volume.fuse = limite
unlock.successLabel.vaultCreated = Le coffre-fort a été créé avec succès
unlock.successLabel.passwordChanged = Le mot de passe a été changé avec succès
unlock.successLabel.upgraded = Cryptomator a été mise à jour avec succès
unlock.label.useOwnMountPath = Utiliser son propre point de montage
welcome.askForUpdateCheck.dialog.title = vérification de la mise à jour
welcome.askForUpdateCheck.dialog.header = Activer le contrôle de mise à jour intégré ?
welcome.askForUpdateCheck.dialog.content = Pour vérifier les mises à jour, Cryptomator récupère la version actuelle sur les serveurs Cryptomator et vous donne un aperçu si une nouvelle version est disponible.\n\nNous vous recommandons d'activer la vérification de mise à jour pour vous assurer que vous avez toujours la dernière version de Cryptomator, avec tous les correctifs de sécurité, installés. Si vous n'activez pas le contrôle de mise à jour, vous pouvez vérifier et télécharger la version actuelle à partir de https\://cryptomator.org/downloads/.\n\nVous pouvez le modifier à tout moment à partir des paramètres.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Le chemin de montage n'est pas défini.
main.gracefulShutdown.dialog.title = Échec en fermant le coffre-fort.
main.gracefulShutdown.dialog.header = Coffre-fort est en cours d'utilisation.
main.gracefulShutdown.dialog.content = Un ou plusieurs coffre-forts sont en cours d'utilisation par d'autres logiciels. S'il vous plait, fermer-les pour permettre à Cryptomator de finir proprement.\n\nSi ça ne marche pas, Cryptomator peut fermer par force, mais cela peut résulter d'une perte de vos fichiers (non recommandé).
main.gracefulShutdown.button.tryAgain = Réessayez
main.gracefulShutdown.button.forceShutdown = Arrêt forcé
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = A titkosítás feloldása meghíu
# unlocked.fxml
unlocked.button.lock = Széf lezárása
unlocked.moreOptions.reveal = Meghajtó felfedése
unlocked.moreOptions.copyUrl = WebDAV URL másolása
unlocked.label.revealFailed = Parancs meghíusúlt
unlocked.label.unmountFailed = Meghajtó leválasztása sikertelen
unlocked.label.statsEncrypted = titkosított
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = Teljesítmény (MiB/s)
# settings.fxml
settings.version.label = Verzió\: %s
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
# tray icon
tray.menu.open = Megnyit
@@ -74,11 +71,10 @@ 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.
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.
settings.prefGvfsScheme.label = WebDAV séma
# upgrade.fxml
upgrade.confirmation.label = Igen, meggyőződtem a szinkronizáció befejeztéről
unlock.label.savePassword = Jelszó mentése
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlock.errorMessage.unauthenticVersionMac = Nem lehet a MAC verziót azonosítani.
unlocked.label.mountFailed = Meghajtó csatlakoztatása sikertelen
unlock.savePassword.delete.confirmation.title = Mentett jelszó törlése
unlock.savePassword.delete.confirmation.header = Biztosan el akarod távolítani a széfhez tartozó mentett jelszót?
@@ -89,18 +85,38 @@ upgrade.version3to4.title = Széf verziófrissítése 3-ról 4-re
upgrade.version4to5.title = Széf verziófrissítése 4-ről 5-re
upgrade.version4to5.msg = Ennek a széfnek egy újabb formátumra való migrációja szükséges. A titkosított könyvtárnevek frissítve lesznek. Kérlek, győződj meg a szinkronizáció befejeztéről mielőtt továbblépnél.\n\nMegjegyzés\: A összes fájl módosításának dátuma az aktuális időre fog módosulni
upgrade.version4to5.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
unlock.label.revealAfterMount = Meghajtó megnyitása
unlocked.lock.force.confirmation.title = Sikertelen lezárás a következőnél\: %1$s
unlocked.lock.force.confirmation.header = Szeretné erőltetni a lezárást?
unlocked.lock.force.confirmation.content = Ez amiatt lehet, mert más programok még mindig használják a széfben lévő fájlokat vagy valamilyen egyéb probléma lépett fel.\n\nA programok, amik használják ezeket a fájlokat, nem működhetnek megfelelően vagy akár adatvesztés is előfordulhat.
unlock.label.unlockAfterStartup = Automatikus feloldás indításnál (kísérleti funkció)
unlock.errorMessage.unlockFailed = A feloldás nem sikerült. Nézze meg a naplófájlokat.
upgrade.version5toX.title = Széf verziófrissítés
upgrade.version5toX.msg = A széf új verzióra történő migrációja szükséges.\nKérlek győződj meg a szinkronizáció befejeztéről, mielőtt más műveletet végeznél.
main.createVault.nonEmptyDir.title = A széf létrehozása sikertelen
main.createVault.nonEmptyDir.header = A kiválasztott mappa nem üres
main.createVault.nonEmptyDir.content = A kiválasztott mappa már tartalmaz fájlokat (valószínűleg rejtett). A széf csak üres mappában hozható létre.
unlock.label.mountPath = Elérési út csatlakoztatása
unlock.label.mountPathButton = Alkalmaz
settings.webdav.port.label = WebDAV Port
settings.webdav.port.prompt = 0 \= Automatikus választás
settings.webdav.port.apply = Alkalmaz
settings.webdav.prefGvfsScheme.label = WebDAV séma
settings.volume.label = Csatlakoztatási mód
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = A széf sikeresen létrehozva.
unlock.successLabel.passwordChanged = A jelszó sikeresen megváltoztatva.
unlock.successLabel.upgraded = A Cryptomator sikeresen frissítésre került.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Próbáld újra
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Decriptaggio fallito
# unlocked.fxml
unlocked.button.lock = Blocca vault
unlocked.moreOptions.reveal = Apri il disco
unlocked.moreOptions.copyUrl = Copia url WebDAV
unlocked.label.revealFailed = Comando fallito
unlocked.label.unmountFailed = Espulsione disco fallita
unlocked.label.statsEncrypted = criptato
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = Volume dati (MiB/s)
# settings.fxml
settings.version.label = Versione %s
settings.checkForUpdates.label = Verifica aggiornamenti
settings.port.label = WebDAV Port *
settings.port.prompt = 0 \= Scegli automaticamente
settings.requiresRestartLabel = * Cryptomator deve essere riavviato
# tray icon
tray.menu.open = Apri
@@ -74,7 +71,6 @@ 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.
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.
settings.prefGvfsScheme.label = Schema WebDAV
# upgrade.fxml
upgrade.confirmation.label = Si, sono sicuro che la sincronizzazione e' terminata
unlock.label.savePassword = Salva Password
@@ -89,18 +85,38 @@ upgrade.version3to4.title = Aggiornamento Vault da versione 3 a 4
upgrade.version4to5.title = Aggiornamento da versione 4 a 5
upgrade.version4to5.msg = Questo vault ha bisogno di essere migrato ad un formato piu' recente. Tutti i files criptati saranno aggiornati. Per favore assicurati che la sincronizzazione sia terminata prima di procedere.\n\nNota\: la data di modifica di tutti i files cambiera' alla data/ora attuale del processo.
upgrade.version4to5.err.io = Migrazione fallita a causa di una eccezione I/O. Verifica il file di log per i dettagli.
settings.port.apply = Conferma
unlock.label.mountAfterUnlock = Monta il disco
unlock.label.revealAfterMount = Mostra il disco
unlocked.lock.force.confirmation.title = Il blocco di %1$s è fallito
unlocked.lock.force.confirmation.header = Vuoi forzare il blocco?
unlocked.lock.force.confirmation.content = E' accaduto questo perchè altri programmi stanno ancora utilizzando i dati nel vault o perchè è accaduto un altro problema
unlock.label.unlockAfterStartup = Blocco automatico all'avvio (Sperimentale)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
unlock.errorMessage.unlockFailed = Sblocco fallito. Guarda il file log per i dettagli.
upgrade.version5toX.title = Aggiornamento di versione del Vault
upgrade.version5toX.msg = Questo vault deve migrare ad un nuovo formato.\nAssicurati che la sincronizzazione sia terminata prima di procedere.
main.createVault.nonEmptyDir.title = Creazione del vaul fallita
main.createVault.nonEmptyDir.header = La directory scelta non è vuota
main.createVault.nonEmptyDir.content = La directory selezionata contiene già dei file (forse nascosti). Un vault può essere creato solo in una directory vuota.
unlock.label.mountPath = Monta il percorso
unlock.label.mountPathButton = Applica
settings.webdav.port.label = WebDAV Port
settings.webdav.port.prompt = 0 \= Scelta automatica
settings.webdav.port.apply = Applica
settings.webdav.prefGvfsScheme.label = WebDAV Scheme
settings.volume.label = Mount-Methode *
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Vaul creato con successo.
unlock.successLabel.passwordChanged = Password modificata con successo.
unlock.successLabel.upgraded = Cryptomator aggiornato con successo.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -12,7 +12,7 @@ welcome.newVersionMessage = バージョン %1$s がダウンロード可能で
initialize.label.password = パスワード
initialize.label.retypePassword = パスワードの再入力
initialize.button.ok = 金庫を作成
initialize.messageLabel.alreadyInitialized = 金庫は既に初期化されています
initialize.messageLabel.alreadyInitialized = 金庫は既に初期化されています
initialize.messageLabel.initializationFailed = 金庫の初期化ができませんでした。詳細はログファイルをご覧ください。
# notfound.fxml
notfound.label = 金庫が見つかりません。移動しましたか?
@@ -31,8 +31,8 @@ unlock.button.advancedOptions.show = オプションを表示
unlock.button.advancedOptions.hide = オプションを非表示
unlock.choicebox.winDriveLetter.auto = 自動的に割り当てる
unlock.errorMessage.wrongPassword = パスワードが無効です
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = サポートされない金庫です。この金庫は古いバージョンの Cryptomator から作成されました。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = サポートされない金庫です。この金庫は新しいバージョンの Cryptomator から作成されました。
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = サポートされない金庫です。この金庫は古いバージョンの Cryptomator を使用して作成されました。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = サポートされない金庫です。この金庫は新しいバージョンの Cryptomator を使用して作成されました。
unlock.messageLabel.startServerFailed = WebDAV サーバーの起動に失敗しました。
# change_password.fxml
changePassword.label.oldPassword = 古いパスワード
@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = 復号に失敗しました。
# unlocked.fxml
unlocked.button.lock = 金庫の施錠
unlocked.moreOptions.reveal = ドライブの表示
unlocked.moreOptions.copyUrl = WebDAV URL のコピー
unlocked.label.revealFailed = 入力エラー
unlocked.label.unmountFailed = ドライブの取り出しに失敗
unlocked.label.statsEncrypted = 暗号化済み
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = スループット (MiB/s)
# settings.fxml
settings.version.label = バージョン %s
settings.checkForUpdates.label = 最新版のチェック
settings.port.label = WebDAV ポート
settings.port.prompt = 0 \= 自動的に選択
settings.requiresRestartLabel = *Cryptomatorの再起動が必要
# tray icon
tray.menu.open = 開く
@@ -74,7 +71,6 @@ main.directoryList.remove.confirmation.header = この金庫を本当に削除
main.directoryList.remove.confirmation.content = 金庫はリストのみで削除されます。完全に削除するには、ファイルシステムからファイルを削除してください。
upgrade.version3to4.msg = この金庫は新しいフォーマットに移行する必要があります。\n暗号化されたフォルダの名前は更新されます。\n続行する前に同期が完了していることをご確認ください。
upgrade.version3to4.err.io = I/O の例外で移行に失敗しました。詳細はログをご確認ください。
settings.prefGvfsScheme.label = WebDAV スキーム
# upgrade.fxml
upgrade.confirmation.label = はい、同期が完了していることを確認しました。
unlock.label.savePassword = パスワードを保存
@@ -89,18 +85,38 @@ upgrade.version3to4.title = 金庫をバージョン 3 から 4 にアップグ
upgrade.version4to5.title = 金庫をバージョン 4 から 5 にアップグレード
upgrade.version4to5.msg = この金庫は新しいフォーマットに移行する必要があります。\n暗号化されたファイルは更新されます。\n続行する前に同期が完了していることをご確認ください。\n\n注意すべてのファイルの変更日は、現在の日付・時刻に変わります。
upgrade.version4to5.err.io = I/O の例外で移行に失敗しました。詳細はログをご確認ください。
settings.port.apply = 適用
unlock.label.mountAfterUnlock = ドライブをマウント
unlock.label.revealAfterMount = ドライブの表示
unlocked.lock.force.confirmation.title = %1$s の施錠に失敗しました
unlocked.lock.force.confirmation.header = 強制的にロックしますか?
unlocked.lock.force.confirmation.content = これは恐らく他のプログラムがこの金庫のファイルをまだアクセスしているか、あるいは別の問題が発生したためです。\n\nまだファイルにアクセスしているプログラムが正しく動作しない可能性があり、それらのプログラムによってまだ書き込まれていないデータが失われる可能性があります。
unlock.label.unlockAfterStartup = 起動時に解錠 (実験的)
unlock.errorMessage.unlockFailed = 施錠に失敗しました。詳細をログファイルで確認してください。
unlocked.moreOptions.mount = ドライブのマウント
unlocked.moreOptions.unmount = ドライブの取り出し
upgrade.version5toX.title = 金庫のバージョンをアップグレード
upgrade.version5toX.msg = この金庫を新しいバージョンに移行する必要があります。\n進行する前に同期が完了していることをご確認ください。
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
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 = 金庫が正常に作成されました。
unlock.successLabel.passwordChanged = パスワードが正常に変更されました。
unlock.successLabel.upgraded = Cryptomator が正常にアップグレードされました。
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = 암호화 해제 실패
# unlocked.fxml
unlocked.button.lock = 보관함 잠그기
unlocked.moreOptions.reveal = 드라이브 표시
unlocked.moreOptions.copyUrl = WebDAV 주소 복사
unlocked.label.revealFailed = 명령 실패
unlocked.label.unmountFailed = 드라이브 꺼내기 실패
unlocked.label.statsEncrypted = 암호화
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = 처리량 (MiB/s)
# settings.fxml
settings.version.label = 버전 %s
settings.checkForUpdates.label = 업데이트 확인
settings.port.label = WebDAV 포트 *
settings.port.prompt = 0 \= 자동으로 선택
settings.requiresRestartLabel = * Cryptomator 재시작 필요
# tray icon
tray.menu.open = 열기
@@ -74,7 +71,6 @@ main.directoryList.remove.confirmation.header = 정말 이 보관함을 삭제
main.directoryList.remove.confirmation.content = 보관함이 목록에서만 제거되었습니다. 데이터를 완전히 제거하시려면, 사용자의 파일시스템이서 제거해 주시기 바랍니다.
upgrade.version3to4.msg = 이 보관함은 새로운 형식으로 이전되어야 합니다. 암호화된 폴더 이름이 업데이트 될 것입니다. 진행하기 전에 동기화가 완료되었는지 확인하기 바랍니다.
upgrade.version3to4.err.io = I/O 예외 문제로 마이그레이션이 실패하였습니다. 자세한 사항은 로그 파일을 확인하세요.
settings.prefGvfsScheme.label = WebDAV 스키마
# upgrade.fxml
upgrade.confirmation.label = 네. 동기화가 완료되었음을 확인하였습니다.
unlock.label.savePassword = 비밀번호 저장
@@ -89,18 +85,38 @@ upgrade.version3to4.title = 보관함 버전 3에서 4로 업그레이드
upgrade.version4to5.title = 보관함 버전 4에서 5로 업그레이드
upgrade.version4to5.msg = 이 보관함은 새로운 형식으로 이전되어야 합니다.\n암호화된 파일들은 업데이트 될 것입니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.\n\n참고\: 모든 파일의 수정 날짜는 과정 진행 중에 현재 날짜/시간으로 바뀔 것입니다.
upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요.
settings.port.apply = 적용
unlock.label.mountAfterUnlock = 드라이브 마운트
unlock.label.revealAfterMount = 드라이브 공개
unlocked.lock.force.confirmation.title = %1$s 잠그기 실패
unlocked.lock.force.confirmation.header = 강제로 잠그시겠습니까?
unlocked.lock.force.confirmation.content = 이는 다른 프로그램이 보관함 내의 파일을 접근하고 있거나, 다른 문제가 발생했기 때문일 수 있습니다.\n\n파일을 접근하고 있는 프로그램이 제대로 동작하지 않을 수 있으며, 프로그램이 쓰지 않은 데이터는 손실될 수 있습니다.
unlock.label.unlockAfterStartup = 시작 시 자동 잠금 해제 (실험적)
unlock.errorMessage.unlockFailed = 잠금 해제 실패. 자세한 사항은 로그 파일을 참조하세요.
unlocked.moreOptions.mount = 드라이브 마운트
unlocked.moreOptions.unmount = 드라이브 꺼내기
upgrade.version5toX.title = 보관함 버전 업그레이드
upgrade.version5toX.msg = 이 보관함은 새로운 버전으로 이전되어야 합니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
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.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Atšifrēšana neizdevās
# unlocked.fxml
unlocked.button.lock = Aizslēgt glabātuvi
unlocked.moreOptions.reveal = Atklāt disku
unlocked.moreOptions.copyUrl = Kopēt WebDAV saiti
unlocked.label.revealFailed = Komunikācija neizdevās
unlocked.label.unmountFailed = Diska izgrūšana neizdevās
unlocked.label.statsEncrypted = šifrēts
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = Caurlaidība (MiB/s)
# settings.fxml
settings.version.label = Versija %s
settings.checkForUpdates.label = Meklēt atjauninājumus
settings.port.label = WebDAV Ports *
settings.port.prompt = 0 \= automātiski
settings.requiresRestartLabel = * Cryptomator nepieciešams restarts
# tray icon
tray.menu.open = Atvērt
@@ -75,7 +72,6 @@ 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.
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.
settings.prefGvfsScheme.label = WebDAV shēma
# upgrade.fxml
upgrade.confirmation.label = Jā, esmu pārliecinājies, ka sinhronizācija ir pabeigta.
unlock.label.savePassword = Saglabāt paroli
@@ -90,18 +86,38 @@ upgrade.version3to4.title = Glabātuves versijas 3 uz 4 atjauninājums
upgrade.version4to5.title = Glabātuves versijas 4 uz 5 atjauninājums
upgrade.version4to5.msg = Šo glabātuvi nepieciešams migrēt uz jaunāku versiju.\nŠifrētās datnes tiks atjauninātas.\nPirms apstiprini, pārliecinies, ka ir beigusies sinhronizācija.\n\nPiezīme\: Visām datnēm modificēšanas datums tiks izmainīts uz šodienas datumu.
upgrade.version4to5.err.io = Migrācijas kļīda dēļ I/O izņēmuma. Sīkāku informāciju skaties žurnālā.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
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 = Preferred Volume Type
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Vault was successfully created.
unlock.successLabel.passwordChanged = Password was successfully changed.
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -47,7 +47,6 @@ changePassword.errorMessage.decryptionFailed = Decoderen mislukt
# unlocked.fxml
unlocked.button.lock = Vergrendel kluis
unlocked.moreOptions.reveal = Maak schijf zichtbaar
unlocked.moreOptions.copyUrl = Kopieer WebDAV URL
unlocked.label.revealFailed = Opdracht mislukt
unlocked.label.unmountFailed = Uitwerpen schijf mislukt
unlocked.label.statsEncrypted = versleuteld
@@ -56,8 +55,6 @@ unlocked.ioGraph.yAxis.label = Doorvoer (MiB/s)
# settings.fxml
settings.version.label = Versie %s
settings.checkForUpdates.label = Controleer op updates
settings.port.label = WebDAV Poort *
settings.port.prompt = 0 \= Kies automatisch
settings.requiresRestartLabel = * Cryptomator dient te worden herstart
# tray icon
tray.menu.open = Open
@@ -76,7 +73,6 @@ 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.
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.
settings.prefGvfsScheme.label = WebDAV schema
# upgrade.fxml
upgrade.confirmation.label = Ja, ik heb geverifieerd dat de synchronisatie voltooid is
unlock.label.savePassword = Wachtwoord Opslaan
@@ -91,18 +87,38 @@ upgrade.version3to4.title = Kluis Versie 3 naar 4 Upgrade
upgrade.version4to5.title = Kluis Versie 4 naar 5 Upgrade
upgrade.version4to5.msg = Deze kluis moet gemigreerd worden naar een nieuw formaat.\nVersleutelde bestanden zullen bijgewerkt worden.\nZorg ervoor dat synchronisatie voltooid is alvorens verder te gaan.\n\nLet op\: Tijdens dit proces zal de wijzigingsdatum van alle bestanden gewijzigd worden naar de huidige datum/tijd.
upgrade.version4to5.err.io = Migratie mislukt door een I/O Exception. Bekijk log file voor details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
unlock.label.revealAfterMount = Maak schijf zichtbaar
unlocked.lock.force.confirmation.title = Blokkeren van %1$s is mislukt
unlocked.lock.force.confirmation.header = Wil je vergrendelen forceren?
unlocked.lock.force.confirmation.content = Dit kan komen omdat er nog andere programma's de bestanden in de kluis gebruik hebben, of door een ander probleem.\n\nProgramma's die de bestanden nog in gebruik hebben werken mogelijk niet goed, en gegevens die nog niet opgeslagen zijn gaan mogelijk verloren.
unlock.label.unlockAfterStartup = Auto-ontgrendelen bij starten (Expirimenteel)
unlock.errorMessage.unlockFailed = Ontgrendelen mislukt. Zie log file voor details.
upgrade.version5toX.title = Upgraden versie kluis
upgrade.version5toX.msg = Deze kluis moet gemigreerd worden naar een nieuwer formaat. Zorg dat de synchronisatie klaar is alvorens verder te gaan.
main.createVault.nonEmptyDir.title = Kluis aanmaken mislukt
main.createVault.nonEmptyDir.header = De gekozen map is niet leeg
main.createVault.nonEmptyDir.content = De geselecteerde map bevat al bestanden (mogelijk verborgen). Een klluis kan alleen worden aangemaakt in een lege map.
unlock.label.mountPath = Mount pad
unlock.label.mountPathButton = Toepassen
settings.webdav.port.label = WebDAV Poort
settings.webdav.port.prompt = 0 \= Automatisch kiezen
settings.webdav.port.apply = Toepassen
settings.webdav.prefGvfsScheme.label = WebDAV Schema
settings.volume.label = Voorkeurs Volume Type
settings.volume.webdav = WebDAV
settings.volume.fuse = STOP
unlock.successLabel.vaultCreated = Kluis was succesvol gecreeerd
unlock.successLabel.passwordChanged = Wachtwoord is succesvol aangepast
unlock.successLabel.upgraded = Cryptomator succesvol vernieuwd.
unlock.label.useOwnMountPath = Gebruik een eigen koppelpunt
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Geintegreerde update check aanzetten
welcome.askForUpdateCheck.dialog.content = Om te controleren op updates haalt Cryptomator het huidige versienummer van de Cryptomatorservers en toont een hint indien een nieuwere versie beschikbaar is.\n\nWe raden aan om de geintegreerde update check aan te zetten om zeker te weten dat je de nieuwste versie van Cryptomator met alle beveiligings aanpassingen hebt geinstalleerd. Indien je deze niet aanzet kun je zelf de versie controleren en downloaden van https\://cryptomatr.org/downloads/.\n\n\nJe kan dit te allen tijden bij instellingen aanpassen.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Eigen koppel pad is niet ingevuld.
main.gracefulShutdown.dialog.title = Vergrendelen kluis/kluizen mislukt
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Probeer opnieuw
main.gracefulShutdown.button.forceShutdown = Geforceerd afsluiten
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -1,106 +1,122 @@
app.name = Cryptomator
# 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.changePassword = Zmień hasło
main.addDirectory.contextMenu.new = Stwórz nową kryptę
main.addDirectory.contextMenu.open = Otwórz istniejącą kryptę
main.directoryList.contextMenu.changePassword = Zmień Hasło
main.addDirectory.contextMenu.new = Utwórz Nowy Portfel
main.addDirectory.contextMenu.open = Otwórz istniejący portfel
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Sprawdzanie aktualizacji...
welcome.newVersionMessage = Nowa wersja %1$s jest dostępna do pobrania.\nObecnie używana wersja to %2$s.
# initialize.fxml
initialize.label.password = Hasło
initialize.label.retypePassword = Powtórz hasło
initialize.button.ok = Stwórz kryptę
initialize.messageLabel.alreadyInitialized = Krypta aktualnie załadowana
initialize.messageLabel.initializationFailed = Nie można załadować krypty. Szczegóły błędu znajdziesz w logach.
initialize.label.retypePassword = Powtórz Hasło
initialize.button.ok = Utwórz Portfel
initialize.messageLabel.alreadyInitialized = Portfel został utworzony
initialize.messageLabel.initializationFailed = Nie można zainicjować portfela. Zobacz plik dziennika, aby poznać szczegóły.
# notfound.fxml
notfound.label = Nie znaleziono krypty. Może została przeniesiona?
notfound.label = Nie znaleziono portfela. Może został przeniesiony?
# upgrade.fxml
upgrade.button = Zaktualizuj kryptę
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.err.alreadyExists = Błąd automatycznej aktualizacji krypty.\n"%s" już istnieje.
upgrade.button = Zaktualizuj Portfel
upgrade.version3dropBundleExtension.msg = Portfel musi zostać zaktualizowany do nowszego formatu.\n"%1$s" zostanie zmienione na "%2$s".\nPrzed kontynuowaniem upewnij się, że synchronizacja została zakończona.
upgrade.version3dropBundleExtension.err.alreadyExists = Automatyczna migracja nie powiodła się.\n"%s" już istnieje.
# unlock.fxml
unlock.label.password = Hasło
unlock.label.mountName = Nazwa dysku
unlock.label.winDriveLetter = Litera dysku
unlock.label.mountName = Nazwa Napędu
unlock.label.winDriveLetter = Litera Napędu
unlock.label.downloadsPageLink = Wszystkie wersje Cryptomatora
unlock.label.advancedHeading = Opcje zaawansowane
unlock.button.unlock = Odblokuj kryptę
unlock.button.advancedOptions.show = Więcej opcji
unlock.button.advancedOptions.hide = Mniej opcji
unlock.label.advancedHeading = Opcje Zaawansowane
unlock.button.unlock = Odblokuj Portfel
unlock.button.advancedOptions.show = Więcej Opcji
unlock.button.advancedOptions.hide = Mniej Opcji
unlock.choicebox.winDriveLetter.auto = Przydziel automatycznie
unlock.errorMessage.wrongPassword = Nieprawidłowe hasło
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Niewspierana wersja krypty. Krypta została utworzona przez starszą wersję Cryptomatora.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Niewspierana wersja krypty. Krypta została utworzona przez nowszą wersję Cryptomatora.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Nieobsługiwana wersja portfela. Ten portfel został utworzony przez starszą wersję Cryptomatora.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Nieobsługiwana wersja portfela. Ten portfel został utworzony przez nowszą wersję Cryptomatora.
unlock.messageLabel.startServerFailed = Nie udało się uruchomić serwera WebDAV.
# change_password.fxml
changePassword.label.oldPassword = Stare hasło
changePassword.label.newPassword = Nowe hasło
changePassword.label.retypePassword = Powtórz hasło
changePassword.label.oldPassword = Stare Hasło
changePassword.label.newPassword = Nowe Hasło
changePassword.label.retypePassword = Powtórz Hasło
changePassword.label.downloadsPageLink = Wszystkie wersje Cryptomatora
changePassword.button.change = Zmień hasło
changePassword.button.change = Zmień Hasło
changePassword.errorMessage.wrongPassword = Nieprawidłowe hasło
changePassword.errorMessage.decryptionFailed = Błąd odszyfrowywania
# unlocked.fxml
unlocked.button.lock = Zablokuj kryptę
unlocked.moreOptions.reveal = Pokaż dysk
unlocked.moreOptions.copyUrl = Skopiuj URL WebDAV
unlocked.label.revealFailed = Błąd pokazywania dysku
unlocked.label.unmountFailed = Błąd odłączania dysku
unlocked.label.statsEncrypted = szyfrowanie
unlocked.label.statsDecrypted = odszyfrowywanie
unlocked.button.lock = Blokuj Portfel
unlocked.moreOptions.reveal = Odkryj Napęd
unlocked.label.revealFailed = Polecenie nie powiodło się
unlocked.label.unmountFailed = Wysuwanie napędu nie powiodło się
unlocked.label.statsEncrypted = szyfrowane
unlocked.label.statsDecrypted = nieszyfrowywane
unlocked.ioGraph.yAxis.label = Wydajność (MiB/s)
# settings.fxml
settings.version.label = Wersja %s
settings.checkForUpdates.label = Sprawdzaj aktualizacje
settings.port.label = Port WebDAV
settings.port.prompt = 0 \= Automatycznie
settings.checkForUpdates.label = Sprawdź aktualizacje
settings.requiresRestartLabel = * Cryptomator wymaga restartu
# tray icon
tray.menu.open = Otwórz
tray.menu.quit = Wyjdź
tray.infoMsg.title = Nadal działa
tray.infoMsg.msg = Cryptomator wciąż jest uruchomiony. Aby go wyłączyć, użyj ikony z obszaru powiadomień.
tray.infoMsg.msg.osx = Cryptomator wciąż jest uruchomiony. Aby go wyłączyć, użyj ikony z paska menu.
tray.infoMsg.title = Nadal Uruchomiony
tray.infoMsg.msg = Cryptomator jest nadal uruchomiony. Zamknij go z ikony z paska zadań.
tray.infoMsg.msg.osx = Cryptomator jest nadal uruchomiony. Zamknij go z ikony z paska menu.
initialize.messageLabel.passwordStrength.0 = Bardzo słabe
initialize.messageLabel.passwordStrength.1 = Słabe
initialize.messageLabel.passwordStrength.2 = W porządku
initialize.messageLabel.passwordStrength.2 = Dostateczne
initialize.messageLabel.passwordStrength.3 = Mocne
initialize.messageLabel.passwordStrength.4 = Bardzo mocne
initialize.label.doNotForget = WAŻNE\: Jeśli zapomnisz hasło, nie ma żadnej możliwości odzyskania danych.
main.directoryList.remove.confirmation.title = Usuń kryptę
main.directoryList.remove.confirmation.header = Czy na pewno chcesz usunąć kryptę?
main.directoryList.remove.confirmation.content = Krypta zostanie usunięta tylko z listy. Jeśli chcesz trwale usunąć, usuń pliki krypty 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.err.io = Błąd aktualizacji z powodu problemów z odczytem/zapisem. Szczegóły błędu znajdziesz w logach.
settings.prefGvfsScheme.label = Schemat WebDAV
initialize.label.doNotForget = WAŻNE\: Jeśli zapomnisz hasło, nie ma żadnej innej możliwości odzyskania twoich danych.
main.directoryList.remove.confirmation.title = Usuń Portfel
main.directoryList.remove.confirmation.header = Czy na pewno chcesz usunąć ten portfel?
main.directoryList.remove.confirmation.content = Ten portfel zostanie usunięty tylko z listy. Jeśli chcesz trwale go usunąć, usuń pliki portfela ze swojego systemu plików.
upgrade.version3to4.msg = Ten portfel wymaga migracji do nowszego formatu.\nZaszyfrowane nazwy folderów zostaną zaktualizowane.\nPrzed kontynuowaniem upewnij się, że synchronizacja została zakończona.
upgrade.version3to4.err.io = Migracja nie powiodła się z powodu wyjątku I/O. Zobacz plik dziennika, aby poznać szczegóły.
# upgrade.fxml
upgrade.confirmation.label = Tak, synchronizacja plików na pewno została ukończona.
unlock.label.savePassword = Zapisz hasło
upgrade.confirmation.label = Tak, upewniłem się że synchronizacja plików została ukończona.
unlock.label.savePassword = Zapisz Hasło
unlock.errorMessage.unauthenticVersionMac = Nie udało się uwierzytelnić wersji MAC
unlocked.label.mountFailed = Błąd podłączanie dysku.
unlock.savePassword.delete.confirmation.title = Usuń zapisane hasło
unlock.savePassword.delete.confirmation.header = Czy na pewno chcesz usunąć zapisane hasło do tej krypty?
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".
settings.debugMode.label = Tryb debugowania *
upgrade.version3dropBundleExtension.title = Aktualizacja krypty do wersji 3 (Drop Bundle Extension)
upgrade.version3to4.title = Aktualizacja krypty z wersji 3 do 4
upgrade.version4to5.title = Aktualizacja krypty 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.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 = Podłącz dysk
unlock.label.revealAfterMount = Pokaż dysk
unlocked.label.mountFailed = Nie udało się połączyć z napędem
unlock.savePassword.delete.confirmation.title = Usuń Zapisane Hasło
unlock.savePassword.delete.confirmation.header = Czy na pewno chcesz usunąć zapisane hasło do tego portfela?
unlock.savePassword.delete.confirmation.content = Zapisane hasło do tego portfela zostanie natychmiast usunięte z systemowego pęku kluczy. Jeśli chcesz ponownie zapisać hasło, musisz odblokować portfel z włączoną opcją "Zapisz hasło".
settings.debugMode.label = Tryb Debugowania *
upgrade.version3dropBundleExtension.title = Aktualizacja portfela do wersji 3 (Drop Bundle Extension)
upgrade.version3to4.title = Aktualizacja portfela z wersji 3 do 4
upgrade.version4to5.title = Aktualizacja portfela z wersji 4 do 5
upgrade.version4to5.msg = Ten portfel wymaga migracji do nowszego formatu.\nZaszyfrowane pliki zostaną zaktualizowane.\nPrzed kontynuowaniem upewnij się, że synchronizacja została zakończona..\n\nUwaga\: Data modyfikacji wszystkich plików zostanie zmieniona w procesie na bieżącą datę/czas.
upgrade.version4to5.err.io = Migracja nie powiodła się z powodu wyjątku I/O. Szczegóły błędu znajdziesz w dzienniku.
unlock.label.revealAfterMount = Pokaż Napęd
unlocked.lock.force.confirmation.title = Zablokowywanie %1$s nie powiodło się
unlocked.lock.force.confirmation.header = Czy chcesz wymusić zablokowanie?
unlocked.lock.force.confirmation.content = Może się tak dziać dlatego, że inne programy wciąż korzystają z plików z 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.errorMessage.unlockFailed = Błąd odblokowywania. Szczegóły błędu znajdziesz w logach.
unlocked.moreOptions.mount = Podłącz dysk
unlocked.moreOptions.unmount = Odłącz dysk
upgrade.version5toX.title = Aktualizacja wersji krypty
upgrade.version5toX.msg = Krypta wymaga aktualizacji do nowszej wersji.\nZanim kontynuujesz, upewnij się, że synchronizacja plików została ukończona.
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.errorMessage.unlockFailed = Błąd odblokowywania. Szczegóły błędu znajdziesz w dzienniku.
upgrade.version5toX.title = Aktualizacja Wersji Portfela
upgrade.version5toX.msg = Ten portfel wymaga migracji do nowszego formatu.\nZanim rozpoczniesz migrację upewnij się, że synchronizacja plików została zakończona.
main.createVault.nonEmptyDir.title = Błąd podczas tworzenia portfela
main.createVault.nonEmptyDir.header = Wybrany katalog nie jest pusty
main.createVault.nonEmptyDir.content = Wybrany katalog zawiera już pliki (prawdopodobnie ukryte). Portfel mozna utworzyć wyłącznie w pustym katalogu.
unlock.label.mountPath = Zamontuj ścieżkę
unlock.label.mountPathButton = Zastosuj
settings.webdav.port.label = Port WebDAV
settings.webdav.port.prompt = 0 \= Wybierz automatycznie
settings.webdav.port.apply = Zastosuj
settings.webdav.prefGvfsScheme.label = System WebDAV
settings.volume.label = Preferowany Typ Woluminu
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Portfel został pomyślnie utworzony.
unlock.successLabel.passwordChanged = Hasło zostało pomyślnie zmienione.
unlock.successLabel.upgraded = Cryptomator został pomyślnie zaktualizowany.
unlock.label.useOwnMountPath = Użyj indywidualnego punktu montowania
welcome.askForUpdateCheck.dialog.title = Sprawdź aktualizację
welcome.askForUpdateCheck.dialog.header = Włącz zintegrowane sprawdzenie aktualizacji?
welcome.askForUpdateCheck.dialog.content = Aby sprawdzić dostępność aktualizacji, Cryptomator pobierze bieżącą wersję z serwerów Cryptomator i wyświetli podpowiedź, jeśli dostępna będzie nowsza wersja.\n\nZalecamy włączenie sprawdzania aktualizacji, aby zawsze mieć pewność, że zainstalowana jest najnowsza wersja Cryptomatora ze wszystkimi poprawkami zabezpieczeń. Jeśli nie włączysz sprawdzania aktualizacji, możesz sprawdzić i pobrać aktualną wersję z https\://cryptomator.org/downloads/.\n\nMożesz to zmienić w dowolnym momencie, korzystając z ustawień.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Indywidualna ścieżka montażu nie jest ustawiona.
main.gracefulShutdown.dialog.title = Nie udało się zablokować porfela(i)
main.gracefulShutdown.dialog.header = Portfel(e) w użyciu
main.gracefulShutdown.dialog.content = Jedna lub więcej porfelii jest nadal używana przez inne programy. Zamknij je, aby umożliwić prawidłowe zamknięcie Cryptomator, a następnie spróbuj ponownie.\n\nJeśli to nie zadziała, Cryptomator może zamknąć na siłę, ale może to spowodować utratę danych i nie jest zalecane.
main.gracefulShutdown.button.tryAgain = Spróbuj ponownie
main.gracefulShutdown.button.forceShutdown = Wymuś zamknięcie
unlock.pendingMessage.unlocking = Unlocking vault...

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?
# upgrade.fxml
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.
# unlock.fxml
unlock.label.password = Senha
@@ -30,32 +30,29 @@ unlock.button.unlock = Abrir cofre
unlock.button.advancedOptions.show = Mais opções
unlock.button.advancedOptions.hide = Menos opções
unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente
unlock.errorMessage.wrongPassword = Senha errada
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não suportado. Esse cofre foi criado por uma versão antiga do Cryptomator.
unlock.errorMessage.wrongPassword = Senha incorreta
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.messageLabel.startServerFailed = Falha ao iniciar servidor WebDAV.
# change_password.fxml
changePassword.label.oldPassword = Senha atual
changePassword.label.newPassword = Nova senha
changePassword.label.retypePassword = Re-digitar senha
changePassword.label.oldPassword = Senha antiga
changePassword.label.newPassword = Senha Nova
changePassword.label.retypePassword = Redigitar senha
changePassword.label.downloadsPageLink = Todas as versões do Cryptomator
changePassword.button.change = Alterar senha
changePassword.errorMessage.wrongPassword = Senha incorreta
changePassword.errorMessage.decryptionFailed = Falha ao desencriptar
changePassword.errorMessage.decryptionFailed = Falha ao descriptografar
# unlocked.fxml
unlocked.button.lock = Fechar cofre
unlocked.moreOptions.reveal = Mostrar drive
unlocked.moreOptions.copyUrl = Copiar URL WebDAV
unlocked.label.revealFailed = Falha ao mostrar drive
unlocked.label.revealFailed = Falha de comando
unlocked.label.unmountFailed = Falha ao ejetar drive
unlocked.label.statsEncrypted = Encriptado
unlocked.label.statsDecrypted = Desencriptado
unlocked.ioGraph.yAxis.label = Taxa de transferência (MiB/s)
unlocked.label.statsEncrypted = Criptografado
unlocked.label.statsDecrypted = Descriptografado
unlocked.ioGraph.yAxis.label = Taxa de transferência (Mbps)
# settings.fxml
settings.version.label = Versão %s
settings.checkForUpdates.label = Verificar por atualizações
settings.port.label = Porta WebDAV *
settings.port.prompt = 0 \= Escolher automaticamente
settings.requiresRestartLabel = * Cryptomator precisa ser reiniciado
# tray icon
tray.menu.open = Abrir
@@ -72,35 +69,54 @@ initialize.label.doNotForget = IMPORTANTE\: se você esquecer a sua senha, não
main.directoryList.remove.confirmation.title = Remover cofre
main.directoryList.remove.confirmation.header = Você realmente quer remover esse cofre?
main.directoryList.remove.confirmation.content = O cofre 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.
settings.prefGvfsScheme.label = Esquema WebDAV
# upgrade.fxml
upgrade.confirmation.label = Sim, tenho certeza de que a sincronização foi concluída
unlock.label.savePassword = Armazenar senha
unlock.label.savePassword = Salvar senha
unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a versão do MAC.
unlocked.label.mountFailed = Falha ao conectar o drive
unlock.savePassword.delete.confirmation.title = Apagar a senha armazenada
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 *
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.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.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
unlock.label.revealAfterMount = Mostrar o Drive
unlocked.lock.force.confirmation.title = O bloqueio do %1$s falhou
unlocked.lock.force.confirmation.header = Você quer forçar o bloqueio?
unlocked.lock.force.confirmation.content = Isto pode ser causado por outros programas que seguem acessando arquivos no cofre ou porque algum outro problema ocorreu.\n\nProgramas que seguem acessando os arquivos podem não funcionar corretamente e os dados ainda não gravados por estes programas podem ser perdidos.
unlock.label.unlockAfterStartup = Auto-desbloqueio ao Iniciar (Experimental)
unlock.errorMessage.unlockFailed = O desbloqueio falhou. Veja o log para mais detalhes.
upgrade.version5toX.title = Atualização da Versão do Cofre
upgrade.version5toX.msg = Este cofre precisa ser migrado a um novo formato. Por favor assegure que a sincronização foi finalizada antes de proceder.
main.createVault.nonEmptyDir.title = Falha ao criar o cofre
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 = Cofre criado com sucesso
unlock.successLabel.passwordChanged = Senha modificada com sucesso
unlock.successLabel.upgraded = Crytomator atualizado com sucesso
unlock.label.useOwnMountPath = Usar Ponto de Montagem Personalizado
welcome.askForUpdateCheck.dialog.title = Verificação de atualização
welcome.askForUpdateCheck.dialog.header = Habilitar a verificação de atualização integrada?
welcome.askForUpdateCheck.dialog.content = Para verificar atualizações, Cryptomator vai buscar a versão atual dos servidores e exibirá uma dica para você se uma nova versão estiver disponível.\n\nNós recomendamos que habilite a verificação de atualização para que sempre tenha certeza de que está usando a última versão do Crytomator, com todos os pacotes de segurança instalados. Se você não habilitar a verificação de atualização, você pode verificar e baixar a versão atual em https\://cryptomator.org/downloads/.\n\nVocê pode mudar isso a qualquer momento através das configurações.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Caminho individual de montagem não está definido.
main.gracefulShutdown.dialog.title = Falha no bloqueio do(s) cofre(s)
main.gracefulShutdown.dialog.header = Cofre(s) em uso
main.gracefulShutdown.dialog.content = Um ou mais cofres ainda estão em uso por outros programas. Por favor, feche-os para permitir que Cryptomator encerre corretamente, em seguida, tente novamente.\n\nSe isso não funcionar, Cryptomator pode forçar o desligamento, mas isso pode causar perda de dados e não é recomendado.
main.gracefulShutdown.button.tryAgain = Tente novamente
main.gracefulShutdown.button.forceShutdown = Forçar desligamento
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -6,7 +6,7 @@ main.directoryList.contextMenu.changePassword = Mudar senha
main.addDirectory.contextMenu.new = Criar novo cofre
main.addDirectory.contextMenu.open = Abrir um Cofre existente
# 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.
# initialize.fxml
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?
# upgrade.fxml
upgrade.button = Atualizar Cofre
upgrade.version3dropBundleExtension.msg = O Cofre precisa ser migrado para o novo formato.\n%1$s" será renomeado para "%2$s".\nPor favor tenha certeza que a sincronização 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 certifique que a sincronização está finalizada antes de prosseguir.
upgrade.version3dropBundleExtension.err.alreadyExists = A Migração automática falhou.\n"%s" já existe.
# unlock.fxml
unlock.label.password = Senha
@@ -32,75 +32,91 @@ unlock.button.advancedOptions.hide = Menos Opções
unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente
unlock.errorMessage.wrongPassword = Senha errada
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não suportado. Esse Cofre foi criado em uma versão antiga do Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse Cofre foi criado em uma versão mais nova do Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse Cofre foi criado em uma versão mais recente do Cryptomator.
unlock.messageLabel.startServerFailed = A inicialização do servidor WebDAV falhou.
# change_password.fxml
changePassword.label.oldPassword = Sua senha antiga
changePassword.label.oldPassword = Senha antiga
changePassword.label.newPassword = Nova senha
changePassword.label.retypePassword = Repita a senha
changePassword.label.downloadsPageLink = Todas as versões do Cyptomator
changePassword.button.change = Alterar senha
changePassword.errorMessage.wrongPassword = Senha errada
changePassword.errorMessage.decryptionFailed = Falha na Desencriptação
changePassword.errorMessage.decryptionFailed = Descriptografia falhou
# unlocked.fxml
unlocked.button.lock = Travar Cofre
unlocked.button.lock = Trancar Cofre
unlocked.moreOptions.reveal = Mostrar volume
unlocked.moreOptions.copyUrl = Copiar endereço do WebDAV
unlocked.label.revealFailed = Falha no comando
unlocked.label.unmountFailed = A ejeção do volume falhou
unlocked.label.statsEncrypted = Encriptado
unlocked.label.statsDecrypted = Desencriptado
unlocked.ioGraph.yAxis.label = Transferência (MiB/s)
unlocked.label.statsEncrypted = criptografado
unlocked.label.statsDecrypted = descriptografado
unlocked.ioGraph.yAxis.label = Transferência (Mbps)
# settings.fxml
settings.version.label = Versão %s
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
# tray icon
tray.menu.open = Abrir
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.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.1 = Fraca
initialize.messageLabel.passwordStrength.2 = Razoável
initialize.messageLabel.passwordStrength.3 = Forte
initialize.messageLabel.passwordStrength.4 = Muito forte
initialize.label.doNotForget = IMPORTANTE\: Se você perder a sua senha, não haverá maneira alguma de recuperar seus dados.
initialize.label.doNotForget = IMPORTANTE\: NÂO existe maneira alguma de recuperar seus dados se você perder a sua senha,
main.directoryList.remove.confirmation.title = Remover Cofre
main.directoryList.remove.confirmation.header = Você realmente quer remover esse Cofre?
main.directoryList.remove.confirmation.content = O Cofre será somente removido da listagem. Para apagá-lo permanentemente, por favor apague os arquivos.
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.
main.directoryList.remove.confirmation.content = O Cofre será removido somente da listagem. Para apagá-lo permanentemente é necessario apagá-lo de seu arquivo de sistema.
upgrade.version3to4.msg = Esse Cofre precisa ser migrado para o novo formato.\nOs nomes das pastas criptografadas serão atualizados.\nPor favor tenha certeza que a sincronização está finalizada antes de prosseguir.
upgrade.version3to4.err.io = A migração falhou devido a uma falha de entrada e saída. Veja o arquivo de log para mais detalhes.
settings.prefGvfsScheme.label = Esquema WebDAV
# upgrade.fxml
upgrade.confirmation.label = Sim, tenho certeza que a sincronização terminada.
upgrade.confirmation.label = Sim, tenho certeza que a sincronização terminou
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
unlock.savePassword.delete.confirmation.title = Apaga senha salva
unlock.savePassword.delete.confirmation.header = Você realmente quer apagar a senha salva para esse Cofre?
unlock.savePassword.delete.confirmation.content = A senha salva para esse Cofre será imediatamente apagada do chaveiro do sistema. Se você quiser salvar a senha novamente, é preciso destravar o Cofre com a opção "Salvar senha" ativada.
unlock.savePassword.delete.confirmation.content = A senha salva para esse Cofre será imediatamente apagada. Para salvar a senha novamente destrave o Cofre com a opção "Salvar senha" ativada.
settings.debugMode.label = Modo Debug *
upgrade.version3dropBundleExtension.title = Atualização do Cofre v3 (Drop Bundle Extension)
upgrade.version3to4.title = Atualização do Cofre v3 para v4
upgrade.version4to5.title = Atualização do Cofre v4 para v5
upgrade.version4to5.msg = Este Cofre precisa ser migrado para o novo formato.\nOs arquivos 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.
settings.port.apply = Aplicar
unlock.label.mountAfterUnlock = Montar Volume
unlock.label.revealAfterMount = Abrir Volume
unlocked.lock.force.confirmation.title = O Travamento para %1$s falhou
unlocked.lock.force.confirmation.header = Deseja forçar o travamento?
unlocked.lock.force.confirmation.content = Isso pode está ocorrendo porque arquivos no Cofre ainda estão sendo acessados ou algum outro problema ocorreu.\n\nProgramas que ainda estão acessando os arquivo podem não funcionar corretamente e os dados não gravados podem serem perdidos.
unlock.label.unlockAfterStartup = Destravar ao iniciar
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
unlocked.lock.force.confirmation.content = Isso pode está ocorrendo porque arquivos no Cofre ainda estão sendo acessados ou algum outro problema ocorreu.\n\nProgramas que ainda estão acessando os arquivos podem não funcionar corretamente e os dados não gravados podem ser perdidos.
unlock.label.unlockAfterStartup = Desbloquear ao iniciar (Experimental)
unlock.errorMessage.unlockFailed = Desbloqueio falhou. Consulte o arquivo de log para obter mais detalhes.
upgrade.version5toX.title = Atualização da Versão do Cofre
upgrade.version5toX.msg = Esse Cofre precisa ser migrado para o novo formato.\nPor favor certifique que a sincronização está finalizada antes de prosseguir.
main.createVault.nonEmptyDir.title = Criação do cofre falhou
main.createVault.nonEmptyDir.header = O diretório escolhido não está vazio
main.createVault.nonEmptyDir.content = O diretório selecionado já contém arquivos (possivelmente ocultos). Um cofre só pode ser criado em um diretório vazio.
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 = Cofre foi criado com sucesso.
unlock.successLabel.passwordChanged = Senha for trocada com sucesso.
unlock.successLabel.upgraded = Cryptomator foi atualizado com sucesso.
unlock.label.useOwnMountPath = Usar ponto de montagem individual
welcome.askForUpdateCheck.dialog.title = Checar atualizações
welcome.askForUpdateCheck.dialog.header = Ativar a checagem por atualizações?
welcome.askForUpdateCheck.dialog.content = Para checar as atualizações, Cryptomator irá verificar a versão mais recente em nossos servidores e avisará se existe uma versão disponível.\n\nRecomendamos ativar a checagem por novas atualizações para ter certeza que se tenha a versão mais recente do Cryptomator, com todas as correções de segurança. Se não ativar as atualizações é possivel checar e baixa-las a versão mais recente em https\://cryptomator.org/downloads/.\n\nVocê pode alterar as configurações a qualquer hora.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Caminho para montagem individual não configurado.
main.gracefulShutdown.dialog.title = Falha ao trancar o cofre
main.gracefulShutdown.dialog.header = Cofre(s) em uso
main.gracefulShutdown.dialog.content = Um ou mais cofres ainda estão em uso por outros programas. Por favor feche-os para permitir ao Cryptomator encerrar apropriadamente, então tente novamente.
main.gracefulShutdown.button.tryAgain = Tente novamente
main.gracefulShutdown.button.forceShutdown = Forçar término da execução
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -8,28 +8,29 @@ main.addDirectory.contextMenu.open = Открыть имеющееся хран
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Проверка обновлений...
# 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.label.password = Пароль
initialize.label.retypePassword = Введите пароль ещё раз
initialize.button.ok = Создать хранилище
initialize.messageLabel.alreadyInitialized = Хранилище уже инициализировано
initialize.messageLabel.initializationFailed = Невозможно инициализировать хранилище. См. подробности в файле-отчёте.
initialize.messageLabel.initializationFailed = Невозможно инициализировать хранилище. См. подробности в файле журнала.
# notfound.fxml
notfound.label = Хранилище не найдено. Оно было перемещено?
# upgrade.fxml
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" уже существует.
# 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.button.advancedOptions.show = Больше опций
unlock.button.advancedOptions.hide = Меньше опций
unlock.choicebox.winDriveLetter.auto = Автоназначение
unlock.errorMessage.wrongPassword = Неверный пароль
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Неподдерживаемое хранилище. Оно было создано в более старой версии Cryptomator.
@@ -38,7 +39,7 @@ unlock.messageLabel.startServerFailed = Ошибка запуска сервер
# change_password.fxml
changePassword.label.oldPassword = Старый пароль
changePassword.label.newPassword = Новый пароль
changePassword.label.retypePassword = Введите пароль ещё раз
changePassword.label.retypePassword = Повторите ввод пароля
changePassword.label.downloadsPageLink = Все версии Cryptomator
changePassword.button.change = Сменить пароль
changePassword.errorMessage.wrongPassword = Неверный пароль
@@ -46,9 +47,8 @@ changePassword.errorMessage.decryptionFailed = Ошибка дешифрован
# unlocked.fxml
unlocked.button.lock = Заблокировать хранилище
# Does it mean "open" drive?
unlocked.moreOptions.reveal = Открыть накопитель
unlocked.moreOptions.copyUrl = Скопировать URL-адрес WebDAV
unlocked.label.revealFailed = Ошибка команды
unlocked.moreOptions.reveal = Открыть диск
unlocked.label.revealFailed = Не удалось выполнить команду
unlocked.label.unmountFailed = Ошибка извлечения диска
unlocked.label.statsEncrypted = зашифровано
unlocked.label.statsDecrypted = расшифровано
@@ -56,53 +56,74 @@ unlocked.ioGraph.yAxis.label = Пропускная способность (Ми
# settings.fxml
settings.version.label = Версия %s
settings.checkForUpdates.label = Проверка обновлений
settings.port.label = Порт WebDAV *
settings.port.prompt = 0 \= автовыбор
settings.requiresRestartLabel = * Требуется перезагрузка Cryptomator
settings.requiresRestartLabel = * Требуется перезапуск Cryptomator
# tray icon
tray.menu.open = Открыть
tray.menu.quit = Выход
tray.infoMsg.title = Всё ещё выполняется
# Не нужно использовать жаргонизмы, а также прибегать к вкусовой правке.
tray.infoMsg.msg = Cryptomator всё ещё работает. Выйдите c помощью значка в области уведомлений.
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.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 = Это хранилище требуется преобразовать в новый формат. Зашифрованные имена папок будут обновлены. Прежде чем продолжить, выполните синхронизацию.
upgrade.version3to4.err.io = Преобразование не выполнено из-за ошибки ввода-вывода. См. подробности в файле-отчёте.
settings.prefGvfsScheme.label = Схема WebDAV
upgrade.version3to4.msg = Это хранилище требуется преобразовать в новый формат.\nИмена зашифрованных папок будут обновлены.\nПеред продолжением убедитесь, что синхронизация завершена.
upgrade.version3to4.err.io = Преобразование не выполнено из-за ошибки ввода-вывода. См. подробности в файле журнала.
# upgrade.fxml
upgrade.confirmation.label = Да, синхронизация точно завершена
upgrade.confirmation.label = Да, синхронизация завершена
unlock.label.savePassword = Сохранить пароль
unlock.errorMessage.unauthenticVersionMac = Не удалось идентифицировать версию MAC.
unlock.errorMessage.unauthenticVersionMac = Не удалось проверить подлинность версии MAC.
unlocked.label.mountFailed = Ошибка подключения к диску
# А как назвать эту правку? Пожалуйста, перестаньте портить перевод.
unlock.savePassword.delete.confirmation.title = Удалить сохранённый пароль
unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохранённый пароль для этого хранилища?
unlock.savePassword.delete.confirmation.content = Сохранённый пароль от этого хранилища будет немедленно удалён из системной связки ключей. Если вы снова захотите сохранить пароль, вам придётся разблокировать хранилище с включённой опцией "Сохранить пароль".
unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохранённый пароль этого хранилища?
unlock.savePassword.delete.confirmation.content = Сохранённый пароль этого хранилища будет немедленно удалён из вашей системной связки ключей. Если вы снова захотите сохранить пароль, вам придётся разблокировать хранилище с включённым параметром "Сохранить пароль".
settings.debugMode.label = Режим отладки *
upgrade.version3dropBundleExtension.title = Обновление хранилища версии 3 (Drop Bundle Extension)
upgrade.version3dropBundleExtension.title = Обновление хранилища версии 3 (расширение пакета)
upgrade.version3to4.title = Обновление хранилища с версии 3 на 4
upgrade.version4to5.title = Обновление хранилища с версии 4 на 5
upgrade.version4to5.msg = Это хранилище нужно преобразовать в более новый формат.\nЗашифрованные файлы будут обновлены.\nПрежде чем продолжить, убедитесь, что завершена синхронизация.\n\nПримечание\: даты изменения всех файлов будут изменены на текущие дату и время на момент обработки.
upgrade.version4to5.err.io = Преобразование не выполнено из-за исключения ввода-вывода. См. подробности в отчёте.
settings.port.apply = Применить
unlock.label.mountAfterUnlock = Смонтировать диск
upgrade.version4to5.msg = Это хранилище нужно преобразовать в более новый формат.\nЗашифрованные файлы будут обновлены.\nПрежде чем продолжить, убедитесь, что завершена синхронизация.\n\nПримечание\: дата и время изменения всех файлов будут изменены на текущие на момент обработки.
upgrade.version4to5.err.io = Преобразование не выполнено из-за ошибки ввода-вывода. См. подробности в файле журнала.
unlock.label.revealAfterMount = Открыть диск
unlocked.lock.force.confirmation.title = Ошибка блокировки %1$s
unlocked.lock.force.confirmation.header = Заблокировать принудительно?
unlocked.lock.force.confirmation.content = Возможно, к файлам в хранилище всё ещё обращаются другие программы, либо возникла иная проблема.\n\nТакие программы могут работать неправильно, а не записанные ими данные могут быть потеряны.
unlock.label.unlockAfterStartup = Автоблокировка при старте (экспериментально)
unlock.errorMessage.unlockFailed = Ошибка разблокировки. См. подробности в отчёте.
unlocked.moreOptions.mount = Смонтировать диск
unlocked.moreOptions.unmount = Извлечь диск
unlocked.lock.force.confirmation.content = Возможно, к файлам в хранилище всё ещё обращаются другие программы, либо возникла иная проблема. Такие программы могут работать неправильно, а не записанные ими данные могут быть потеряны.
# Авторазблокировка при старте (экспериментально)
unlock.label.unlockAfterStartup = Авторазблокировка при запуске (экспериментально)
unlock.errorMessage.unlockFailed = Ошибка разблокировки. См. подробности в файле журнала.
upgrade.version5toX.title = Обновление версии хранилища
upgrade.version5toX.msg = Это хранилище нужно преобразовать в новый формат. Прежде чем продолжить, убедитесь, что завершена синхронизация.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
main.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 = Хранилище успешно создано.
unlock.successLabel.passwordChanged = Пароль успешно изменён.
unlock.successLabel.upgraded = Обновление Cryptomator успешно выполнено.
unlock.label.useOwnMountPath = Своя точка монтирования
welcome.askForUpdateCheck.dialog.title = Проверка обновлений
welcome.askForUpdateCheck.dialog.header = Включить встроенную проверку обновлений?
welcome.askForUpdateCheck.dialog.content = Для проверки наличия обновлений Cryptomator будет получать номер текущей версии со своих серверов и показывать подсказку, что доступна более новая версия.\n\nРекомендуем включить проверку обновлений, чтобы быть уверенным, что у вас всегда новейшая версия программы, содержащая все патчи безопасности. Если вы не хотите включать проверку обновлений, то проверить наличие новой версии и загрузить её можно по адресу https\://cryptomator.org/downloads/\n\nЭтот параметр можно всегда изменить в настройках программы.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Не установлен индивидуальный путь монтирования.
main.gracefulShutdown.dialog.title = Ошибка блокировки хранилища
main.gracefulShutdown.dialog.header = Используемые хранилища
main.gracefulShutdown.dialog.content = Одно или несколько хранилищ всё ещё используются другими программами. Закройте их, чтобы Cryptomator мог корректно завершить работу, и повторите попытку.\n\nЕсли это не поможет, Cryptomator может завершить работу принудительно, но с риском потери данных, и потому это не рекомендуется.
main.gracefulShutdown.button.tryAgain = Попробовать снова
main.gracefulShutdown.button.forceShutdown = Принудительно завершить работу
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -48,7 +48,6 @@ changePassword.errorMessage.decryptionFailed = Dešifrovanie zlyhalo.
# unlocked.fxml
unlocked.button.lock = Zamknúť trezor
unlocked.moreOptions.reveal = Odhaliť jednotku
unlocked.moreOptions.copyUrl = Kopírovať WebDAV URL
unlocked.label.revealFailed = Príkaz zlyhal
unlocked.label.unmountFailed = Odpájanie jednotky zlyhalo
unlocked.label.statsEncrypted = zašifrované
@@ -57,8 +56,6 @@ unlocked.ioGraph.yAxis.label = Priepustnosť (MiB/s)
# settings.fxml
settings.version.label = Verzia %s
settings.checkForUpdates.label = Skontrolovať aktualizácie
settings.port.label = WebDAV Port *
settings.port.prompt = 0 \= Vybrať automaticky
settings.requiresRestartLabel = * Cryptomator vyžaduje reštart
# tray icon
tray.menu.open = Otvoriť
@@ -77,7 +74,6 @@ 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.
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
settings.prefGvfsScheme.label = WebDAV Schéma
# upgrade.fxml
upgrade.confirmation.label = Áno, som si istý že synchronizácia je hotová
unlock.label.savePassword = Uložiť heslo
@@ -92,18 +88,38 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
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 = Preferred Volume Type
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Vault was successfully created.
unlock.successLabel.passwordChanged = Password was successfully changed.
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = การถอดรหัสล
# unlocked.fxml
unlocked.button.lock = ล็อคกล่องข้อมูล
unlocked.moreOptions.reveal = โชว์ไดรฟ์
unlocked.moreOptions.copyUrl = คัดลอก WebDEV ลิ้งค์
unlocked.label.revealFailed = คำสั่งล้มเหลว
unlocked.label.unmountFailed = Eject ไดรว์ล้มเหลว
unlocked.label.statsEncrypted = เข้ารหัสแล้ว
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = ความเร็วอ่านเขีย
# settings.fxml
settings.version.label = เวอร์ชั่น %s
settings.checkForUpdates.label = ค้นหาอัพเดท
settings.port.label = WebDAV Port
settings.port.prompt = 0 \= เลือกอัตโนมัติ
settings.requiresRestartLabel = * ต้องรีสตาร์ท Cryptomator ใหม่
# tray icon
tray.menu.open = เปิด
@@ -74,7 +71,6 @@ main.directoryList.remove.confirmation.header = คุณต้องการ
main.directoryList.remove.confirmation.content = กล่องข้อมูลแค่ถูกลบออกจากรายการ หากต้องการลบข้อมูล ต้องไปลบในที่อยู่ไฟล์ของคุณ
upgrade.version3to4.msg = กล่องข้อมูลต้องการอัพเกรดเป็นเวอร์ชั่นใหม่\nชื่อโฟลเดอร์จะถูกอัพเดท\nกรุณารอการอัพเกรดให้เสร็จสิ้นก่อนเริ่มใช้งาน
upgrade.version3to4.err.io = อัพเกรดล้มเหลวเนื่องจากข้อยกเว้น I/O ดูรายละเอียดได้ใน Log ไฟล์
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = ใช่ ฉันมั่นใจว่าอัพเกรดเสร็จเรียบร้อยแล้ว
unlock.label.savePassword = เซฟรหัสผ่าน
@@ -89,18 +85,38 @@ upgrade.version3to4.title = อัพเกรดกล่องข้อมู
upgrade.version4to5.title = อัพเกรดกล่องข้อมูลเวอร์ชั่น 4 ไปยัง 5
upgrade.version4to5.msg = กล่องข้อมูลนี้ต้องการอัพเกรดเป็นเวอร์ชั่นใหม่\nไฟล์เข้ารหัสจะได้รับการอัพเกรด\nกรุณารอการอัพเกรดให้เสร็จสิ้นก่อนเริ่มใช้งาน\n\nเพิ่มเติม\: วันที่ Modification ของไฟล์จะถูกเปลี่ยนเป็นเวลา ณ ปัจจุบัน
upgrade.version4to5.err.io = อัพเกรดล้มเหลวเนื่องจากข้อยกเว้น I/O ดูรายละเอียดได้ใน Log ไฟล์
settings.port.apply = ตกลง
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กล่องข้อมูลสามารถสร้างได้จากโฟลเดอร์เปล่าเท่านั้น
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 = Preferred Volume Type
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Vault was successfully created.
unlock.successLabel.passwordChanged = Password was successfully changed.
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

View File

@@ -45,7 +45,6 @@ changePassword.errorMessage.decryptionFailed = Şifre çözme başarısız
# unlocked.fxml
unlocked.button.lock = Kasayı kilitle
unlocked.moreOptions.reveal = Sürücüyü göster
unlocked.moreOptions.copyUrl = WebDAV URl'sini kopyala
unlocked.label.revealFailed = Komut başarısız
unlocked.label.unmountFailed = Sürücü çıkarma başarısız
unlocked.label.statsEncrypted = şifrelenmiş
@@ -54,8 +53,6 @@ unlocked.ioGraph.yAxis.label = Veri hacmi (MiB/s)
# settings.fxml
settings.version.label = Sürüm %s
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
# tray icon
tray.menu.open = Aç
@@ -74,7 +71,6 @@ 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.
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
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
unlock.label.savePassword = Save Password
@@ -89,18 +85,38 @@ upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.port.apply = Apply
unlock.label.mountAfterUnlock = Mount Drive
unlock.label.revealAfterMount = Reveal Drive
unlocked.lock.force.confirmation.title = Locking of %1$s failed
unlocked.lock.force.confirmation.header = Do you want to force locking?
unlocked.lock.force.confirmation.content = This may be because other programs are still accessing files in the vault or because some other problem occurred.\n\nPrograms still accessing the files may not work correctly and data not already written by those programs may be lost.
unlock.label.unlockAfterStartup = Auto-Unlock on Start (Experimental)
unlock.errorMessage.unlockFailed = Unlock failed. See log file for details.
unlocked.moreOptions.mount = Mount Drive
unlocked.moreOptions.unmount = Eject Drive
upgrade.version5toX.title = Vault Version Upgrade
upgrade.version5toX.msg = This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
main.createVault.nonEmptyDir.title = Creating vault failed
main.createVault.nonEmptyDir.header = Chosen directory is not empty
main.createVault.nonEmptyDir.content = The selected directory already contains files (possibly hidden). A vault can only be created in an empty directory.
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 = Preferred Volume Type
settings.volume.webdav = WebDAV
settings.volume.fuse = FUSE
unlock.successLabel.vaultCreated = Vault was successfully created.
unlock.successLabel.passwordChanged = Password was successfully changed.
unlock.successLabel.upgraded = Cryptomator was successfully upgraded.
unlock.label.useOwnMountPath = Use Custom Mount Point
welcome.askForUpdateCheck.dialog.title = Update check
welcome.askForUpdateCheck.dialog.header = Enable the integrated update check?
welcome.askForUpdateCheck.dialog.content = Recommended\: Enable the update check to always be sure you have the newest version of Cryptomator, with all security patches, installed.\n\nYou can change this from within the settings at any time.
settings.volume.dokany = Dokany
unlock.errorMessage.invalidMountPath = Use of custom mount path selected, but no path given.
main.gracefulShutdown.dialog.title = Locking vault(s) failed
main.gracefulShutdown.dialog.header = Vault(s) in use
main.gracefulShutdown.dialog.content = One or more vaults are still in use by other programs. Please close them to allow Cryptomator to shut down properly, then try again.\n\nIf this doesn't work, Cryptomator can shut down forcefully, but this can incur data loss and is not recommended.
main.gracefulShutdown.button.tryAgain = Try again
main.gracefulShutdown.button.forceShutdown = Force shutdown
unlock.pendingMessage.unlocking = Unlocking vault...

Some files were not shown because too many files have changed in this diff Show More