Compare commits

...
37 Commits
Author SHA1 Message Date
Armin Schrenk 24839985e9 Merge branch 'develop' into release/1.7.0 2023-02-14 11:40:10 +01:00
Armin Schrenk a7b2802f34 show correct error message when using custom mountpoint with webdav (Http address) 2023-02-14 11:39:16 +01:00
Armin Schrenk c85d0b4beb bump webdav-nio-adapter 2023-02-14 11:22:11 +01:00
Armin Schrenk 3dff3a8664 Fixes #2682
* allow windows installer to remove same version
* add revisionNumber to installer version
2023-02-14 11:20:22 +01:00
Armin Schrenk 5b0bbf539b improve FailOnRunningApp action 2023-02-13 23:34:43 +01:00
Armin Schrenk 1ff7c40fd9 Fixes #2672 and fixes #2668 2023-02-13 10:42:17 +01:00
Armin SchrenkandGitHub d0875ef49e Merge pull request #2669 from cryptomator/feature/virtual-volume-doc-link
Add link to volume type documentation
2023-02-09 13:06:03 +01:00
Armin Schrenk e35ed9af72 enable localization of tooltip 2023-02-08 20:11:34 +01:00
Armin Schrenk ac43efe149 change UI to be not so clunky:
* only use question mark icon
* use tooltip at icon instead of explicit label
* icon is the hyperlink
2023-02-08 11:33:41 +01:00
Armin Schrenk 202a2ea79f Load revealPathServiceProvider at app startup 2023-02-08 11:14:54 +01:00
Armin Schrenk c19a86a348 add link to mounting documentation 2023-02-07 15:23:04 +01:00
Armin Schrenk 539dcaa85a Update issue template 2023-02-07 12:23:25 +01:00
Armin Schrenk fb91c1a461 Merge branch 'develop' into release/1.7.0 2023-02-06 14:45:56 +01:00
CryptobotandGitHub bd75370dfd New Crowdin updates (#2646)
New translations strings.properties

Catalan; Chinese Simplified; Dutch; Italian; Persian; Polish; Slovak;

[ci skip]
2023-02-06 14:44:45 +01:00
Armin Schrenk 7a9a9cf4eb Follow up of 69d73d0fb9: Remove standalone launchers 2023-02-06 12:31:56 +01:00
Armin Schrenk 489e9fce90 bump integrations-win to 1.2.0-beta2
Closes #2657
2023-02-03 13:19:53 +01:00
Armin Schrenk d378d84832 bump fuse-nio-adapter 2023-02-03 13:19:43 +01:00
Armin Schrenk 69d73d0fb9 Remove standalone launchers 2023-02-03 13:15:03 +01:00
Armin Schrenk 97c0cb4f5f add to settings.json the app version written to it last 2023-02-02 16:44:03 +01:00
Armin Schrenk b4faae7fa0 make debug logs readable by filter out internal fuse-nio locking 2023-02-02 10:36:31 +01:00
Armin Schrenk 55d76b65cc Add IOException to log message during revealPath 2023-02-01 22:31:27 +01:00
Armin Schrenk fd6e1e6741 fix bug 2023-02-01 19:23:28 +01:00
Armin Schrenk 155558caa8 add style class to text object 2023-02-01 13:50:56 +01:00
Armin Schrenk 28217b2de3 only perform mountpoint move and cleanup, if mountpoint is not a drive letter 2023-02-01 13:44:57 +01:00
Armin SchrenkandGitHub b9e57ce895 Merge pull request #2654 from cryptomator/feature/2652-migrate-dir-mounts
Feature/2652 migrate dir mounts
2023-02-01 11:17:11 +01:00
Armin Schrenk 95ea23ee6e add more comments regarding removal evaluation of this workaround 2023-02-01 11:07:23 +01:00
Armin Schrenk c269184217 ensure that settings.json is a file 2023-01-31 18:05:31 +01:00
Armin Schrenk 68d32957e4 fix errors 2023-01-31 16:37:25 +01:00
Armin Schrenk a771f0a5b7 doc doc doc 2023-01-31 13:59:18 +01:00
Armin Schrenk e56e6a8359 integrate script into installer 2023-01-31 13:58:56 +01:00
Armin Schrenk 5f9b77241f extend migration script to all local users 2023-01-31 13:40:25 +01:00
Armin Schrenk fb54ee04a6 Remove Dokany advertisement from msi installer 2023-01-30 13:32:56 +01:00
Armin Schrenk a106b04c7e prototpye for powershell script to be executed after installation 2023-01-30 13:30:06 +01:00
Armin Schrenk 285d48b70b Merge branch 'develop' into release/1.7.0 2023-01-27 13:27:31 +01:00
Armin Schrenk 0d8d7e4ee5 fix debian artifact upload 2023-01-27 13:27:03 +01:00
Armin Schrenk f232f9d958 Merge branch 'develop' into release/1.7.0 2023-01-27 12:31:00 +01:00
Armin Schrenk 88c3b0cc4f remove tag-name from release action to just add to current release on debian build 2023-01-27 12:30:44 +01:00
31 changed files with 263 additions and 106 deletions
+12 -7
View File
@@ -37,14 +37,19 @@ body:
id: volume-type id: volume-type
attributes: attributes:
label: Volume Type label: Volume Type
description: What is selected under Settings → Virtual Drive? description: What volume type is selected under Settings → Virtual Drive?
multiple: true value: |
options: - WinFsp
- FUSE - WinFsp (Local Drive)
- Dokany - FUSE-T
- WebDAV - macFUSE
- WebDAV (Windows Explorer)
- WebDAV (AppleScript)
- WebDAV (gio)
- WebDAV (HTTP Address)
- Dokany (1.5)
validations: validations:
required: false required: true
- type: textarea - type: textarea
id: reproduction-steps id: reproduction-steps
attributes: attributes:
-1
View File
@@ -47,7 +47,6 @@ jobs:
- name: Patch target dir - name: Patch target dir
run: | run: |
cp LICENSE.txt target cp LICENSE.txt target
cp dist/linux/launcher.sh target
cp target/cryptomator-*.jar target/mods cp target/cryptomator-*.jar target/mods
- name: Run jlink - name: Run jlink
run: > run: >
+5 -8
View File
@@ -148,11 +148,8 @@ jobs:
echo "TAG_NAME=${REF##*/}" >> $GITHUB_ENV echo "TAG_NAME=${REF##*/}" >> $GITHUB_ENV
- name: Publish Debian package on GitHub Releases - name: Publish Debian package on GitHub Releases
if: startsWith(inputs.ref, 'refs/tags/') if: startsWith(inputs.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1 env:
with: GITHUB_TOKEN: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }}
fail_on_unmatched_files: true run: |
tag_name: ${{ inputs.ref }} artifacts=$(ls | grep cryptomator*.deb)
token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} gh release upload ${{ env.TAG_NAME }} $artifacts
files: |
cryptomator_*_amd64.deb
cryptomator_*.asc
-1
View File
@@ -61,7 +61,6 @@ jobs:
- name: Patch target dir - name: Patch target dir
run: | run: |
cp LICENSE.txt target cp LICENSE.txt target
cp dist/mac/launcher.sh target
cp target/cryptomator-*.jar target/mods cp target/cryptomator-*.jar target/mods
- name: Run jlink - name: Run jlink
run: > run: >
+1 -2
View File
@@ -55,7 +55,6 @@ jobs:
- name: Patch target dir - name: Patch target dir
run: | run: |
cp LICENSE.txt target cp LICENSE.txt target
cp dist/linux/launcher.sh target
cp target/cryptomator-*.jar target/mods cp target/cryptomator-*.jar target/mods
- name: Run jlink - name: Run jlink
run: > run: >
@@ -157,7 +156,7 @@ jobs:
--name Cryptomator --name Cryptomator
--vendor "Skymatic GmbH" --vendor "Skymatic GmbH"
--copyright "(C) 2016 - 2023 Skymatic GmbH" --copyright "(C) 2016 - 2023 Skymatic GmbH"
--app-version "${{ needs.get-version.outputs.semVerNum }}" --app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
--win-menu --win-menu
--win-dir-chooser --win-dir-chooser
--win-shortcut-prompt --win-shortcut-prompt
-15
View File
@@ -1,15 +0,0 @@
#!/bin/sh
cd $(dirname $0)
java \
-p "mods" \
-cp "libs/*" \
-Dcryptomator.settingsPath="~/.config/Cryptomator/settings.json" \
-Dcryptomator.ipcSocketPath="~/.config/Cryptomator/ipc.socket" \
-Dcryptomator.logDir="~/.local/share/Cryptomator/logs" \
-Dcryptomator.mountPointsDir="~/.local/share/Cryptomator/mnt" \
-Djdk.gtk.version=2 \
-Xss2m \
-Xmx512m \
--enable-preview \
--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64 \
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
cd $(dirname $0)
java \
-p "mods" \
-cp "libs/*" \
-Dcryptomator.settingsPath="~/Library/Application Support/Cryptomator/settings.json" \
-Dcryptomator.ipcSocketPath="~/Library/Application Support/Cryptomator/ipc.socket" \
-Dcryptomator.logDir="~/Library/Logs/Cryptomator" \
-Dcryptomator.mountPointsDir="/Volumes" \
-Xss20m \
-Xmx512m \
--enable-preview \
--enable-native-access=org.cryptomator.jfuse.mac \
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+1 -1
View File
@@ -129,7 +129,7 @@ $Env:JP_WIXWIZARD_RESOURCES = "$buildDir\resources"
--name $AppName ` --name $AppName `
--vendor $Vendor ` --vendor $Vendor `
--copyright $copyright ` --copyright $copyright `
--app-version "$semVerNo" ` --app-version "$semVerNo.$revisionNo" `
--win-menu ` --win-menu `
--win-dir-chooser ` --win-dir-chooser `
--win-shortcut-prompt ` --win-shortcut-prompt `
-12
View File
@@ -1,12 +0,0 @@
@echo off
java ^
-p "app/mods" ^
-cp "app/*" ^
-Dcryptomator.settingsPath="~/AppData/Roaming/Cryptomator/settings.json" ^
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
-Xss20m ^
-Xmx512m ^
-m org.cryptomator.desktop/org.cryptomator.launcher.Cryptomator
+5
View File
@@ -0,0 +1,5 @@
@echo off
:: see comments in file ./version170-migrate-settings.ps1
cd %~dp0
powershell -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -Command .\version170-migrate-settings.ps1
+45
View File
@@ -0,0 +1,45 @@
# This script migrates Cryptomator settings for all local users on Windows in case the users uses custom directories as mountpoint
# See also https://github.com/cryptomator/cryptomator/pull/2654.
#
# TODO: This script should be evaluated in a yearly interval if it is still needed and if not, should be removed
#
#Requires -RunAsAdministrator
#Get all active, local user profiles
$profileList = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList'
$localUsers = Get-LocalUser | Where-Object {$_.Enabled} | ForEach-Object { $_.Name}
Get-ChildItem $profileList | ForEach-Object { $_.GetValue("ProfileImagePath") } | Where-Object {
$profileNameMatches = ($_ | Select-String -Pattern "\\([^\\]+)$").Matches
if($profileNameMatches.Count -eq 1) {
#check if the last path part is contained in the local user name list
#otherwise do not touch it
return $localUsers.Contains($profileNameMatches[0].Groups[1].Value)
} else {
return $false;
}
} | ForEach-Object {
$settingsPath = "$_\AppData\Roaming\Cryptomator\settings.json"
if(!(Test-Path -Path $settingsPath -PathType Leaf)) {
#No settings file, nothing to do.
return;
}
$settings = Get-Content -Path $settingsPath | ConvertFrom-Json
if($settings.preferredVolumeImpl -ne "FUSE") {
#Fuse not used, nothing to do
return;
}
#check if customMountPoints are used
$atLeastOneCustomPath = $false;
foreach ($vault in $settings.directories){
$atLeastOneCustomPath = $atLeastOneCustomPath -or ($vault.useCustomMountPath -eq "True")
}
#if so, use WinFsp Local Drive
if( $atLeastOneCustomPath ) {
Add-Member -Force -InputObject $settings -Name "mountService" -Value "org.cryptomator.frontend.fuse.mount.WinFspMountProvider" -MemberType NoteProperty
$newSettings = $settings | Select-Object * -ExcludeProperty "preferredVolumeImpl"
ConvertTo-Json $newSettings | Set-Content -Path $settingsPath
}
}
+2 -5
View File
@@ -65,13 +65,10 @@
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogTitle)" /> <Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogTitle)" />
<!-- TODO: localize? --> <!-- TODO: localize? -->
<Control Id="Suggestion" Type="Text" X="135" Y="100" Width="220" Height="60" Transparent="yes" NoPrefix="yes"> <Control Id="Suggestion" Type="Text" X="135" Y="100" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
<Text>We recommend for the best user experience to download and install one of the following third party Windows drivers:</Text> <Text>We recommend for the best user experience to download and install the following third party Windows driver:</Text>
</Control> </Control>
<Control Id="WinFsp" Type="Hyperlink" X="140" Y="125" Width="220" Height="60" Transparent="yes"> <Control Id="WinFsp" Type="Hyperlink" X="140" Y="125" Width="220" Height="60" Transparent="yes">
<Text><![CDATA[WinFsp (<a href="http://www.secfs.net/winfsp/rel/">Homepage</a>)]]></Text> <Text><![CDATA[WinFsp (<a href="https://winfsp.dev/">Homepage</a>)]]></Text>
</Control>
<Control Id="Dokany" Type="Hyperlink" X="140" Y="137" Width="220" Height="60" Transparent="yes">
<Text><![CDATA[• Dokany (<a href="https://dokan-dev.github.io/">Homepage</a>)]]></Text>
</Control> </Control>
</Dialog> </Dialog>
+8 -4
View File
@@ -54,7 +54,7 @@
Property="JP_UPGRADABLE_FOUND" Property="JP_UPGRADABLE_FOUND"
Maximum="$(var.JpAppVersion)" Maximum="$(var.JpAppVersion)"
MigrateFeatures="yes" MigrateFeatures="yes"
IncludeMaximum="$(var.JpUpgradeVersionOnlyDetectUpgrade)" /> IncludeMaximum="yes" /> <!-- TODO: check if this needs to be set to yes-->
<UpgradeVersion <UpgradeVersion
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)" OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
Property="JP_DOWNGRADABLE_FOUND" Property="JP_DOWNGRADABLE_FOUND"
@@ -132,6 +132,9 @@
<!-- WebDAV patches --> <!-- WebDAV patches -->
<CustomAction Id="PatchWebDAV" Impersonate="no" ExeCommand="[INSTALLDIR]patchWebDAV.bat" Directory="INSTALLDIR" Execute="deferred" Return="asyncWait" /> <CustomAction Id="PatchWebDAV" Impersonate="no" ExeCommand="[INSTALLDIR]patchWebDAV.bat" Directory="INSTALLDIR" Execute="deferred" Return="asyncWait" />
<!-- Special Settings migration for 1.7.0,. Should be removed eventually, for more info, see ../contrib/version170-migrate-settings.ps1-->
<CustomAction Id="V170MigrateSettings" Impersonate="no" ExeCommand="[INSTALLDIR]version170-migrate-settings.bat" Directory="INSTALLDIR" Execute="deferred" Return="asyncWait" />
<!-- Running App detection and exit --> <!-- Running App detection and exit -->
<Property Id="FOUNDRUNNINGAPP" Admin="yes"/> <Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
<util:CloseApplication <util:CloseApplication
@@ -140,11 +143,11 @@
CloseMessage="no" CloseMessage="no"
RebootPrompt="no" RebootPrompt="no"
PromptToContinue="yes" PromptToContinue="yes"
Description="A running instance of $(var.JpAppName) is found. Please close it to continue." Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
Property="FOUNDRUNNINGAPP" Property="FOUNDRUNNINGAPP"
> >
</util:CloseApplication> </util:CloseApplication>
<CustomAction Id="FailOnRunningApp" Impersonate="no" ExeCommand="[SystemFolder]\cmd.exe /c &quot;exit 1&quot;" Directory="INSTALLDIR" Execute="immediate" Return="check" /> <CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
<?ifdef JpIcon ?> <?ifdef JpIcon ?>
<Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/> <Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
@@ -179,9 +182,10 @@
<Custom Action="WixCloseApplications" Before="InstallValidate"></Custom> <Custom Action="WixCloseApplications" Before="InstallValidate"></Custom>
<Custom Action="FailOnRunningApp" After="WixCloseApplications" >FOUNDRUNNINGAPP</Custom> <Custom Action="FailOnRunningApp" After="WixCloseApplications" >FOUNDRUNNINGAPP</Custom>
<RemoveExistingProducts After="InstallValidate"/> <RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to WixCloseApplications -->
<Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom> <Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
<Custom Action="V170MigrateSettings" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
</InstallExecuteSequence> </InstallExecuteSequence>
<WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" /> <WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
+4 -4
View File
@@ -31,12 +31,12 @@
<cryptomator.cryptolib.version>2.1.1</cryptomator.cryptolib.version> <cryptomator.cryptolib.version>2.1.1</cryptomator.cryptolib.version>
<cryptomator.cryptofs.version>2.6.1</cryptomator.cryptofs.version> <cryptomator.cryptofs.version>2.6.1</cryptomator.cryptofs.version>
<cryptomator.integrations.version>1.2.0-beta4</cryptomator.integrations.version> <cryptomator.integrations.version>1.2.0-beta4</cryptomator.integrations.version>
<cryptomator.integrations.win.version>1.2.0-beta1</cryptomator.integrations.win.version> <cryptomator.integrations.win.version>1.2.0-beta3</cryptomator.integrations.win.version>
<cryptomator.integrations.mac.version>1.2.0-beta2</cryptomator.integrations.mac.version> <cryptomator.integrations.mac.version>1.2.0-beta2</cryptomator.integrations.mac.version>
<cryptomator.integrations.linux.version>1.2.0-beta1</cryptomator.integrations.linux.version> <cryptomator.integrations.linux.version>1.2.0-beta2</cryptomator.integrations.linux.version>
<cryptomator.fuse.version>2.0.0-beta4</cryptomator.fuse.version> <cryptomator.fuse.version>2.0.0-beta5</cryptomator.fuse.version>
<cryptomator.dokany.version>2.0.0-beta2</cryptomator.dokany.version> <cryptomator.dokany.version>2.0.0-beta2</cryptomator.dokany.version>
<cryptomator.webdav.version>2.0.0-beta4</cryptomator.webdav.version> <cryptomator.webdav.version>2.0.0-beta5</cryptomator.webdav.version>
<!-- 3rd party dependencies --> <!-- 3rd party dependencies -->
<commons-lang3.version>3.12.0</commons-lang3.version> <commons-lang3.version>3.12.0</commons-lang3.version>
@@ -16,6 +16,7 @@ import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.common.vaults.VaultComponent; import org.cryptomator.common.vaults.VaultComponent;
import org.cryptomator.common.vaults.VaultListModule; import org.cryptomator.common.vaults.VaultListModule;
import org.cryptomator.cryptolib.common.MasterkeyFileAccess; import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
import org.cryptomator.integrations.revealpath.RevealPathService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -26,6 +27,7 @@ import java.net.InetSocketAddress;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Comparator; import java.util.Comparator;
import java.util.Optional;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue; import java.util.concurrent.SynchronousQueue;
@@ -83,6 +85,13 @@ public abstract class CommonsModule {
return new SemVerComparator(); return new SemVerComparator();
} }
@Provides
@Singleton
static Optional<RevealPathService> provideRevealPathService() {
return RevealPathService.get().findFirst();
}
@Provides @Provides
@Singleton @Singleton
static Settings provideSettings(SettingsProvider settingsProvider) { static Settings provideSettings(SettingsProvider settingsProvider) {
@@ -14,7 +14,6 @@ import javafx.beans.value.ObservableValue;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Objects;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_AS_DRIVE_LETTER; import static org.cryptomator.integrations.mount.MountCapability.MOUNT_AS_DRIVE_LETTER;
import static org.cryptomator.integrations.mount.MountCapability.MOUNT_TO_EXISTING_DIR; import static org.cryptomator.integrations.mount.MountCapability.MOUNT_TO_EXISTING_DIR;
@@ -60,7 +59,7 @@ public class Mounter {
case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode().get()); case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode().get());
case MOUNT_FLAGS -> { case MOUNT_FLAGS -> {
var mountFlags = vaultSettings.mountFlags().get(); var mountFlags = vaultSettings.mountFlags().get();
if( mountFlags == null || mountFlags.isBlank()) { if (mountFlags == null || mountFlags.isBlank()) {
builder.setMountFlags(service.getDefaultMountFlags()); builder.setMountFlags(service.getDefaultMountFlags());
} else { } else {
builder.setMountFlags(mountFlags); builder.setMountFlags(mountFlags);
@@ -81,9 +80,10 @@ public class Mounter {
var canMountToDriveLetter = service.hasCapability(MOUNT_AS_DRIVE_LETTER); var canMountToDriveLetter = service.hasCapability(MOUNT_AS_DRIVE_LETTER);
var canMountToParent = service.hasCapability(MOUNT_WITHIN_EXISTING_PARENT); var canMountToParent = service.hasCapability(MOUNT_WITHIN_EXISTING_PARENT);
var canMountToDir = service.hasCapability(MOUNT_TO_EXISTING_DIR); var canMountToDir = service.hasCapability(MOUNT_TO_EXISTING_DIR);
var canMountToSystem = service.hasCapability(MOUNT_TO_SYSTEM_CHOSEN_PATH);
if (userChosenMountPoint == null) { if (userChosenMountPoint == null) {
if (service.hasCapability(MOUNT_TO_SYSTEM_CHOSEN_PATH)) { if (canMountToSystem) {
// no need to set a mount point // no need to set a mount point
} else if (canMountToDriveLetter) { } else if (canMountToDriveLetter) {
builder.setMountpoint(driveLetters.getFirstDesiredAvailable().orElseThrow()); //TODO: catch exception and translate builder.setMountpoint(driveLetters.getFirstDesiredAvailable().orElseThrow()); //TODO: catch exception and translate
@@ -96,7 +96,8 @@ public class Mounter {
builder.setMountpoint(mountPoint); builder.setMountpoint(mountPoint);
} }
} else { } else {
if (canMountToParent && !canMountToDir) { var mpIsDriveLetter = userChosenMountPoint.toString().matches("[A-Z]:\\\\");
if (!mpIsDriveLetter && canMountToParent && !canMountToDir) {
MountWithinParentUtil.prepareParentNoMountPoint(userChosenMountPoint); MountWithinParentUtil.prepareParentNoMountPoint(userChosenMountPoint);
cleanup = () -> { cleanup = () -> {
MountWithinParentUtil.cleanup(userChosenMountPoint); MountWithinParentUtil.cleanup(userChosenMountPoint);
@@ -104,9 +105,11 @@ public class Mounter {
} }
try { try {
builder.setMountpoint(userChosenMountPoint); builder.setMountpoint(userChosenMountPoint);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException | UnsupportedOperationException e) {
var mpIsDriveLetter = userChosenMountPoint.toString().matches("[A-Z]:\\\\"); var configNotSupported = (!canMountToDriveLetter && mpIsDriveLetter) //mounting as driveletter, albeit not supported
var configNotSupported = (!canMountToDriveLetter && mpIsDriveLetter) || (!canMountToDir && !mpIsDriveLetter) || (!canMountToParent && !mpIsDriveLetter); || (!canMountToDir && !mpIsDriveLetter) //mounting to directory, albeit not supported
|| (!canMountToParent && !mpIsDriveLetter) //
|| (!canMountToDir && !canMountToParent && !canMountToSystem && !canMountToDriveLetter);
if (configNotSupported) { if (configNotSupported) {
throw new MountPointNotSupportedException(e.getMessage()); throw new MountPointNotSupportedException(e.getMessage());
} else if (canMountToDir && !canMountToParent && !Files.exists(userChosenMountPoint)) { } else if (canMountToDir && !canMountToParent && !Files.exists(userChosenMountPoint)) {
@@ -37,6 +37,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
@Override @Override
public void write(JsonWriter out, Settings value) throws IOException { public void write(JsonWriter out, Settings value) throws IOException {
out.beginObject(); out.beginObject();
out.name("lastWrittenByVersion").value(env.getAppVersion()+env.getBuildNumber().map("-"::concat).orElse(""));
out.name("directories"); out.name("directories");
writeVaultSettingsArray(out, value.getDirectories()); writeVaultSettingsArray(out, value.getDirectories());
out.name("askedForUpdateCheck").value(value.askedForUpdateCheck().get()); out.name("askedForUpdateCheck").value(value.askedForUpdateCheck().get());
@@ -84,6 +84,10 @@ public class LogbackConfigurator extends ContextAwareBase implements Configurato
upgrades.addAppender(upgrade); upgrades.addAppender(upgrade);
upgrades.addAppender(file); upgrades.addAppender(file);
upgrades.setAdditive(false); upgrades.setAdditive(false);
// configure fuse file locking logger:
Logger fuseLocking = context.getLogger("org.cryptomator.frontend.fuse.locks");
fuseLocking.setLevel(Level.OFF);
} }
return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY; return ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY;
} }
@@ -42,6 +42,7 @@ public enum FontAwesome5Icon {
PLUS("\uF067"), // PLUS("\uF067"), //
PRINT("\uF02F"), // PRINT("\uF02F"), //
QUESTION("\uF128"), // QUESTION("\uF128"), //
QUESTION_CIRCLE("\uf059"), //
REDO("\uF01E"), // REDO("\uF01E"), //
SEARCH("\uF002"), // SEARCH("\uF002"), //
SPINNER("\uF110"), // SPINNER("\uF110"), //
@@ -54,6 +54,7 @@ public class VaultDetailUnlockedController implements FxController {
private final VaultService vaultService; private final VaultService vaultService;
private final WrongFileAlertComponent.Builder wrongFileAlert; private final WrongFileAlertComponent.Builder wrongFileAlert;
private final Stage mainWindow; private final Stage mainWindow;
private final Optional<RevealPathService> revealPathService;
private final ResourceBundle resourceBundle; private final ResourceBundle resourceBundle;
private final LoadingCache<Vault, VaultStatisticsComponent> vaultStats; private final LoadingCache<Vault, VaultStatisticsComponent> vaultStats;
private final VaultStatisticsComponent.Builder vaultStatsBuilder; private final VaultStatisticsComponent.Builder vaultStatsBuilder;
@@ -67,12 +68,13 @@ public class VaultDetailUnlockedController implements FxController {
public Button dropZone; public Button dropZone;
@Inject @Inject
public VaultDetailUnlockedController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, VaultService vaultService, VaultStatisticsComponent.Builder vaultStatsBuilder, WrongFileAlertComponent.Builder wrongFileAlert, @MainWindow Stage mainWindow, ResourceBundle resourceBundle) { public VaultDetailUnlockedController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, VaultService vaultService, VaultStatisticsComponent.Builder vaultStatsBuilder, WrongFileAlertComponent.Builder wrongFileAlert, @MainWindow Stage mainWindow, Optional<RevealPathService> revealPathService, ResourceBundle resourceBundle) {
this.vault = vault; this.vault = vault;
this.appWindows = appWindows; this.appWindows = appWindows;
this.vaultService = vaultService; this.vaultService = vaultService;
this.wrongFileAlert = wrongFileAlert; this.wrongFileAlert = wrongFileAlert;
this.mainWindow = mainWindow; this.mainWindow = mainWindow;
this.revealPathService = revealPathService;
this.resourceBundle = resourceBundle; this.resourceBundle = resourceBundle;
this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats)); this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats));
this.vaultStatsBuilder = vaultStatsBuilder; this.vaultStatsBuilder = vaultStatsBuilder;
@@ -171,35 +173,27 @@ public class VaultDetailUnlockedController implements FxController {
} }
return Optional.of(vault.get().getCiphertextPath(cleartextPath)); return Optional.of(vault.get().getCiphertextPath(cleartextPath));
} catch (IOException e) { } catch (IOException e) {
LOG.warn("Unable to get ciphertext path from path: {}", path); LOG.warn("Unable to get ciphertext path from path: {}", path, e);
return Optional.empty(); return Optional.empty();
} }
} }
private void revealOrCopyPaths(List<Path> paths) { private void revealOrCopyPaths(List<Path> paths) {
if (!revealPaths(paths)) { revealPathService.ifPresentOrElse(svc -> revealPaths(svc, paths), () -> {
LOG.warn("No service provider to reveal files found."); LOG.warn("No service provider to reveal files found.");
copyPathsToClipboard(paths); copyPathsToClipboard(paths);
} });
} }
/** private void revealPaths(RevealPathService service, List<Path> paths) {
* Reveals the paths over the {@link RevealPathService} in the file system paths.forEach(path -> {
* try {
* @param paths List of Paths to reveal LOG.debug("Revealing {}", path);
* @return true, if at least one service provider was present, false otherwise service.reveal(path);
*/ } catch (RevealFailedException e) {
private boolean revealPaths(List<Path> paths) { LOG.error("Revealing ciphertext file failed.", e);
return RevealPathService.get().findAny().map(s -> { }
paths.forEach(path -> { });
try {
s.reveal(path);
} catch (RevealFailedException e) {
LOG.error("Revealing ciphertext file failed.", e);
}
});
return true;
}).orElse(false);
} }
private void copyPathsToClipboard(List<Path> paths) { private void copyPathsToClipboard(List<Path> paths) {
@@ -1,5 +1,6 @@
package org.cryptomator.ui.preferences; package org.cryptomator.ui.preferences;
import dagger.Lazy;
import org.cryptomator.common.ObservableUtil; import org.cryptomator.common.ObservableUtil;
import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.Settings;
import org.cryptomator.integrations.mount.MountCapability; import org.cryptomator.integrations.mount.MountCapability;
@@ -7,6 +8,7 @@ import org.cryptomator.integrations.mount.MountService;
import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxController;
import javax.inject.Inject; import javax.inject.Inject;
import javafx.application.Application;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanExpression; import javafx.beans.binding.BooleanExpression;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@@ -21,6 +23,8 @@ import java.util.ResourceBundle;
@PreferencesScoped @PreferencesScoped
public class VolumePreferencesController implements FxController { public class VolumePreferencesController implements FxController {
private static final String DOCS_MOUNTING_URL = "https://docs.cryptomator.org/en/1.7/desktop/vault-mounting/";
private final Settings settings; private final Settings settings;
private final ObservableValue<MountService> selectedMountService; private final ObservableValue<MountService> selectedMountService;
private final ResourceBundle resourceBundle; private final ResourceBundle resourceBundle;
@@ -29,14 +33,16 @@ public class VolumePreferencesController implements FxController {
private final ObservableValue<Boolean> mountToDriveLetterSupported; private final ObservableValue<Boolean> mountToDriveLetterSupported;
private final ObservableValue<Boolean> mountFlagsSupported; private final ObservableValue<Boolean> mountFlagsSupported;
private final ObservableValue<Boolean> readonlySupported; private final ObservableValue<Boolean> readonlySupported;
private final Lazy<Application> application;
private final List<MountService> mountProviders; private final List<MountService> mountProviders;
public ChoiceBox<MountService> volumeTypeChoiceBox; public ChoiceBox<MountService> volumeTypeChoiceBox;
public TextField loopbackPortField; public TextField loopbackPortField;
public Button loopbackPortApplyButton; public Button loopbackPortApplyButton;
@Inject @Inject
VolumePreferencesController(Settings settings, List<MountService> mountProviders, ResourceBundle resourceBundle) { VolumePreferencesController(Settings settings, Lazy<Application> application, List<MountService> mountProviders, ResourceBundle resourceBundle) {
this.settings = settings; this.settings = settings;
this.application = application;
this.mountProviders = mountProviders; this.mountProviders = mountProviders;
this.resourceBundle = resourceBundle; this.resourceBundle = resourceBundle;
@@ -141,4 +147,8 @@ public class VolumePreferencesController implements FxController {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }
public void openDocs() {
application.get().getHostServices().showDocument(DOCS_MOUNTING_URL);
}
} }
@@ -5,10 +5,12 @@
<?import javafx.geometry.Insets?> <?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?> <?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?> <?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?> <?import javafx.scene.control.Label?>
<?import javafx.scene.control.Separator?> <?import javafx.scene.control.Separator?>
<?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Tooltip?>
<VBox xmlns:fx="http://javafx.com/fxml" <VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx" xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.preferences.VolumePreferencesController" fx:controller="org.cryptomator.ui.preferences.VolumePreferencesController"
@@ -20,6 +22,14 @@
<HBox spacing="12" alignment="CENTER_LEFT"> <HBox spacing="12" alignment="CENTER_LEFT">
<Label text="%preferences.volume.type"/> <Label text="%preferences.volume.type"/>
<ChoiceBox fx:id="volumeTypeChoiceBox"/> <ChoiceBox fx:id="volumeTypeChoiceBox"/>
<Hyperlink contentDisplay="GRAPHIC_ONLY" onAction="#openDocs">
<graphic>
<FontAwesome5IconView glyph="QUESTION_CIRCLE" styleClass="glyph-icon-muted"/>
</graphic>
<tooltip>
<Tooltip text="%preferences.volume.docsTooltip" showDelay="100ms"/>
</tooltip>
</Hyperlink>
</HBox> </HBox>
<HBox spacing="12" alignment="CENTER_LEFT" visible="${controller.loopbackPortSupported}" managed="${controller.loopbackPortSupported}"> <HBox spacing="12" alignment="CENTER_LEFT" visible="${controller.loopbackPortSupported}" managed="${controller.loopbackPortSupported}">
@@ -26,7 +26,7 @@
</padding> </padding>
<children> <children>
<TextFlow> <TextFlow>
<Text text="%vaultOptions.mount.info"/> <Text text="%vaultOptions.mount.info" styleClass="label"/>
<Text text=" "/> <Text text=" "/>
<Hyperlink styleClass="hyperlink-underline" text="%vaultOptions.mount.linkToPreferences" onAction="#openVolumePreferences" wrapText="true"/> <Hyperlink styleClass="hyperlink-underline" text="%vaultOptions.mount.linkToPreferences" onAction="#openVolumePreferences" wrapText="true"/>
</TextFlow> </TextFlow>
@@ -278,6 +278,7 @@ preferences.interface.showTrayIcon=Show tray icon (requires restart)
preferences.volume=Virtual Drive preferences.volume=Virtual Drive
preferences.volume.type=Volume Type (requires restart) preferences.volume.type=Volume Type (requires restart)
preferences.volume.type.automatic=Automatic preferences.volume.type.automatic=Automatic
preferences.volume.docsTooltip=Open the documentation to learn more about the different volume types.
preferences.volume.tcp.port=TCP Port preferences.volume.tcp.port=TCP Port
preferences.volume.supportedFeatures=The chosen volume type supports the following features: preferences.volume.supportedFeatures=The chosen volume type supports the following features:
preferences.volume.feature.mountAuto=Automatic mount point selection preferences.volume.feature.mountAuto=Automatic mount point selection
+39 -2
View File
@@ -73,7 +73,7 @@ addvault.new.readme.storageLocation.4=• modifiqueu cap fitxer dins d'aquest d
addvault.new.readme.storageLocation.5=• enganxeu cap fitxer a xifrar en aquest directori. addvault.new.readme.storageLocation.5=• enganxeu cap fitxer a xifrar en aquest directori.
addvault.new.readme.storageLocation.6=Si voleu xifrar fitxers i veure el contigut de la caixa forta, feu el següent: addvault.new.readme.storageLocation.6=Si voleu xifrar fitxers i veure el contigut de la caixa forta, feu el següent:
addvault.new.readme.storageLocation.7=1. Afegiu aquesta caixa forta a Cryptomator. addvault.new.readme.storageLocation.7=1. Afegiu aquesta caixa forta a Cryptomator.
addvault.new.readme.storageLocation.8=2. Desbloquejeu la caixa forta enCryptomator. addvault.new.readme.storageLocation.8=2. Desbloqueu la caixa forta a Cryptomator.
addvault.new.readme.storageLocation.9=3. Feu click damunt del botó "Mostra" per obrir la ubicació d'accès. addvault.new.readme.storageLocation.9=3. Feu click damunt del botó "Mostra" per obrir la ubicació d'accès.
addvault.new.readme.storageLocation.10=Si us cal ajuda, llegiu la documentació: %s addvault.new.readme.storageLocation.10=Si us cal ajuda, llegiu la documentació: %s
addvault.new.readme.accessLocation.fileName=BENVINGUTS.rtf addvault.new.readme.accessLocation.fileName=BENVINGUTS.rtf
@@ -123,6 +123,10 @@ unlock.success.description=S'ha desblocat %s correctament! Podeu accedir a la vo
unlock.success.rememberChoice=Recorda l'elecció. No ho tornis a mostrar. unlock.success.rememberChoice=Recorda l'elecció. No ho tornis a mostrar.
unlock.success.revealBtn=Mostra la unitat unlock.success.revealBtn=Mostra la unitat
## Failure ## Failure
unlock.error.customPath.message=No es pot muntar la caixa forta en la ruta personalitzada
unlock.error.customPath.description.notSupported=Si vol continuar fent servir una ruta personalitzada, vagi si us plau a Preferències i seleccioni un tipus de volum que la suporti. Altrament, vagi a les opcions de la caixa forta i escolli un punt de muntatge suportat.
unlock.error.customPath.description.notExists=La ruta de muntatge personalitzada no existeix. Creï-la o canviï-la en les opcions de la caixa forta.
unlock.error.customPath.description.generic=Ha seleccionat una ruta personalitzada on muntar la caixa forta, però ha fallat amb aquest missatge: %s
## Hub ## Hub
hub.noKeychain.message=No es pot accedir a la clau del dispositiu hub.noKeychain.message=No es pot accedir a la clau del dispositiu
hub.noKeychain.description=Per poder desblocar caixes fortes del Hub es requereix la clau d'un dispositiu, que s'emmagatzema de forma segura en un clauer. Per continuar, habiliti "%s" i seleccioni un clauer en les Preferències. hub.noKeychain.description=Per poder desblocar caixes fortes del Hub es requereix la clau d'un dispositiu, que s'emmagatzema de forma segura en un clauer. Per continuar, habiliti "%s" i seleccioni un clauer en les Preferències.
@@ -133,18 +137,25 @@ hub.auth.description=Hauríeu de ser redirigits a la pàgina d'accés.
hub.auth.loginLink=No heu estat redirigit? Feu clic aquí per a obrir-la. hub.auth.loginLink=No heu estat redirigit? Feu clic aquí per a obrir-la.
### Receive Key ### Receive Key
hub.receive.message=S'està processant la resposta… hub.receive.message=S'està processant la resposta…
hub.receive.description=Cryptomator està rebent i processant la resposta del Hub. Espereu, si us plau.
### Register Device ### Register Device
hub.register.message=Cal un nom de dispositiu hub.register.message=Cal un nom de dispositiu
hub.register.description=Sembla que és el primer accés al Hub des d'aquest dispositiu. Per identificar-lo i poder autoritzar l'accés necessiteu anomenar aquest dispositiu.
hub.register.nameLabel=Nom del dispositiu hub.register.nameLabel=Nom del dispositiu
hub.register.occupiedMsg=El nom ja està en ús hub.register.occupiedMsg=El nom ja està en ús
hub.register.registerBtn=Confirma hub.register.registerBtn=Confirma
### Registration Success ### Registration Success
hub.registerSuccess.message=Unitat anomenada
hub.registerSuccess.description=Per a accedir a la caixa forta, el vostre dispositiu ha de ser autoritzat pel propietari de la caixa. hub.registerSuccess.description=Per a accedir a la caixa forta, el vostre dispositiu ha de ser autoritzat pel propietari de la caixa.
### Registration Failed ### Registration Failed
hub.registerFailed.message=Error al nombrar el dispositiu
hub.registerFailed.description=S'ha produït un error en el procés de nomenament. Per més detalls vegeu el registre de l'aplicació.
### Unauthorized ### Unauthorized
hub.unauthorized.message=Accés denegat hub.unauthorized.message=Accés denegat
hub.unauthorized.description=El vostre dispositiu no ha estat encara autoritzat a accedir a aquesta caixa forta. Demaneu autorització al propietari. hub.unauthorized.description=El vostre dispositiu no ha estat encara autoritzat a accedir a aquesta caixa forta. Demaneu autorització al propietari.
### License Exceeded ### License Exceeded
hub.licenseExceeded.message=Llicència caducada
hub.licenseExceeded.description=Cryptomator Hub ha donat accés a més usuaris dels permesos en la llicència. Si us plau contacteu amb l'administrador del Hub per actualitzar la llicència o amb l'administrador de la caixa forta per treure usuaris.
# Lock # Lock
@@ -161,6 +172,11 @@ lock.fail.description=La caixa forta "%s" no s'ha pogut blocar. Assegureu-vos qu
migration.title=Actualitza la caixa forta migration.title=Actualitza la caixa forta
## Start ## Start
migration.start.header=Actualitza la caixa forta migration.start.header=Actualitza la caixa forta
migration.start.text=Per obrir la caixa forta "%s" en aquesta nova versió de Cryptomator, la caixa forta necessita actualitzar-se al nou format. Abans de fer-ho, cal que sabeu el següent:
migration.start.remarkUndone=Aquesta actualització no pot ser desfeta.
migration.start.remarkVersions=Versions antigues de Cryptomator no podran obrir la caixa forta actualitzada.
migration.start.remarkCanRun=Assegureu-vos que tots els dispositius des dels quals accediu a la caixa forta poden executar aquesta versió de Cryptomator.
migration.start.remarkSynced=Assegureu-vos que la caixa forta està completament sincronitzada en aquest i altres dispositius abans d'actualitzar-la.
migration.start.confirm=He llegit i entès la informació anterior migration.start.confirm=He llegit i entès la informació anterior
## Run ## Run
migration.run.enterPassword=Introduïu la contrasenya per a "%s" migration.run.enterPassword=Introduïu la contrasenya per a "%s"
@@ -218,6 +234,10 @@ health.result.severityFilter.good=Bé
health.result.severityFilter.info=Info health.result.severityFilter.info=Info
health.result.severityFilter.warn=Avís health.result.severityFilter.warn=Avís
health.result.severityFilter.crit=Crític health.result.severityFilter.crit=Crític
health.result.severityTip.good=Gravetat: Bona.\nEstructura de la caixa forta correcta.
health.result.severityTip.info=Gravetat: Informació\nCaixa forta intacta, es recomana però arreglar-la.
health.result.severityTip.warn=Gravetat: Avís\nCaixa forta corrompuda, és altament recomanable arreglar-la.
health.result.severityTip.crit=Gravetat: Crítica\nCaixa forta corrompuda, s'ha determinat que s'han perdut dades.
health.result.fixStateFilter.all=Estat de reparació - Tot health.result.fixStateFilter.all=Estat de reparació - Tot
health.result.fixStateFilter.fixable=Es pot arreglar health.result.fixStateFilter.fixable=Es pot arreglar
health.result.fixStateFilter.notFixable=No es pot arreglar health.result.fixStateFilter.notFixable=No es pot arreglar
@@ -255,7 +275,15 @@ preferences.interface.showMinimizeButton=Mostra el botó 'minimitzar'
preferences.interface.showTrayIcon=Mostra la icona en la barra (cal reiniciar) preferences.interface.showTrayIcon=Mostra la icona en la barra (cal reiniciar)
## Volume ## Volume
preferences.volume=Unitat virtual preferences.volume=Unitat virtual
preferences.volume.type=Tipus de volum (requereix reiniciar)
preferences.volume.type.automatic=Automàtic preferences.volume.type.automatic=Automàtic
preferences.volume.tcp.port=Port TCP
preferences.volume.supportedFeatures=El tipus de volum escollit suporta les següents característiques:
preferences.volume.feature.mountAuto=Selecció automàtica del punt de muntatge
preferences.volume.feature.mountToDir=Directori personalitzat com a punt de muntatge
preferences.volume.feature.mountToDriveLetter=Lletra de la unitat com a punt de muntatge
preferences.volume.feature.mountFlags=Opcions de muntatge personalitzades
preferences.volume.feature.readOnly=Muntar de només lectura
## Updates ## Updates
preferences.updates=Actualitzacions preferences.updates=Actualitzacions
preferences.updates.currentVersion=Versió actual: %s preferences.updates.currentVersion=Versió actual: %s
@@ -336,6 +364,7 @@ main.vaultDetail.passwordSavedInKeychain=Contrasenya desada
main.vaultDetail.unlockedStatus=DESBLOQUEJADA main.vaultDetail.unlockedStatus=DESBLOQUEJADA
main.vaultDetail.accessLocation=Els continguts de la vostra caixa forta són accessibles aquí: main.vaultDetail.accessLocation=Els continguts de la vostra caixa forta són accessibles aquí:
main.vaultDetail.revealBtn=Mostra la unitat main.vaultDetail.revealBtn=Mostra la unitat
main.vaultDetail.copyUri=Copiar URI
main.vaultDetail.lockBtn=Bloqueja main.vaultDetail.lockBtn=Bloqueja
main.vaultDetail.bytesPerSecondRead=Lectura: main.vaultDetail.bytesPerSecondRead=Lectura:
main.vaultDetail.bytesPerSecondWritten=Escriu: main.vaultDetail.bytesPerSecondWritten=Escriu:
@@ -343,8 +372,12 @@ main.vaultDetail.throughput.idle=inactiu
main.vaultDetail.throughput.kbps=%.1f kiB/s main.vaultDetail.throughput.kbps=%.1f kiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Estadístiques de la caixa forta main.vaultDetail.stats=Estadístiques de la caixa forta
main.vaultDetail.locateEncryptedFileBtn=Trobar fitxer xifrat
main.vaultDetail.locateEncryptedFileBtn.tooltip=Esculli un fitxer de la caixa forta per trobar el seu homòleg xifrat
main.vaultDetail.encryptedPathsCopied=Rutes copiades al porta-retalls!
main.vaultDetail.filePickerTitle=Seleccioni un fitxer dins la caixa forta
### Missing ### Missing
main.vaultDetail.missing.info=Cryptomator no ha trobat una caixa forta en aquest camí. main.vaultDetail.missing.info=Cryptomator no ha trobat una caixa forta en aquesta ruta.
main.vaultDetail.missing.recheck=Torna a comprovar main.vaultDetail.missing.recheck=Torna a comprovar
main.vaultDetail.missing.remove=Eliminar de la llista de la caixa forta… main.vaultDetail.missing.remove=Eliminar de la llista de la caixa forta…
main.vaultDetail.missing.changeLocation=Canvia la localització de la caixa forta… main.vaultDetail.missing.changeLocation=Canvia la localització de la caixa forta…
@@ -381,13 +414,17 @@ vaultOptions.general.startHealthCheckBtn=Inicia la comprovació
## Mount ## Mount
vaultOptions.mount=Muntatge vaultOptions.mount=Muntatge
vaultOptions.mount.info=Les opcions depenen del tipus de volum escollit.
vaultOptions.mount.linkToPreferences=Obre les preferències del disc virtual
vaultOptions.mount.readonly=Només lectura vaultOptions.mount.readonly=Només lectura
vaultOptions.mount.customMountFlags=Senyaladors de muntatge personalitzats vaultOptions.mount.customMountFlags=Senyaladors de muntatge personalitzats
vaultOptions.mount.winDriveLetterOccupied=ocupat vaultOptions.mount.winDriveLetterOccupied=ocupat
vaultOptions.mount.mountPoint=Punt de muntatge vaultOptions.mount.mountPoint=Punt de muntatge
vaultOptions.mount.mountPoint.auto=Tria automàticament una ubicació adequada vaultOptions.mount.mountPoint.auto=Tria automàticament una ubicació adequada
vaultOptions.mount.mountPoint.driveLetter=Utilitza la lletra de la unitat assignada vaultOptions.mount.mountPoint.driveLetter=Utilitza la lletra de la unitat assignada
vaultOptions.mount.mountPoint.custom=Faci servir el directori escollit
vaultOptions.mount.mountPoint.directoryPickerButton=Trieu… vaultOptions.mount.mountPoint.directoryPickerButton=Trieu…
vaultOptions.mount.mountPoint.directoryPickerTitle=Triï un directori
## Master Key ## Master Key
vaultOptions.masterkey=Contrasenya vaultOptions.masterkey=Contrasenya
vaultOptions.masterkey.changePasswordBtn=Canvi de contrasenya vaultOptions.masterkey.changePasswordBtn=Canvi de contrasenya
@@ -16,6 +16,7 @@ generic.button.print=چاپ
# Error # Error
error.message=خطایی رخ داده است error.message=خطایی رخ داده است
error.technicalDetails=جزئیات:
# Defaults # Defaults
defaults.vault.vaultName=گاوصندوق defaults.vault.vaultName=گاوصندوق
@@ -28,13 +29,24 @@ traymenu.vault.lock=قفل
traymenu.vault.reveal=ظاهر traymenu.vault.reveal=ظاهر
# Add Vault Wizard # Add Vault Wizard
addvaultwizard.title=اضافه کردن گاوصندوق
## Welcome ## Welcome
addvaultwizard.welcome.newButton=ساخت گاوصندوق جدید
addvaultwizard.welcome.existingButton=باز کردن گاوصندوق موجود
## New ## New
### Name ### Name
addvaultwizard.new.nameInstruction=یک نام برای گاوصندوق انتخاب کنید
addvaultwizard.new.namePrompt=نام گاوصندوق
### Location ### Location
addvaultwizard.new.locationLabel=مکان ذخیره‌سازی
addvaultwizard.new.directoryPickerLabel=مکان سفارشی
addvaultwizard.new.directoryPickerButton=انتخاب کنید…
addvaultwizard.new.fileAlreadyExists=در حال حاضر یک فایل یا پوشه با همین نام وجود دارد
addvaultwizard.new.validCharacters.numbers=اعداد
### Password ### Password
### Information ### Information
## Existing ## Existing
addvaultwizard.existing.chooseBtn=انتخاب کنید…
## Success ## Success
# Remove Vault # Remove Vault
@@ -100,6 +112,7 @@ main.closeBtn.tooltip=ببند
main.supporterCertificateMissing.tooltip=لطفا کمک مالی در نظر بگیرند main.supporterCertificateMissing.tooltip=لطفا کمک مالی در نظر بگیرند
## Vault List ## Vault List
main.vaultlist.contextMenu.lock=قفل main.vaultlist.contextMenu.lock=قفل
main.vaultlist.addVaultBtn=اضافه کردن گاوصندوق
## Vault Detail ## Vault Detail
### Welcome ### Welcome
### Locked ### Locked
@@ -113,8 +126,10 @@ main.vaultDetail.lockBtn=قفل
# Vault Options # Vault Options
## General ## General
vaultOptions.general.vaultName=نام گاوصندوق
## Mount ## Mount
vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
## Master Key ## Master Key
@@ -123,6 +123,10 @@ unlock.success.description="%s" sbloccato correttamente! La tua cassaforte è or
unlock.success.rememberChoice=Ricorda la scelta, non mostrarmelo più unlock.success.rememberChoice=Ricorda la scelta, non mostrarmelo più
unlock.success.revealBtn=Rivela l'Unità unlock.success.revealBtn=Rivela l'Unità
## Failure ## Failure
unlock.error.customPath.message=Impossibile montare la cassaforte sul percorso personalizzato
unlock.error.customPath.description.notSupported=Se desideri continuare a utilizzare il percorso personalizzato, vai alle preferenze e seleziona un tipo di volume che lo supporta. Altrimenti, vai alle opzioni della cassaforte e scegli un punto di montaggio supportato.
unlock.error.customPath.description.notExists=Il percorso di mount personalizzato non esiste. Crealo nel tuo file system locale o cambialo nelle opzioni della cassaforte.
unlock.error.customPath.description.generic=Hai selezionato un percorso di montaggio personalizzato per questa cassaforte, ma il suo utilizzo è fallito col messaggio: %s
## Hub ## Hub
hub.noKeychain.message=Impossibile accedere alla chiave del dispositivo hub.noKeychain.message=Impossibile accedere alla chiave del dispositivo
hub.noKeychain.description=Per sbloccare le casseforti Hub, è necessaria una chiave del dispositivo, che è protetta tramite un portachiavi. Per procedere, abilita "%s" e seleziona un portachiavi nelle preferenze. hub.noKeychain.description=Per sbloccare le casseforti Hub, è necessaria una chiave del dispositivo, che è protetta tramite un portachiavi. Per procedere, abilita "%s" e seleziona un portachiavi nelle preferenze.
@@ -271,7 +275,15 @@ preferences.interface.showMinimizeButton=Mostra il pulsante minimizza
preferences.interface.showTrayIcon=Mostra l'icona della barra d'applicazioni (richiede il riavvio) preferences.interface.showTrayIcon=Mostra l'icona della barra d'applicazioni (richiede il riavvio)
## Volume ## Volume
preferences.volume=Unità Virtuale preferences.volume=Unità Virtuale
preferences.volume.type=Tipo di volume (richiede riavvio)
preferences.volume.type.automatic=Automatico preferences.volume.type.automatic=Automatico
preferences.volume.tcp.port=Porta TCP
preferences.volume.supportedFeatures=Il tipo di volume scelto supporta le seguenti caratteristiche:
preferences.volume.feature.mountAuto=Selezione automatica del punto di montaggio
preferences.volume.feature.mountToDir=Directory personalizzata come punto di montaggio
preferences.volume.feature.mountToDriveLetter=Lettera dispositivo come punto di montaggio
preferences.volume.feature.mountFlags=Opzioni di montaggio personalizzate
preferences.volume.feature.readOnly=Montaggio di sola lettura
## Updates ## Updates
preferences.updates=Aggiornamenti preferences.updates=Aggiornamenti
preferences.updates.currentVersion=Versione Corrente: %s preferences.updates.currentVersion=Versione Corrente: %s
@@ -352,6 +364,7 @@ main.vaultDetail.passwordSavedInKeychain=Password salvata
main.vaultDetail.unlockedStatus=SBLOCCATA main.vaultDetail.unlockedStatus=SBLOCCATA
main.vaultDetail.accessLocation=I contenuti della tua cassaforte sono accessibili qui: main.vaultDetail.accessLocation=I contenuti della tua cassaforte sono accessibili qui:
main.vaultDetail.revealBtn=Rivela Unità main.vaultDetail.revealBtn=Rivela Unità
main.vaultDetail.copyUri=Copia URI
main.vaultDetail.lockBtn=Blocca main.vaultDetail.lockBtn=Blocca
main.vaultDetail.bytesPerSecondRead=Lettura: main.vaultDetail.bytesPerSecondRead=Lettura:
main.vaultDetail.bytesPerSecondWritten=Scrittura: main.vaultDetail.bytesPerSecondWritten=Scrittura:
@@ -359,7 +372,10 @@ main.vaultDetail.throughput.idle=inattivo
main.vaultDetail.throughput.kbps=%.1f kiB/s main.vaultDetail.throughput.kbps=%.1f kiB/s
main.vaultDetail.throughput.mbps=%.1f MiB/s main.vaultDetail.throughput.mbps=%.1f MiB/s
main.vaultDetail.stats=Statistiche della Cassaforte main.vaultDetail.stats=Statistiche della Cassaforte
main.vaultDetail.locateEncryptedFileBtn=Individua File Crittografato
main.vaultDetail.locateEncryptedFileBtn.tooltip=Scegli un file dalla cassaforte per individuare la controparte cifrata
main.vaultDetail.encryptedPathsCopied=Percorsi copiati negli Appunti! main.vaultDetail.encryptedPathsCopied=Percorsi copiati negli Appunti!
main.vaultDetail.filePickerTitle=Seleziona File Nella Cassaforte
### Missing ### Missing
main.vaultDetail.missing.info=Cryptomator non è riuscito a trovare una cassaforte in questo percorso. main.vaultDetail.missing.info=Cryptomator non è riuscito a trovare una cassaforte in questo percorso.
main.vaultDetail.missing.recheck=Ricontrolla main.vaultDetail.missing.recheck=Ricontrolla
@@ -398,13 +414,17 @@ vaultOptions.general.startHealthCheckBtn=Avvia il Controllo della Salute
## Mount ## Mount
vaultOptions.mount=Montaggio vaultOptions.mount=Montaggio
vaultOptions.mount.info=Le opzioni dipendono dal tipo di volume selezionato.
vaultOptions.mount.linkToPreferences=Apri le preferenze dell'unità virtuale
vaultOptions.mount.readonly=Sola Lettura vaultOptions.mount.readonly=Sola Lettura
vaultOptions.mount.customMountFlags=Flag di Montaggio Personalizzati vaultOptions.mount.customMountFlags=Flag di Montaggio Personalizzati
vaultOptions.mount.winDriveLetterOccupied=occupato vaultOptions.mount.winDriveLetterOccupied=occupato
vaultOptions.mount.mountPoint=Punto di Montaggio vaultOptions.mount.mountPoint=Punto di Montaggio
vaultOptions.mount.mountPoint.auto=Scegli automaticamente una posizione idonea vaultOptions.mount.mountPoint.auto=Scegli automaticamente una posizione idonea
vaultOptions.mount.mountPoint.driveLetter=Usa la lettera del drive assegnata vaultOptions.mount.mountPoint.driveLetter=Usa la lettera del drive assegnata
vaultOptions.mount.mountPoint.custom=Usa la directory scelta
vaultOptions.mount.mountPoint.directoryPickerButton=Scegli… vaultOptions.mount.mountPoint.directoryPickerButton=Scegli…
vaultOptions.mount.mountPoint.directoryPickerTitle=Scegli una directory
## Master Key ## Master Key
vaultOptions.masterkey=Password vaultOptions.masterkey=Password
vaultOptions.masterkey.changePasswordBtn=Modifica password vaultOptions.masterkey.changePasswordBtn=Modifica password
@@ -125,6 +125,7 @@ unlock.success.revealBtn=Toon Schijf
## Failure ## Failure
unlock.error.customPath.message=Kan kluis niet aan aangepast pad koppelen unlock.error.customPath.message=Kan kluis niet aan aangepast pad koppelen
unlock.error.customPath.description.notSupported=Als je het aangepaste pad wilt blijven gebruiken, ga dan naar de voorkeuren en selecteer een volume type dat het ondersteunt. Anders ga je naar de kluis opties en kies je een steunpunt voor het koppelplaten. unlock.error.customPath.description.notSupported=Als je het aangepaste pad wilt blijven gebruiken, ga dan naar de voorkeuren en selecteer een volume type dat het ondersteunt. Anders ga je naar de kluis opties en kies je een steunpunt voor het koppelplaten.
unlock.error.customPath.description.notExists=Het aangepaste koppelpad bestaat niet. Maak het aan in uw lokale bestandssysteem of verander het in de kluis opties.
unlock.error.customPath.description.generic=Je hebt een aangepast koppel pad geselecteerd voor deze kluis, maar het gebruik ervan is mislukt met het bericht: %s unlock.error.customPath.description.generic=Je hebt een aangepast koppel pad geselecteerd voor deze kluis, maar het gebruik ervan is mislukt met het bericht: %s
## Hub ## Hub
hub.noKeychain.message=Geen toegang tot de apparaatsleutel hub.noKeychain.message=Geen toegang tot de apparaatsleutel
@@ -123,6 +123,10 @@ unlock.success.description=Odblokowano "%s" pomyślnie! Twój sejf jest teraz do
unlock.success.rememberChoice=Zapamiętaj wybór, nie pokazuj tego ponownie unlock.success.rememberChoice=Zapamiętaj wybór, nie pokazuj tego ponownie
unlock.success.revealBtn=Pokaż Dysk unlock.success.revealBtn=Pokaż Dysk
## Failure ## Failure
unlock.error.customPath.message=Nie można zamontować sejfu na niestandardowej ścieżce
unlock.error.customPath.description.notSupported=Jeśli chcesz nadal używać niestandardowej ścieżki, przejdź do preferencji i wybierz typ woluminu, który ją obsługuje. W przeciwnym razie przejdź do opcji sejfu i wybierz obsługiwany punkt montowania.
unlock.error.customPath.description.notExists=Niestandardowa ścieżka montowania nie istnieje. Stwórz ją w lokalnym systemie plików lub zmień ją w opcjach sejfu.
unlock.error.customPath.description.generic=Wybrałeś niestandardową ścieżkę montowania dla tego sejfu, ale użycie jej nie powiodło się z wiadomością: %s
## Hub ## Hub
hub.noKeychain.message=Brak dostępu do klucza urządzenia hub.noKeychain.message=Brak dostępu do klucza urządzenia
hub.noKeychain.description=Aby odblokować sejfy na Hubie, wymagany jest klucz urządzenia zabezpieczony za pomocą pęku kluczy. Aby kontynuować, włącz "%s" i wybierz Pęk kluczy w ustawieniach. hub.noKeychain.description=Aby odblokować sejfy na Hubie, wymagany jest klucz urządzenia zabezpieczony za pomocą pęku kluczy. Aby kontynuować, włącz "%s" i wybierz Pęk kluczy w ustawieniach.
@@ -271,7 +275,15 @@ preferences.interface.showMinimizeButton=Pokaż przycisk minimalizacji
preferences.interface.showTrayIcon=Pokaż ikonę zasobnika (wymaga restartu) preferences.interface.showTrayIcon=Pokaż ikonę zasobnika (wymaga restartu)
## Volume ## Volume
preferences.volume=Dysk wirtualny preferences.volume=Dysk wirtualny
preferences.volume.type=Typ woluminu (wymaga ponownego uruchomienia)
preferences.volume.type.automatic=Automatyczny preferences.volume.type.automatic=Automatyczny
preferences.volume.tcp.port=Port TCP
preferences.volume.supportedFeatures=Wybrany typ woluminu obsługuje następujące funkcje:
preferences.volume.feature.mountAuto=Automatyczny wybór punktu montowania
preferences.volume.feature.mountToDir=Niestandardowy katalog jako punkt montowania
preferences.volume.feature.mountToDriveLetter=Litera dysku jako punkt montowania
preferences.volume.feature.mountFlags=Własne opcje montowania
preferences.volume.feature.readOnly=Montowanie tylko do odczytu
## Updates ## Updates
preferences.updates=Aktualizacje preferences.updates=Aktualizacje
preferences.updates.currentVersion=Obecna wersja: %s preferences.updates.currentVersion=Obecna wersja: %s
@@ -352,6 +364,7 @@ main.vaultDetail.passwordSavedInKeychain=Hasło zapisane
main.vaultDetail.unlockedStatus=ODBLOKOWANE main.vaultDetail.unlockedStatus=ODBLOKOWANE
main.vaultDetail.accessLocation=Zawartość Twojego sejfu dostępna jest tutaj: main.vaultDetail.accessLocation=Zawartość Twojego sejfu dostępna jest tutaj:
main.vaultDetail.revealBtn=Otwórz lokalizację main.vaultDetail.revealBtn=Otwórz lokalizację
main.vaultDetail.copyUri=Kopiuj URI
main.vaultDetail.lockBtn=Blokuj main.vaultDetail.lockBtn=Blokuj
main.vaultDetail.bytesPerSecondRead=Odczyt: main.vaultDetail.bytesPerSecondRead=Odczyt:
main.vaultDetail.bytesPerSecondWritten=Zapisz: main.vaultDetail.bytesPerSecondWritten=Zapisz:
@@ -397,13 +410,17 @@ vaultOptions.general.startHealthCheckBtn=Rozpocznij Test Spójności
## Mount ## Mount
vaultOptions.mount=Montowanie vaultOptions.mount=Montowanie
vaultOptions.mount.info=Opcje zależą od wybranego typu woluminu.
vaultOptions.mount.linkToPreferences=Otwórz ustawienia dysku wirtualnego
vaultOptions.mount.readonly=Tylko do odczytu vaultOptions.mount.readonly=Tylko do odczytu
vaultOptions.mount.customMountFlags=Własne flagi montowania udziału vaultOptions.mount.customMountFlags=Własne flagi montowania udziału
vaultOptions.mount.winDriveLetterOccupied=zajęty vaultOptions.mount.winDriveLetterOccupied=zajęty
vaultOptions.mount.mountPoint=Punkt montowania vaultOptions.mount.mountPoint=Punkt montowania
vaultOptions.mount.mountPoint.auto=Automatycznie wybierz odpowiednią lokalizację vaultOptions.mount.mountPoint.auto=Automatycznie wybierz odpowiednią lokalizację
vaultOptions.mount.mountPoint.driveLetter=Użyj przypisanej litery dysku vaultOptions.mount.mountPoint.driveLetter=Użyj przypisanej litery dysku
vaultOptions.mount.mountPoint.custom=Użyj wybranego katalogu
vaultOptions.mount.mountPoint.directoryPickerButton=Wybierz… vaultOptions.mount.mountPoint.directoryPickerButton=Wybierz…
vaultOptions.mount.mountPoint.directoryPickerTitle=Wybierz katalog
## Master Key ## Master Key
vaultOptions.masterkey=Hasło vaultOptions.masterkey=Hasło
vaultOptions.masterkey.changePasswordBtn=Zmiana Hasła vaultOptions.masterkey.changePasswordBtn=Zmiana Hasła
@@ -272,6 +272,9 @@ preferences.interface.showTrayIcon=Ukázať ikonu na sytémovej lište (vyžaduj
## Volume ## Volume
preferences.volume=Virtuálny disk preferences.volume=Virtuálny disk
preferences.volume.type.automatic=Automaticky preferences.volume.type.automatic=Automaticky
preferences.volume.tcp.port=TCP port
preferences.volume.feature.mountFlags=Vlastné parametre mapovania
preferences.volume.feature.readOnly=Mapovanie len na čítanie
## Updates ## Updates
preferences.updates=Aktualizácie preferences.updates=Aktualizácie
preferences.updates.currentVersion=Aktuálna verzia: %s preferences.updates.currentVersion=Aktuálna verzia: %s
@@ -352,6 +355,7 @@ main.vaultDetail.passwordSavedInKeychain=Heslo uložené
main.vaultDetail.unlockedStatus=Odomknutý main.vaultDetail.unlockedStatus=Odomknutý
main.vaultDetail.accessLocation=Obsah Vášho trezora je dostupný tu: main.vaultDetail.accessLocation=Obsah Vášho trezora je dostupný tu:
main.vaultDetail.revealBtn=Odkry disk main.vaultDetail.revealBtn=Odkry disk
main.vaultDetail.copyUri=Kopírovať URI
main.vaultDetail.lockBtn=Uzamknúť main.vaultDetail.lockBtn=Uzamknúť
main.vaultDetail.bytesPerSecondRead=Čítanie: main.vaultDetail.bytesPerSecondRead=Čítanie:
main.vaultDetail.bytesPerSecondWritten=Zápis: main.vaultDetail.bytesPerSecondWritten=Zápis:
@@ -401,13 +405,17 @@ vaultOptions.general.startHealthCheckBtn=Spustiť kontrolu zdravia
## Mount ## Mount
vaultOptions.mount=Mapovanie vaultOptions.mount=Mapovanie
vaultOptions.mount.info=Voľby závisia od typu zvolenej jednotky.
vaultOptions.mount.linkToPreferences=Otvoriť vlastnosti virtuálnej jednotky
vaultOptions.mount.readonly=Len-čítanie vaultOptions.mount.readonly=Len-čítanie
vaultOptions.mount.customMountFlags=Vlastné parametre mapovania vaultOptions.mount.customMountFlags=Vlastné parametre mapovania
vaultOptions.mount.winDriveLetterOccupied=obsadený vaultOptions.mount.winDriveLetterOccupied=obsadený
vaultOptions.mount.mountPoint=Bod mapovania vaultOptions.mount.mountPoint=Bod mapovania
vaultOptions.mount.mountPoint.auto=Automaticky zvoľ vhodné umiestnenie vaultOptions.mount.mountPoint.auto=Automaticky zvoľ vhodné umiestnenie
vaultOptions.mount.mountPoint.driveLetter=Použiť pridelené písmeno disku vaultOptions.mount.mountPoint.driveLetter=Použiť pridelené písmeno disku
vaultOptions.mount.mountPoint.custom=Použiť zvolený adresár
vaultOptions.mount.mountPoint.directoryPickerButton=Zvoliť… vaultOptions.mount.mountPoint.directoryPickerButton=Zvoliť…
vaultOptions.mount.mountPoint.directoryPickerTitle=Vyberte adresár
## Master Key ## Master Key
vaultOptions.masterkey=Heslo vaultOptions.masterkey=Heslo
vaultOptions.masterkey.changePasswordBtn=Zmeniť heslo vaultOptions.masterkey.changePasswordBtn=Zmeniť heslo
@@ -123,6 +123,10 @@ unlock.success.description=已成功解锁 "%s"! 您现在可以通过其虚拟
unlock.success.rememberChoice=记住选项且不再显示 unlock.success.rememberChoice=记住选项且不再显示
unlock.success.revealBtn=显示驱动器 unlock.success.revealBtn=显示驱动器
## Failure ## Failure
unlock.error.customPath.message=无法将保险库挂载到自定义路径
unlock.error.customPath.description.notSupported=如果您仍想使用自定义路径,请转至首选项并选择支持它的卷类型。否则,请转至保险库选项并选择受支持的挂载点
unlock.error.customPath.description.notExists=自定义挂载路径不存在,请在您的本地文件系统中创建它或在保险库选项中进行更改
unlock.error.customPath.description.generic=您已为此保险库选择了自定义挂载路径,但使用失败,错误消息:%s
## Hub ## Hub
hub.noKeychain.message=无法访问设备密钥 hub.noKeychain.message=无法访问设备密钥
hub.noKeychain.description=为了解锁 Hub 保险库,需要使用由钥匙串保护的设备密钥。若要继续,请启用“%s”并在首选项中选择一个钥匙串 hub.noKeychain.description=为了解锁 Hub 保险库,需要使用由钥匙串保护的设备密钥。若要继续,请启用“%s”并在首选项中选择一个钥匙串
@@ -271,7 +275,15 @@ preferences.interface.showMinimizeButton=显示最小化按钮
preferences.interface.showTrayIcon=显示托盘图标 (需重启) preferences.interface.showTrayIcon=显示托盘图标 (需重启)
## Volume ## Volume
preferences.volume=虚拟磁盘 preferences.volume=虚拟磁盘
preferences.volume.type=卷类型(需重启)
preferences.volume.type.automatic=自动 preferences.volume.type.automatic=自动
preferences.volume.tcp.port=TCP 端口
preferences.volume.supportedFeatures=选定的卷类型支持以下功能:
preferences.volume.feature.mountAuto=自动选择挂载点
preferences.volume.feature.mountToDir=自定义目录作为挂载点
preferences.volume.feature.mountToDriveLetter=盘符作为挂载点
preferences.volume.feature.mountFlags=自定义挂载选项
preferences.volume.feature.readOnly=只读挂载
## Updates ## Updates
preferences.updates=更新 preferences.updates=更新
preferences.updates.currentVersion=当前版本:%s preferences.updates.currentVersion=当前版本:%s
@@ -352,6 +364,7 @@ main.vaultDetail.passwordSavedInKeychain=密码已保存
main.vaultDetail.unlockedStatus=已解锁 main.vaultDetail.unlockedStatus=已解锁
main.vaultDetail.accessLocation=您的保险库内容在此处访问: main.vaultDetail.accessLocation=您的保险库内容在此处访问:
main.vaultDetail.revealBtn=显示驱动器 main.vaultDetail.revealBtn=显示驱动器
main.vaultDetail.copyUri=复制 URI
main.vaultDetail.lockBtn=锁定 main.vaultDetail.lockBtn=锁定
main.vaultDetail.bytesPerSecondRead=读取: main.vaultDetail.bytesPerSecondRead=读取:
main.vaultDetail.bytesPerSecondWritten=写入: main.vaultDetail.bytesPerSecondWritten=写入:
@@ -401,13 +414,17 @@ vaultOptions.general.startHealthCheckBtn=开始健康检查
## Mount ## Mount
vaultOptions.mount=挂载 vaultOptions.mount=挂载
vaultOptions.mount.info=选项取决于所选的卷类型
vaultOptions.mount.linkToPreferences=打开虚拟驱动器首选项
vaultOptions.mount.readonly=只读 vaultOptions.mount.readonly=只读
vaultOptions.mount.customMountFlags=自定义挂载标志 vaultOptions.mount.customMountFlags=自定义挂载标志
vaultOptions.mount.winDriveLetterOccupied=已占用 vaultOptions.mount.winDriveLetterOccupied=已占用
vaultOptions.mount.mountPoint=挂载点 vaultOptions.mount.mountPoint=挂载点
vaultOptions.mount.mountPoint.auto=自动选择一个合适的位置 vaultOptions.mount.mountPoint.auto=自动选择一个合适的位置
vaultOptions.mount.mountPoint.driveLetter=使用分配的驱动器字符 vaultOptions.mount.mountPoint.driveLetter=使用分配的驱动器字符
vaultOptions.mount.mountPoint.custom=使用选定的目录
vaultOptions.mount.mountPoint.directoryPickerButton=选择... vaultOptions.mount.mountPoint.directoryPickerButton=选择...
vaultOptions.mount.mountPoint.directoryPickerTitle=选择目录
## Master Key ## Master Key
vaultOptions.masterkey=密码 vaultOptions.masterkey=密码
vaultOptions.masterkey.changePasswordBtn=更改密码 vaultOptions.masterkey.changePasswordBtn=更改密码