Compare commits

...
Author SHA1 Message Date
JaniruTEC 415cb78d87 Renamed errorComponent vars to genericErrorBuilder 2021-04-11 02:25:16 +02:00
JaniruTEC 4f43463649 Renamed files/constants used by the generic error report 2021-04-11 02:25:15 +02:00
JaniruTEC dc1f313082 Moved error report related files to new package 2021-04-11 01:55:35 +02:00
JaniruTEC 41d2a2c77e Added .idea/uiDesigner.xml to .gitignore 2021-04-10 23:16:00 +02:00
Armin Schrenk cf7cbae567 Set dev branch back to SNAPSHOT version
[ci skip]
2021-03-31 11:32:06 +02:00
Armin Schrenk 803f517c62 Merge tag '1.5.14' into develop
1.5.14
2021-03-31 11:11:34 +02:00
Armin Schrenk 0afa7b8e37 Merge branch 'release/1.5.14' 2021-03-31 11:11:27 +02:00
Armin Schrenk 1a0f70f8e8 updating third-party-licenses 2021-03-31 10:59:21 +02:00
Armin Schrenk 8737eb83f0 Bumping webdav-nio-adapter dependency 2021-03-31 10:58:23 +02:00
Armin Schrenk a96239a19f closes #1245 2021-03-31 10:52:30 +02:00
Armin Schrenk 2b7cfcd1dc preparing 1.5.14 2021-03-31 09:52:24 +02:00
Sebastian StenzelandGitHub ebccb61750 New Crowdin updates (#1560) 2021-03-31 09:46:45 +02:00
Armin Schrenk 285f2aec23 unify wording
[ci skip]
2021-03-30 16:10:24 +02:00
Armin SchrenkandGitHub 217e31fbd7 Merge pull request #1595 from cryptomator/feature/MCGA
Feature: Make Context menu Great Again
* adding additional entries
* fixes #1478
* only appears on a selected vault
2021-03-30 16:03:41 +02:00
Sebastian Stenzel f0ebf7a638 EasyBind rulez 2021-03-30 14:20:05 +02:00
Armin Schrenk c05c5e3f90 closes #961 2021-03-30 13:57:21 +02:00
Sebastian Stenzel 30f0c5e697 split VaultList and ContextMenu into two separate controllers 2021-03-30 13:43:37 +02:00
Armin Schrenk f989b8627c Update java-jwt 2021-03-30 13:10:54 +02:00
Armin Schrenk ff84230566 structure constructor 2021-03-30 11:53:30 +02:00
Armin Schrenk 3b4f6276b5 Improve selection model of list view:
* Clear selection if an empty space is clicked
* only open context menu if an item is selected
2021-03-30 11:25:22 +02:00
Armin Schrenk 2be7a050a4 refine wording
[ci skip]
2021-03-30 09:47:11 +02:00
Armin Schrenk 96a612127c add reveal entry to context menu. 2021-03-29 16:23:24 +02:00
Armin Schrenk 0bdfb7c9f9 Distinct between "unlock" and "unlock now" in context menu:
* inject keychainManager
* bind/unbind passphraseStored property to selected vault
* rename bindings to show possible action
* removed unused binding
* initialize properties properly
2021-03-29 12:59:48 +02:00
Armin Schrenk f556301249 fix suggestion 2021-03-29 12:47:46 +02:00
f77b237e59 simplify private function
Co-authored-by: Sebastian Stenzel <overheadhunter@users.noreply.github.com>
2021-03-29 12:44:57 +02:00
Armin Schrenk 61b7a39aad change level of a log message from warn to debug
[ci skip]
2021-03-29 10:53:48 +02:00
Tobias HagemannandGitHub 16bd84ee62 Update README.md
[ci skip]
2021-03-26 10:46:49 +01:00
Tobias HagemannandGitHub 3d0a97fcdf Update README.md
[ci skip]
2021-03-25 17:06:15 +01:00
Armin Schrenk 786d156b9f change wording in context menu entries 2021-03-23 15:08:23 +01:00
Armin Schrenk 9dc8b2cb47 Use Bindings instead of properties 2021-03-23 10:50:04 +01:00
Armin Schrenk 0e32e96c7d made context menu great again:
* added entry to unlock / lock a vault
* added entry to show vault options
2021-03-22 17:10:45 +01:00
Armin Schrenk 97afadd7b9 fixes #1478 2021-03-22 12:58:45 +01:00
Armin Schrenk b199b65e38 closes #176 2021-03-22 12:51:07 +01:00
Tobias HagemannandGitHub 999abf3c13 Update README.md
[ci skip]
2021-03-22 12:24:54 +01:00
Sebastian StenzelandGitHub 31e938de6a Merge pull request #1587 from cryptomator/feature/jdk-16
Update to JDK 16
2021-03-17 12:29:29 +01:00
Sebastian Stenzel 4c10ab764a updated README 2021-03-17 09:33:43 +01:00
Sebastian Stenzel 4e075ab0ca using pattern-matching instanceof where applicable 2021-03-17 09:22:16 +01:00
Sebastian Stenzel f73ae9759f use new Stream.toList() where applicable 2021-03-17 09:16:44 +01:00
Sebastian Stenzel f6283b2f7e using text blocks where applicable 2021-03-17 09:12:54 +01:00
Sebastian Stenzel b23d2e4def allow use of reflection in codacy coverage reporter 2021-03-17 08:19:58 +01:00
Sebastian Stenzel 91a2943599 update to JDK 16 2021-03-17 08:16:26 +01:00
Sebastian Stenzel e083fd0bcc skip certain steps on forks 2021-03-02 11:55:20 +01:00
ff687f1bae fix: main/pom.xml to reduce vulnerabilities (#1569)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JAVA-ORGECLIPSEJETTY-1080611

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2021-03-02 08:43:10 +01:00
Sebastian Stenzel 84d2644f19 fix wrong versions that have been merged from main branch 2021-02-26 10:05:26 +01:00
Armin Schrenk f9a9d7b870 Merge tag '1.5.13' into develop
1.5.13
2021-02-24 16:21:07 +01:00
Armin Schrenk d75a8c4bba Merge branch 'release/1.5.13' 2021-02-24 16:21:06 +01:00
Armin Schrenk d326c7c990 preparing 1.5.13 2021-02-24 16:17:35 +01:00
Armin SchrenkandGitHub e8e63ca4fc Merge pull request #1517 from cryptomator/feature/translations
New Crowdin updates
2021-02-24 16:12:30 +01:00
Armin SchrenkandGitHub 6878f2e94b Merge pull request #1556 from cryptomator/feature/win-auto-theme
Feature/win auto theme
2021-02-24 14:31:17 +01:00
Armin Schrenk a17b416262 only remove system theme change listener, if one was previously registered. 2021-02-24 12:54:56 +01:00
Armin Schrenk fed572694f Merge branch 'develop' into feature/win-auto-theme
# Conflicts:
#	main/pom.xml
2021-02-24 12:25:04 +01:00
Armin Schrenk fe3d67d937 update build workflow 2021-02-24 12:21:13 +01:00
Armin Schrenk 3dcdeb1033 refactor pom to store targeted jdk build version in variable 2021-02-24 12:19:12 +01:00
Armin Schrenk 0898158c5a remove bintray as source repository in pom 2021-02-24 12:18:38 +01:00
Armin Schrenk 81091d4bdf bump integrations-* repos and implement new interface methods 2021-02-24 12:18:24 +01:00
Martin Beyer c9b1b1baa5 Fixes #1291 (Windows Automatic Theme) 2021-02-23 17:26:50 +01:00
Tobias Hagemann c81f3bd972 updated dependencies 2021-02-23 13:43:07 +01:00
Sebastian Stenzel 9f86b74320 New translations strings.properties (Greek)
[ci skip]
2021-02-23 09:32:09 +01:00
Sebastian Stenzel 2d8390a0f3 New translations strings.properties (Chinese Simplified)
[ci skip]
2021-02-22 11:47:50 +01:00
Sebastian Stenzel 8d3671175f New translations strings.properties (Swedish)
[ci skip]
2021-02-21 16:16:10 +01:00
Sebastian Stenzel 366011a222 New translations strings.properties (Swedish)
[ci skip]
2021-02-21 15:45:39 +01:00
Sebastian Stenzel c0c2e21055 New translations strings.properties (Korean)
[ci skip]
2021-02-20 02:29:34 +01:00
Sebastian Stenzel 63be96a151 New translations strings.properties (Korean)
[ci skip]
2021-02-20 01:58:05 +01:00
Sebastian Stenzel fc1df4bd99 New translations strings.properties (Catalan)
[ci skip]
2021-02-19 21:46:49 +01:00
Sebastian Stenzel 7657330931 New translations strings.properties (German)
[ci skip]
2021-02-19 13:17:33 +01:00
Sebastian Stenzel 4e44de3c3b New translations strings.properties (Portuguese, Brazilian)
[ci skip]
2021-02-19 01:07:24 +01:00
Sebastian Stenzel 8d902a72ca New translations strings.properties (Turkish)
[ci skip]
2021-02-18 19:39:40 +01:00
Sebastian Stenzel 7378031a72 New translations strings.properties (Spanish)
[ci skip]
2021-02-18 17:15:20 +01:00
Sebastian Stenzel f898c07c27 New translations strings.properties (German)
[ci skip]
2021-02-18 16:41:50 +01:00
Sebastian Stenzel c8f02d1045 New translations strings.properties (Czech)
[ci skip]
2021-02-18 14:56:07 +01:00
Sebastian Stenzel 4cc13b986b New translations strings.properties (Slovak)
[ci skip]
2021-02-18 14:22:12 +01:00
Sebastian Stenzel af7b6780f3 New translations strings.properties (Italian)
[ci skip]
2021-02-18 14:22:10 +01:00
Sebastian Stenzel 4a17d01004 New translations strings.properties (French)
[ci skip]
2021-02-18 13:42:57 +01:00
Sebastian Stenzel 1d68408e21 New translations strings.properties (Japanese)
[ci skip]
2021-02-18 13:42:49 +01:00
Sebastian Stenzel 821b1ee660 New translations strings.properties (Russian)
[ci skip]
2021-02-18 13:42:45 +01:00
Sebastian Stenzel c6616bd467 New translations strings.properties (Slovak)
[ci skip]
2021-02-18 13:42:44 +01:00
Sebastian Stenzel 4bb2589f16 New translations strings.properties (Polish)
[ci skip]
2021-02-18 13:42:37 +01:00
Sebastian Stenzel 896c3b3565 New translations strings.properties (Norwegian Bokmal)
[ci skip]
2021-02-18 13:09:32 +01:00
Sebastian Stenzel 6ee717a693 New translations strings.properties (French)
[ci skip]
2021-02-18 13:09:31 +01:00
Sebastian Stenzel 07ec858e1e New translations strings.properties (Spanish)
[ci skip]
2021-02-18 13:09:29 +01:00
Sebastian Stenzel a7c1e43ebc New translations strings.properties (Arabic)
[ci skip]
2021-02-18 13:09:28 +01:00
Sebastian Stenzel ac1cd3b073 New translations strings.properties (Catalan)
[ci skip]
2021-02-18 13:09:27 +01:00
Sebastian Stenzel 7474519faf New translations strings.properties (Czech)
[ci skip]
2021-02-18 13:09:26 +01:00
Sebastian Stenzel 340e474c33 New translations strings.properties (German)
[ci skip]
2021-02-18 13:09:24 +01:00
Sebastian Stenzel c90ab75427 New translations strings.properties (Greek)
[ci skip]
2021-02-18 13:09:23 +01:00
Sebastian Stenzel 848b3f77d3 New translations strings.properties (Hungarian)
[ci skip]
2021-02-18 13:09:21 +01:00
Sebastian Stenzel fb8cdb31ca New translations strings.properties (Italian)
[ci skip]
2021-02-18 13:09:20 +01:00
Sebastian Stenzel ba5f8053fb New translations strings.properties (Japanese)
[ci skip]
2021-02-18 13:09:19 +01:00
Sebastian Stenzel 38165becca New translations strings.properties (Korean)
[ci skip]
2021-02-18 13:09:17 +01:00
Sebastian Stenzel f731ac5c90 New translations strings.properties (Dutch)
[ci skip]
2021-02-18 13:09:16 +01:00
Sebastian Stenzel 0291702736 New translations strings.properties (Polish)
[ci skip]
2021-02-18 13:09:15 +01:00
Sebastian Stenzel ab63929861 New translations strings.properties (Portuguese)
[ci skip]
2021-02-18 13:09:12 +01:00
Sebastian Stenzel ca36fb8af3 New translations strings.properties (Slovak)
[ci skip]
2021-02-18 13:09:11 +01:00
Sebastian Stenzel 8cb29ff83b New translations strings.properties (Swedish)
[ci skip]
2021-02-18 13:09:10 +01:00
Sebastian Stenzel 304fa67dd7 New translations strings.properties (Turkish)
[ci skip]
2021-02-18 13:09:09 +01:00
Sebastian Stenzel a80ec32d2c New translations strings.properties (Chinese Simplified)
[ci skip]
2021-02-18 13:09:07 +01:00
Sebastian Stenzel dc4f21162e New translations strings.properties (Chinese Traditional)
[ci skip]
2021-02-18 13:09:06 +01:00
Sebastian Stenzel 3b8d7e0241 New translations strings.properties (Portuguese, Brazilian)
[ci skip]
2021-02-18 13:09:05 +01:00
Sebastian Stenzel 6891c68cf1 New translations strings.properties (Norwegian Nynorsk)
[ci skip]
2021-02-18 13:09:01 +01:00
Sebastian Stenzel 18b26fbc58 New translations strings.properties (Latvian)
[ci skip]
2021-02-18 13:09:00 +01:00
Sebastian Stenzel 1db8da6b6b New translations strings.properties (Bosnian)
[ci skip]
2021-02-18 13:08:57 +01:00
Sebastian Stenzel 14bce7e91d New translations strings.properties (Russian)
[ci skip]
2021-02-18 13:08:56 +01:00
Sebastian Stenzel 2674bc6f23 New translations strings.properties (Punjabi)
[ci skip]
2021-02-18 13:08:55 +01:00
Tobias HagemannandGitHub 74e1d6f991 Merge pull request #1545 from cryptomator/feature/save-password-clarification
"Save Password" Clarification
2021-02-18 13:07:04 +01:00
Tobias Hagemann 25dba028f8 added deep-linking to vault options tabs, changed "password saved" label to hyperlink 2021-02-18 11:32:14 +01:00
Tobias Hagemann bf51cc13d1 renamed "save password" to "remember password", switched placements of "vault options" hyperlink/button and "password saved" label 2021-02-18 09:15:19 +01:00
Sebastian Stenzel 24be36cccb New translations strings.properties (Spanish)
[ci skip]
2021-02-15 18:19:27 +01:00
Sebastian Stenzel 797e15c775 New translations strings.properties (Chinese Traditional)
[ci skip]
2021-02-15 17:08:04 +01:00
Sebastian Stenzel 2395dbcae9 New translations strings.properties (Italian)
[ci skip]
2021-02-15 16:09:11 +01:00
Sebastian Stenzel efacbbe2b6 New translations strings.properties (Bosnian)
[ci skip]
2021-02-15 15:40:45 +01:00
Sebastian Stenzel 2518086e46 New translations strings.properties (Polish)
[ci skip]
2021-02-15 15:40:44 +01:00
Sebastian Stenzel c733247611 New translations strings.properties (Japanese)
[ci skip]
2021-02-15 15:40:42 +01:00
Sebastian Stenzel 4f44e71e13 New translations strings.properties (Czech)
[ci skip]
2021-02-15 15:40:40 +01:00
Sebastian Stenzel 02aa46ece8 New translations strings.properties (Bosnian)
[ci skip]
2021-02-15 15:09:58 +01:00
Sebastian Stenzel 635f64c847 New translations strings.properties (German)
[ci skip]
2021-02-15 15:09:56 +01:00
Sebastian Stenzel 0a8516ae9a New translations strings.properties (French)
[ci skip]
2021-02-15 15:09:55 +01:00
Sebastian Stenzel c1edb30472 New translations strings.properties (Bosnian)
[ci skip]
2021-02-15 14:41:51 +01:00
Sebastian Stenzel 93c78b63ca New translations strings.properties (Russian)
[ci skip]
2021-02-15 14:41:50 +01:00
Sebastian Stenzel 3ccae93757 New translations strings.properties (Norwegian Bokmal)
[ci skip]
2021-02-15 14:09:30 +01:00
Sebastian Stenzel 450dec2baf New translations strings.properties (French)
[ci skip]
2021-02-15 14:09:29 +01:00
Sebastian Stenzel 36121527ca New translations strings.properties (Spanish)
[ci skip]
2021-02-15 14:09:27 +01:00
Sebastian Stenzel f30451f7e1 New translations strings.properties (Catalan)
[ci skip]
2021-02-15 14:09:25 +01:00
Sebastian Stenzel 74d7f63f64 New translations strings.properties (Czech)
[ci skip]
2021-02-15 14:09:24 +01:00
Sebastian Stenzel 350a4ab762 New translations strings.properties (German)
[ci skip]
2021-02-15 14:09:23 +01:00
Sebastian Stenzel 0e0e75b89c New translations strings.properties (Greek)
[ci skip]
2021-02-15 14:09:22 +01:00
Sebastian Stenzel e76440d928 New translations strings.properties (Hungarian)
[ci skip]
2021-02-15 14:09:20 +01:00
Sebastian Stenzel 0cbace67a5 New translations strings.properties (Italian)
[ci skip]
2021-02-15 14:09:19 +01:00
Sebastian Stenzel 84a3082589 New translations strings.properties (Japanese)
[ci skip]
2021-02-15 14:09:17 +01:00
Sebastian Stenzel cdfcca06d1 New translations strings.properties (Korean)
[ci skip]
2021-02-15 14:09:16 +01:00
Sebastian Stenzel 630bfa4cee New translations strings.properties (Dutch)
[ci skip]
2021-02-15 14:09:15 +01:00
Sebastian Stenzel 90cb7beb1f New translations strings.properties (Polish)
[ci skip]
2021-02-15 14:09:14 +01:00
Sebastian Stenzel d37fa33278 New translations strings.properties (Slovak)
[ci skip]
2021-02-15 14:09:11 +01:00
Sebastian Stenzel eed9c906cc New translations strings.properties (Swedish)
[ci skip]
2021-02-15 14:09:09 +01:00
Sebastian Stenzel 2b7ed5f4dd New translations strings.properties (Turkish)
[ci skip]
2021-02-15 14:09:08 +01:00
Sebastian Stenzel 6a7a309a2b New translations strings.properties (Chinese Simplified)
[ci skip]
2021-02-15 14:09:07 +01:00
Sebastian Stenzel 0382069995 New translations strings.properties (Chinese Traditional)
[ci skip]
2021-02-15 14:09:05 +01:00
Sebastian Stenzel 7c5f40d7d1 New translations strings.properties (Portuguese, Brazilian)
[ci skip]
2021-02-15 14:09:04 +01:00
Sebastian Stenzel 09e9530660 New translations strings.properties (Russian)
[ci skip]
2021-02-15 14:08:57 +01:00
Sebastian Stenzel 947d25b335 New translations strings.properties (Punjabi)
[ci skip]
2021-02-15 14:08:56 +01:00
Sebastian Stenzel 80cbc6699a fixed label
[ci skip]
2021-02-15 13:53:05 +01:00
Sebastian Stenzel da0933fa92 New translations strings.properties (Punjabi)
[ci skip]
2021-02-08 04:36:28 +01:00
Sebastian Stenzel adc9f32fb3 Merge branch 'master' into develop 2021-02-04 12:31:18 +01:00
Armin Schrenk 970216dd59 Merge tag '1.5.12' into develop
1.5.12
2021-02-04 10:49:52 +01:00
Sebastian Stenzel e4709ed6fe Refactored FxmlFile and FxmlLoaderFactory 2021-02-01 12:06:38 +01:00
Sebastian Stenzel 01929c2288 New translations strings.properties (Hungarian)
[ci skip]
2021-01-22 13:48:57 +01:00
Sebastian Stenzel 2634433b2c New translations strings.properties (Hungarian)
[ci skip]
2021-01-22 13:19:41 +01:00
Sebastian Stenzel cb2bc17283 New translations strings.properties (Hungarian)
[ci skip]
2021-01-21 11:06:22 +01:00
103 changed files with 1137 additions and 531 deletions
+12 -6
View File
@@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
with:
java-version: 14
java-version: 16
- uses: actions/cache@v1
with:
path: ~/.m2/repository
@@ -25,12 +25,13 @@ jobs:
- name: Build and Test
run: mvn -B install --file main/pom.xml -Pcoverage
- name: Run Codacy Coverage Reporter
if: github.repository == 'cryptomator/cryptomator'
run: |
curl -o ~/codacy-coverage-reporter.jar https://repo.maven.apache.org/maven2/com/codacy/codacy-coverage-reporter/7.1.0/codacy-coverage-reporter-7.1.0-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/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
$JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar report -l Java -r main/commons/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar report -l Java -r main/ui/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar report -l Java -r main/launcher/target/site/jacoco/jacoco.xml --partial
$JAVA_HOME/bin/java --illegal-access=permit -jar ~/codacy-coverage-reporter.jar final
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
- name: Assemble buildkit-linux.zip
@@ -59,7 +60,7 @@ jobs:
name: Draft a Release on GitHub Releases
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/')
if: startsWith(github.ref, 'refs/tags/') && github.repository == 'cryptomator/cryptomator'
steps:
- name: Download buildkit-linux.zip
uses: actions/download-artifact@v1
@@ -86,6 +87,11 @@ jobs:
release_name: ${{ github.ref }}
body: |
:construction: Work in Progress
TODO:
* [ ] add Linux appimage, zsync file and signature file
* [ ] add Windows installer and signature file
* [ ] add MacOs disk image and signature file
draft: true
prerelease: false
- name: Upload buildkit-linux.zip to GitHub Releases
+1
View File
@@ -21,5 +21,6 @@ pom.xml.versionsBackup
.idea/compiler.xml
.idea/encodings.xml
.idea/jarRepositories.xml
.idea/uiDesigner.xml
.idea/**/libraries/
*.iml
+1 -1
View File
@@ -8,7 +8,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_14" default="false" project-jdk-name="14" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="16" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
+19 -4
View File
@@ -2,7 +2,7 @@
[![Build](https://github.com/cryptomator/cryptomator/workflows/Build/badge.svg)](https://github.com/cryptomator/cryptomator/actions?query=workflow%3ABuild)
[![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)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/2a0adf3cec6a4143b91035d3924178f1)](https://www.codacy.com/gh/cryptomator/cryptomator/dashboard)
[![Twitter](https://img.shields.io/badge/twitter-@Cryptomator-blue.svg?style=flat)](http://twitter.com/Cryptomator)
[![Crowdin](https://badges.crowdin.net/cryptomator/localized.svg)](https://translate.cryptomator.org/)
[![Latest Release](https://img.shields.io/github/release/cryptomator/cryptomator.svg)](https://github.com/cryptomator/cryptomator/releases/latest)
@@ -17,11 +17,26 @@ Cryptomator is provided free of charge as an open-source project despite the hig
### Gold Sponsors
[<img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="96">](https://www.gee-whiz.de/)
<table>
<tbody>
<tr>
<td><a href="https://www.gee-whiz.de/"><img src="https://cryptomator.org/img/sponsors/geewhiz.svg" alt="gee-whiz" height="80"></a></td>
<td><a href="https://proxy-hub.com/"><img src="https://cryptomator.org/img/sponsors/proxyhub.svg" alt="Proxy-Hub" height="80"></a></td>
</tr>
</tbody>
</table>
### Silver Sponsors
[![TheBestVPN](https://cryptomator.org/img/sponsors/thebestvpn.png)](https://thebestvpn.com/)
<table>
<tbody>
<tr>
<td><a href="https://thebestvpn.com/"><img src="https://cryptomator.org/img/sponsors/thebestvpn@2x.png" alt="TheBestVPN" height="64"></a></td>
</tr>
</tbody>
</table>
- [Jameson Lopp](https://www.lopp.net/)
---
@@ -65,7 +80,7 @@ For more information on the security details visit [cryptomator.org](https://doc
### Dependencies
* JDK 14 (e.g. adoptopenjdk)
* JDK 16 (e.g. adoptopenjdk)
* 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))
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.5.12</version>
<version>1.6.0-SNAPSHOT</version>
</parent>
<artifactId>buildkit</artifactId>
<packaging>pom</packaging>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.5.12</version>
<version>1.6.0-SNAPSHOT</version>
</parent>
<artifactId>commons</artifactId>
<name>Cryptomator Commons</name>
@@ -47,10 +47,12 @@ public abstract class CommonsModule {
@Named("licensePublicKey")
static String provideLicensePublicKey() {
// in PEM format without the dash-escaped begin/end lines
return "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW" //
+ "fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV" //
+ "gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE" //
+ "r0DzRyj4ixPIt38CQB8=";
return """
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQB7NfnqiZbg2KTmoflmZ71PbXru7oW\
fmnV2yv3eDjlDfGruBrqz9TtXBZV/eYWt31xu1osIqaT12lKBvZ511aaAkIBeOEV\
gwcBIlJr6kUw7NKzeJt7r2rrsOyQoOG2nWc/Of/NBqA3mIZRHk5Aq1YupFdD26QE\
r0DzRyj4ixPIt38CQB8=\
""";
}
@Provides
@@ -33,8 +33,8 @@ class LicenseChecker {
try {
byte[] keyBytes = BaseEncoding.base64().decode(pemEncodedPublicKey);
PublicKey key = KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(keyBytes));
if (key instanceof ECPublicKey) {
return (ECPublicKey) key;
if (key instanceof ECPublicKey k) {
return k;
} else {
throw new IllegalStateException("Key not an EC public key.");
}
@@ -68,6 +68,11 @@ public class KeychainManager implements KeychainAccessProvider {
return keychain.getValue() != null;
}
@Override
public boolean isLocked() {
return keychain.getValue() == null || keychain.get().isLocked();
}
/**
* Checks if the keychain knows a passphrase for the given key.
* <p>
@@ -8,7 +8,7 @@ public enum UiTheme {
AUTOMATIC("preferences.general.theme.automatic");
public static UiTheme[] applicableValues() {
if (SystemUtils.IS_OS_MAC) {
if (SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_WINDOWS) {
return values();
} else {
return new UiTheme[]{LIGHT, DARK};
@@ -173,8 +173,7 @@ public class VaultSettings {
@Override
public boolean equals(Object obj) {
if (obj instanceof VaultSettings && obj.getClass().equals(this.getClass())) {
VaultSettings other = (VaultSettings) obj;
if (obj instanceof VaultSettings other && obj.getClass().equals(this.getClass())) {
return Objects.equals(this.id, other.id);
} else {
return false;
@@ -45,7 +45,9 @@ public class FuseVolume extends AbstractVolume {
try {
Mounter mounter = FuseMountFactory.getMounter();
EnvironmentVariables envVars = EnvironmentVariables.create() //
.withFlags(splitFlags(mountFlags)).withMountPoint(mountPoint) //
.withFlags(splitFlags(mountFlags)) //
.withMountPoint(mountPoint) //
.withFileNameTranscoder(mounter.defaultFileNameTranscoder()) //
.build();
this.mount = mounter.mount(root, envVars);
} catch (CommandFailedException | FuseNotSupportedException e) {
@@ -355,8 +355,7 @@ public class Vault {
@Override
public boolean equals(Object obj) {
if (obj instanceof Vault && obj.getClass().equals(this.getClass())) {
final Vault other = (Vault) obj;
if (obj instanceof Vault other && obj.getClass().equals(this.getClass())) {
return Objects.equals(this.vaultSettings, other.vaultSettings);
} else {
return false;
@@ -22,10 +22,10 @@ class VaultListChangeListener implements ListChangeListener<Vault> {
public void onChanged(Change<? extends Vault> c) {
while (c.next()) {
if (c.wasAdded()) {
List<VaultSettings> addedSettings = c.getAddedSubList().stream().map(Vault::getVaultSettings).collect(Collectors.toList());
List<VaultSettings> addedSettings = c.getAddedSubList().stream().map(Vault::getVaultSettings).toList();
vaultSettingsList.addAll(c.getFrom(), addedSettings);
} else if (c.wasRemoved()) {
List<VaultSettings> removedSettings = c.getRemoved().stream().map(Vault::getVaultSettings).collect(Collectors.toList());
List<VaultSettings> removedSettings = c.getRemoved().stream().map(Vault::getVaultSettings).toList();
vaultSettingsList.removeAll(removedSettings);
}
}
@@ -79,7 +79,7 @@ public class VaultListManager {
}
private void addAll(Collection<VaultSettings> vaultSettings) {
Collection<Vault> vaults = vaultSettings.stream().map(this::create).collect(Collectors.toList());
Collection<Vault> vaults = vaultSettings.stream().map(this::create).toList();
vaultList.addAll(vaults);
}
@@ -32,7 +32,7 @@ class EnvironmentTest {
public void testSettingsPath() {
System.setProperty("cryptomator.settingsPath", "~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json");
List<Path> result = env.getSettingsPath().collect(Collectors.toList());
List<Path> result = env.getSettingsPath().toList();
MatcherAssert.assertThat(result, Matchers.hasSize(2));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/settings.json"), //
Paths.get("/home/testuser/.Cryptomator/settings.json")));
@@ -43,7 +43,7 @@ class EnvironmentTest {
public void testIpcPortPath() {
System.setProperty("cryptomator.ipcPortPath", "~/.config/Cryptomator/ipcPort.bin:~/.Cryptomator/ipcPort.bin");
List<Path> result = env.getIpcPortPath().collect(Collectors.toList());
List<Path> result = env.getIpcPortPath().toList();
MatcherAssert.assertThat(result, Matchers.hasSize(2));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/ipcPort.bin"), //
Paths.get("/home/testuser/.Cryptomator/ipcPort.bin")));
@@ -54,7 +54,7 @@ class EnvironmentTest {
public void testKeychainPath() {
System.setProperty("cryptomator.keychainPath", "~/AppData/Roaming/Cryptomator/keychain.json");
List<Path> result = env.getKeychainPath().collect(Collectors.toList());
List<Path> result = env.getKeychainPath().toList();
MatcherAssert.assertThat(result, Matchers.hasSize(1));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/AppData/Roaming/Cryptomator/keychain.json")));
}
@@ -88,7 +88,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=")
public void testEmptyList() {
System.setProperty("test.path.property", "");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList());
List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(0));
}
@@ -97,7 +97,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=/foo/bar/test")
public void testSingleAbsolutePath() {
System.setProperty("test.path.property", "/foo/bar/test");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList());
List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(1));
MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/foo/bar/test")));
@@ -107,7 +107,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=~/test")
public void testSingleHomeRelativePath() {
System.setProperty("test.path.property", "~/test");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList());
List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(1));
MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/home/testuser/test")));
@@ -117,7 +117,7 @@ class EnvironmentTest {
@DisplayName("test.path.property=~/test:~/test2:/foo/bar/test")
public void testMultiplePaths() {
System.setProperty("test.path.property", "~/test:~/test2:/foo/bar/test");
List<Path> result = env.getPaths("test.path.property").collect(Collectors.toList());
List<Path> result = env.getPaths("test.path.property").toList();
MatcherAssert.assertThat(result, Matchers.hasSize(3));
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/test"), //
@@ -9,10 +9,12 @@ import java.util.Optional;
class LicenseCheckerTest {
private static final String PUBLIC_KEY = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ" //
+ "PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47" //
+ "6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM" //
+ "Al8G7CqwoJOsW7Kddns=";
private static final String PUBLIC_KEY = """
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ\
PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47\
6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM\
Al8G7CqwoJOsW7Kddns=\
""";
private LicenseChecker licenseChecker;
@@ -44,4 +44,9 @@ class MapKeychainAccess implements KeychainAccessProvider {
return true;
}
@Override
public boolean isLocked() {
return false;
}
}
@@ -21,13 +21,18 @@ public class SettingsJsonAdapterTest {
@Test
public void testDeserialize() throws IOException {
String vault1Json = "{\"id\": \"1\", \"path\": \"/vault1\", \"mountName\": \"vault1\", \"winDriveLetter\": \"X\"}";
String vault2Json = "{\"id\": \"2\", \"path\": \"/vault2\", \"mountName\": \"vault2\", \"winDriveLetter\": \"Y\"}";
String json = "{\"directories\": [" + vault1Json + "," + vault2Json + "]," //
+ "\"checkForUpdatesEnabled\": true,"//
+ "\"port\": 8080,"//
+ "\"numTrayNotifications\": 42,"//
+ "\"preferredVolumeImpl\": \"FUSE\"}";
String json = """
{
"directories": [
{"id": "1", "path": "/vault1", "mountName": "vault1", "winDriveLetter": "X"},
{"id": "2", "path": "/vault2", "mountName": "vault2", "winDriveLetter": "Y"}
],
"checkForUpdatesEnabled": true,
"port": 8080,
"numTrayNotifications": 42,
"preferredVolumeImpl": "FUSE"
}
""";
Settings settings = adapter.fromJson(json);
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.5.12</version>
<version>1.6.0-SNAPSHOT</version>
</parent>
<artifactId>launcher</artifactId>
<name>Cryptomator Launcher</name>
@@ -41,7 +41,7 @@ class FileOpenRequestHandler {
}
private void openFiles(OpenFilesEvent evt) {
Collection<Path> pathsToOpen = evt.getFiles().stream().map(File::toPath).collect(Collectors.toList());
Collection<Path> pathsToOpen = evt.getFiles().stream().map(File::toPath).toList();
AppLaunchEvent launchEvent = new AppLaunchEvent(AppLaunchEvent.EventType.OPEN_FILE, pathsToOpen);
tryToEnqueueFileOpenRequest(launchEvent);
}
@@ -59,7 +59,7 @@ class FileOpenRequestHandler {
LOG.trace("Argument not a valid path: {}", str);
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
}).filter(Objects::nonNull).toList();
if (!pathsToOpen.isEmpty()) {
AppLaunchEvent launchEvent = new AppLaunchEvent(AppLaunchEvent.EventType.OPEN_FILE, pathsToOpen);
tryToEnqueueFileOpenRequest(launchEvent);
@@ -47,8 +47,8 @@ public class LoggerModule {
@Singleton
static LoggerContext provideLoggerContext() {
ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
if (loggerFactory instanceof LoggerContext) {
return (LoggerContext) loggerFactory;
if (loggerFactory instanceof LoggerContext context) {
return context;
} else {
throw new IllegalStateException("SLF4J not bound to Logback.");
}
+13 -25
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.5.12</version>
<version>1.6.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Cryptomator</name>
@@ -22,24 +22,25 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.jdk.version>16</project.jdk.version>
<!-- cryptomator dependencies -->
<cryptomator.cryptofs.version>1.9.13</cryptomator.cryptofs.version>
<cryptomator.integrations.version>0.1.6</cryptomator.integrations.version>
<cryptomator.integrations.win.version>0.2.1</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>0.1.0-beta3</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>0.1.1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>1.2.8</cryptomator.fuse.version>
<cryptomator.dokany.version>1.2.3</cryptomator.dokany.version>
<cryptomator.webdav.version>1.1.1</cryptomator.webdav.version>
<cryptomator.cryptofs.version>1.9.14</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.0.0-beta2</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.0.0-beta2</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.0.0-beta2</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.0.0-beta1</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>1.3.0</cryptomator.fuse.version>
<cryptomator.dokany.version>1.2.4</cryptomator.dokany.version>
<cryptomator.webdav.version>1.2.0</cryptomator.webdav.version>
<!-- 3rd party dependencies -->
<javafx.version>15</javafx.version>
<commons-lang3.version>3.11</commons-lang3.version>
<jwt.version>3.12.0</jwt.version>
<jwt.version>3.13.0</jwt.version>
<easybind.version>2.1.0</easybind.version>
<guava.version>30.0-jre</guava.version>
<dagger.version>2.29.1</dagger.version>
<dagger.version>2.32</dagger.version>
<gson.version>2.8.6</gson.version>
<slf4j.version>1.7.30</slf4j.version>
<logback.version>1.2.3</logback.version>
@@ -50,13 +51,6 @@
<hamcrest.version>2.2</hamcrest.version>
</properties>
<repositories>
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<!-- modules -->
@@ -224,12 +218,6 @@
<scope>test</scope>
</dependency>
<!-- TODO: temporary fix for XXE attack, can be removed once java-jwt is updated -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.5.1</version>
</dependency>
</dependencies>
</dependencyManagement>
@@ -437,7 +425,7 @@
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>14</release>
<release>${project.jdk.version}</release>
<annotationProcessorPaths>
<path>
<groupId>com.google.dagger</groupId>
-5
View File
@@ -1,11 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This file lists false positives found by org.owasp:dependency-check-maven build plugin -->
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.2.xsd">
<suppress>
<notes><![CDATA[ Upstream fix backported from 2.11.0 to 2.10.5.1, see https://github.com/FasterXML/jackson-databind/issues/2589#issuecomment-714833837. ]]></notes>
<gav>com.fasterxml.jackson.core:jackson-databind:2.10.5.1</gav>
<cve>CVE-2020-25649</cve>
</suppress>
<suppress>
<notes><![CDATA[ Suppress known vulnerabilities in FUSE libraries for fuse-nio-adapter. For more info, see suppression.xml of https://github.com/cryptomator/fuse-nio-adapter ]]></notes>
<gav regex="true">^org\.cryptomator:fuse-nio-adapter:.*$</gav>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.5.12</version>
<version>1.6.0-SNAPSHOT</version>
</parent>
<artifactId>ui</artifactId>
<name>Cryptomator GUI</name>
@@ -6,7 +6,7 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -43,8 +43,8 @@ public abstract class AddVaultModule {
@Provides
@AddVaultWizardWindow
@AddVaultWizardScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -91,50 +91,50 @@ public abstract class AddVaultModule {
@Provides
@FxmlScene(FxmlFile.ADDVAULT_WELCOME)
@AddVaultWizardScoped
static Scene provideWelcomeScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_WELCOME.getRessourcePathString());
static Scene provideWelcomeScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_WELCOME);
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_EXISTING)
@AddVaultWizardScoped
static Scene provideChooseExistingVaultScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_EXISTING.getRessourcePathString());
static Scene provideChooseExistingVaultScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_EXISTING);
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_NEW_NAME)
@AddVaultWizardScoped
static Scene provideCreateNewVaultNameScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_NAME.getRessourcePathString());
static Scene provideCreateNewVaultNameScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_NAME);
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION)
@AddVaultWizardScoped
static Scene provideCreateNewVaultLocationScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_LOCATION.getRessourcePathString());
static Scene provideCreateNewVaultLocationScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_LOCATION);
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD)
@AddVaultWizardScoped
static Scene provideCreateNewVaultPasswordScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_PASSWORD.getRessourcePathString());
static Scene provideCreateNewVaultPasswordScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_PASSWORD);
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY)
@AddVaultWizardScoped
static Scene provideCreateNewVaultRecoveryKeyScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY.getRessourcePathString());
static Scene provideCreateNewVaultRecoveryKeyScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY);
}
@Provides
@FxmlScene(FxmlFile.ADDVAULT_SUCCESS)
@AddVaultWizardScoped
static Scene provideCreateNewVaultSuccessScene(@AddVaultWizardWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_SUCCESS.getRessourcePathString());
static Scene provideCreateNewVaultSuccessScene(@AddVaultWizardWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ADDVAULT_SUCCESS);
}
// ------------------
@@ -4,7 +4,7 @@ import dagger.Lazy;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -34,7 +34,7 @@ public class ChooseExistingVaultController implements FxController {
private final Stage window;
private final Lazy<Scene> welcomeScene;
private final Lazy<Scene> successScene;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
private final ObjectProperty<Path> vaultPath;
private final ObjectProperty<Vault> vault;
private final VaultListManager vaultListManager;
@@ -43,11 +43,11 @@ public class ChooseExistingVaultController implements FxController {
private Image screenshot;
@Inject
ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy<Scene> welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, ErrorComponent.Builder errorComponent, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, VaultListManager vaultListManager, ResourceBundle resourceBundle) {
ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy<Scene> welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, GenericErrorComponent.Builder genericErrorBuilder, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, VaultListManager vaultListManager, ResourceBundle resourceBundle) {
this.window = window;
this.welcomeScene = welcomeScene;
this.successScene = successScene;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
this.vaultPath = vaultPath;
this.vault = vault;
this.vaultListManager = vaultListManager;
@@ -83,7 +83,7 @@ public class ChooseExistingVaultController implements FxController {
window.setScene(successScene.get());
} catch (NoSuchFileException e) {
LOG.error("Failed to open existing vault.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
}
}
@@ -1,7 +1,7 @@
package org.cryptomator.ui.addvaultwizard;
import dagger.Lazy;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -43,7 +43,7 @@ public class CreateNewVaultLocationController implements FxController {
private final Stage window;
private final Lazy<Scene> chooseNameScene;
private final Lazy<Scene> choosePasswordScene;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
private final LocationPresets locationPresets;
private final ObjectProperty<Path> vaultPath;
private final StringProperty vaultName;
@@ -61,11 +61,11 @@ public class CreateNewVaultLocationController implements FxController {
public RadioButton customRadioButton;
@Inject
CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, ErrorComponent.Builder errorComponent, LocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
CreateNewVaultLocationController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_NAME) Lazy<Scene> chooseNameScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_PASSWORD) Lazy<Scene> choosePasswordScene, GenericErrorComponent.Builder genericErrorBuilder, LocationPresets locationPresets, ObjectProperty<Path> vaultPath, @Named("vaultName") StringProperty vaultName, ResourceBundle resourceBundle) {
this.window = window;
this.chooseNameScene = chooseNameScene;
this.choosePasswordScene = choosePasswordScene;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
this.locationPresets = locationPresets;
this.vaultPath = vaultPath;
this.vaultName = vaultName;
@@ -129,7 +129,7 @@ public class CreateNewVaultLocationController implements FxController {
warningText.set(resourceBundle.getString("addvaultwizard.new.locationDoesNotExist"));
} catch (IOException e) {
LOG.error("Failed to create and delete directory at chosen vault path.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
}
@@ -5,7 +5,7 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -53,7 +53,7 @@ public class CreateNewVaultPasswordController implements FxController {
private final Lazy<Scene> chooseLocationScene;
private final Lazy<Scene> recoveryKeyScene;
private final Lazy<Scene> successScene;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
private final ExecutorService executor;
private final RecoveryKeyFactory recoveryKeyFactory;
private final StringProperty vaultNameProperty;
@@ -73,12 +73,12 @@ public class CreateNewVaultPasswordController implements FxController {
public Toggle skipRecoveryKey;
@Inject
CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy<Scene> chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy<Scene> recoveryKeyScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, ErrorComponent.Builder errorComponent, ExecutorService executor, RecoveryKeyFactory recoveryKeyFactory, @Named("vaultName") StringProperty vaultName, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, @Named("recoveryKey") StringProperty recoveryKey, VaultListManager vaultListManager, ResourceBundle resourceBundle, @Named("newPassword") ObjectProperty<CharSequence> password, ReadmeGenerator readmeGenerator) {
CreateNewVaultPasswordController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy<Scene> chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_NEW_RECOVERYKEY) Lazy<Scene> recoveryKeyScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy<Scene> successScene, GenericErrorComponent.Builder genericErrorBuilder, ExecutorService executor, RecoveryKeyFactory recoveryKeyFactory, @Named("vaultName") StringProperty vaultName, ObjectProperty<Path> vaultPath, @AddVaultWizardWindow ObjectProperty<Vault> vault, @Named("recoveryKey") StringProperty recoveryKey, VaultListManager vaultListManager, ResourceBundle resourceBundle, @Named("newPassword") ObjectProperty<CharSequence> password, ReadmeGenerator readmeGenerator) {
this.window = window;
this.chooseLocationScene = chooseLocationScene;
this.recoveryKeyScene = recoveryKeyScene;
this.successScene = successScene;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
this.executor = executor;
this.recoveryKeyFactory = recoveryKeyFactory;
this.vaultNameProperty = vaultName;
@@ -113,7 +113,7 @@ public class CreateNewVaultPasswordController implements FxController {
Files.createDirectory(pathToVault);
} catch (IOException e) {
LOG.error("Failed to create vault directory.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
return;
}
@@ -138,7 +138,7 @@ public class CreateNewVaultPasswordController implements FxController {
window.setScene(recoveryKeyScene.get());
}).onError(IOException.class, e -> {
LOG.error("Failed to initialize vault.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}).andFinally(() -> {
processing.set(false);
}).runOnce(executor);
@@ -154,7 +154,7 @@ public class CreateNewVaultPasswordController implements FxController {
window.setScene(successScene.get());
}).onError(IOException.class, e -> {
LOG.error("Failed to initialize vault.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}).andFinally(() -> {
processing.set(false);
}).runOnce(executor);
@@ -6,7 +6,7 @@ import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
import org.slf4j.Logger;
@@ -23,7 +23,6 @@ import javafx.scene.control.CheckBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Optional;
import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
@@ -35,7 +34,7 @@ public class ChangePasswordController implements FxController {
private final Stage window;
private final Vault vault;
private final ObjectProperty<CharSequence> newPassword;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
private final KeychainManager keychain;
public NiceSecurePasswordField oldPasswordField;
@@ -43,11 +42,11 @@ public class ChangePasswordController implements FxController {
public Button finishButton;
@Inject
public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, @Named("newPassword") ObjectProperty<CharSequence> newPassword, ErrorComponent.Builder errorComponent, KeychainManager keychain) {
public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, @Named("newPassword") ObjectProperty<CharSequence> newPassword, GenericErrorComponent.Builder genericErrorBuilder, KeychainManager keychain) {
this.window = window;
this.vault = vault;
this.newPassword = newPassword;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
this.keychain = keychain;
}
@@ -73,7 +72,7 @@ public class ChangePasswordController implements FxController {
updatePasswordInSystemkeychain();
} catch (IOException e) {
LOG.error("IO error occured during password change. Unable to perform operation.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
} catch (InvalidPassphraseException e) {
Animations.createShakeWindowAnimation(window).play();
oldPasswordField.selectAll();
@@ -5,7 +5,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -37,8 +37,8 @@ abstract class ChangePasswordModule {
@Provides
@ChangePasswordWindow
@ChangePasswordScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -56,8 +56,8 @@ abstract class ChangePasswordModule {
@Provides
@FxmlScene(FxmlFile.CHANGEPASSWORD)
@ChangePasswordScoped
static Scene provideUnlockScene(@ChangePasswordWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/changepassword.fxml");
static Scene provideUnlockScene(@ChangePasswordWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.CHANGEPASSWORD);
}
@@ -42,8 +42,8 @@ public class DefaultSceneFactory implements Function<Parent, Scene> {
protected void configureScene(Scene scene) {
scene.windowProperty().addListener(observable -> {
Window window = scene.getWindow();
if (window instanceof Stage) {
setupDefaultAccelerators(scene, (Stage) window);
if (window instanceof Stage s) {
setupDefaultAccelerators(scene, s);
}
});
}
@@ -9,8 +9,8 @@ public enum FxmlFile {
ADDVAULT_SUCCESS("/fxml/addvault_success.fxml"), //
ADDVAULT_WELCOME("/fxml/addvault_welcome.fxml"), //
CHANGEPASSWORD("/fxml/changepassword.fxml"), //
ERROR("/fxml/error.fxml"), //
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
GENERIC_ERROR("/fxml/generic_error.fxml"), //
LOCK_FORCED("/fxml/lock_forced.fxml"), //
LOCK_FAILED("/fxml/lock_failed.fxml"), //
MAIN_WINDOW("/fxml/main_window.fxml"), //
@@ -39,7 +39,7 @@ public enum FxmlFile {
this.ressourcePathString = ressourcePathString;
}
public String getRessourcePathString() {
String getRessourcePathString() {
return ressourcePathString;
}
}
@@ -11,13 +11,13 @@ import java.util.Map;
import java.util.ResourceBundle;
import java.util.function.Function;
public class FXMLLoaderFactory {
public class FxmlLoaderFactory {
private final Map<Class<? extends FxController>, Provider<FxController>> controllerFactories;
private final Function<Parent, Scene> sceneFactory;
private final ResourceBundle resourceBundle;
public FXMLLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> controllerFactories, Function<Parent, Scene> sceneFactory, ResourceBundle resourceBundle) {
public FxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> controllerFactories, Function<Parent, Scene> sceneFactory, ResourceBundle resourceBundle) {
this.controllerFactories = controllerFactories;
this.sceneFactory = sceneFactory;
this.resourceBundle = resourceBundle;
@@ -48,13 +48,17 @@ public class FXMLLoaderFactory {
return loader;
}
public Scene createScene(FxmlFile fxmlFile) {
return createScene(fxmlFile.getRessourcePathString());
}
/**
* {@link #load(String) Loads} the FXML file and creates a new Scene containing the loaded ui.
*
* @param fxmlResourceName Name of the resource (as in {@link Class#getResource(String)}).
* @throws UncheckedIOException wrapping any IOException thrown by {@link #load(String)).
*/
public Scene createScene(String fxmlResourceName) {
private Scene createScene(String fxmlResourceName) {
final FXMLLoader loader;
try {
loader = load(fxmlResourceName);
@@ -1,9 +1,15 @@
package org.cryptomator.ui.common;
package org.cryptomator.ui.error;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import javax.inject.Named;
import javax.inject.Provider;
@@ -18,8 +24,8 @@ import java.util.ResourceBundle;
abstract class ErrorModule {
@Provides
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -33,13 +39,13 @@ abstract class ErrorModule {
@Binds
@IntoMap
@FxControllerKey(ErrorController.class)
abstract FxController bindErrorController(ErrorController controller);
@FxControllerKey(GenericErrorController.class)
abstract FxController bindErrorController(GenericErrorController controller);
@Provides
@FxmlScene(FxmlFile.ERROR)
static Scene provideErrorScene(FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.ERROR.getRessourcePathString());
@FxmlScene(FxmlFile.GENERIC_ERROR)
static Scene provideErrorScene(FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.GENERIC_ERROR);
}
@@ -1,7 +1,9 @@
package org.cryptomator.ui.common;
package org.cryptomator.ui.error;
import dagger.BindsInstance;
import dagger.Subcomponent;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javax.annotation.Nullable;
import javafx.application.Platform;
@@ -9,11 +11,11 @@ import javafx.scene.Scene;
import javafx.stage.Stage;
@Subcomponent(modules = {ErrorModule.class})
public interface ErrorComponent {
public interface GenericErrorComponent {
Stage window();
@FxmlScene(FxmlFile.ERROR)
@FxmlScene(FxmlFile.GENERIC_ERROR)
Scene scene();
default void showErrorScene() {
@@ -42,7 +44,7 @@ public interface ErrorComponent {
@BindsInstance
Builder returnToScene(@Nullable Scene previousScene);
ErrorComponent build();
GenericErrorComponent build();
}
@@ -1,4 +1,6 @@
package org.cryptomator.ui.common;
package org.cryptomator.ui.error;
import org.cryptomator.ui.common.FxController;
import javax.annotation.Nullable;
import javax.inject.Inject;
@@ -7,14 +9,14 @@ import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class ErrorController implements FxController {
public class GenericErrorController implements FxController {
private final String stackTrace;
private final Scene previousScene;
private final Stage window;
@Inject
ErrorController(@Named("stackTrace") String stackTrace, @Nullable Scene previousScene, Stage window) {
GenericErrorController(@Named("stackTrace") String stackTrace, @Nullable Scene previousScene, Stage window) {
this.stackTrace = stackTrace;
this.previousScene = previousScene;
this.window = window;
@@ -5,7 +5,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -29,8 +29,8 @@ abstract class ForgetPasswordModule {
@Provides
@ForgetPasswordWindow
@ForgetPasswordScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -62,8 +62,8 @@ abstract class ForgetPasswordModule {
@Provides
@FxmlScene(FxmlFile.FORGET_PASSWORD)
@ForgetPasswordScoped
static Scene provideForgetPasswordScene(@ForgetPasswordWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/forget_password.fxml");
static Scene provideForgetPasswordScene(@ForgetPasswordWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.FORGET_PASSWORD);
}
// ------------------
@@ -86,7 +86,7 @@ public class FxApplication extends Application {
}
private void hasVisibleStagesChanged(@SuppressWarnings("unused") ObservableValue<? extends Boolean> observableValue, @SuppressWarnings("unused") boolean oldValue, boolean newValue) {
LOG.warn("has visible stages: {}", newValue);
LOG.debug("has visible stages: {}", newValue);
if (newValue) {
trayIntegration.ifPresent(TrayIntegrationProvider::restoredFromTray);
} else {
@@ -137,13 +137,13 @@ public class FxApplication extends Application {
}
private void appThemeChanged(@SuppressWarnings("unused") ObservableValue<? extends UiTheme> observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) {
appearanceProvider.ifPresent(appearanceProvider -> {
if (appearanceProvider.isPresent() && oldValue == UiTheme.AUTOMATIC && newValue != UiTheme.AUTOMATIC) {
try {
appearanceProvider.removeListener(systemInterfaceThemeListener);
appearanceProvider.get().removeListener(systemInterfaceThemeListener);
} catch (UiAppearanceException e) {
LOG.error("Failed to disable automatic theme switching.");
}
});
}
loadSelectedStyleSheet(newValue);
}
@@ -9,7 +9,7 @@ import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.lock.LockComponent;
import org.cryptomator.ui.mainwindow.MainWindowComponent;
@@ -19,16 +19,14 @@ import org.cryptomator.ui.unlock.UnlockComponent;
import javax.inject.Named;
import javafx.application.Application;
import javafx.collections.ObservableSet;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.List;
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {MainWindowComponent.class, PreferencesComponent.class, UnlockComponent.class, LockComponent.class, QuitComponent.class, ErrorComponent.class})
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {MainWindowComponent.class, PreferencesComponent.class, UnlockComponent.class, LockComponent.class, QuitComponent.class, GenericErrorComponent.class})
abstract class FxApplicationModule {
@Provides
@@ -15,6 +15,7 @@ import javafx.beans.property.StringProperty;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.util.Duration;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
@@ -39,8 +40,13 @@ public abstract class UpdateCheckerModule {
@Provides
@FxApplicationScoped
static HttpClient provideHttpClient() {
return HttpClient.newHttpClient();
static Optional<HttpClient> provideHttpClient() {
try {
return Optional.of(HttpClient.newHttpClient());
} catch (UncheckedIOException e) {
LOG.error("HttpClient for update check cannot be created.", e);
return Optional.empty();
}
}
@Provides
@@ -66,11 +72,20 @@ public abstract class UpdateCheckerModule {
@Provides
@FxApplicationScoped
static ScheduledService<String> provideCheckForUpdatesService(ExecutorService executor, HttpClient httpClient, HttpRequest checkForUpdatesRequest, @Named("checkForUpdatesInterval") ObjectBinding<Duration> period) {
static ScheduledService<String> provideCheckForUpdatesService(ExecutorService executor, Optional<HttpClient> httpClient, HttpRequest checkForUpdatesRequest, @Named("checkForUpdatesInterval") ObjectBinding<Duration> period) {
ScheduledService<String> service = new ScheduledService<>() {
@Override
protected Task<String> createTask() {
return new UpdateCheckerTask(httpClient, checkForUpdatesRequest);
if (httpClient.isPresent()) {
return new UpdateCheckerTask(httpClient.get(), checkForUpdatesRequest);
} else {
return new Task<>() {
@Override
protected String call() {
throw new NullPointerException("No HttpClient present.");
}
};
}
}
};
service.setOnFailed(event -> LOG.error("Failed to execute update service", service.getException()));
@@ -1,5 +1,6 @@
package org.cryptomator.ui.launcher;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.ui.fxapp.FxApplication;
import org.slf4j.Logger;
@@ -55,7 +56,7 @@ class AppLaunchEventHandler {
case REVEAL_APP -> fxApplicationStarter.get().thenAccept(FxApplication::showMainWindow);
case OPEN_FILE -> fxApplicationStarter.get().thenRun(() -> {
Platform.runLater(() -> {
event.getPathsToOpen().forEach(this::addVault);
event.getPathsToOpen().forEach(this::addOrRevealVault);
});
});
default -> LOG.warn("Unsupported event type: {}", event.getType());
@@ -63,13 +64,18 @@ class AppLaunchEventHandler {
}
// TODO dedup MainWindowController...
private void addVault(Path potentialVaultPath) {
private void addOrRevealVault(Path potentialVaultPath) {
assert Platform.isFxApplicationThread();
try {
final Vault v;
if (potentialVaultPath.getFileName().toString().equals(MASTERKEY_FILENAME)) {
vaultListManager.add(potentialVaultPath.getParent());
v = vaultListManager.add(potentialVaultPath.getParent());
} else {
vaultListManager.add(potentialVaultPath);
v = vaultListManager.add(potentialVaultPath);
}
if (v.isUnlocked()) {
fxApplicationStarter.get().thenAccept(app -> app.getVaultService().reveal(v));
}
LOG.debug("Added vault {}", potentialVaultPath);
} catch (NoSuchFileException e) {
@@ -6,7 +6,7 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -40,8 +40,8 @@ abstract class LockModule {
@Provides
@LockWindow
@LockScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -63,15 +63,15 @@ abstract class LockModule {
@Provides
@FxmlScene(FxmlFile.LOCK_FORCED)
@LockScoped
static Scene provideForceLockScene(@LockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/lock_forced.fxml");
static Scene provideForceLockScene(@LockWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.LOCK_FORCED);
}
@Provides
@FxmlScene(FxmlFile.LOCK_FAILED)
@LockScoped
static Scene provideLockFailedScene(@LockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/lock_failed.fxml");
static Scene provideLockFailedScene(@LockWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.LOCK_FAILED);
}
// ------------------
@@ -6,7 +6,7 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -39,8 +39,8 @@ abstract class MainWindowModule {
@Provides
@MainWindow
@MainWindowScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, MainWindowSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, MainWindowSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -60,8 +60,8 @@ abstract class MainWindowModule {
@Provides
@FxmlScene(FxmlFile.MAIN_WINDOW)
@MainWindowScoped
static Scene provideMainScene(@MainWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/main_window.fxml");
static Scene provideMainScene(@MainWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.MAIN_WINDOW);
}
// ------------------
@@ -86,6 +86,11 @@ abstract class MainWindowModule {
@FxControllerKey(VaultListController.class)
abstract FxController bindVaultListController(VaultListController controller);
@Binds
@IntoMap
@FxControllerKey(VaultListContextMenuController.class)
abstract FxController bindVaultListContextMenuController(VaultListContextMenuController controller);
@Binds
@IntoMap
@FxControllerKey(VaultDetailController.class)
@@ -5,6 +5,7 @@ import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.fxapp.FxApplication;
import org.cryptomator.ui.vaultoptions.SelectedVaultOptionsTab;
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
import javax.inject.Inject;
@@ -47,7 +48,12 @@ public class VaultDetailLockedController implements FxController {
@FXML
public void showVaultOptions() {
vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow();
vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
}
@FXML
public void showKeyVaultOptions() {
vaultOptionsWindow.vault(vault.get()).build().showVaultOptionsWindow(SelectedVaultOptionsTab.KEY);
}
/* Getter/Setter */
@@ -1,7 +1,7 @@
package org.cryptomator.ui.mainwindow;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.controls.DraggableListCell;
import javax.inject.Inject;
@@ -17,10 +17,10 @@ import java.io.UncheckedIOException;
@MainWindowScoped
public class VaultListCellFactory implements Callback<ListView<Vault>, ListCell<Vault>> {
private final FXMLLoaderFactory fxmlLoaders;
private final FxmlLoaderFactory fxmlLoaders;
@Inject
VaultListCellFactory(@MainWindow FXMLLoaderFactory fxmlLoaders) {
VaultListCellFactory(@MainWindow FxmlLoaderFactory fxmlLoaders) {
this.fxmlLoaders = fxmlLoaders;
}
@@ -0,0 +1,135 @@
package org.cryptomator.ui.mainwindow;
import com.tobiasdiez.easybind.EasyBind;
import com.tobiasdiez.easybind.optional.ObservableOptionalValue;
import com.tobiasdiez.easybind.optional.OptionalBinding;
import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.fxapp.FxApplication;
import org.cryptomator.ui.removevault.RemoveVaultComponent;
import org.cryptomator.ui.vaultoptions.SelectedVaultOptionsTab;
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
import javax.inject.Inject;
import javafx.beans.binding.Binding;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.fxml.FXML;
import javafx.stage.Stage;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Optional;
import static org.cryptomator.common.vaults.VaultState.ERROR;
import static org.cryptomator.common.vaults.VaultState.LOCKED;
import static org.cryptomator.common.vaults.VaultState.MISSING;
import static org.cryptomator.common.vaults.VaultState.NEEDS_MIGRATION;
import static org.cryptomator.common.vaults.VaultState.UNLOCKED;
@MainWindowScoped
public class VaultListContextMenuController implements FxController {
private final ObservableOptionalValue<Vault> selectedVault;
private final Stage mainWindow;
private final FxApplication application;
private final KeychainManager keychain;
private final RemoveVaultComponent.Builder removeVault;
private final VaultOptionsComponent.Builder vaultOptionsWindow;
private final OptionalBinding<VaultState> selectedVaultState;
private final Binding<Boolean> selectedVaultPassphraseStored;
private final Binding<Boolean> selectedVaultRemovable;
private final Binding<Boolean> selectedVaultUnlockable;
private final Binding<Boolean> selectedVaultLockable;
@Inject
VaultListContextMenuController(ObjectProperty<Vault> selectedVault, @MainWindow Stage mainWindow, FxApplication application, KeychainManager keychain, RemoveVaultComponent.Builder removeVault, VaultOptionsComponent.Builder vaultOptionsWindow) {
this.selectedVault = EasyBind.wrapNullable(selectedVault);
this.mainWindow = mainWindow;
this.application = application;
this.keychain = keychain;
this.removeVault = removeVault;
this.vaultOptionsWindow = vaultOptionsWindow;
this.selectedVaultState = this.selectedVault.mapObservable(Vault::stateProperty);
this.selectedVaultPassphraseStored = this.selectedVault.map(this::isPasswordStored).orElse(false);
this.selectedVaultRemovable = selectedVaultState.map(EnumSet.of(LOCKED, MISSING, ERROR, NEEDS_MIGRATION)::contains).orElse(false);
this.selectedVaultUnlockable = selectedVaultState.map(LOCKED::equals).orElse(false);
this.selectedVaultLockable = selectedVaultState.map(UNLOCKED::equals).orElse(false);
}
private boolean isPasswordStored(Vault vault) {
return keychain.getPassphraseStoredProperty(vault.getId()).get();
}
@FXML
public void didClickRemoveVault() {
selectedVault.ifValuePresent(v -> {
removeVault.vault(v).build().showRemoveVault();
});
}
@FXML
public void didClickShowVaultOptions() {
selectedVault.ifValuePresent(v -> {
vaultOptionsWindow.vault(v).build().showVaultOptionsWindow(SelectedVaultOptionsTab.ANY);
});
}
@FXML
public void didClickUnlockVault() {
selectedVault.ifValuePresent(v -> {
application.startUnlockWorkflow(v, Optional.of(mainWindow));
});
}
@FXML
public void didClickLockVault() {
selectedVault.ifValuePresent(v -> {
application.startLockWorkflow(v, Optional.of(mainWindow));
});
}
@FXML
public void didClickRevealVault() {
selectedVault.ifValuePresent(v -> {
application.getVaultService().reveal(v);
});
}
// Getter and Setter
public Binding<Boolean> selectedVaultUnlockableProperty() {
return selectedVaultUnlockable;
}
public boolean isSelectedVaultUnlockable() {
return selectedVaultUnlockable.getValue();
}
public Binding<Boolean> selectedVaultLockableProperty() {
return selectedVaultLockable;
}
public boolean isSelectedVaultLockable() {
return selectedVaultLockable.getValue();
}
public Binding<Boolean> selectedVaultRemovableProperty() {
return selectedVaultRemovable;
}
public boolean isSelectedVaultRemovable() {
return selectedVaultRemovable.getValue();
}
public Binding<Boolean> selectedVaultPassphraseStoredProperty() {
return selectedVaultPassphraseStored;
}
public boolean isSelectedVaultPassphraseStored() {
return selectedVaultPassphraseStored.getValue();
}
}
@@ -4,9 +4,6 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultListManager;
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.removevault.RemoveVaultComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.beans.binding.Bindings;
@@ -17,30 +14,30 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.MouseEvent;
@MainWindowScoped
public class VaultListController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(VaultListController.class);
private final ObservableList<Vault> vaults;
private final ObjectProperty<Vault> selectedVault;
private final VaultListCellFactory cellFactory;
private final AddVaultWizardComponent.Builder addVaultWizard;
private final RemoveVaultComponent.Builder removeVault;
private final BooleanBinding noVaultSelected;
private final BooleanBinding emptyVaultList;
public ListView<Vault> vaultList;
@Inject
VaultListController(ObservableList<Vault> vaults, ObjectProperty<Vault> selectedVault, VaultListCellFactory cellFactory, AddVaultWizardComponent.Builder addVaultWizard, RemoveVaultComponent.Builder removeVault) {
VaultListController(ObservableList<Vault> vaults, ObjectProperty<Vault> selectedVault, VaultListCellFactory cellFactory, AddVaultWizardComponent.Builder addVaultWizard) {
this.vaults = vaults;
this.selectedVault = selectedVault;
this.cellFactory = cellFactory;
this.addVaultWizard = addVaultWizard;
this.removeVault = removeVault;
this.noVaultSelected = selectedVault.isNull();
this.emptyVaultList = Bindings.isEmpty(vaults);
selectedVault.addListener(this::selectedVaultDidChange);
}
@@ -56,6 +53,19 @@ public class VaultListController implements FxController {
}
}
});
vaultList.addEventFilter(MouseEvent.MOUSE_RELEASED, this::deselect);
vaultList.addEventFilter(ContextMenuEvent.CONTEXT_MENU_REQUESTED, request -> {
if (selectedVault.get() == null) {
request.consume();
}
});
}
private void deselect(MouseEvent released) {
if (released.getY() > (vaultList.getItems().size() * vaultList.fixedCellSizeProperty().get())) {
vaultList.getSelectionModel().clearSelection();
released.consume();
}
}
private void selectedVaultDidChange(@SuppressWarnings("unused") ObservableValue<? extends Vault> observableValue, @SuppressWarnings("unused") Vault oldValue, Vault newValue) {
@@ -70,16 +80,6 @@ public class VaultListController implements FxController {
addVaultWizard.build().showAddVaultWizard();
}
@FXML
public void didClickRemoveVault() {
Vault v = selectedVault.get();
if (v != null) {
removeVault.vault(v).build().showRemoveVault();
} else {
LOG.debug("Cannot remove a vault if none is selected.");
}
}
// Getter and Setter
public BooleanBinding emptyVaultListProperty() {
@@ -90,11 +90,4 @@ public class VaultListController implements FxController {
return emptyVaultList.get();
}
public BooleanBinding noVaultSelectedProperty() {
return noVaultSelected;
}
public boolean isNoVaultSelected() {
return noVaultSelected.get();
}
}
@@ -6,7 +6,7 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.cryptofs.common.FileSystemCapabilityChecker;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -30,8 +30,8 @@ abstract class MigrationModule {
@Provides
@MigrationWindow
@MigrationScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -56,36 +56,36 @@ abstract class MigrationModule {
@Provides
@FxmlScene(FxmlFile.MIGRATION_START)
@MigrationScoped
static Scene provideMigrationStartScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/migration_start.fxml");
static Scene provideMigrationStartScene(@MigrationWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.MIGRATION_START);
}
@Provides
@FxmlScene(FxmlFile.MIGRATION_RUN)
@MigrationScoped
static Scene provideMigrationRunScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/migration_run.fxml");
static Scene provideMigrationRunScene(@MigrationWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.MIGRATION_RUN);
}
@Provides
@FxmlScene(FxmlFile.MIGRATION_SUCCESS)
@MigrationScoped
static Scene provideMigrationSuccessScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/migration_success.fxml");
static Scene provideMigrationSuccessScene(@MigrationWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.MIGRATION_SUCCESS);
}
@Provides
@FxmlScene(FxmlFile.MIGRATION_CAPABILITY_ERROR)
@MigrationScoped
static Scene provideMigrationCapabilityErrorScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/migration_capability_error.fxml");
static Scene provideMigrationCapabilityErrorScene(@MigrationWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.MIGRATION_CAPABILITY_ERROR);
}
@Provides
@FxmlScene(FxmlFile.MIGRATION_IMPOSSIBLE)
@MigrationScoped
static Scene provideMigrationImpossibleScene(@MigrationWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/migration_impossible.fxml");
static Scene provideMigrationImpossibleScene(@MigrationWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.MIGRATION_IMPOSSIBLE);
}
// ------------------
@@ -12,7 +12,7 @@ import org.cryptomator.cryptofs.migration.api.MigrationProgressListener;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -56,7 +56,7 @@ public class MigrationRunController implements FxController {
private final ScheduledExecutorService scheduler;
private final KeychainManager keychain;
private final ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
private final Lazy<Scene> startScene;
private final Lazy<Scene> successScene;
private final Lazy<Scene> impossibleScene;
@@ -68,14 +68,14 @@ public class MigrationRunController implements FxController {
public NiceSecurePasswordField passwordField;
@Inject
public MigrationRunController(@MigrationWindow Stage window, @MigrationWindow Vault vault, ExecutorService executor, ScheduledExecutorService scheduler, KeychainManager keychain, @Named("capabilityErrorCause") ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> startScene, @FxmlScene(FxmlFile.MIGRATION_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.MIGRATION_CAPABILITY_ERROR) Lazy<Scene> capabilityErrorScene, @FxmlScene(FxmlFile.MIGRATION_IMPOSSIBLE) Lazy<Scene> impossibleScene, ErrorComponent.Builder errorComponent) {
public MigrationRunController(@MigrationWindow Stage window, @MigrationWindow Vault vault, ExecutorService executor, ScheduledExecutorService scheduler, KeychainManager keychain, @Named("capabilityErrorCause") ObjectProperty<FileSystemCapabilityChecker.Capability> missingCapability, @FxmlScene(FxmlFile.MIGRATION_START) Lazy<Scene> startScene, @FxmlScene(FxmlFile.MIGRATION_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.MIGRATION_CAPABILITY_ERROR) Lazy<Scene> capabilityErrorScene, @FxmlScene(FxmlFile.MIGRATION_IMPOSSIBLE) Lazy<Scene> impossibleScene, GenericErrorComponent.Builder genericErrorBuilder) {
this.window = window;
this.vault = vault;
this.executor = executor;
this.scheduler = scheduler;
this.keychain = keychain;
this.missingCapability = missingCapability;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
this.startScene = startScene;
this.successScene = successScene;
this.migrateButtonContentDisplay = Bindings.createObjectBinding(this::getMigrateButtonContentDisplay, vault.stateProperty());
@@ -136,12 +136,12 @@ public class MigrationRunController implements FxController {
}).onError(FileNameTooLongException.class, e -> {
LOG.error("Migration failed because the underlying file system does not support long filenames.", e);
vault.setState(VaultState.NEEDS_MIGRATION);
errorComponent.cause(e).window(window).returnToScene(startScene.get()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(startScene.get()).build().showErrorScene();
window.setScene(impossibleScene.get());
}).onError(Exception.class, e -> { // including RuntimeExceptions
LOG.error("Migration failed for technical reasons.", e);
vault.setState(VaultState.NEEDS_MIGRATION);
errorComponent.cause(e).window(window).returnToScene(startScene.get()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(startScene.get()).build().showErrorScene();
}).andFinally(() -> {
passwordField.setDisable(false);
progressSyncTask.cancel(true);
@@ -8,7 +8,7 @@ import org.cryptomator.common.settings.UiTheme;
import org.cryptomator.integrations.autostart.AutoStartProvider;
import org.cryptomator.integrations.autostart.ToggleAutoStartFailedException;
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.traymenu.TrayMenuComponent;
import org.slf4j.Logger;
@@ -49,7 +49,7 @@ public class GeneralPreferencesController implements FxController {
private final Application application;
private final Environment environment;
private final Set<KeychainAccessProvider> keychainAccessProviders;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
public ChoiceBox<UiTheme> themeChoiceBox;
public ChoiceBox<KeychainBackend> keychainBackendChoiceBox;
public CheckBox showMinimizeButtonCheckbox;
@@ -63,7 +63,7 @@ public class GeneralPreferencesController implements FxController {
@Inject
GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, TrayMenuComponent trayMenu, Optional<AutoStartProvider> autoStartProvider, Set<KeychainAccessProvider> keychainAccessProviders, ObjectProperty<SelectedPreferencesTab> selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle, Application application, Environment environment, ErrorComponent.Builder errorComponent) {
GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, TrayMenuComponent trayMenu, Optional<AutoStartProvider> autoStartProvider, Set<KeychainAccessProvider> keychainAccessProviders, ObjectProperty<SelectedPreferencesTab> selectedTabProperty, LicenseHolder licenseHolder, ResourceBundle resourceBundle, Application application, Environment environment, GenericErrorComponent.Builder genericErrorBuilder) {
this.window = window;
this.settings = settings;
this.trayMenuInitialized = trayMenu.isInitialized();
@@ -75,7 +75,7 @@ public class GeneralPreferencesController implements FxController {
this.resourceBundle = resourceBundle;
this.application = application;
this.environment = environment;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
}
@FXML
@@ -146,7 +146,7 @@ public class GeneralPreferencesController implements FxController {
} catch (ToggleAutoStartFailedException e) {
autoStartCheckbox.setSelected(!enableAutoStart); // restore previous state
LOG.error("Failed to toggle autostart.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
});
}
@@ -5,7 +5,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -32,8 +32,8 @@ abstract class PreferencesModule {
@Provides
@PreferencesWindow
@PreferencesScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -49,8 +49,8 @@ abstract class PreferencesModule {
@Provides
@FxmlScene(FxmlFile.PREFERENCES)
@PreferencesScoped
static Scene providePreferencesScene(@PreferencesWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/preferences.fxml");
static Scene providePreferencesScene(@PreferencesWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.PREFERENCES);
}
// ------------------
@@ -5,7 +5,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -25,8 +25,8 @@ abstract class QuitModule {
@Provides
@QuitWindow
@QuitScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -43,8 +43,8 @@ abstract class QuitModule {
@Provides
@FxmlScene(FxmlFile.QUIT)
@QuitScoped
static Scene provideQuitScene(@QuitWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/quit.fxml");
static Scene provideQuitScene(@QuitWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.QUIT);
}
// ------------------
@@ -4,7 +4,7 @@ import dagger.Lazy;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -32,18 +32,18 @@ public class RecoveryKeyCreationController implements FxController {
private final ExecutorService executor;
private final RecoveryKeyFactory recoveryKeyFactory;
private final StringProperty recoveryKeyProperty;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
public NiceSecurePasswordField passwordField;
@Inject
public RecoveryKeyCreationController(@RecoveryKeyWindow Stage window, @FxmlScene(FxmlFile.RECOVERYKEY_SUCCESS) Lazy<Scene> successScene, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @RecoveryKeyWindow StringProperty recoveryKey, ErrorComponent.Builder errorComponent) {
public RecoveryKeyCreationController(@RecoveryKeyWindow Stage window, @FxmlScene(FxmlFile.RECOVERYKEY_SUCCESS) Lazy<Scene> successScene, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @RecoveryKeyWindow StringProperty recoveryKey, GenericErrorComponent.Builder genericErrorBuilder) {
this.window = window;
this.successScene = successScene;
this.vault = vault;
this.executor = executor;
this.recoveryKeyFactory = recoveryKeyFactory;
this.recoveryKeyProperty = recoveryKey;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
}
@FXML
@@ -62,7 +62,7 @@ public class RecoveryKeyCreationController implements FxController {
Animations.createShakeWindowAnimation(window).play();
} else {
LOG.error("Creation of recovery key failed.", task.getException());
errorComponent.cause(task.getException()).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(task.getException()).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
});
executor.submit(task);
@@ -6,7 +6,7 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -33,8 +33,8 @@ abstract class RecoveryKeyModule {
@Provides
@RecoveryKeyWindow
@RecoveryKeyScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -69,29 +69,29 @@ abstract class RecoveryKeyModule {
@Provides
@FxmlScene(FxmlFile.RECOVERYKEY_CREATE)
@RecoveryKeyScoped
static Scene provideRecoveryKeyCreationScene(@RecoveryKeyWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/recoverykey_create.fxml");
static Scene provideRecoveryKeyCreationScene(@RecoveryKeyWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.RECOVERYKEY_CREATE);
}
@Provides
@FxmlScene(FxmlFile.RECOVERYKEY_SUCCESS)
@RecoveryKeyScoped
static Scene provideRecoveryKeySuccessScene(@RecoveryKeyWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/recoverykey_success.fxml");
static Scene provideRecoveryKeySuccessScene(@RecoveryKeyWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.RECOVERYKEY_SUCCESS);
}
@Provides
@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER)
@RecoveryKeyScoped
static Scene provideRecoveryKeyRecoverScene(@RecoveryKeyWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/recoverykey_recover.fxml");
static Scene provideRecoveryKeyRecoverScene(@RecoveryKeyWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.RECOVERYKEY_RECOVER);
}
@Provides
@FxmlScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD)
@RecoveryKeyScoped
static Scene provideRecoveryKeyResetPasswordScene(@RecoveryKeyWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/recoverykey_reset_password.fxml");
static Scene provideRecoveryKeyResetPasswordScene(@RecoveryKeyWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.RECOVERYKEY_RESET_PASSWORD);
}
// ------------------
@@ -2,7 +2,7 @@ package org.cryptomator.ui.recoverykey;
import dagger.Lazy;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
@@ -35,10 +35,10 @@ public class RecoveryKeyResetPasswordController implements FxController {
private final ObjectProperty<CharSequence> newPassword;
private final Lazy<Scene> recoverScene;
private final BooleanBinding invalidNewPassword;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
@Inject
public RecoveryKeyResetPasswordController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @RecoveryKeyWindow StringProperty recoveryKey, @Named("newPassword") ObjectProperty<CharSequence> newPassword, @FxmlScene(FxmlFile.RECOVERYKEY_RECOVER) Lazy<Scene> recoverScene, ErrorComponent.Builder errorComponent) {
public RecoveryKeyResetPasswordController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, RecoveryKeyFactory recoveryKeyFactory, ExecutorService executor, @RecoveryKeyWindow StringProperty recoveryKey, @Named("newPassword") ObjectProperty<CharSequence> newPassword, @FxmlScene(FxmlFile.RECOVERYKEY_RECOVER) Lazy<Scene> recoverScene, GenericErrorComponent.Builder genericErrorBuilder) {
this.window = window;
this.vault = vault;
this.recoveryKeyFactory = recoveryKeyFactory;
@@ -47,7 +47,7 @@ public class RecoveryKeyResetPasswordController implements FxController {
this.newPassword = newPassword;
this.recoverScene = recoverScene;
this.invalidNewPassword = Bindings.createBooleanBinding(this::isInvalidNewPassword, newPassword);
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
}
@FXML
@@ -68,7 +68,7 @@ public class RecoveryKeyResetPasswordController implements FxController {
});
task.setOnFailed(event -> {
LOG.error("Resetting password failed.", task.getException());
errorComponent.cause(task.getException()).window(window).returnToScene(recoverScene.get()).build().showErrorScene();
genericErrorBuilder.cause(task.getException()).window(window).returnToScene(recoverScene.get()).build().showErrorScene();
});
executor.submit(task);
}
@@ -5,7 +5,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -26,8 +26,8 @@ abstract class RemoveVaultModule {
@Provides
@RemoveVaultWindow
@RemoveVaultScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -45,8 +45,8 @@ abstract class RemoveVaultModule {
@Provides
@FxmlScene(FxmlFile.REMOVE_VAULT)
@RemoveVaultScoped
static Scene provideRemoveVaultScene(@RemoveVaultWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/remove_vault.fxml");
static Scene provideRemoveVaultScene(@RemoveVaultWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.REMOVE_VAULT);
}
// ------------------
@@ -11,7 +11,7 @@ import javafx.stage.Stage;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.common.vaults.VaultState;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -29,8 +29,8 @@ abstract class VaultStatisticsModule {
@Provides
@VaultStatisticsWindow
@VaultStatisticsScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -60,8 +60,8 @@ abstract class VaultStatisticsModule {
@Provides
@FxmlScene(FxmlFile.VAULT_STATISTICS)
@VaultStatisticsScoped
static Scene provideVaultStatisticsScene(@VaultStatisticsWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/stats.fxml");
static Scene provideVaultStatisticsScene(@VaultStatisticsWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.VAULT_STATISTICS);
}
// ------------------
@@ -8,7 +8,7 @@ import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -78,8 +78,8 @@ abstract class UnlockModule {
@Provides
@UnlockWindow
@UnlockScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -101,22 +101,22 @@ abstract class UnlockModule {
@Provides
@FxmlScene(FxmlFile.UNLOCK)
@UnlockScoped
static Scene provideUnlockScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/unlock.fxml");
static Scene provideUnlockScene(@UnlockWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.UNLOCK);
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_SUCCESS)
@UnlockScoped
static Scene provideUnlockSuccessScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/unlock_success.fxml");
static Scene provideUnlockSuccessScene(@UnlockWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.UNLOCK_SUCCESS);
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT)
@UnlockScoped
static Scene provideInvalidMountPointScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/unlock_invalid_mount_point.fxml");
static Scene provideInvalidMountPointScene(@UnlockWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT);
}
// ------------------
@@ -10,7 +10,7 @@ import org.cryptomator.common.vaults.Volume.VolumeException;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.ErrorComponent;
import org.cryptomator.ui.error.GenericErrorComponent;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.UserInteractionLock;
@@ -57,10 +57,10 @@ public class UnlockWorkflow extends Task<Boolean> {
private final Lazy<Scene> unlockScene;
private final Lazy<Scene> successScene;
private final Lazy<Scene> invalidMountPointScene;
private final ErrorComponent.Builder errorComponent;
private final GenericErrorComponent.Builder genericErrorBuilder;
@Inject
UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, AtomicReference<char[]> password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional<char[]> savedPassword, UserInteractionLock<PasswordEntry> passwordEntryLock, KeychainManager keychain, @FxmlScene(FxmlFile.UNLOCK) Lazy<Scene> unlockScene, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, ErrorComponent.Builder errorComponent) {
UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, AtomicReference<char[]> password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional<char[]> savedPassword, UserInteractionLock<PasswordEntry> passwordEntryLock, KeychainManager keychain, @FxmlScene(FxmlFile.UNLOCK) Lazy<Scene> unlockScene, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, GenericErrorComponent.Builder genericErrorBuilder) {
this.window = window;
this.vault = vault;
this.vaultService = vaultService;
@@ -72,12 +72,12 @@ public class UnlockWorkflow extends Task<Boolean> {
this.unlockScene = unlockScene;
this.successScene = successScene;
this.invalidMountPointScene = invalidMountPointScene;
this.errorComponent = errorComponent;
this.genericErrorBuilder = genericErrorBuilder;
setOnFailed(event -> {
Throwable throwable = event.getSource().getException();
if (throwable instanceof InvalidMountPointException) {
handleInvalidMountPoint((InvalidMountPointException) throwable);
if (throwable instanceof InvalidMountPointException e) {
handleInvalidMountPoint(e);
} else {
handleGenericError(throwable);
}
@@ -196,7 +196,7 @@ public class UnlockWorkflow extends Task<Boolean> {
private void handleGenericError(Throwable e) {
LOG.error("Unlock failed for technical reasons.", e);
errorComponent.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
genericErrorBuilder.cause(e).window(window).returnToScene(window.getScene()).build().showErrorScene();
}
private void wipePassword(char[] pw) {
@@ -0,0 +1,23 @@
package org.cryptomator.ui.vaultoptions;
public enum SelectedVaultOptionsTab {
/**
* Let the controller decide which tab to show.
*/
ANY,
/**
* Show general tab
*/
GENERAL,
/**
* Show mounting tab
*/
MOUNT,
/**
* Show password tab
*/
KEY,
}
@@ -12,6 +12,7 @@ import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import javafx.beans.property.ObjectProperty;
import javafx.scene.Scene;
import javafx.stage.Stage;
@@ -25,7 +26,10 @@ public interface VaultOptionsComponent {
@FxmlScene(FxmlFile.VAULT_OPTIONS)
Lazy<Scene> scene();
default void showVaultOptionsWindow() {
ObjectProperty<SelectedVaultOptionsTab> selectedTabProperty();
default void showVaultOptionsWindow(SelectedVaultOptionsTab selectedTab) {
selectedTabProperty().set(selectedTab);
Stage stage = window();
stage.setScene(scene().get());
stage.show();
@@ -1,13 +1,67 @@
package org.cryptomator.ui.vaultoptions;
import org.cryptomator.ui.common.FxController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.beans.property.ObjectProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
@VaultOptionsScoped
public class VaultOptionsController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(VaultOptionsController.class);
private final Stage window;
private final ObjectProperty<SelectedVaultOptionsTab> selectedTabProperty;
public TabPane tabPane;
public Tab generalTab;
public Tab mountTab;
public Tab keyTab;
@Inject
VaultOptionsController() {}
VaultOptionsController(@VaultOptionsWindow Stage window, ObjectProperty<SelectedVaultOptionsTab> selectedTabProperty) {
this.window = window;
this.selectedTabProperty = selectedTabProperty;
}
@FXML
public void initialize() {
window.setOnShowing(this::windowWillAppear);
selectedTabProperty.addListener(observable -> this.selectChosenTab());
tabPane.getSelectionModel().selectedItemProperty().addListener(observable -> this.selectedTabChanged());
}
private void selectChosenTab() {
Tab toBeSelected = getTabToSelect(selectedTabProperty.get());
tabPane.getSelectionModel().select(toBeSelected);
}
private Tab getTabToSelect(SelectedVaultOptionsTab selectedTab) {
return switch (selectedTab) {
case ANY, GENERAL -> generalTab;
case MOUNT -> mountTab;
case KEY -> keyTab;
};
}
private void selectedTabChanged() {
Tab selectedTab = tabPane.getSelectionModel().getSelectedItem();
try {
SelectedVaultOptionsTab selectedVaultOptionsTab = SelectedVaultOptionsTab.valueOf(selectedTab.getId());
selectedTabProperty.set(selectedVaultOptionsTab);
} catch (IllegalArgumentException e) {
LOG.error("Unknown vault options tab id: {}", selectedTab.getId());
}
}
private void windowWillAppear(@SuppressWarnings("unused") WindowEvent windowEvent) {
selectChosenTab();
}
}
@@ -7,16 +7,18 @@ import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.changepassword.ChangePasswordComponent;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.mainwindow.MainWindow;
import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
import javax.inject.Provider;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
@@ -26,11 +28,17 @@ import java.util.ResourceBundle;
@Module(subcomponents = {ChangePasswordComponent.class, RecoveryKeyComponent.class})
abstract class VaultOptionsModule {
@Provides
@VaultOptionsScoped
static ObjectProperty<SelectedVaultOptionsTab> provideSelectedTabProperty() {
return new SimpleObjectProperty<>(SelectedVaultOptionsTab.ANY);
}
@Provides
@VaultOptionsWindow
@VaultOptionsScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -50,8 +58,8 @@ abstract class VaultOptionsModule {
@Provides
@FxmlScene(FxmlFile.VAULT_OPTIONS)
@VaultOptionsScoped
static Scene provideVaultOptionsScene(@VaultOptionsWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/vault_options.fxml");
static Scene provideVaultOptionsScene(@VaultOptionsWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.VAULT_OPTIONS);
}
// ------------------
@@ -5,7 +5,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FXMLLoaderFactory;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -26,8 +26,8 @@ abstract class WrongFileAlertModule {
@Provides
@WrongFileAlertWindow
@WrongFileAlertScoped
static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@@ -45,8 +45,8 @@ abstract class WrongFileAlertModule {
@Provides
@FxmlScene(FxmlFile.WRONGFILEALERT)
@WrongFileAlertScoped
static Scene provideWrongFileAlertScene(@WrongFileAlertWindow FXMLLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene("/fxml/wrongfilealert.fxml");
static Scene provideWrongFileAlertScene(@WrongFileAlertWindow FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.WRONGFILEALERT);
}
// ------------------
@@ -12,7 +12,7 @@
<?import javafx.scene.shape.Circle?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.common.ErrorController"
fx:controller="org.cryptomator.ui.error.GenericErrorController"
prefWidth="450"
prefHeight="450"
spacing="12"
@@ -3,7 +3,6 @@
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.VBox?>
@@ -25,18 +24,20 @@
<FontAwesome5IconView glyph="KEY" glyphSize="15"/>
</graphic>
</Button>
<Hyperlink text="%main.vaultDetail.optionsBtn" onAction="#showVaultOptions">
<Hyperlink text="%main.vaultDetail.passwordSavedInKeychain" visible="${controller.passwordSaved}" onAction="#showKeyVaultOptions">
<graphic>
<FontAwesome5IconView glyph="COG"/>
<FontAwesome5IconView glyph="LOCK"/>
</graphic>
</Hyperlink>
<Region VBox.vgrow="ALWAYS"/>
<HBox alignment="CENTER_RIGHT" spacing="6">
<Label styleClass="label-small,label-muted" text="%main.vaultDetail.passwordSavedInKeychain" visible="${controller.passwordSaved}">
<HBox alignment="BOTTOM_RIGHT">
<Button text="%main.vaultDetail.optionsBtn" minWidth="120" onAction="#showVaultOptions">
<graphic>
<FontAwesome5IconView styleClass="glyph-icon-muted" glyph="LOCK"/>
<FontAwesome5IconView glyph="COG"/>
</graphic>
</Label>
</Button>
</HBox>
</children>
</VBox>
@@ -2,10 +2,8 @@
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ContextMenu?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
@@ -15,13 +13,9 @@
fx:controller="org.cryptomator.ui.mainwindow.VaultListController"
minWidth="206">
<StackPane VBox.vgrow="ALWAYS">
<ListView fx:id="vaultList" editable="true">
<ListView fx:id="vaultList" editable="true" fixedCellSize="60">
<contextMenu>
<ContextMenu>
<items>
<MenuItem text="%main.vaultlist.contextMenu.remove" onAction="#didClickRemoveVault" disable="${controller.noVaultSelected}"/>
</items>
</ContextMenu>
<fx:include source="vault_list_contextmenu.fxml"/>
</contextMenu>
</ListView>
<VBox visible="${controller.emptyVaultList}" spacing="6" alignment="CENTER">
@@ -13,6 +13,7 @@
prefWidth="200"
spacing="12"
alignment="CENTER_LEFT">
<!-- Remark Check the containing list view for a fixed cell size before editing height properties -->
<padding>
<Insets topRightBottomLeft="12"/>
</padding>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ContextMenu?>
<?import javafx.scene.control.MenuItem?>
<ContextMenu xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.mainwindow.VaultListContextMenuController">
<items>
<MenuItem fx:id="revealEntry" text="%main.vaultlist.contextMenu.reveal" onAction="#didClickRevealVault" visible="${controller.selectedVaultLockable}"/>
<MenuItem fx:id="lockEntry" text="%main.vaultlist.contextMenu.lock" onAction="#didClickLockVault" visible="${controller.selectedVaultLockable}"/>
<MenuItem fx:id="unlockEntry" text="%main.vaultlist.contextMenu.unlock" onAction="#didClickUnlockVault" visible="${controller.selectedVaultUnlockable &amp;&amp; !controller.selectedVaultPassphraseStored}"/>
<MenuItem fx:id="unlockNowEntry" text="%main.vaultlist.contextMenu.unlockNow" onAction="#didClickUnlockVault" visible="${controller.selectedVaultUnlockable &amp;&amp; controller.selectedVaultPassphraseStored}"/>
<MenuItem fx:id="optionsEntry" text="%main.vaultlist.contextMenu.vaultoptions" onAction="#didClickShowVaultOptions" disable="${!controller.selectedVaultUnlockable}"/>
<MenuItem fx:id="removeEntry" text="%main.vaultlist.contextMenu.remove" onAction="#didClickRemoveVault" disable="${!controller.selectedVaultRemovable}"/>
</items>
</ContextMenu>
@@ -12,7 +12,7 @@
tabClosingPolicy="UNAVAILABLE"
tabDragPolicy="FIXED">
<tabs>
<Tab fx:id="generalTab" text="%vaultOptions.general">
<Tab fx:id="generalTab" id="GENERAL" text="%vaultOptions.general">
<graphic>
<FontAwesome5IconView glyph="WRENCH"/>
</graphic>
@@ -20,7 +20,7 @@
<fx:include source="/fxml/vault_options_general.fxml"/>
</content>
</Tab>
<Tab fx:id="mountTab" text="%vaultOptions.mount">
<Tab fx:id="mountTab" id="MOUNT" text="%vaultOptions.mount">
<graphic>
<FontAwesome5IconView glyph="HDD"/>
</graphic>
@@ -28,7 +28,7 @@
<fx:include source="/fxml/vault_options_mount.fxml"/>
</content>
</Tab>
<Tab fx:id="keyTab" text="%vaultOptions.masterkey">
<Tab fx:id="keyTab" id="KEY" text="%vaultOptions.masterkey">
<graphic>
<FontAwesome5IconView glyph="KEY"/>
</graphic>
@@ -96,12 +96,12 @@ forgetPassword.confirmBtn=Forget Password
# Unlock
unlock.title=Unlock Vault
unlock.passwordPrompt=Enter password for "%s":
unlock.savePassword=Save Password
unlock.savePassword=Remember Password
unlock.unlockBtn=Unlock
## Success
unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible.
unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible via its virtual drive.
unlock.success.rememberChoice=Remember choice, don't show this again
unlock.success.revealBtn=Reveal Vault
unlock.success.revealBtn=Reveal Drive
## Failure
unlock.error.heading=Unable to unlock vault
### Invalid Mount Point
@@ -203,7 +203,7 @@ stats.read.accessCount=Total reads: %d
stats.write.throughput.idle=Write: idle
stats.write.throughput.kibs=Write: %.2f kiB/s
stats.write.throughput.mibs=Write: %.2f MiB/s
stats.write.total.data.none=Data read: -
stats.write.total.data.none=Data written: -
stats.write.total.data.kib=Data written: %.1f kiB
stats.write.total.data.mib=Data written: %.1f MiB
stats.write.total.data.gib=Data written: %.1f GiB
@@ -224,7 +224,12 @@ main.dropZone.dropVault=Add this vault
main.dropZone.unknownDragboardContent=If you want to add a vault, drag it to this window
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Click here to add a vault
main.vaultlist.contextMenu.remove=Remove Vault
main.vaultlist.contextMenu.remove=Remove…
main.vaultlist.contextMenu.lock=Lock
main.vaultlist.contextMenu.unlock=Unlock…
main.vaultlist.contextMenu.unlockNow=Unlock Now
main.vaultlist.contextMenu.vaultoptions=Show Vault Options
main.vaultlist.contextMenu.reveal=Reveal Drive
main.vaultlist.addVaultBtn=Add Vault
## Vault Detail
### Welcome
@@ -95,12 +95,10 @@ forgetPassword.confirmBtn=نسيت كلمة المرور
# Unlock
unlock.title=افتح الحافظة
unlock.passwordPrompt=‮أدخل كلمة السر لـ "%s":
unlock.savePassword=احفظ كلمة المرور
unlock.unlockBtn=افتح
## Success
unlock.success.message=تم فتح المخزن "%s" بنجاح! يمكنك الوصول إليه الآن.
unlock.success.rememberChoice=تذكر اختياري ولا تظهر هذا مرة أخرى
unlock.success.revealBtn=افتح الحافظة
unlock.success.revealBtn=اظهار القرص
## Failure
unlock.error.heading=غير قادر على فتح الخزنة
### Invalid Mount Point
@@ -196,7 +194,10 @@ main.dropZone.dropVault=أضف هذا المخزن
main.dropZone.unknownDragboardContent=إذا كنت ترغب في إضافة مخزن، قم بسحبه إلى هذه النافذة
## Vault List
main.vaultlist.emptyList.onboardingInstruction=انقر هنا لإضافة خزنة
main.vaultlist.contextMenu.remove=حذف الخزنة…
main.vaultlist.contextMenu.lock=قفل
main.vaultlist.contextMenu.unlock=فتح…
main.vaultlist.contextMenu.unlockNow=افتح الان
main.vaultlist.contextMenu.reveal=اظهار القرص
main.vaultlist.addVaultBtn=أضِف مخزنًا
## Vault Detail
### Welcome
@@ -95,71 +95,225 @@ forgetPassword.confirmBtn=Zaboravili ste šifru
# Unlock
unlock.title=Otključaj sef
unlock.passwordPrompt=Unesite lozinku za "%s":
unlock.savePassword=Snimi lozinku
unlock.unlockBtn=Otključaj
## Success
unlock.success.message=Uspješno ste otključali "%s"! Vaš sef je sada dostupan.
unlock.success.rememberChoice=Zapamtite izbor, ne pokazujte ovo ponovo
unlock.success.revealBtn=Otkrij sef
unlock.success.revealBtn=Otkrij pogon
## Failure
unlock.error.heading=Sef nije moguće otključati
### Invalid Mount Point
unlock.error.invalidMountPoint.notExisting=Tačka postavljanja "%s" nije direktorij, nije prazna ili ne postoji.
unlock.error.invalidMountPoint.existing=Tačka povezivanja "%s" već postoji ili nadređeni folder nedostaje.
# Lock
## Force
lock.forced.heading=Zaključavanje nije uspjelo
lock.forced.message=Zaključavanje "%s" blokirano je operacijama na čekanju ili otvorenim datotekama. Možete prisilno zaključati ovaj sef, međutim prekid U / I-a može rezultirati gubitkom nespremljenih podataka.
lock.forced.confirmBtn=Prisilno zaključaj
## Failure
lock.fail.heading=Zaključavanje sefa nije uspjelo.
lock.fail.message=Sef "%s" nije moguće zaključati. Osigurajte da je nespremljeni rad sačuvan negdje drugdje i da su važne operacije čitanja / pisanja završene. Da biste zatvorili sef, zaustavite Cryptomator proces.
# Migration
migration.title=Nadogradi sef
## Start
migration.start.prompt=Sef "%s" treba ažurirati na noviji format. Prije nastavka, provjerite da nije na čekanju sinkronizacija koja utječe na ovaj sef.
migration.start.confirm=Da, moj sef je u potpunosti sinhroniziran
## Run
migration.run.enterPassword=Unesite lozinku za "%s"
migration.run.startMigrationBtn=Nadogradi sef
migration.run.progressHint=Ovo bi moglo potrajati…
## Sucess
migration.success.nextStepsInstructions="%s" je uspješno nadograđen.\nSada možete otključati svoj sef.
migration.success.unlockNow=Otključaj sada
## Missing file system capabilities
migration.error.missingFileSystemCapabilities.title=Nepodržan tip datoteke
migration.error.missingFileSystemCapabilities.description=Migracija nije započeta, jer se vaš sef nalazi u neadekvatnom sistemu datoteka.
migration.error.missingFileSystemCapabilities.reason.LONG_FILENAMES=Sistem datoteka ne podržava duga imena datoteka.
migration.error.missingFileSystemCapabilities.reason.LONG_PATHS=Sistem datoteka ne podržava duga imena datoteka.
migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Sistem datoteka ne dozvoljava čitanje.
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Sistem datoteka ne dozvoljava pisanje.
## Impossible
migration.impossible.heading=Sef se ne može nadograditi
migration.impossible.reason=Sef se ne može automatski migrirati jer njegovo mjesto za pohranu ili pristupna točka nisu kompatibilni.
migration.impossible.moreInfo=Sef se i dalje može otvoriti sa starijom verzijom. Za upute o ručnom migriranju sefa posjetite
# Preferences
preferences.title=Postavke
## General
preferences.general=Generalno
preferences.general.theme=Izgled
preferences.general.theme.automatic=Automatski
preferences.general.theme.light=Svijetlo
preferences.general.theme.dark=Tamno
preferences.general.unlockThemes=Otključaj tamni mod
preferences.general.showMinimizeButton=Pokaži dugme za minimiziranje
preferences.general.showTrayIcon=Prikaži tray ikonu (potrebnan restart)
preferences.general.startHidden=Sakrij prozor prilikom pokretanja Cryptomatora
preferences.general.debugLogging=Omogući evidenciju otklanjanja pogrešaka
preferences.general.debugDirectory=Pokaži dnevnik podataka
preferences.general.autoStart=Pokreni Cryptomator pri pokretanju sistema
preferences.general.keychainBackend=Pohrani lozinku sa
preferences.general.keychainBackend.org.cryptomator.linux.keychain.SecretServiceKeychainAccess=Gnome Keyring
preferences.general.keychainBackend.org.cryptomator.linux.keychain.KDEWalletKeychainAccess=KDE Wallet
preferences.general.keychainBackend.org.cryptomator.macos.keychain.MacSystemKeychainAccess=macOS Keychain Access
preferences.general.keychainBackend.org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess=Windows Data Protection
preferences.general.interfaceOrientation=Orijentacija Interfejsa
preferences.general.interfaceOrientation.ltr=S lijeva ka desno
preferences.general.interfaceOrientation.rtl=Sa desna ka lijevo
## Volume
preferences.volume=Virtuelni pogon
preferences.volume.type=Tip volumena
preferences.volume.webdav.port=WebDAV Port
preferences.volume.webdav.scheme=WebDAV Scheme
## Updates
preferences.updates=Ažuriranja
preferences.updates.currentVersion=Trenutna verzija: %s
preferences.updates.autoUpdateCheck=Automatski provjeri ima li ažuriranja
preferences.updates.checkNowBtn=Provjeri sada
preferences.updates.updateAvailable=Dostupno ažuriranje na verziju %s.
## Donation Key
preferences.donationKey=Donacija
preferences.donationKey.registeredFor=Registrovan za %s
preferences.donationKey.noDonationKey=Nije pronađen važeći ključ za donaciju. To je poput licence, ali za sjajne ljude koji koriste besplatni softver. ;-)
preferences.donationKey.getDonationKey=Nabavite ključ za donaciju
## About
preferences.about=O programu
# Vault Statistics
stats.title=Statistika za %s
stats.cacheHitRate=Brzina učitavanja u predmemoriju
## Read
stats.read.throughput.idle=Čitaj: U pripravnosti
stats.read.throughput.kibs=Čitanje: %.2f kiB/s
stats.read.throughput.mibs=Čitanje: %.2f MiB/s
stats.read.total.data.none=Pročitano podataka: -
stats.read.total.data.kib=Pročitano podataka: %.1f kiB
stats.read.total.data.mib=Pročitano podataka: %.1f MiB
stats.read.total.data.gib=Pročitano podataka: %.1f GiB
stats.decr.total.data.none=Otključani podaci: -
stats.decr.total.data.kib=Otključano podataka: %.1f kiB
stats.decr.total.data.mib=Otključano podataka: %.1f MiB
stats.decr.total.data.gib=Otključano podataka: %.1f GiB
stats.read.accessCount=Ukupno pročitano: %d
## Write
stats.write.throughput.idle=Pisanje: U pripravnosti
stats.write.throughput.kibs=Upisano: %.2f kiB/s
stats.write.throughput.mibs=Upisano: %.2f MiB/s
stats.write.total.data.none=Podaci su upisani:-
stats.write.total.data.kib=Upisano podataka: %.1f kiB
stats.write.total.data.mib=Upisano podataka: %.1f MiB
stats.write.total.data.gib=Upisano podataka: %.1f GiB
stats.encr.total.data.none=Otključano podataka: -
stats.encr.total.data.kib=Otključano podataka: %.1f kiB
stats.encr.total.data.mib=Otključano podataka: %.1f MiB
stats.encr.total.data.gib=Otključano podataka: %.1f GiB
stats.write.accessCount=Ukupno upisano: %d
# Main Window
main.closeBtn.tooltip=Zatvori
main.minimizeBtn.tooltip=Minimiziraj
main.preferencesBtn.tooltip=Postavke
main.debugModeEnabled.tooltip=Omogućen je mod otklanjanja pogrešaka
main.donationKeyMissing.tooltip=Molimo razmislite o doniranju
## Drag 'n' Drop
main.dropZone.dropVault=Dodajte ovaj sef
main.dropZone.unknownDragboardContent=Ako želite dodati sef, povucite ga u ovaj prozor
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Kliknite ovdje da dodate sef
main.vaultlist.contextMenu.lock=Zaključaj
main.vaultlist.contextMenu.unlock=Otključaj…
main.vaultlist.contextMenu.unlockNow=Otključaj sada
main.vaultlist.contextMenu.reveal=Otkrij pogon
main.vaultlist.addVaultBtn=Dodaj sef
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Hvala što ste izabrali Cryptomator za zaštitu podataka. Ako vam je potrebna pomoć, pogledajte naše vodiče za početak:
### Locked
main.vaultDetail.lockedStatus=ZAKLJUČANO
main.vaultDetail.unlockBtn=Otključaj…
main.vaultDetail.unlockNowBtn=Otključaj sada
main.vaultDetail.optionsBtn=Opcije sefa
main.vaultDetail.passwordSavedInKeychain=Šifra sačuvana
### Unlocked
main.vaultDetail.unlockedStatus=OTKLJUČANO
main.vaultDetail.accessLocation=Sadržaj Vašeg sefa je dostupan ovdje:
main.vaultDetail.revealBtn=Otkrij pogon
main.vaultDetail.lockBtn=Zaključaj
main.vaultDetail.bytesPerSecondRead=Čitaj:
main.vaultDetail.bytesPerSecondWritten=Piši:
main.vaultDetail.throughput.idle=u stanju mirovanja
main.vaultDetail.throughput.kbps=%.1f kiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Statistika sefa
### Missing
main.vaultDetail.missing.info=Cryptomator nije mogao pronaći disk na ovoj lokaciji.
main.vaultDetail.missing.recheck=Provjeri ponovo
main.vaultDetail.missing.remove=Ukloni sa liste sefova…
main.vaultDetail.missing.changeLocation=Promijeni lokaciju sefa…
### Needs Migration
main.vaultDetail.migrateButton=Nadogradi sef
main.vaultDetail.migratePrompt=Da biste mogli pristupiti svom sefu, morate ga nadograditi na novi format
# Wrong File Alert
wrongFileAlert.title=Kako enkriptovati podatke
wrongFileAlert.header.title=Da li ste pokušali enkriptovati ove datoteke?
wrongFileAlert.header.lead=U tu svrhu Cryptomator kreira volumen u vašem upravljačkom sistemu.
wrongFileAlert.instruction.0=Da biste enkriptovali datoteke, slijedite ove korake:
wrongFileAlert.instruction.1=1. Otključajte sef.
wrongFileAlert.instruction.2=2. Kliknite "Otkrivanje" da biste otvorili volumen u vašem upravitelju datotekama.
wrongFileAlert.instruction.3=3. Dodajte datoteke u ovaj disk.
wrongFileAlert.link=Za dalju podršku, posjetite
# Vault Options
## General
vaultOptions.general=Generalno
vaultOptions.general.vaultName=Ime sefa
vaultOptions.general.unlockAfterStartup=Otključaj sef pri pokretanju Cryptomatora
vaultOptions.general.actionAfterUnlock=Nakon uspješnog otključavanja
vaultOptions.general.actionAfterUnlock.ignore=Ne radi ništa
vaultOptions.general.actionAfterUnlock.reveal=Otkrij pogon
vaultOptions.general.actionAfterUnlock.ask=Pitaj
## Mount
vaultOptions.mount=Povezivanje
vaultOptions.mount.readonly=Samo čitanje
vaultOptions.mount.customMountFlags=Prilagođena obilježja povezivanja
vaultOptions.mount.winDriveLetterOccupied=zauzeto
vaultOptions.mount.mountPoint=Tačka povezivanja
vaultOptions.mount.mountPoint.auto=Automatski odaberi pogodnu lokaciju
vaultOptions.mount.mountPoint.driveLetter=Koristi dodjeljeno slovo (oznaku) diska
vaultOptions.mount.mountPoint.custom=Prilagođena adresa
vaultOptions.mount.mountPoint.directoryPickerButton=Odaberi…
vaultOptions.mount.mountPoint.directoryPickerTitle=Izaberi praznu mapu
## Master Key
vaultOptions.masterkey=Šifra
vaultOptions.masterkey.changePasswordBtn=Promjeni lozinku
vaultOptions.masterkey.forgetSavedPasswordBtn=Zaborav spremljenu šifru
vaultOptions.masterkey.recoveryKeyExpanation=Ključ za oporavak je vaše jedino sredstvo za vraćanje pristupa sefu ako izgubite lozinku.
vaultOptions.masterkey.showRecoveryKeyBtn=Pokaži ključ za oporavak
vaultOptions.masterkey.recoverPasswordBtn=Povrati šifru
# Recovery Key
recoveryKey.title=Ključ za oporavak
recoveryKey.enterPassword.prompt=Unesite šifru da biste prikazali ključ za oporavak za "%s":
recoveryKey.display.message=Sljedeći ključ za oporavak može se koristiti za vraćanje pristupa "%s":
recoveryKey.display.StorageHints=Pohranite ga negdje vrlo sigurno, npr.:\n • Spremite ga pomoću menadžera lozinki\n • Spremite ga na USB disk\n • Odštampajte ga na papiru
recoveryKey.recover.prompt=Unesite ključ za oporavak za "%s":
recoveryKey.recover.validKey=Ključ za oporavak je ispravan
recoveryKey.printout.heading=Cryptomator Ključ za oporavak za \n"%s"\n
# New Password
newPassword.promptText=Unesi novu šifru
newPassword.reenterPassword=Potvrdi novu šifru
newPassword.passwordsMatch=Šifra odgovara!
newPassword.passwordsDoNotMatch=Šifre se ne poklapaju
passwordStrength.messageLabel.tooShort=Upotrijebite najmanje %d znakova
passwordStrength.messageLabel.0=Veoma slabo
passwordStrength.messageLabel.1=Slabo
passwordStrength.messageLabel.2=Dovoljno
passwordStrength.messageLabel.3=Sigurno
passwordStrength.messageLabel.4=Veoma sigurno
# Quit
quit.prompt=Zatvoriti prijavu? Postoje otključani sefovi.
quit.lockAndQuit=Zaključaj i zatvori
@@ -98,9 +98,8 @@ unlock.passwordPrompt=Introduïu la contrasenya de "%s":
unlock.savePassword=Recorda la contrasenya
unlock.unlockBtn=Desbloqueja
## Success
unlock.success.message="%s" s'ha desbloquejat correctament! Ja es pot accedir a la caixa forta.
unlock.success.rememberChoice=Recorda l'elecció. No ho tornis a mostrar.
unlock.success.revealBtn=Mostra la caixa forta
unlock.success.revealBtn=Mostra la unitat
## Failure
unlock.error.heading=No ha estat possible desblocar la caixa forta
### Invalid Mount Point
@@ -202,7 +201,7 @@ stats.read.accessCount=Lectures en total: %d
stats.write.throughput.idle=Escriu: inactiu
stats.write.throughput.kibs=Escriu: %.2f kiB/s
stats.write.throughput.mibs=Escriu: %.2f MiB/s
stats.write.total.data.none=Dades llegides: -
stats.write.total.data.none=Dades escrites
stats.write.total.data.kib=Dades escrites: %.1f kiB
stats.write.total.data.mib=Dades escrites: %.1f MiB
stats.write.total.data.gib=Dades escrites: %.1f GiB
@@ -223,7 +222,10 @@ main.dropZone.dropVault=Afegeix aquesta caixa forta
main.dropZone.unknownDragboardContent=Si voleu afegir una caixa forta, arrossegueu-la a aquesta finestra
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Feu clic aquí per afegir una caixa forta
main.vaultlist.contextMenu.remove=Elimina la caixa forta…
main.vaultlist.contextMenu.lock=Bloqueja
main.vaultlist.contextMenu.unlock=Desbloca…
main.vaultlist.contextMenu.unlockNow=Desbloqueja ara
main.vaultlist.contextMenu.reveal=Mostra la unitat
main.vaultlist.addVaultBtn=Afegir una caixa forta
## Vault Detail
### Welcome
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=Zapomenout heslo
# Unlock
unlock.title=Odemknout trezor
unlock.passwordPrompt=Zadejte heslo pro "%s":
unlock.savePassword=Uložit heslo
unlock.savePassword=Zapamatovat heslo
unlock.unlockBtn=Odemknout
## Success
unlock.success.message=Trezor "%s" byl úspěšně odemčen a nyní je dostupný.
unlock.success.rememberChoice=Pamatovat si volbu, nezobrazovat to znovu
unlock.success.revealBtn=Zobrazit trezor
unlock.success.revealBtn=Zobrazit jednotku
## Failure
unlock.error.heading=Nelze odemknout trezor
### Invalid Mount Point
@@ -109,6 +108,8 @@ unlock.error.invalidMountPoint.existing=Připojovací bod %s již existuje nebo
# Lock
## Force
lock.forced.heading=Běžné uzamčení selhalo
lock.forced.confirmBtn=Přesto uzamknout
## Failure
# Migration
@@ -197,7 +198,7 @@ stats.read.accessCount=Celkem přečteno: %d
stats.write.throughput.idle=Zápis: nečinný
stats.write.throughput.kibs=Zápis: %.2f kiB/s
stats.write.throughput.mibs=Zápis: %.2f MiB/s
stats.write.total.data.none=Přečteno: -
stats.write.total.data.none=Zapsaná data: -
stats.write.total.data.kib=Zapsáno: %.1f kiB
stats.write.total.data.mib=Zapsáno: %.1f MiB
stats.write.total.data.gib=Zapsáno: %.1f GiB
@@ -218,7 +219,11 @@ main.dropZone.dropVault=Přidat tento trezor
main.dropZone.unknownDragboardContent=Pokud chcete přidat trezor, přetáhněte jej do tohoto okna
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Klikněte zde pro přidání nového trezoru
main.vaultlist.contextMenu.remove=Odstranit trezor
main.vaultlist.contextMenu.remove=Odstranit…
main.vaultlist.contextMenu.lock=Zamknout
main.vaultlist.contextMenu.unlock=Odemknout…
main.vaultlist.contextMenu.unlockNow=Odemknout nyní
main.vaultlist.contextMenu.reveal=Zobrazit jednotku
main.vaultlist.addVaultBtn=Přidat trezor
## Vault Detail
### Welcome
@@ -95,12 +95,12 @@ forgetPassword.confirmBtn=Passwort vergessen
# Unlock
unlock.title=Tresor entsperren
unlock.passwordPrompt=Gib das Passwort für „%s“ ein:
unlock.savePassword=Passwort speichern
unlock.savePassword=Passwort merken
unlock.unlockBtn=Entsperren
## Success
unlock.success.message=„%s“ erfolgreich entsperrt! Nun kannst du auf deinen Tresor zugreifen.
unlock.success.message=„%s“ erfolgreich entsperrt! Nun kannst du über das virtuelle Laufwerk auf deinen Tresor zugreifen.
unlock.success.rememberChoice=Auswahl speichern und nicht mehr anzeigen
unlock.success.revealBtn=Tresor anzeigen
unlock.success.revealBtn=Laufwerk anzeigen
## Failure
unlock.error.heading=Tresor konnte nicht entsperrt werden
### Invalid Mount Point
@@ -189,28 +189,28 @@ stats.cacheHitRate=Cache-Trefferrate
stats.read.throughput.idle=Lesen: Leerlauf
stats.read.throughput.kibs=Lesen: %.2f kiB/s
stats.read.throughput.mibs=Lesen: %.2f MiB/s
stats.read.total.data.none=Daten gelesen: -
stats.read.total.data.kib=Daten gelesen: %.1f kiB
stats.read.total.data.mib=Daten gelesen: %.1f MiB
stats.read.total.data.gib=Daten gelesen: %.1f GiB
stats.decr.total.data.none=Daten entschlüsselt: -
stats.decr.total.data.kib=Daten entschlüsselt: %.1f kiB
stats.decr.total.data.mib=Daten entschlüsselt: %.1f MiB
stats.decr.total.data.gib=Daten entschlüsselt: %.1f GiB
stats.read.accessCount=Gesamt gelesen: %d
stats.read.total.data.none=Gelesen: -
stats.read.total.data.kib=Gelesen: %.1f kiB
stats.read.total.data.mib=Gelesen: %.1f MiB
stats.read.total.data.gib=Gelesen: %.1f GiB
stats.decr.total.data.none=Entschlüsselt: -
stats.decr.total.data.kib=Entschlüsselt: %.1f kiB
stats.decr.total.data.mib=Entschlüsselt: %.1f MiB
stats.decr.total.data.gib=Entschlüsselt: %.1f GiB
stats.read.accessCount=Lesezugriffe: %d
## Write
stats.write.throughput.idle=Schreiben: Leerlauf
stats.write.throughput.kibs=Schreiben: %.2f kiB/s
stats.write.throughput.mibs=Schreiben: %.2f MiB/s
stats.write.total.data.none=Daten gelesen: -
stats.write.total.data.kib=Daten geschrieben: %.1f kiB
stats.write.total.data.mib=Daten geschrieben: %.1f MiB
stats.write.total.data.gib=Daten geschrieben: %.1f GiB
stats.encr.total.data.none=Daten verschlüsselt: -
stats.encr.total.data.kib=Daten verschlüsselt: %.1f kiB
stats.encr.total.data.mib=Datenverschlüsselt: %.1f MiB
stats.encr.total.data.gib=Daten verschlüsselt: %.1f GiB
stats.write.accessCount=Gesamt geschrieben: %d
stats.write.total.data.none=Geschrieben: -
stats.write.total.data.kib=Geschrieben: %.1f kiB
stats.write.total.data.mib=Geschrieben: %.1f MiB
stats.write.total.data.gib=Geschrieben: %.1f GiB
stats.encr.total.data.none=Verschlüsselt: -
stats.encr.total.data.kib=Verschlüsselt: %.1f kiB
stats.encr.total.data.mib=Verschlüsselt: %.1f MiB
stats.encr.total.data.gib=Verschlüsselt: %.1f GiB
stats.write.accessCount=Schreibzugriffe: %d
# Main Window
main.closeBtn.tooltip=Schließen
@@ -223,7 +223,12 @@ main.dropZone.dropVault=Diesen Tresor hinzufügen
main.dropZone.unknownDragboardContent=Wenn Sie einen Tresor hinzufügen möchten, ziehen Sie ihn in dieses Fenster
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Klicke hier, um einen Tresor hinzuzufügen
main.vaultlist.contextMenu.remove=Tresor entfernen…
main.vaultlist.contextMenu.remove=Entfernen
main.vaultlist.contextMenu.lock=Sperren
main.vaultlist.contextMenu.unlock=Entsperren …
main.vaultlist.contextMenu.unlockNow=Jetzt entsperren
main.vaultlist.contextMenu.vaultoptions=Tresoroptionen anzeigen
main.vaultlist.contextMenu.reveal=Laufwerk anzeigen
main.vaultlist.addVaultBtn=Tresor hinzufügen
## Vault Detail
### Welcome
@@ -280,7 +285,7 @@ vaultOptions.mount.customMountFlags=Benutzerdefinierte Mount-Flags
vaultOptions.mount.winDriveLetterOccupied=belegt
vaultOptions.mount.mountPoint=Einhängepunkt
vaultOptions.mount.mountPoint.auto=Automatisch einen passenden Ort auswählen
vaultOptions.mount.mountPoint.driveLetter=Zugewiesenen Laufwerksbuchstaben verwenden
vaultOptions.mount.mountPoint.driveLetter=Laufwerksbuchstaben zuweisen
vaultOptions.mount.mountPoint.custom=Pfad selbst wählen
vaultOptions.mount.mountPoint.directoryPickerButton=Durchsuchen …
vaultOptions.mount.mountPoint.directoryPickerTitle=Wähle ein leeres Verzeichnis
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=Ξέχασα τον κωδικό πρόσβασης
# Unlock
unlock.title=Ξεκλείδωμα Vault
unlock.passwordPrompt=Εισάγετε τον κωδικό για "%s":
unlock.savePassword=Αποθήκευση κωδικού
unlock.savePassword=Απομνημόνευση κωδικού πρόσβασης
unlock.unlockBtn=Ξεκλείδωμα
## Success
unlock.success.message="%s" ξεκλειδώθηκε επιτυχώς! Το vault σας είναι διαθέσιμο.
unlock.success.rememberChoice=Απομνημόνευση επιλογής, μην ρωτήσεις ξανά
unlock.success.revealBtn=Αποκάλυψη Vault
unlock.success.revealBtn=Αποκάλυψη εικονικού δίσκου
## Failure
unlock.error.heading=Αδυναμία ξεκλειδώματος vault
### Invalid Mount Point
@@ -149,6 +148,8 @@ preferences.general.theme.automatic=Αυτόματα
preferences.general.theme.light=Ανοιχτό
preferences.general.theme.dark=Σκούρο
preferences.general.unlockThemes=Ξεκλείδωσε το σκούρο θέμα
preferences.general.showMinimizeButton=Εμφάνιση κουμπιού ελαχιστοποίησης
preferences.general.showTrayIcon=Εμφάνιση εικονιδίου κοντά στο ρολόι (απαιτεί επανεκκίνηση)
preferences.general.startHidden=Απόκρυψη παραθύρου όταν ξεκινά το Cryptomator
preferences.general.debugLogging=Ενεργοποίηση καταγραφής σφαλμάτων
preferences.general.debugDirectory=Αποκάλυψη αρχείων καταγραφής
@@ -200,7 +201,7 @@ stats.read.accessCount=Συνολικές αναγνώσεις: %d
stats.write.throughput.idle=Εγγραφή: ηρεμία
stats.write.throughput.kibs=Εγγραφή: %.2f kiB/s
stats.write.throughput.mibs=Εγγραφή: %.2f MiB/s
stats.write.total.data.none=Ανάγνωση δεδομένων: -
stats.write.total.data.none=Δεδομένα που γράφηκαν: -
stats.write.total.data.kib=Δεδομένα που γράφτηκαν: %.1f kiB
stats.write.total.data.mib=Δεδομένα που γράφτηκαν: %.1f MiB
stats.write.total.data.gib=Δεδομένα που γράφτηκαν: %.1f GiB
@@ -221,7 +222,10 @@ main.dropZone.dropVault=Προσθήκη vault
main.dropZone.unknownDragboardContent=Αν θέλετε να προσθέσετε ένα vault, σύρετε το σε αυτό το παράθυρο
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Κάντε κλικ εδώ για να προσθέσετε ένα vault
main.vaultlist.contextMenu.remove=Διαγραφή Vault…
main.vaultlist.contextMenu.lock=Κλείδωμα
main.vaultlist.contextMenu.unlock=Ξεκλείδωμα…
main.vaultlist.contextMenu.unlockNow=Ξεκλείδωμα τώρα
main.vaultlist.contextMenu.reveal=Αποκάλυψη εικονικού δίσκου
main.vaultlist.addVaultBtn=Προσθήκη Vault
## Vault Detail
### Welcome
@@ -95,12 +95,12 @@ forgetPassword.confirmBtn=Olvidar contraseña
# Unlock
unlock.title=Desbloquear bóveda
unlock.passwordPrompt=Ingresar contraseña para "%s":
unlock.savePassword=Guardar contraseña
unlock.savePassword=Recordar contraseña
unlock.unlockBtn=Desbloquear
## Success
unlock.success.message=¡"%s" se desbloqueó con éxito! La bóveda ya es accesible.
unlock.success.message=¡Desbloqueo de "%s" exitoso! Su bóveda ahora es accesible a través de su unidad virtual.
unlock.success.rememberChoice=Recordar opción y no mostrar de nuevo
unlock.success.revealBtn=Revelar bóveda
unlock.success.revealBtn=Revelar unidad
## Failure
unlock.error.heading=No se puede desbloquear la bóveda
### Invalid Mount Point
@@ -202,7 +202,7 @@ stats.read.accessCount=Total leídos: %d
stats.write.throughput.idle=Escritura: inactivo
stats.write.throughput.kibs=Escritura: %.2f kiB/s
stats.write.throughput.mibs=Escritura: %.2f MiB/s
stats.write.total.data.none=Datos leídos: -
stats.write.total.data.none=Datos escritos:-
stats.write.total.data.kib=Datos escritos: %.1f kiB
stats.write.total.data.mib=Datos escritos: %.1f MiB
stats.write.total.data.gib=Datos escritos: %.1f GiB
@@ -223,7 +223,12 @@ main.dropZone.dropVault=Añadir esta bóveda
main.dropZone.unknownDragboardContent=Si desea añadir una bóveda, arrástrela a esta ventana
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Hacer clic aquí para añadir una bóveda
main.vaultlist.contextMenu.remove=Eliminar bóveda
main.vaultlist.contextMenu.remove=Eliminar…
main.vaultlist.contextMenu.lock=Bloquear
main.vaultlist.contextMenu.unlock=Desbloquear…
main.vaultlist.contextMenu.unlockNow=Desbloquear ahora
main.vaultlist.contextMenu.vaultoptions=Mostrar opciones de la bóveda
main.vaultlist.contextMenu.reveal=Revelar unidad
main.vaultlist.addVaultBtn=Añadir bóveda
## Vault Detail
### Welcome
@@ -95,12 +95,12 @@ forgetPassword.confirmBtn=Oublier le mot de passe
# Unlock
unlock.title=Déverrouiller le coffre
unlock.passwordPrompt=Entrez le mot de passe pour “%s” :
unlock.savePassword=Enregistrer le mot de passe
unlock.savePassword=Mémoriser le mot de passe
unlock.unlockBtn=Déverrouiller
## Success
unlock.success.message=“%s” déverrouillé ! Le contenu de votre coffre est maintenant accessible.
unlock.success.message=“%s” déverrouillé ! Le contenu de votre coffre est maintenant accessible par son lecteur virtuel.
unlock.success.rememberChoice=Se souvenir de mon choix et ne plus me demander
unlock.success.revealBtn=Révéler le coffre
unlock.success.revealBtn=Révéler le lecteur
## Failure
unlock.error.heading=Impossible de déverrouiller le coffre
### Invalid Mount Point
@@ -202,7 +202,7 @@ stats.read.accessCount=Total des lectures: %d
stats.write.throughput.idle=Écriture : inactif
stats.write.throughput.kibs=Écriture : %.2f kiO/s
stats.write.throughput.mibs=Écriture : %.2f Mo/s
stats.write.total.data.none=Lecture des données : -
stats.write.total.data.none=Données écrites : -
stats.write.total.data.kib=Données écrites : %.1f kiO
stats.write.total.data.mib=Données écrites : %.1f MiO
stats.write.total.data.gib=Données écrites : %.1f GiO
@@ -223,7 +223,12 @@ main.dropZone.dropVault=Ajouter ce coffre
main.dropZone.unknownDragboardContent=Si vous voulez ajouter un coffre, faites-le glisser dans cette fenêtre
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Cliquez ici pour ajouter un coffre
main.vaultlist.contextMenu.remove=Supprimer le coffre
main.vaultlist.contextMenu.remove=Retirer
main.vaultlist.contextMenu.lock=Verrouiller
main.vaultlist.contextMenu.unlock=Déverrouiller…
main.vaultlist.contextMenu.unlockNow=Déverrouiller maintenant
main.vaultlist.contextMenu.vaultoptions=Afficher les options du coffre
main.vaultlist.contextMenu.reveal=Révéler le lecteur
main.vaultlist.addVaultBtn=Ajouter un coffre
## Vault Detail
### Welcome
@@ -106,6 +106,7 @@ main.closeBtn.tooltip=बंद करें
main.preferencesBtn.tooltip=प्राथमिकताएं
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=लॉक करें
main.vaultlist.addVaultBtn=वाउल्ट डालें
## Vault Detail
### Welcome
@@ -1,5 +1,4 @@
# Locale Specific CSS files such as CJK, RTL,...
additionalStyleSheets=
# Generics
## Button
@@ -41,7 +40,6 @@ addvaultwizard.new.namePrompt=A széf neve
### Location
addvaultwizard.new.locationInstruction=Hova mentse a Cryptomator a széf titkosított fájljait?
addvaultwizard.new.locationLabel=Tárolási hely
addvaultwizard.new.locationPrompt=
addvaultwizard.new.directoryPickerLabel=Egyedi hely
addvaultwizard.new.directoryPickerButton=Választás…
addvaultwizard.new.directoryPickerTitle=Könyvtár kiválasztása
@@ -49,7 +47,7 @@ addvaultwizard.new.fileAlreadyExists=Nem lehet a széfet létrehozni ezen a hely
addvaultwizard.new.locationDoesNotExist=Nem lehet a széfet létrehozni ezen a helyen, mert az útvonal legalább egy darabja nem létezik.
addvaultwizard.new.invalidName=Érvénytelen széf elnevezés. Kérjük vegye figyelembe a szabályos könyvtárelnevezésre vonatkozó szabályokat.
### Password
addvaultwizard.new.createVaultBtn=Széf létrehozása
addvaultwizard.new.createVaultBtn=Új széf létrehozása
addvaultwizard.new.generateRecoveryKeyChoice=Nem fog tudni hozzáférni az adataihoz a jelszó nélkül. Akar egy visszaállítási kulcsot arra az esetre, ha elveszíti a jelszavát?
addvaultwizard.new.generateRecoveryKeyChoice.yes=Igen kérem, jobb félni, mint megijedni.
addvaultwizard.new.generateRecoveryKeyChoice.no=Nem köszönöm, nem fogom elveszíteni a jelszavam.
@@ -96,10 +94,8 @@ forgetPassword.confirmBtn=Jelszó elfelejtése
# Unlock
unlock.title=Széf feloldása
unlock.passwordPrompt=Írja be a jelszavát a következő széfhez "%s":
unlock.savePassword=Jelszó mentése
unlock.unlockBtn=Feloldás
## Success
unlock.success.message="%s" sikreresen feloldásra került! Mostmár hozzáférhet a széféhez.
unlock.success.rememberChoice=Jegyezze meg a választást és ne mutassa többet
unlock.success.revealBtn=Széf megjelenítése
## Failure
@@ -108,6 +104,10 @@ unlock.error.heading=Nem lehet feloldani a széfet
unlock.error.invalidMountPoint.notExisting=A csatolási pont "%s" nem egy könyvtár, nem üres vagy nem létezik.
unlock.error.invalidMountPoint.existing=A csatolási pont "%s" már létezik vagy a already exists or szülőmappa hiányzik.
# Lock
## Force
## Failure
# Migration
migration.title=Széf frissítése
## Start
@@ -115,7 +115,7 @@ migration.start.prompt=A "%s" széf formátuma frissítésre szorul. A folytatá
migration.start.confirm=Igen, a széfem teljes mértékben szinkronizálva van
## Run
migration.run.enterPassword=Írja be a jelszót a következőhöz Enter the password for "%s"
migration.run.startMigrationBtn=Széf migrációja
migration.run.startMigrationBtn=Széf frissítése
migration.run.progressHint=Ez eltarthat egy darabig…
## Sucess
migration.success.nextStepsInstructions=A "%s" sikeresen migrálva. \nMost már feloldhatja a széfet.
@@ -146,18 +146,12 @@ preferences.general.debugLogging=Hibakeresési naplózás engedélyezése
preferences.general.debugDirectory=Naplófájlok megjelenítése
preferences.general.autoStart=Cryptomator indítása a rendszerrel együtt
preferences.general.keychainBackend=Itt tárolja a jelszavakat
preferences.general.keychainBackend.org.cryptomator.linux.keychain.SecretServiceKeychainAccess=Gnome Keyring
preferences.general.keychainBackend.org.cryptomator.linux.keychain.KDEWalletKeychainAccess=KDE Wallet
preferences.general.keychainBackend.org.cryptomator.macos.keychain.MacSystemKeychainAccess=macOS Keychain Access
preferences.general.keychainBackend.org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess=Windows Data Protection
preferences.general.interfaceOrientation=Felhasználói felület orientációja
preferences.general.interfaceOrientation.ltr=Balról jobbra
preferences.general.interfaceOrientation.rtl=Jobbról balra
## Volume
preferences.volume=Virtuális meghajtó
preferences.volume.type=Kötet tipusa
preferences.volume.webdav.port=WebDAV Port
preferences.volume.webdav.scheme=WebDAV Scheme
## Updates
preferences.updates=Frissítések
preferences.updates.currentVersion=Jelenlegi verzió: %s
@@ -192,7 +186,6 @@ stats.read.accessCount=Összes olvasás: %d
stats.write.throughput.idle=Írás: tétlen
stats.write.throughput.kibs=Írás: %.2f kiB/s
stats.write.throughput.mibs=Írás: %.2f MiB/s
stats.write.total.data.none=Írott adat: -
stats.write.total.data.kib=Írott adat: %.1f kiB
stats.write.total.data.mib=Írott adat: %.1f MiB
stats.write.total.data.gib=Írott adat: %.1f GiB
@@ -213,7 +206,10 @@ main.dropZone.dropVault=Adja hozzá ezt a széfet
main.dropZone.unknownDragboardContent=Ha egy széfet szeretne hozzáadni, akkor húzza át erre az ablakra.
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Kattintson ide egy széf hozzáadásához
main.vaultlist.contextMenu.remove=Széf eltávolítása…
main.vaultlist.contextMenu.lock=Zárolás
main.vaultlist.contextMenu.unlock=Feloldás…
main.vaultlist.contextMenu.unlockNow=Azonnali feloldás
main.vaultlist.contextMenu.reveal=Széf megjelenítése
main.vaultlist.addVaultBtn=Széf hozzáadása
## Vault Detail
### Welcome
@@ -232,8 +228,6 @@ main.vaultDetail.lockBtn=Zárolás
main.vaultDetail.bytesPerSecondRead=Olvasás:
main.vaultDetail.bytesPerSecondWritten=Írás:
main.vaultDetail.throughput.idle=tétlen
main.vaultDetail.throughput.kbps=%.1f kiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Széf statisztika
### Missing
main.vaultDetail.missing.info=A Cryptomator nem talált széfet ezen az útvonalon.
@@ -262,22 +256,22 @@ vaultOptions.general.unlockAfterStartup=A széf feloldása a Cryptomator indít
vaultOptions.general.actionAfterUnlock=Sikeres feloldás után
vaultOptions.general.actionAfterUnlock.ignore=Ne tegyen semmit
vaultOptions.general.actionAfterUnlock.reveal=Jelenítse meg a kötetet
vaultOptions.general.actionAfterUnlock.ask=Kérdezzen
vaultOptions.general.actionAfterUnlock.ask=Kérdez
## Mount
vaultOptions.mount=Csatolás
vaultOptions.mount.readonly=Csak olvasható
vaultOptions.mount=Felcsatolás
vaultOptions.mount.readonly=Csak-olvasható
vaultOptions.mount.customMountFlags=Egyedi csatolási paraméterek
vaultOptions.mount.winDriveLetterOccupied=foglalt
vaultOptions.mount.mountPoint=Csatolási pont
vaultOptions.mount.mountPoint.auto=Válasszon egy megfelelő helyet autómatikusan
vaultOptions.mount.mountPoint.auto=Válasszon egy megfelelő helyet automatikusan
vaultOptions.mount.mountPoint.driveLetter=Használja a kiválasztott meghajtó betűjelét
vaultOptions.mount.mountPoint.custom=Egyedi útvonal
vaultOptions.mount.mountPoint.directoryPickerButton=Kiválasztás
vaultOptions.mount.mountPoint.directoryPickerButton=Kiválaszt…
vaultOptions.mount.mountPoint.directoryPickerTitle=Válasszon egy üres könyvtárat
## Master Key
vaultOptions.masterkey=Jelszó
vaultOptions.masterkey.changePasswordBtn=Jelszó megváltoztatása
vaultOptions.masterkey.forgetSavedPasswordBtn=Elmentett jelszó elfelejtése
vaultOptions.masterkey.forgetSavedPasswordBtn=Mentett jelszó törlése
vaultOptions.masterkey.recoveryKeyExpanation=A helyreállítási kulcs az egyetlen módja annak, hogy visszaállítsa a széfhez való hozzáférést, ha elveíti a jelszavát.
vaultOptions.masterkey.showRecoveryKeyBtn=Visszaállítási kulcs megjelenítése
vaultOptions.masterkey.recoverPasswordBtn=Jelszó visszaállítása
@@ -292,8 +286,8 @@ recoveryKey.recover.validKey=Ez egy érvényes visszaállítási kulcs
recoveryKey.printout.heading=Cryptomator visszaállítási kulcs\n"%s"\n
# New Password
newPassword.promptText=Írja be az új jelszavát
newPassword.reenterPassword=Erősítse meg az új jelszavát
newPassword.promptText=Adjon meg egy új jelszót
newPassword.reenterPassword=Az új jelszó megerősítése
newPassword.passwordsMatch=A jelszavak megegyeznek!
newPassword.passwordsDoNotMatch=A jelszavak nem egyeznek meg
passwordStrength.messageLabel.tooShort=Használjon legalább %d karaktert
@@ -109,6 +109,7 @@ main.closeBtn.tooltip=Tutup
main.preferencesBtn.tooltip=Preferensi
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=Gembok
main.vaultlist.addVaultBtn=Tambah Brankas
## Vault Detail
### Welcome
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=Password dimenticata
# Unlock
unlock.title=Sblocca Cassaforte
unlock.passwordPrompt=Inserisci la password per "%s":
unlock.savePassword=Salva password
unlock.savePassword=Ricorda la Password
unlock.unlockBtn=Sblocca
## Success
unlock.success.message=Sbloccato "%s" con successo! La tua cassaforte è ora accessibile.
unlock.success.rememberChoice=Ricorda la scelta, non mostrare ancora
unlock.success.revealBtn=Rivela Cassaforte
unlock.success.revealBtn=Visualizza disco
## Failure
unlock.error.heading=Impossibile sbloccare la cassaforte
### Invalid Mount Point
@@ -200,7 +199,7 @@ stats.read.accessCount=Totale lettura: %d
stats.write.throughput.idle=Scrivi: inattivo
stats.write.throughput.kibs=Scrittura: %.2f kiB/s
stats.write.throughput.mibs=Scrittura: %.2f MiB/s
stats.write.total.data.none=Dati letti: -
stats.write.total.data.none=Dati scritti: -
stats.write.total.data.kib=Dati scritti: %.1f kiB
stats.write.total.data.mib=Dati scritti: %.1f MiB
stats.write.total.data.gib=Dati scritti: %.1f GiB
@@ -221,7 +220,10 @@ main.dropZone.dropVault=Aggiungi questa cassaforte
main.dropZone.unknownDragboardContent=Se vuoi aggiungere una cassaforte, trascinala in questa finestra
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Clicca qui per aggiungere una cassaforte
main.vaultlist.contextMenu.remove=Rimuovi Cassaforte…
main.vaultlist.contextMenu.lock=Blocca
main.vaultlist.contextMenu.unlock=Sblocca…
main.vaultlist.contextMenu.unlockNow=Sblocca adesso
main.vaultlist.contextMenu.reveal=Visualizza disco
main.vaultlist.addVaultBtn=Aggiungi Cassaforte
## Vault Detail
### Welcome
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=パスワードを削除
# Unlock
unlock.title=金庫を解錠
unlock.passwordPrompt="%s" のパスワードを入力してください:
unlock.savePassword=パスワードを保存
unlock.savePassword=パスワードを記憶させる
unlock.unlockBtn=解錠
## Success
unlock.success.message="%s" の解錠に成功しました! 金庫にアクセス可能です。
unlock.success.rememberChoice=選択を記憶させて、再度表示しない
unlock.success.revealBtn=金庫を表示
unlock.success.revealBtn=ドライブを表示
## Failure
unlock.error.heading=金庫の解錠に失敗
### Invalid Mount Point
@@ -202,7 +201,7 @@ stats.read.accessCount=合計読み取り: %d
stats.write.throughput.idle=書き込み: アイドル状態
stats.write.throughput.kibs=書き込み: %.2f kiB/s
stats.write.throughput.mibs=書き込み: %.2f MiB/s
stats.write.total.data.none=データ読み込み: -
stats.write.total.data.none=書き込み済みデータ: -
stats.write.total.data.kib=書き込み済みデータ: %.1f kiB
stats.write.total.data.mib=書き込み済みデータ: %.1f MiB
stats.write.total.data.gib=書き込み済みデータ: %.1f GiB
@@ -223,7 +222,10 @@ main.dropZone.dropVault=この金庫を追加
main.dropZone.unknownDragboardContent=このウィンドウにドラッグして、金庫を追加
## Vault List
main.vaultlist.emptyList.onboardingInstruction=ここをクリックして金庫を追加
main.vaultlist.contextMenu.remove=金庫を削除...
main.vaultlist.contextMenu.lock=施錠
main.vaultlist.contextMenu.unlock=解錠...
main.vaultlist.contextMenu.unlockNow=今すぐ解錠
main.vaultlist.contextMenu.reveal=ドライブを表示
main.vaultlist.addVaultBtn=金庫を追加
## Vault Detail
### Welcome
@@ -67,7 +67,7 @@ addvault.new.readme.storageLocation.10=만일 도움이 필요하신 경우, 다
addvault.new.readme.accessLocation.fileName=WELCOME.rtf
addvault.new.readme.accessLocation.1=🔐️ 암호화 된 볼륨 🔐️
addvault.new.readme.accessLocation.2=이것은 당신의 Vault 접근 위치입니다.
addvault.new.readme.accessLocation.3=이 볼륨에 추가된 모든 파일은 Cryptomator로 암호화됩니다. 다른 드라이브/폴더처럼 작업할 수 있습니다. 볼륨의 내용은 복호화 된 것 처럼 보여질 뿐이며, 모든 파일은 항상 암호화되어 하드디스크에 저장됩니다.
addvault.new.readme.accessLocation.3=이 볼륨에 추가된 모든 파일은 Cryptomator로 암호화됩니다. 다른 드라이브/폴더처럼 작업할 수 있습니다. 볼륨의 내용은 복호화 된 것 처럼 보여지지만, 모든 파일은 항상 암호화되어 하드디스크에 저장됩니다.
addvault.new.readme.accessLocation.4=이 파일은 지우셔도 무방합니다.
## Existing
addvaultwizard.existing.instruction=기존 Vault 의 "masterkey.cryptomator" 파일을 선택하여 주십시요.
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=비밀번호 분실
# Unlock
unlock.title=Vault 잠금해제
unlock.passwordPrompt="%s"의 비밀번호를 입력하십시요.
unlock.savePassword=비밀번호 저장
unlock.savePassword=비밀번호 기억
unlock.unlockBtn=잠금해제
## Success
unlock.success.message="%s"의 잠금해제가 성공적으로 수행되었습니다! 이제 이 Vault의 접근이 가능합니다.
unlock.success.rememberChoice=선택 기억함, 다시 묻지 않음
unlock.success.revealBtn=Vault 표시
unlock.success.revealBtn=드라이브 표시
## Failure
unlock.error.heading=Vault 잠금을 해제 할 수 없습니다.
### Invalid Mount Point
@@ -149,6 +148,8 @@ preferences.general.theme.automatic=자동
preferences.general.theme.light=밝게
preferences.general.theme.dark=어둡게
preferences.general.unlockThemes=다크모드 해제
preferences.general.showMinimizeButton=최소화 버튼 표시
preferences.general.showTrayIcon=트레이 아이콘 보기 (재시작 필요)
preferences.general.startHidden=Cryptomator를 시작할 때 창 숨김
preferences.general.debugLogging=디버그 로그기록을 사용하도록 설정
preferences.general.debugDirectory=Log 파일 표시
@@ -200,7 +201,7 @@ stats.read.accessCount=총 읽기 횟수: %d
stats.write.throughput.idle=쓰기: 대기중
stats.write.throughput.kibs=쓰기: %.2f kiB/s
stats.write.throughput.mibs=쓰기: %.2f MiB/s
stats.write.total.data.none=데이터 기: -
stats.write.total.data.none=데이터 기록됨: -
stats.write.total.data.kib=데이터 쓰기: %.1f kiB
stats.write.total.data.mib=데이터 쓰기: %.1f MiB
stats.write.total.data.gib=데이터 쓰기: %.1f GiB
@@ -221,7 +222,10 @@ main.dropZone.dropVault=이 Vault를 추가
main.dropZone.unknownDragboardContent=Vault를 추가하려면, 이 창에 드래그 하십시요.
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Vault를 추가하기 위해 이곳을 클릭합니다.
main.vaultlist.contextMenu.remove=Vault 제거...
main.vaultlist.contextMenu.lock=잠금
main.vaultlist.contextMenu.unlock=잠금해제...
main.vaultlist.contextMenu.unlockNow=지금 잠금해제
main.vaultlist.contextMenu.reveal=드라이브 표시
main.vaultlist.addVaultBtn=Vault 추가
## Vault Detail
### Welcome
@@ -292,7 +296,7 @@ vaultOptions.masterkey.recoverPasswordBtn=비밀번호 복구
# Recovery Key
recoveryKey.title=복구 키
recoveryKey.enterPassword.prompt="%s"의 복구 키를 표시하려면 비밀번호를 입력하여 주십시요.
recoveryKey.enterPassword.prompt="%s"의 복구 키를 표시하려면 비밀번호를 입력해 주세요.
recoveryKey.display.message="%s" 데이터 접근을 복원하는데 사용 할 수 있는 복구 키 입니다:
recoveryKey.display.StorageHints=매우 안전한곳에 보관하십시요. 예시:\n • 비밀번호 관리자를 사용하여 저장\n • USB 플래시 드라이브에 저장\n • 종이에 출력
recoveryKey.recover.prompt="%s"의 복구키를 입력하십시요:
@@ -300,7 +304,7 @@ recoveryKey.recover.validKey=올바른 복구 키 입니다.
recoveryKey.printout.heading=Cryptomator 복구 키\n"%s"\n
# New Password
newPassword.promptText=새 비밀번호를 입력하십시요.
newPassword.promptText=새 비밀번호를 입력하세요
newPassword.reenterPassword=새 비밀번호를 확인하여 주십시요.
newPassword.passwordsMatch=비밀번호가 일치합니다!
newPassword.passwordsDoNotMatch=비밀번호가 일치하지 않습니다.
@@ -93,11 +93,9 @@ forgetPassword.confirmBtn=Aizmirst paroli
# Unlock
unlock.title=Atslēgt glabātuvi
unlock.passwordPrompt=Ievadiet "%s" paroli:
unlock.savePassword=Saglabāt paroli
unlock.unlockBtn=Atslēgt
## Success
unlock.success.message="%s" sekmīgi atslēgts! Jūsu glabātuve tagad ir pieejama.
unlock.success.revealBtn=Atklāt glabātuvi
unlock.success.revealBtn=Atklāt disku
## Failure
### Invalid Mount Point
@@ -172,6 +170,9 @@ main.dropZone.dropVault=Pievienot šo glabātuvi
main.dropZone.unknownDragboardContent=Ja jūs vēlaties pievienot glabātuvi, velciet to uz šo logu
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Spied šeit, lai pievienotu glabātuvi
main.vaultlist.contextMenu.lock=Aizslēgt
main.vaultlist.contextMenu.unlockNow=Atslēgt tagad
main.vaultlist.contextMenu.reveal=Atklāt disku
main.vaultlist.addVaultBtn=Pievienot glabātuvi
## Vault Detail
### Welcome
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=Glem passord
# Unlock
unlock.title=Lås opp hvelvet
unlock.passwordPrompt=Skriv inn passordet for "%s":
unlock.savePassword=Lagre passord
unlock.savePassword=Husk passord
unlock.unlockBtn=Lås opp
## Success
unlock.success.message=Vellykket opplåsning av "%s"! Hvelvet ditt er nå tilgjengelig.
unlock.success.rememberChoice=Husk valget - ikke vis dette igjen
unlock.success.revealBtn=Gjør hvelvet synlig
unlock.success.revealBtn=Gjør enheten synlig
## Failure
unlock.error.heading=Klarer ikke å låse opp hvelvet
### Invalid Mount Point
@@ -202,7 +201,7 @@ stats.read.accessCount=Lesninger totalt: %d
stats.write.throughput.idle=Skrive: inaktiv
stats.write.throughput.kibs=Skriver: %.2f kiB/s
stats.write.throughput.mibs=Skriver: %.2f MiB/s
stats.write.total.data.none=Data lest: -
stats.write.total.data.none=Data skrevet: -
stats.write.total.data.kib=Data skrevet: %.1f kiB
stats.write.total.data.mib=Data skrevet: %.1f MiB
stats.write.total.data.gib=Data skrevet: %.1f GiB
@@ -223,7 +222,10 @@ main.dropZone.dropVault=Legg til dette hvelvet
main.dropZone.unknownDragboardContent=Hvis du vil legge til et hvelv, kan du dra det til dette vinduet
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Klikk her for å legge til et hvelv
main.vaultlist.contextMenu.remove=Fjern hvelvet…
main.vaultlist.contextMenu.lock=Lås
main.vaultlist.contextMenu.unlock=Lås opp…
main.vaultlist.contextMenu.unlockNow=Lås opp nå
main.vaultlist.contextMenu.reveal=Gjør enheten synlig
main.vaultlist.addVaultBtn=Legg til hvelv
## Vault Detail
### Welcome
@@ -95,12 +95,10 @@ forgetPassword.confirmBtn=Wachtwoord vergeten
# Unlock
unlock.title=Kluis ontgrendelen
unlock.passwordPrompt=Voer wachtwoord voor "%s" in:
unlock.savePassword=Wachtwoord Opslaan
unlock.unlockBtn=Ontgrendel
## Success
unlock.success.message="%s" is met succes ontgrendeld! Uw kluis is nu toegankelijk.
unlock.success.rememberChoice=Keuze onthouden en dit niet opnieuw tonen
unlock.success.revealBtn=Toon kluis
unlock.success.revealBtn=Toon Schijf
## Failure
unlock.error.heading=Kan kluis niet ontgrendelen
### Invalid Mount Point
@@ -202,7 +200,6 @@ stats.read.accessCount=Totaal gelezen: %d
stats.write.throughput.idle=Schrijven: inactief
stats.write.throughput.kibs=Schrijven: %.2f kiB/s
stats.write.throughput.mibs=Schrijven: %.2f MiB/s
stats.write.total.data.none=Gegevens gelezen: -
stats.write.total.data.kib=Gegevens geschreven: %.1f kiB
stats.write.total.data.mib=Gegevens geschreven: %.1f MiB
stats.write.total.data.gib=Gegevens geschreven: %.1f GiB
@@ -223,7 +220,10 @@ main.dropZone.dropVault=Voeg deze kluis toe
main.dropZone.unknownDragboardContent=Als u een kluis wilt toevoegen, sleep deze dan naar dit venster
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Klik hier om een kluis toe te voegen
main.vaultlist.contextMenu.remove=Verwijder Kluis…
main.vaultlist.contextMenu.lock=Vergrendel
main.vaultlist.contextMenu.unlock=Ontgrendelen…
main.vaultlist.contextMenu.unlockNow=Nu Ontgrendelen
main.vaultlist.contextMenu.reveal=Toon Schijf
main.vaultlist.addVaultBtn=Kluis toevoegen
## Vault Detail
### Welcome
@@ -94,12 +94,10 @@ forgetPassword.confirmBtn=Gløym passord
# Unlock
unlock.title=Lås opp kvelven
unlock.passwordPrompt=Skriv inn passordet for "%s":
unlock.savePassword=Lagre passordet
unlock.unlockBtn=Låse opp
## Success
unlock.success.message=Vellykka opplåsning av "%s"! Kvelven din er no tilgjengeleg.
unlock.success.rememberChoice=Hugs valet - ikkje vis dette igjen
unlock.success.revealBtn=Gjer kvelven synleg
unlock.success.revealBtn=Gjer eininga synleg
## Failure
### Invalid Mount Point
@@ -179,6 +177,10 @@ main.dropZone.dropVault=Legg til denne kvelven
main.dropZone.unknownDragboardContent=Viss du vil legga til ein kvelv, kan du dra det til dette vindauget
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Klikk her for å legga til ein kvelv
main.vaultlist.contextMenu.lock=Lås
main.vaultlist.contextMenu.unlock=Lås opp…
main.vaultlist.contextMenu.unlockNow=Lås opp no
main.vaultlist.contextMenu.reveal=Gjer eininga synleg
main.vaultlist.addVaultBtn=Legg til kvelv
## Vault Detail
### Welcome
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=ਪਾਸਵਰਡ ਭੁੱਲ ਗਏ
# Unlock
unlock.title=ਵਾਲਟ ਅਣ-ਲਾਕ ਕਰੋ
unlock.passwordPrompt="%s" ਲਈ ਪਾਸਵਰਡ ਦਿਓ:
unlock.savePassword=ਪਾਸਵਰਡ ਸੰਭਾਲ
unlock.savePassword=ਪਾਸਵਰਡ ਯਾਦ ਰੱਖ
unlock.unlockBtn=ਅਣ-ਲਾਕ ਕਰੋ
## Success
unlock.success.message="%s" ਕਾਮਯਾਬੀ ਨਾਲ ਅਣ-ਲਾਕ ਕੀਤਾ! ਤੁਹਾਡਾ ਵਾਲਟ ਹੁਣ ਵਰਤਿਆ ਜਾ ਸਕਦਾ ਹੈ।
unlock.success.rememberChoice=ਚੋਣਾਂ ਯਾਦ ਰੱਖੋ, ਇਹ ਮੁੜ ਕੇ ਨਾ ਵੇਖਾਓ
unlock.success.revealBtn=ਾਲਟ ਦਿਖਾਓ
unlock.success.revealBtn=ਡਰਾਇਵ ਦਿਖਾਓ
## Failure
unlock.error.heading=ਵਾਲਟ ਅਣ-ਲਾਕ ਕਰਨ ਲਈ ਅਸਮਰੱਥ
### Invalid Mount Point
@@ -149,6 +148,8 @@ preferences.general.theme.automatic=ਆਟੋਮੈਟਿਕ
preferences.general.theme.light=ਹਲਕਾ
preferences.general.theme.dark=ਗੂੜ੍ਹਾ
preferences.general.unlockThemes=ਗੂੜ੍ਹਾ ਢੰਗ ਅਣ-ਲਾਕ ਕਰੋ
preferences.general.showMinimizeButton=ਘੱਟੋ-ਘੱਟ ਬਟਨ ਦਿਖਾਓ
preferences.general.showTrayIcon=ਟਰੇ ਆਈਕਾਨ ਵੇਖਾਓ (ਮੁੜ-ਚਾਲੂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ)
preferences.general.startHidden=ਜਦੋਂ Cryptomator ਸ਼ੁਰੂ ਹੋਵੇ ਤਾਂ ਵਿੰਡੋ ਲੁਕਾਓ
preferences.general.debugLogging=ਡੀਬੱਗ ਲਾਗ ਸਮਰੱਥ ਕਰੋ
preferences.general.debugDirectory=ਲਾਗ ਫਾਇਲਾਂ ਦਿਖਾਓ
@@ -200,7 +201,7 @@ stats.read.accessCount=ਕੁੱਲ ਪੜ੍ਹੇ: %d
stats.write.throughput.idle=ਲਿਖੇ: ਵੇਹਲ
stats.write.throughput.kibs=ਲਿਖੇ: %.2f kiB/s
stats.write.throughput.mibs=ਲਿਖੇ: %.2f MiB/s
stats.write.total.data.none=ਡਾਟਾ ਪੜ੍ਹਿਆ: -
stats.write.total.data.none=ਲਿਖਿਆ ਡਾਟਾ: -
stats.write.total.data.kib=ਡਾਟਾ ਲਿਖਿਆ: %.1f kiB
stats.write.total.data.mib=ਡਾਟਾ ਲਿਖਿਆ: %.1f MiB
stats.write.total.data.gib=ਡਾਟਾ ਲਿਖਿਆ: %.1f GiB
@@ -221,7 +222,10 @@ main.dropZone.dropVault=ਇਹ ਵਾਲਟ ਜੋੜੋ
main.dropZone.unknownDragboardContent=ਜੇ ਤੁਸੀਂ ਵਾਲਟ ਜੋੜਨਾ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਇਸ ਨੂੰ ਬੰਦ ਵਿੰਡੋ ਉੱਤੇ ਖਿੱਚੋ
## Vault List
main.vaultlist.emptyList.onboardingInstruction=ਵਾਲਟ ਜੋੜਨ ਲਈ ਇੱਥੇ ਕਲਿੱਕ ਕਰੋ
main.vaultlist.contextMenu.remove=…ਵਾਲਟ ਹਟਾਓ
main.vaultlist.contextMenu.lock=ਲਾਕ ਕਰੋ
main.vaultlist.contextMenu.unlock=ਅਣ-ਲਾਕ ਕਰੋ…
main.vaultlist.contextMenu.unlockNow=ਹੁਣੇ ਅਣ-ਲਾਕ ਕਰੋ
main.vaultlist.contextMenu.reveal=ਡਰਾਇਵ ਦਿਖਾਓ
main.vaultlist.addVaultBtn=ਵਾਲਟ ਜੋੜੋ
## Vault Detail
### Welcome
@@ -98,9 +98,9 @@ unlock.passwordPrompt=Wprowadź hasło dla "%s":
unlock.savePassword=Zapamiętaj hasło
unlock.unlockBtn=Odblokuj
## Success
unlock.success.message="%s" został odblokowany! Twój sejf jest teraz dostępny.
unlock.success.message=Odblokowano "%s" pomyślnie! Twój sejf jest teraz dostępny za pomocą dysku wirtualnego.
unlock.success.rememberChoice=Zapamiętaj wybór, nie pokazuj tego ponownie
unlock.success.revealBtn=Otwórz sejf
unlock.success.revealBtn=Ujawnij Dysk
## Failure
unlock.error.heading=Nie można odblokować sejfu
### Invalid Mount Point
@@ -202,7 +202,7 @@ stats.read.accessCount=Całkowite odczyty: %d
stats.write.throughput.idle=Zapis: bezczynny
stats.write.throughput.kibs=Zapis: %.2f kiB/s
stats.write.throughput.mibs=Zapis: %.2f kiB/s
stats.write.total.data.none=Dane odczytywane: -
stats.write.total.data.none=Zapisane dane: -
stats.write.total.data.kib=Zapisane dane: %.1f kiB
stats.write.total.data.mib=Zapisane dane: %.1f MiB
stats.write.total.data.gib=Zapisane dane: %.1f kiB
@@ -223,7 +223,12 @@ main.dropZone.dropVault=Dodaj ten sejf
main.dropZone.unknownDragboardContent=Jeśli chcesz dodać sejf, przeciągnij go do tego okna
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Kliknij tutaj, aby dodać sejf
main.vaultlist.contextMenu.remove=Usuń sejf
main.vaultlist.contextMenu.remove=Usuń…
main.vaultlist.contextMenu.lock=Zablokuj
main.vaultlist.contextMenu.unlock=Odblokuj…
main.vaultlist.contextMenu.unlockNow=Odblokuj teraz
main.vaultlist.contextMenu.vaultoptions=Pokaż opcje sejfu
main.vaultlist.contextMenu.reveal=Otwórz lokalizację
main.vaultlist.addVaultBtn=Dodaj sejf
## Vault Detail
### Welcome
@@ -86,12 +86,9 @@ forgetPassword.confirmBtn=Esqueci a Senha
# Unlock
unlock.title=Destrancar Cofre
unlock.passwordPrompt=Insira a senha para "%s":
unlock.savePassword=Lembrar Senha
unlock.unlockBtn=Destrancar
## Success
unlock.success.message=Desbloqueado "%s" com sucesso! O seu cofre está agora acessível.
unlock.success.rememberChoice=Lembrar escolha, não mostrar isto novamente
unlock.success.revealBtn=Revelar Cofre
## Failure
### Invalid Mount Point
@@ -141,6 +138,8 @@ main.minimizeBtn.tooltip=Minimizar
main.preferencesBtn.tooltip=Preferências
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.lock=Trancar
main.vaultlist.contextMenu.unlockNow=Destrancar agora
main.vaultlist.addVaultBtn=Adicionar Cofre
## Vault Detail
### Welcome
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=Esquecer Senha
# Unlock
unlock.title=Desbloquear Cofre
unlock.passwordPrompt=Digite a senha para "%s":
unlock.savePassword=Salvar Senha
unlock.savePassword=Lembrar Senha
unlock.unlockBtn=Desbloquear
## Success
unlock.success.message="%s" foi desbloqueado com sucesso! Seu cofre agora está acessível.
unlock.success.rememberChoice=Lembrar opção escolhida, não mostrar isto novamente
unlock.success.revealBtn=Revelar Cofre
unlock.success.revealBtn=Revelar Volume
## Failure
unlock.error.heading=Não foi possível desbloquear o cofre
### Invalid Mount Point
@@ -202,7 +201,7 @@ stats.read.accessCount=Total de leituras: %d
stats.write.throughput.idle=Escrita: ociosa
stats.write.throughput.kibs=Escrita: %.2f kiB/s
stats.write.throughput.mibs=Escrita: %.2f MiB/s
stats.write.total.data.none=Dados lidos: -
stats.write.total.data.none=Dados gravados: -
stats.write.total.data.kib=Dados gravados: %.1f kiB
stats.write.total.data.mib=Dados gravados: %.1f MiB
stats.write.total.data.gib=Dados gravados: %.1f GiB
@@ -223,7 +222,10 @@ main.dropZone.dropVault=Adicionar este cofre
main.dropZone.unknownDragboardContent=Se você quer adicionar um cofre, arraste-o para esta janela
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Clique aqui para adicionar um cofre
main.vaultlist.contextMenu.remove=Remover Cofre…
main.vaultlist.contextMenu.lock=Bloquear
main.vaultlist.contextMenu.unlock=Desbloquear…
main.vaultlist.contextMenu.unlockNow=Desbloquear Agora
main.vaultlist.contextMenu.reveal=Revelar Volume
main.vaultlist.addVaultBtn=Adicionar Cofre
## Vault Detail
### Welcome
@@ -95,12 +95,12 @@ forgetPassword.confirmBtn=Не помню пароль
# Unlock
unlock.title=Разблокировать хранилище
unlock.passwordPrompt=Введите пароль для "%s"
unlock.savePassword=Сохранить пароль
unlock.savePassword=Запомнить пароль
unlock.unlockBtn=Разблокировать
## Success
unlock.success.message=Разблокировка "%s" успешно выполнена! Доступ в хранилище открыт.
unlock.success.message=Разблокировка "%s" успешно выполнена! Доступ в хранилище открыт через его виртуальный диск.
unlock.success.rememberChoice=Запомнить выбор и больше не спрашивать
unlock.success.revealBtn=Показать хранилище
unlock.success.revealBtn=Показать диск
## Failure
unlock.error.heading=Не удалось разблокировать хранилище
### Invalid Mount Point
@@ -202,7 +202,7 @@ stats.read.accessCount=Всего операций чтения: %d
stats.write.throughput.idle=Запись: бездействие
stats.write.throughput.kibs=Запись: %.2f КиБ/с
stats.write.throughput.mibs=Запись: %.2f МиБ/с
stats.write.total.data.none=Прочитано: -
stats.write.total.data.none=Записано данных: -
stats.write.total.data.kib=Записано: %.1f КиБ
stats.write.total.data.mib=Записано: %.1f МиБ
stats.write.total.data.gib=Записано: %.1f ГиБ
@@ -223,7 +223,12 @@ main.dropZone.dropVault=Добавить это хранилище
main.dropZone.unknownDragboardContent=Если вы хотите добавить хранилище, перетащите его в это окно
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Нажмите здесь, чтобы добавить хранилище
main.vaultlist.contextMenu.remove=Удалить хранилище
main.vaultlist.contextMenu.remove=Удалить…
main.vaultlist.contextMenu.lock=Заблокировать
main.vaultlist.contextMenu.unlock=Разблокировка…
main.vaultlist.contextMenu.unlockNow=Разблокировать
main.vaultlist.contextMenu.vaultoptions=Параметры хранилища
main.vaultlist.contextMenu.reveal=Показать диск
main.vaultlist.addVaultBtn=Добавить хранилище
## Vault Detail
### Welcome
@@ -93,11 +93,9 @@ forgetPassword.confirmBtn=Zabudnuté heslo
# Unlock
unlock.title=Odomknúť trezor
unlock.passwordPrompt=Zadajte heslo pre "%s":
unlock.savePassword=Uložiť heslo
unlock.savePassword=Odomknúť.uložiťHeslo
unlock.unlockBtn=Odomknúť
## Success
unlock.success.message=Úspešne sa odomkol "%s"! Váš trezor je teraz prístupný.
unlock.success.revealBtn=Odhaliť trezor
## Failure
unlock.error.heading=Nie je možné odomknúť účet
### Invalid Mount Point
@@ -125,6 +123,8 @@ migration.success.unlockNow=Odomknúť teraz
preferences.title=Predvoľby
## General
preferences.general.theme.automatic=Automaticky
preferences.general.showMinimizeButton=Predvoľba.hlavná.ukážMinimalizujTlačítko
preferences.general.showTrayIcon=Predvoľba.hlavná.ukážIkonaSytémovejlišty
preferences.general.keychainBackend.org.cryptomator.linux.keychain.SecretServiceKeychainAccess=Gnome klúčenka
preferences.general.keychainBackend.org.cryptomator.linux.keychain.KDEWalletKeychainAccess=KDE účet
preferences.general.keychainBackend.org.cryptomator.macos.keychain.MacSystemKeychainAccess=maccOS reťazový prístup
@@ -154,7 +154,7 @@ stats.read.accessCount=Spolu načítané: %d
stats.write.throughput.idle=Zápis: nečinnosť
stats.write.throughput.kibs=Zápis: %.2f KiB/s
stats.write.throughput.mibs=Zápis: %.2f MiB/s
stats.write.total.data.none=Čítanie dát: -
stats.write.total.data.none=štatistika.zápis.celkové.dáta.nič
stats.write.total.data.kib=Zapísaných dát: %.1f kiB
stats.write.total.data.mib=Zapísaných dát: %.1f MiB
stats.write.total.data.gib=Zapísaných dát: %.1f GiB
@@ -170,7 +170,9 @@ main.preferencesBtn.tooltip=Predvoľby
main.debugModeEnabled.tooltip=Debagovací mód je aktivovaný
## Drag 'n' Drop
## Vault List
main.vaultlist.contextMenu.remove=Odstrániť peňaženku…
main.vaultlist.contextMenu.lock=Uzamknúť
main.vaultlist.contextMenu.unlock=Odomknúť…
main.vaultlist.contextMenu.unlockNow=Odomknúť teraz
main.vaultlist.addVaultBtn=Pridať trezor
## Vault Detail
### Welcome
@@ -0,0 +1,75 @@
# Locale Specific CSS files such as CJK, RTL,...
# Generics
## Button
## Error
# Defaults
# Tray Menu
# Add Vault Wizard
## Welcome
## New
### Name
### Location
### Password
### Information
## Existing
## Success
# Remove Vault
# Change Password
# Forget Password
# Unlock
## Success
## Failure
### Invalid Mount Point
# Lock
## Force
## Failure
# Migration
## Start
## Run
## Sucess
## Missing file system capabilities
## Impossible
# Preferences
## General
## Volume
## Updates
## Donation Key
## About
# Vault Statistics
## Read
## Write
# Main Window
## Drag 'n' Drop
## Vault List
## Vault Detail
### Welcome
### Locked
### Unlocked
### Missing
### Needs Migration
# Wrong File Alert
# Vault Options
## General
## Mount
## Master Key
# Recovery Key
# New Password
# Quit
@@ -14,7 +14,7 @@ generic.button.next=Nästa
generic.button.print=Skriv ut
## Error
generic.error.title=Ett oväntat fel uppstod
generic.error.instruction=Det här borde inte ha hänt. Vänligen rapportera feltexten nedan och inkludera en beskrivning av vilka steg som ledde till detta fel.
generic.error.instruction=Detta borde inte hänt. Vänligen rapportera feltexten nedan och inkludera en beskrivning av vilka steg som ledde till detta fel.
# Defaults
defaults.vault.vaultName=Valv
@@ -56,7 +56,7 @@ addvaultwizard.new.generateRecoveryKeyChoice.no=Nej tack. Här slarvas inga lös
addvault.new.readme.storageLocation.fileName=VIKTIGT.rtf
addvault.new.readme.storageLocation.1=⚠️ VALVFILER ⚠️
addvault.new.readme.storageLocation.2=Detta är ditt valvs lagringsplats.
addvault.new.readme.storageLocation.3=INTE
addvault.new.readme.storageLocation.3=DU SKA INTE
addvault.new.readme.storageLocation.4=• ändra någon fil i denna katalog eller
addvault.new.readme.storageLocation.5=• klistra in filer för kryptering i denna katalog.
addvault.new.readme.storageLocation.6=Om du vill kryptera filer och se innehållet i valvet, gör följande:
@@ -74,7 +74,7 @@ addvaultwizard.existing.instruction=Välj "masterkey.cryptomator" för ditt befi
addvaultwizard.existing.chooseBtn=Välj…
addvaultwizard.existing.filePickerTitle=Välj Masterkey-fil
## Success
addvaultwizard.success.nextStepsInstructions=Lade till valv "%s".\nDu behöver låsa upp detta valv för att komma åt eller lägga till innehåll. Du kan även låsa upp det vid ett senare tillfälle.
addvaultwizard.success.nextStepsInstructions=Lade till valv "%s".\nDu måste låsa upp detta valv för att komma åt eller lägga till innehåll. Du kan även låsa upp det vid ett senare tillfälle.
addvaultwizard.success.unlockNow=Lås upp nu
# Remove Vault
@@ -95,12 +95,11 @@ forgetPassword.confirmBtn=Glöm lösenord
# Unlock
unlock.title=Lås upp valv
unlock.passwordPrompt=Ange lösenord för "%s":
unlock.savePassword=Spara lösenord
unlock.savePassword=Kom ihåg lösenord
unlock.unlockBtn=Lås upp
## Success
unlock.success.message="%s" upplåst! Ditt valv är nu åtkomligt.
unlock.success.rememberChoice=Kom ihåg valet, visa inte detta igen
unlock.success.revealBtn=Visa valv
unlock.success.revealBtn=Visa enhet
## Failure
unlock.error.heading=Kan inte låsa upp valvet
### Invalid Mount Point
@@ -109,7 +108,12 @@ unlock.error.invalidMountPoint.existing=Monteringspunkten "%s" finns redan eller
# Lock
## Force
lock.forced.heading=Normal låsning misslyckades
lock.forced.message=Låsning av "%s" förhindras av pågående operationer eller öppna filer. Du kan tvinga låsning av detta valv, men det kan resultera i förlust av osparade data.
lock.forced.confirmBtn=Tvinga låsning
## Failure
lock.fail.heading=Låsning av valv misslyckades.
lock.fail.message=Valvet "%s" kunde inte låsas. Se till att osparat arbete sparas någon annanstans och viktiga läs- och skrivfunktioner är klara. För att stänga valvet, avsluta Cryptomator-processen.
# Migration
migration.title=Uppgradera valv
@@ -121,7 +125,7 @@ migration.run.enterPassword=Ange lösenordet för "%s"
migration.run.startMigrationBtn=Migrera valv
migration.run.progressHint=Detta kan ta lite tid…
## Sucess
migration.success.nextStepsInstructions="%s" migrerades fullständigt.\nDu kan nu låsa upp ditt valv.
migration.success.nextStepsInstructions="%s" migrerades korrekt.\nDu kan nu låsa upp ditt valv.
migration.success.unlockNow=Lås upp nu
## Missing file system capabilities
migration.error.missingFileSystemCapabilities.title=Filsystemet stöds ej
@@ -132,7 +136,7 @@ migration.error.missingFileSystemCapabilities.reason.READ_ACCESS=Filsystemet til
migration.error.missingFileSystemCapabilities.reason.WRITE_ACCESS=Filsystemet tillåter inte att skrivas till.
## Impossible
migration.impossible.heading=Kan inte migrera valv
migration.impossible.reason=Valvet kan inte migreras automatiskt eftersom dess lagringsplats eller åtkomstpunkt inte är kompatibel.
migration.impossible.reason=Valvet kan inte migreras automatiskt eftersom dess lagringsplats eller åtkomstpunkt inte är kompatibelt.
migration.impossible.moreInfo=Valvet kan fortfarande öppnas med en äldre version. För instruktioner om hur du manuellt migrerar ett valv, besök
# Preferences
@@ -144,6 +148,8 @@ preferences.general.theme.automatic=Automatiskt
preferences.general.theme.light=Ljust
preferences.general.theme.dark=Mörkt
preferences.general.unlockThemes=Lås upp mörkt läge
preferences.general.showMinimizeButton=Visa minimera-knappen
preferences.general.showTrayIcon=Visa ikon i aktivitetsfältet (kräver omstart)
preferences.general.startHidden=Dölj fönster när Cryptomator startar
preferences.general.debugLogging=Aktivera loggning för felsökning
preferences.general.debugDirectory=Visa loggfiler
@@ -164,7 +170,7 @@ preferences.volume.webdav.scheme=WebDAV Schema
## Updates
preferences.updates=Uppdateringar
preferences.updates.currentVersion=Nuvarande version: %s
preferences.updates.autoUpdateCheck=Kontrollera uppdateringar automatiskt
preferences.updates.autoUpdateCheck=Sök efter uppdateringar automatiskt
preferences.updates.checkNowBtn=Kontrollera nu
preferences.updates.updateAvailable=Uppdatering till version %s finns tillgänglig.
## Donation Key
@@ -195,7 +201,7 @@ stats.read.accessCount=Totalt läst: %d
stats.write.throughput.idle=Skriv: inaktiv
stats.write.throughput.kibs=Skriv: %.2f kiB/s
stats.write.throughput.mibs=Skriv: %.2f MiB/s
stats.write.total.data.none=Data läst: -
stats.write.total.data.none=Data skrivet: -
stats.write.total.data.kib=Data skrivet: %.1f kiB
stats.write.total.data.mib=Data skrivet: %.1f MiB
stats.write.total.data.gib=Data skrivet: %.1f GiB
@@ -216,11 +222,14 @@ main.dropZone.dropVault=Lägg till detta valv
main.dropZone.unknownDragboardContent=Om du vill lägga till ett valv, dra in det till detta fönster
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Klicka här för att lägga till valv
main.vaultlist.contextMenu.remove=Ta bort valv…
main.vaultlist.contextMenu.lock=Lås
main.vaultlist.contextMenu.unlock=Lås upp…
main.vaultlist.contextMenu.unlockNow=Lås upp nu
main.vaultlist.contextMenu.reveal=Visa enhet
main.vaultlist.addVaultBtn=Lägg till valv
## Vault Detail
### Welcome
main.vaultDetail.welcomeOnboarding=Tack för att du väljer Cryptomator för att skydda dina filer. Om du behöver hjälp, kolla in våra kom-gång guider:
main.vaultDetail.welcomeOnboarding=Tack för att du väljer Cryptomator för att skydda dina filer. Om du behöver hjälp kan du kolla in våra guider:
### Locked
main.vaultDetail.lockedStatus=LÅST
main.vaultDetail.unlockBtn=Lås upp…
@@ -239,7 +248,7 @@ main.vaultDetail.throughput.kbps=%.1f kiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Valv Statistik
### Missing
main.vaultDetail.missing.info=Cryptomator kunde inte hitta ett valv i denna sökväg.
main.vaultDetail.missing.info=Cryptomator kunde inte hitta någt valv i denna sökväg.
main.vaultDetail.missing.recheck=Kontrollera igen
main.vaultDetail.missing.remove=Ta bort från listan…
main.vaultDetail.missing.changeLocation=Ändra valvets plats…
@@ -95,12 +95,12 @@ forgetPassword.confirmBtn=Şifreyi Unut
# Unlock
unlock.title=Kasa Kilidini Aç
unlock.passwordPrompt="%s" için şifre girin:
unlock.savePassword=Şifreyi Kaydet
unlock.savePassword=Şifreyi Hatırla
unlock.unlockBtn=Kilidi Aç
## Success
unlock.success.message="%s" 'nin kilidi başarıyla açıldı! Kasanız şimdi erişilebilir durumda.
unlock.success.message="%s" 'nin kilidi başarıyla açıldı! Kasanız şimdi sanal sürücüsü ile erişilebilir durumda.
unlock.success.rememberChoice=Seçimi hatırla, bunu bir daha gösterme
unlock.success.revealBtn=Kasayı Göster
unlock.success.revealBtn=Sürücüyü Göster
## Failure
unlock.error.heading=Kasanın kilidi açılamıyor
### Invalid Mount Point
@@ -202,7 +202,7 @@ stats.read.accessCount=Toplam okuma: %d
stats.write.throughput.idle=Yazma: boşta
stats.write.throughput.kibs=Yazma: %.2f kB/s
stats.write.throughput.mibs=Yazma: %.2f MB/s
stats.write.total.data.none=Yazılan veri: -
stats.write.total.data.none=Yazılmış veri: -
stats.write.total.data.kib=Yazılan veri: %.1f kB
stats.write.total.data.mib=Yazılan veri: %.1f MB
stats.write.total.data.gib=Yazılan veri: %.1f GB
@@ -223,7 +223,12 @@ main.dropZone.dropVault=Bu kasayı ekle
main.dropZone.unknownDragboardContent=Bir kasa eklemek istiyorsanız, onu bu pencereye sürükleyin
## Vault List
main.vaultlist.emptyList.onboardingInstruction=Kasa eklemek için buraya tıklayın
main.vaultlist.contextMenu.remove=Kasayı Sil
main.vaultlist.contextMenu.remove=Kaldır
main.vaultlist.contextMenu.lock=Kilitle
main.vaultlist.contextMenu.unlock=Kilit aç…
main.vaultlist.contextMenu.unlockNow=Kilidi Şimdi Aç
main.vaultlist.contextMenu.vaultoptions=Kasa Ayarları'nı Göster
main.vaultlist.contextMenu.reveal=Sürücüyü Göster
main.vaultlist.addVaultBtn=Kasa Ekle
## Vault Detail
### Welcome
@@ -98,9 +98,8 @@ unlock.passwordPrompt=输入 "%s" 的密码
unlock.savePassword=记住密码
unlock.unlockBtn=解锁
## Success
unlock.success.message=已成功解锁 "%s"! 您现在可以访问该保险库
unlock.success.rememberChoice=记住选项且不再显示
unlock.success.revealBtn=显示保险库
unlock.success.revealBtn=显示驱动器
## Failure
unlock.error.heading=无法解锁保险库
### Invalid Mount Point
@@ -202,7 +201,7 @@ stats.read.accessCount=读取总数:%d
stats.write.throughput.idle=写入:空闲
stats.write.throughput.kibs=写入:%.2f kiB/s
stats.write.throughput.mibs=写入:%.2f MiB/s
stats.write.total.data.none=读取数据:-
stats.write.total.data.none=写入数据: -
stats.write.total.data.kib=已写入数据:%.1f kiB
stats.write.total.data.mib=已写入数据:%.1f MiB
stats.write.total.data.gib=已写入数据:%.1f GiB
@@ -223,7 +222,10 @@ main.dropZone.dropVault=添加此保险库
main.dropZone.unknownDragboardContent=如果您想要添加一个保险库,将其拖动到此窗口
## Vault List
main.vaultlist.emptyList.onboardingInstruction=点击此处添加一个保险库
main.vaultlist.contextMenu.remove=删除保险库…
main.vaultlist.contextMenu.lock=锁定
main.vaultlist.contextMenu.unlock=解锁…
main.vaultlist.contextMenu.unlockNow=立即解锁
main.vaultlist.contextMenu.reveal=显示驱动器
main.vaultlist.addVaultBtn=添加保险库
## Vault Detail
### Welcome

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