Compare commits

...

19 Commits
1.2.2 ... 1.2.4

Author SHA1 Message Date
Tobias Hagemann
0c0fb1c4c5 Merge branch 'release/1.2.4' 2017-01-27 11:22:14 +01:00
Tobias Hagemann
ab39bd1667 updated to version 1.2.4 2017-01-27 11:12:45 +01:00
Tobias Hagemann
b41636a208 added japanese localization, updated other localizations 2017-01-26 16:01:49 +01:00
Tobias Hagemann
0902de821a fixed unit test 2017-01-25 17:32:50 +01:00
Tobias Hagemann
8a6265658e fixed range requests 2017-01-25 15:48:21 +01:00
Sebastian Stenzel
28fedafb59 added linux-launcher-* to RPM [ci skip] 2016-12-12 11:39:23 +01:00
Tobias Hagemann
d9bff68555 updated localization stuff
- added title text to upgrade strategy
- added texts for upgrade 4 to 5
- changed most texts to title style capitalization
2016-11-30 17:22:29 +01:00
Tobias Hagemann
cef3a5fc77 Merge branch 'release/1.2.3'
# Conflicts:
#	main/ant-kit/pom.xml
#	main/commons-test/pom.xml
#	main/commons/pom.xml
#	main/filesystem-api/pom.xml
#	main/filesystem-charsets/pom.xml
#	main/filesystem-crypto-integration-tests/pom.xml
#	main/filesystem-crypto/pom.xml
#	main/filesystem-inmemory/pom.xml
#	main/filesystem-invariants-tests/pom.xml
#	main/filesystem-nameshortening/pom.xml
#	main/filesystem-nio/pom.xml
#	main/filesystem-stats/pom.xml
#	main/frontend-api/pom.xml
#	main/frontend-webdav/pom.xml
#	main/jacoco-report/pom.xml
#	main/keychain/pom.xml
#	main/pom.xml
#	main/uber-jar/pom.xml
#	main/ui/pom.xml
2016-11-29 23:03:26 +01:00
Tobias Hagemann
9956f43fd9 updated to version 1.2.3 2016-11-29 22:24:26 +01:00
Tobias Hagemann
2b84593bde updated localization 2016-11-29 22:16:46 +01:00
Markus Kreusch
4e728fd387 Merge branch 'feature/issue-363' into develop 2016-11-29 15:21:48 +01:00
Tobias Hagemann
438ade1106 fixes #382 2016-11-27 14:28:44 +01:00
Sebastian Stenzel
fe54f4ec66 Update README.md
As suggested by @tallesh in #135
2016-11-27 10:14:34 +01:00
Markus Kreusch
fe86b4c593 Implemented #363 2016-11-14 22:26:55 +01:00
Markus Kreusch
a583afeb60 Merge branch 'feature/issue-393' into develop 2016-11-14 15:08:31 +01:00
Sebastian Stenzel
a585d3cf16 cherry picked from bac1d6f [ci skip] 2016-11-12 17:04:58 +01:00
Sebastian Stenzel
39ee8a9cde coverity issue 151831 2016-11-11 17:11:21 +01:00
Markus Kreusch
1263b3af81 fixed 'a' really bad thing in the last commit 2016-11-11 09:56:45 +01:00
Markus Kreusch
dafa29d8a3 Implemented #393 2016-11-10 22:58:45 +01:00
73 changed files with 900 additions and 404 deletions

View File

@@ -53,9 +53,11 @@ For more information on the security details visit [cryptomator.org](https://cry
``` ```
cd main cd main
mvn clean install mvn clean install -Prelease
``` ```
An executable jar file will be created inside `main/uber-jar/target`.
## Contributing to Cryptomator ## Contributing to Cryptomator
Please read our [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md), if you would like to report a bug, ask a question or help us with coding. Please read our [contribution guide](https://github.com/cryptomator/cryptomator/blob/master/CONTRIBUTING.md), if you would like to report a bug, ask a question or help us with coding.

View File

@@ -8,7 +8,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>ant-kit</artifactId> <artifactId>ant-kit</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>

View File

@@ -60,6 +60,7 @@
<fx:resources> <fx:resources>
<fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" /> <fx:fileset dir="antbuild" type="jar" includes="Cryptomator-${project.version}.jar" />
<fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/> <fx:fileset dir="libs" type="jar" includes="*.jar" excludes="ui-${project.version}.jar"/>
<fx:fileset dir="fixed-binaries" type="data" includes="linux-launcher-*" arch=""/>
</fx:resources> </fx:resources>
<fx:permissions elevated="false" /> <fx:permissions elevated="false" />
<fx:preferences install="true" /> <fx:preferences install="true" />

View File

@@ -10,7 +10,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>commons-test</artifactId> <artifactId>commons-test</artifactId>
<name>Cryptomator common test dependencies</name> <name>Cryptomator common test dependencies</name>

View File

@@ -10,7 +10,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>commons</artifactId> <artifactId>commons</artifactId>
<name>Cryptomator common</name> <name>Cryptomator common</name>

View File

@@ -9,7 +9,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-api</artifactId> <artifactId>filesystem-api</artifactId>
<name>Cryptomator filesystem: API</name> <name>Cryptomator filesystem: API</name>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-charsets</artifactId> <artifactId>filesystem-charsets</artifactId>
<name>Cryptomator filesystem: Charset compatibility layer</name> <name>Cryptomator filesystem: Charset compatibility layer</name>

View File

@@ -40,9 +40,9 @@ class NormalizedNameFolder extends DelegatingFolder<NormalizedNameFolder, Normal
NormalizedNameFile nfcFile = super.file(nfcName); NormalizedNameFile nfcFile = super.file(nfcName);
NormalizedNameFile nfdFile = super.file(nfdName); NormalizedNameFile nfdFile = super.file(nfdName);
if (!nfcName.equals(nfdName) && nfcFile.exists() && nfdFile.exists()) { if (!nfcName.equals(nfdName) && nfcFile.exists() && nfdFile.exists()) {
LOG.warn("Ambiguous file names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC)."); LOG.debug("Ambiguous file names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC).");
} else if (!nfcName.equals(nfdName) && !nfcFile.exists() && nfdFile.exists()) { } else if (!nfcName.equals(nfdName) && !nfcFile.exists() && nfdFile.exists()) {
LOG.info("Moving file from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC)."); LOG.debug("Moving file from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC).");
nfdFile.moveTo(nfcFile); nfdFile.moveTo(nfcFile);
} }
return nfcFile; return nfcFile;
@@ -60,9 +60,9 @@ class NormalizedNameFolder extends DelegatingFolder<NormalizedNameFolder, Normal
NormalizedNameFolder nfcFolder = super.folder(nfcName); NormalizedNameFolder nfcFolder = super.folder(nfcName);
NormalizedNameFolder nfdFolder = super.folder(nfdName); NormalizedNameFolder nfdFolder = super.folder(nfdName);
if (!nfcName.equals(nfdName) && nfcFolder.exists() && nfdFolder.exists()) { if (!nfcName.equals(nfdName) && nfcFolder.exists() && nfdFolder.exists()) {
LOG.warn("Ambiguous folder names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC)."); LOG.debug("Ambiguous folder names \"" + nfcName + "\" (NFC) vs. \"" + nfdName + "\" (NFD). Both files exist. Using \"" + nfcName + "\" (NFC).");
} else if (!nfcName.equals(nfdName) && !nfcFolder.exists() && nfdFolder.exists()) { } else if (!nfcName.equals(nfdName) && !nfcFolder.exists() && nfdFolder.exists()) {
LOG.info("Moving folder from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC)."); LOG.debug("Moving folder from \"" + nfcName + "\" (NFD) to \"" + nfdName + "\" (NFC).");
nfdFolder.moveTo(nfcFolder); nfdFolder.moveTo(nfcFolder);
} }
return nfcFolder; return nfcFolder;

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-crypto-integration-tests</artifactId> <artifactId>filesystem-crypto-integration-tests</artifactId>
<name>Cryptomator filesystem: Encryption layer tests</name> <name>Cryptomator filesystem: Encryption layer tests</name>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-crypto</artifactId> <artifactId>filesystem-crypto</artifactId>
<name>Cryptomator filesystem: Encryption layer</name> <name>Cryptomator filesystem: Encryption layer</name>

View File

@@ -68,7 +68,7 @@ final class ConflictResolver {
String alternativeCiphertext = nameEncryptor.apply(alternativeCleartext).get(); String alternativeCiphertext = nameEncryptor.apply(alternativeCleartext).get();
alternativeFile = folder.file(isDirectory ? DIR_PREFIX + alternativeCiphertext : alternativeCiphertext); alternativeFile = folder.file(isDirectory ? DIR_PREFIX + alternativeCiphertext : alternativeCiphertext);
} while (alternativeFile.exists()); } while (alternativeFile.exists());
LOG.info("Detected conflict {}:\n{}\n{}", conflictId, canonicalFile, conflictingFile); LOG.debug("Detected conflict {}:\n{}\n{}", conflictId, canonicalFile, conflictingFile);
conflictingFile.moveTo(alternativeFile); conflictingFile.moveTo(alternativeFile);
return alternativeFile; return alternativeFile;
} }

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-inmemory</artifactId> <artifactId>filesystem-inmemory</artifactId>
<name>Cryptomator filesystem: In-memory mock</name> <name>Cryptomator filesystem: In-memory mock</name>

View File

@@ -9,7 +9,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-invariants-tests</artifactId> <artifactId>filesystem-invariants-tests</artifactId>
<name>Cryptomator filesystem: Invariants tests</name> <name>Cryptomator filesystem: Invariants tests</name>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-nameshortening</artifactId> <artifactId>filesystem-nameshortening</artifactId>
<name>Cryptomator filesystem: Name shortening layer</name> <name>Cryptomator filesystem: Name shortening layer</name>

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-nio</artifactId> <artifactId>filesystem-nio</artifactId>
<name>Cryptomator filesystem: NIO-based physical layer</name> <name>Cryptomator filesystem: NIO-based physical layer</name>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>filesystem-stats</artifactId> <artifactId>filesystem-stats</artifactId>
<name>Cryptomator filesystem: Throughput statistics</name> <name>Cryptomator filesystem: Throughput statistics</name>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>frontend-api</artifactId> <artifactId>frontend-api</artifactId>
<name>Cryptomator frontend: API</name> <name>Cryptomator frontend: API</name>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>frontend-webdav</artifactId> <artifactId>frontend-webdav</artifactId>
<name>Cryptomator frontend: WebDAV frontend</name> <name>Cryptomator frontend: WebDAV frontend</name>

View File

@@ -18,6 +18,10 @@ class ContextPaths {
return format("/%s/%s", id, name); return format("/%s/%s", id, name);
} }
public static String removeFrontendId(String path) {
return path.replaceAll("/" + FRONTEND_ID_PATTERN + "/", "/[...]/");
}
public static Optional<FrontendId> extractFrontendId(String path) { public static Optional<FrontendId> extractFrontendId(String path) {
Matcher matcher = SERVLET_PATH_WITH_FRONTEND_ID_PATTERN.matcher(path); Matcher matcher = SERVLET_PATH_WITH_FRONTEND_ID_PATTERN.matcher(path);
if (matcher.matches()) { if (matcher.matches()) {

View File

@@ -0,0 +1,17 @@
package org.cryptomator.frontend.webdav;
import org.eclipse.jetty.server.HandlerContainer;
import org.eclipse.jetty.servlet.ServletContextHandler;
class FontendIdHidingServletContextHandler extends ServletContextHandler {
public FontendIdHidingServletContextHandler(HandlerContainer parent, String contextPath, int options) {
super(parent, contextPath, options);
}
@Override
public String toString() {
return ContextPaths.removeFrontendId(super.toString());
}
}

View File

@@ -8,8 +8,6 @@
*******************************************************************************/ *******************************************************************************/
package org.cryptomator.frontend.webdav; package org.cryptomator.frontend.webdav;
import static java.lang.String.format;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Collection; import java.util.Collection;
@@ -110,7 +108,7 @@ public class WebDavServer implements FrontendFactory {
@Override @Override
public Frontend create(Folder root, FrontendId id, String name) throws FrontendCreationFailedException { public Frontend create(Folder root, FrontendId id, String name) throws FrontendCreationFailedException {
String contextPath = format("/%s/%s", id, name); String contextPath = ContextPaths.from(id, name);
final URI uri; final URI uri;
try { try {
uri = new URI("http", null, "localhost", getPort(), contextPath, null, null); uri = new URI("http", null, "localhost", getPort(), contextPath, null, null);
@@ -118,10 +116,10 @@ public class WebDavServer implements FrontendFactory {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
final ServletContextHandler handler = addServlet(root, uri); final ServletContextHandler handler = addServlet(root, uri);
LOG.info("Servlet available under " + uri); LOG.info("Servlet available under " + ContextPaths.removeFrontendId(uri.toString()));
return new WebDavFrontend(webdavMounterProvider, handler, uri); return new WebDavFrontend(webdavMounterProvider, handler, uri);
} }
public void setValidFrontendIds(Collection<FrontendId> validFrontendIds) { public void setValidFrontendIds(Collection<FrontendId> validFrontendIds) {
tarpit.setValidFrontendIds(validFrontendIds); tarpit.setValidFrontendIds(validFrontendIds);
} }

View File

@@ -35,9 +35,10 @@ import org.eclipse.jetty.servlet.ServletHolder;
class WebDavServletContextFactory { class WebDavServletContextFactory {
private static final String WILDCARD = "/*"; private static final String WILDCARD = "/*";
@Inject @Inject
public WebDavServletContextFactory() {} public WebDavServletContextFactory() {
}
/** /**
* Creates a new Jetty ServletContextHandler, that can be be added to a servletCollection as follows: * Creates a new Jetty ServletContextHandler, that can be be added to a servletCollection as follows:
@@ -63,7 +64,7 @@ class WebDavServletContextFactory {
} }
}; };
final String contextPath = StringUtils.removeEnd(contextRoot.getPath(), "/"); final String contextPath = StringUtils.removeEnd(contextRoot.getPath(), "/");
final ServletContextHandler servletContext = new ServletContextHandler(null, contextPath, ServletContextHandler.SESSIONS); final ServletContextHandler servletContext = new FontendIdHidingServletContextHandler(null, contextPath, ServletContextHandler.SESSIONS);
final ServletHolder servletHolder = new ServletHolder(contextPath, new WebDavServlet(contextRoot, root)); final ServletHolder servletHolder = new ServletHolder(contextPath, new WebDavServlet(contextRoot, root));
servletContext.addServlet(servletHolder, WILDCARD); servletContext.addServlet(servletHolder, WILDCARD);
servletContext.addFilter(LoopbackFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST)); servletContext.addFilter(LoopbackFilter.class, WILDCARD, EnumSet.of(DispatcherType.REQUEST));

View File

@@ -16,7 +16,6 @@ import java.util.Objects;
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavServletResponse; import org.apache.jackrabbit.webdav.DavServletResponse;
import org.apache.jackrabbit.webdav.DavSession; import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.io.OutputContext; import org.apache.jackrabbit.webdav.io.OutputContext;
@@ -36,7 +35,7 @@ class DavFileWithRange extends DavFile {
private final Pair<String, String> requestRange; private final Pair<String, String> requestRange;
public DavFileWithRange(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, FileLocator node, Pair<String, String> requestRange) throws DavException { public DavFileWithRange(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, FileLocator node, Pair<String, String> requestRange) {
super(factory, lockManager, session, node); super(factory, lockManager, session, node);
this.requestRange = Objects.requireNonNull(requestRange); this.requestRange = Objects.requireNonNull(requestRange);
} }
@@ -48,18 +47,18 @@ class DavFileWithRange extends DavFile {
return; return;
} }
final long contentLength = node.size(); final long contentLength = node.size();
final Pair<Long, Long> range = getEffectiveRange(contentLength);
if (range.getLeft() < 0 || range.getLeft() > range.getRight() || range.getRight() > contentLength) {
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), "bytes */" + contentLength);
throw new UncheckedDavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE, "Valid Range would be in [0, " + contentLength + "]");
}
final Long rangeLength = range.getRight() - range.getLeft() + 1;
outputContext.setContentLength(rangeLength);
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), contentRangeResponseHeader(range.getLeft(), range.getRight(), contentLength));
outputContext.setContentType(CONTENT_TYPE_VALUE);
outputContext.setProperty(CONTENT_DISPOSITION_HEADER, CONTENT_DISPOSITION_VALUE);
outputContext.setProperty(X_CONTENT_TYPE_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_VALUE);
try (ReadableFile src = node.openReadable(); OutputStream out = outputContext.getOutputStream()) { try (ReadableFile src = node.openReadable(); OutputStream out = outputContext.getOutputStream()) {
final Pair<Long, Long> range = getEffectiveRange(contentLength);
if (range.getLeft() < 0 || range.getLeft() > range.getRight() || range.getRight() > contentLength) {
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), "bytes */" + contentLength);
throw new UncheckedDavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE, "Valid Range would be in [0, " + contentLength + "]");
}
final Long rangeLength = range.getRight() - range.getLeft() + 1;
outputContext.setContentLength(rangeLength);
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), contentRangeResponseHeader(range.getLeft(), range.getRight(), contentLength));
outputContext.setContentType(CONTENT_TYPE_VALUE);
outputContext.setProperty(CONTENT_DISPOSITION_HEADER, CONTENT_DISPOSITION_VALUE);
outputContext.setProperty(X_CONTENT_TYPE_OPTIONS_HEADER, X_CONTENT_TYPE_OPTIONS_VALUE);
src.position(range.getLeft()); src.position(range.getLeft());
InputStream limitedIn = ByteStreams.limit(Channels.newInputStream(src), rangeLength); InputStream limitedIn = ByteStreams.limit(Channels.newInputStream(src), rangeLength);
ByteStreams.copy(limitedIn, out); ByteStreams.copy(limitedIn, out);

View File

@@ -1,50 +0,0 @@
/*******************************************************************************
* Copyright (c) 2016 Sebastian Stenzel and others.
* This file is licensed under the terms of the MIT license.
* See the LICENSE.txt file for more info.
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
package org.cryptomator.frontend.webdav.jackrabbitservlet;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.Channels;
import org.apache.jackrabbit.webdav.DavException;
import org.apache.jackrabbit.webdav.DavSession;
import org.apache.jackrabbit.webdav.io.OutputContext;
import org.apache.jackrabbit.webdav.lock.LockManager;
import org.cryptomator.filesystem.ReadableFile;
import org.cryptomator.filesystem.jackrabbit.FileLocator;
import org.eclipse.jetty.http.HttpHeader;
import com.google.common.io.ByteStreams;
/**
* Sends the full file in reaction to an unsatisfiable range.
*
* @see {@link https://tools.ietf.org/html/rfc7233#section-4.2}
*/
class DavFileWithUnsatisfiableRange extends DavFile {
public DavFileWithUnsatisfiableRange(FilesystemResourceFactory factory, LockManager lockManager, DavSession session, FileLocator node) throws DavException {
super(factory, lockManager, session, node);
}
@Override
public void spool(OutputContext outputContext) throws IOException {
outputContext.setModificationTime(node.lastModified().toEpochMilli());
if (!outputContext.hasStream()) {
return;
}
final long contentLength = node.size();
outputContext.setContentLength(contentLength);
outputContext.setProperty(HttpHeader.CONTENT_RANGE.asString(), "bytes */" + contentLength);
try (ReadableFile src = node.openReadable(); OutputStream out = outputContext.getOutputStream()) {
ByteStreams.copy(src, Channels.newChannel(out));
}
}
}

View File

@@ -85,17 +85,11 @@ class FilesystemResourceFactory implements DavResourceFactory {
final String rangeHeader = request.getHeader(HttpHeader.RANGE.asString()); final String rangeHeader = request.getHeader(HttpHeader.RANGE.asString());
try { try {
// 206 for ranged resources: // 206 for ranged resources:
final Pair<String, String> parsedRange = parseRangeRequestHeader(rangeHeader); final Pair<String, String> parsedRange = parseSingleByteRange(rangeHeader);
response.setStatus(DavServletResponse.SC_PARTIAL_CONTENT); response.setStatus(DavServletResponse.SC_PARTIAL_CONTENT);
return new DavFileWithRange(this, lockManager, session, file, parsedRange); return new DavFileWithRange(this, lockManager, session, file, parsedRange);
} catch (DavException ex) { } catch (NotASingleByteRangeException ex) {
if (ex.getErrorCode() == DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE) { return createFile(file, session);
// 416 for unsatisfiable ranges:
response.setStatus(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
return new DavFileWithUnsatisfiableRange(this, lockManager, session, file);
} else {
throw new DavException(ex.getErrorCode(), ex);
}
} }
} }
@@ -108,17 +102,18 @@ class FilesystemResourceFactory implements DavResourceFactory {
* </code> * </code>
* *
* @return Tuple of lower and upper range. * @return Tuple of lower and upper range.
* @throws DavException HTTP statuscode 400 for malformed requests. 416 if requested range is not supported. * @throws DavException HTTP statuscode 400 for malformed requests.
* @throws NotASingleByteRangeException Indicating a range that is not supported by this server, i.e. range header should be ignored.
*/ */
private Pair<String, String> parseRangeRequestHeader(String rangeHeader) throws DavException { private Pair<String, String> parseSingleByteRange(String rangeHeader) throws DavException, NotASingleByteRangeException {
assert rangeHeader != null; assert rangeHeader != null;
if (!rangeHeader.startsWith(RANGE_BYTE_PREFIX)) { if (!rangeHeader.startsWith(RANGE_BYTE_PREFIX)) {
throw new DavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); throw new NotASingleByteRangeException();
} }
final String byteRangeSet = StringUtils.removeStartIgnoreCase(rangeHeader, RANGE_BYTE_PREFIX); final String byteRangeSet = StringUtils.removeStartIgnoreCase(rangeHeader, RANGE_BYTE_PREFIX);
final String[] byteRanges = StringUtils.split(byteRangeSet, RANGE_SET_SEP); final String[] byteRanges = StringUtils.split(byteRangeSet, RANGE_SET_SEP);
if (byteRanges.length != 1) { if (byteRanges.length != 1) {
throw new DavException(DavServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE); throw new NotASingleByteRangeException();
} }
final String byteRange = byteRanges[0]; final String byteRange = byteRanges[0];
final String[] bytePos = StringUtils.splitPreserveAllTokens(byteRange, RANGE_SEP); final String[] bytePos = StringUtils.splitPreserveAllTokens(byteRange, RANGE_SEP);
@@ -146,4 +141,7 @@ class FilesystemResourceFactory implements DavResourceFactory {
} }
} }
private static class NotASingleByteRangeException extends Exception {
}
} }

View File

@@ -376,7 +376,7 @@ public class WebDavServerTest {
final HttpMethod getMethod = new GetMethod(servletRoot + "/foo.txt"); final HttpMethod getMethod = new GetMethod(servletRoot + "/foo.txt");
getMethod.addRequestHeader("Range", "chunks=1-2"); getMethod.addRequestHeader("Range", "chunks=1-2");
final int statusCode = client.executeMethod(getMethod); final int statusCode = client.executeMethod(getMethod);
Assert.assertEquals(416, statusCode); Assert.assertEquals(200, statusCode);
Assert.assertArrayEquals(testContent, getMethod.getResponseBody()); Assert.assertArrayEquals(testContent, getMethod.getResponseBody());
getMethod.releaseConnection(); getMethod.releaseConnection();
} }

View File

@@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>jacoco-report</artifactId> <artifactId>jacoco-report</artifactId>
<name>Cryptomator Code Coverage Report</name> <name>Cryptomator Code Coverage Report</name>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>keychain</artifactId> <artifactId>keychain</artifactId>
<name>System Keychain Access</name> <name>System Keychain Access</name>

View File

@@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Cryptomator</name> <name>Cryptomator</name>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>uber-jar</artifactId> <artifactId>uber-jar</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>

View File

@@ -12,7 +12,7 @@
<parent> <parent>
<groupId>org.cryptomator</groupId> <groupId>org.cryptomator</groupId>
<artifactId>main</artifactId> <artifactId>main</artifactId>
<version>1.2.2</version> <version>1.2.4</version>
</parent> </parent>
<artifactId>ui</artifactId> <artifactId>ui</artifactId>
<name>Cryptomator GUI</name> <name>Cryptomator GUI</name>

View File

@@ -20,6 +20,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.util.ApplicationVersion;
import org.cryptomator.ui.util.SingleInstanceManager; import org.cryptomator.ui.util.SingleInstanceManager;
import org.cryptomator.ui.util.SingleInstanceManager.RemoteInstance; import org.cryptomator.ui.util.SingleInstanceManager.RemoteInstance;
import org.eclipse.jetty.util.ConcurrentHashSet; import org.eclipse.jetty.util.ConcurrentHashSet;
@@ -33,63 +34,62 @@ public class Cryptomator {
public static final CompletableFuture<Consumer<File>> OPEN_FILE_HANDLER = new CompletableFuture<>(); public static final CompletableFuture<Consumer<File>> OPEN_FILE_HANDLER = new CompletableFuture<>();
private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class); private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class);
private static final Set<Runnable> SHUTDOWN_TASKS = new ConcurrentHashSet<>(); private static final Set<Runnable> SHUTDOWN_TASKS = new ConcurrentHashSet<>();
private static final CleanShutdownPerformer CLEAN_SHUTDOWN_PERFORMER = new CleanShutdownPerformer();
public static void main(String[] args) { public static void main(String[] args) {
String cryptomatorVersion = Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion()).orElse("SNAPSHOT"); LOG.info("Starting Cryptomator {} on {} {} ({})", ApplicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
LOG.info("Starting Cryptomator {} on {} {} ({})", cryptomatorVersion, SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
if (SystemUtils.IS_OS_MAC_OSX) { if (SystemUtils.IS_OS_MAC_OSX) {
/* addOsxFileOpenHandler();
* On OSX we're in an awkward position. We need to register a handler in the main thread of this application. However, we can't
* even pass objects to the application, so we're forced to use a static CompletableFuture for the handler, which actually opens
* the file in the application.
*
* Code taken from https://github.com/axet/desktop/blob/master/src/main/java/com/github/axet/desktop/os/mac/AppleHandlers.java
*/
try {
final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
final Class<?> openFilesHandlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
final Method getApplication = applicationClass.getMethod("getApplication");
final Object application = getApplication.invoke(null);
final Method setOpenFileHandler = applicationClass.getMethod("setOpenFileHandler", openFilesHandlerClass);
final ClassLoader openFilesHandlerClassLoader = openFilesHandlerClass.getClassLoader();
final OpenFilesHandlerClassHandler openFilesHandlerHandler = new OpenFilesHandlerClassHandler();
final Object openFilesHandlerObject = Proxy.newProxyInstance(openFilesHandlerClassLoader, new Class<?>[] {openFilesHandlerClass}, openFilesHandlerHandler);
setOpenFileHandler.invoke(application, openFilesHandlerObject);
} catch (ReflectiveOperationException | RuntimeException e) {
// Since we're trying to call OS-specific code, we'll just have
// to hope for the best.
LOG.error("exception adding OSX file open handler", e);
}
} }
/* new CleanShutdownPerformer().registerShutdownHook();
* Perform certain things on VM termination.
*/
Runtime.getRuntime().addShutdownHook(CLEAN_SHUTDOWN_PERFORMER);
/* final Optional<RemoteInstance> runningInstance = SingleInstanceManager.getRemoteInstance(MainApplication.APPLICATION_KEY);
* Before starting the application, we check if there is already an instance running on this computer. If so, we send our command if (runningInstance.isPresent()) {
* line arguments to that instance and quit. sendArgsToRunningInstance(args, runningInstance);
*/
final Optional<RemoteInstance> remoteInstance = SingleInstanceManager.getRemoteInstance(MainApplication.APPLICATION_KEY);
if (remoteInstance.isPresent()) {
try (RemoteInstance instance = remoteInstance.get()) {
LOG.info("An instance of Cryptomator is already running at {}.", instance.getRemotePort());
for (int i = 0; i < args.length; i++) {
remoteInstance.get().sendMessage(args[i], 100);
}
} catch (Exception e) {
LOG.error("Error forwarding arguments to remote instance", e);
}
} else { } else {
Application.launch(MainApplication.class, args); Application.launch(MainApplication.class, args);
} }
} }
private static void addOsxFileOpenHandler() {
/*
* On OSX we're in an awkward position. We need to register a handler in the main thread of this application. However, we can't
* even pass objects to the application, so we're forced to use a static CompletableFuture for the handler, which actually opens
* the file in the application.
*
* Code taken from https://github.com/axet/desktop/blob/master/src/main/java/com/github/axet/desktop/os/mac/AppleHandlers.java
*/
try {
final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
final Class<?> openFilesHandlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
final Method getApplication = applicationClass.getMethod("getApplication");
final Object application = getApplication.invoke(null);
final Method setOpenFileHandler = applicationClass.getMethod("setOpenFileHandler", openFilesHandlerClass);
final ClassLoader openFilesHandlerClassLoader = openFilesHandlerClass.getClassLoader();
final OpenFilesHandlerClassHandler openFilesHandlerHandler = new OpenFilesHandlerClassHandler();
final Object openFilesHandlerObject = Proxy.newProxyInstance(openFilesHandlerClassLoader, new Class<?>[] {openFilesHandlerClass}, openFilesHandlerHandler);
setOpenFileHandler.invoke(application, openFilesHandlerObject);
} catch (ReflectiveOperationException | RuntimeException e) {
// Since we're trying to call OS-specific code, we'll just have
// to hope for the best.
LOG.error("exception adding OSX file open handler", e);
}
}
private static void sendArgsToRunningInstance(String[] args, final Optional<RemoteInstance> remoteInstance) {
try (RemoteInstance instance = remoteInstance.get()) {
LOG.info("An instance of Cryptomator is already running at {}.", instance.getRemotePort());
for (int i = 0; i < args.length; i++) {
remoteInstance.get().sendMessage(args[i], 100);
}
} catch (Exception e) {
LOG.error("Error forwarding arguments to remote instance", e);
}
}
public static void addShutdownTask(Runnable r) { public static void addShutdownTask(Runnable r) {
SHUTDOWN_TASKS.add(r); SHUTDOWN_TASKS.add(r);
} }
@@ -111,6 +111,10 @@ public class Cryptomator {
}); });
SHUTDOWN_TASKS.clear(); SHUTDOWN_TASKS.clear();
} }
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(this);
}
} }
private static void handleOpenFileRequest(File file) { private static void handleOpenFileRequest(File file) {

View File

@@ -37,6 +37,8 @@ interface CryptomatorComponent {
ExitUtil exitUtil(); ExitUtil exitUtil();
DebugMode debugMode();
Optional<MacFunctions> nativeMacFunctions(); Optional<MacFunctions> nativeMacFunctions();
} }

View File

@@ -0,0 +1,75 @@
package org.cryptomator.ui;
import static java.util.Arrays.asList;
import static org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME;
import java.util.Collection;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.cryptomator.ui.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class DebugMode {
private static final Logger LOG = LoggerFactory.getLogger(DebugMode.class);
private static final Collection<LoggerUpgrade> LOGGER_UPGRADES = asList( //
loggerUpgrade(ROOT_LOGGER_NAME, Level.INFO), //
loggerUpgrade("org.cryptomator", Level.TRACE), //
loggerUpgrade("org.eclipse.jetty.server.Server", Level.DEBUG) //
);
private final Settings settings;
@Inject
public DebugMode(Settings settings) {
this.settings = settings;
}
public void initialize() {
if (settings.getDebugMode()) {
enable();
LOG.debug("Debug mode initialized");
}
}
private void enable() {
LoggerContext context = (LoggerContext) LogManager.getContext(false);
Configuration config = context.getConfiguration();
LOGGER_UPGRADES.forEach(loggerUpgrade -> loggerUpgrade.execute(config));
context.updateLoggers();
}
private static LoggerUpgrade loggerUpgrade(String loggerName, Level minLevel) {
return new LoggerUpgrade(loggerName, minLevel);
}
private static class LoggerUpgrade {
private final Level level;
private final String loggerName;
public LoggerUpgrade(String loggerName, Level minLevel) {
this.loggerName = loggerName;
this.level = minLevel;
}
public void execute(Configuration config) {
LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
if (loggerConfig.getLevel().isMoreSpecificThan(level)) {
loggerConfig.setLevel(level);
}
}
}
}

View File

@@ -43,18 +43,46 @@ public class MainApplication extends Application {
@Override @Override
public void start(Stage primaryStage) throws IOException { public void start(Stage primaryStage) throws IOException {
LOG.info("JavaFX application started"); LOG.info("JavaFX application started");
final CryptomatorComponent comp;
CryptomatorComponent comp = createCryptomatorComponent(primaryStage);
MainController mainCtrl = comp.mainController();
closer = comp.deferredCloser();
comp.debugMode().initialize();
setupFXMLClassLoader();
setupStylesheets();
initializeStage(primaryStage, mainCtrl);
showWindow(primaryStage);
registerExitHandler(comp);
openFilesRequestedDuringStartup(primaryStage, mainCtrl);
registerApplicationToProcessOpenFileRequests(primaryStage, comp, mainCtrl);
}
@Override
public void stop() {
try { try {
comp = DaggerCryptomatorComponent.builder() // closer.close();
} catch (ExecutionException e) {
LOG.error("Error closing ressources", e);
}
}
private CryptomatorComponent createCryptomatorComponent(Stage primaryStage) {
try {
return DaggerCryptomatorComponent.builder() //
.cryptomatorModule(new CryptomatorModule(this, primaryStage)) // .cryptomatorModule(new CryptomatorModule(this, primaryStage)) //
.secureRandomModule(new SecureRandomModule(SecureRandom.getInstanceStrong())) // .secureRandomModule(new SecureRandomModule(SecureRandom.getInstanceStrong())) //
.build(); .build();
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("Every implementation of the Java platform is required to support at least one strong SecureRandom implementation.", e); throw new IllegalStateException("Every implementation of the Java platform is required to support at least one strong SecureRandom implementation.", e);
} }
final MainController mainCtrl = comp.mainController(); }
closer = comp.deferredCloser();
private void setupFXMLClassLoader() {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
FXMLLoader.setDefaultClassLoader(contextClassLoader); FXMLLoader.setDefaultClassLoader(contextClassLoader);
Platform.runLater(() -> { Platform.runLater(() -> {
@@ -66,35 +94,55 @@ public class MainApplication extends Application {
Thread.currentThread().setContextClassLoader(contextClassLoader); Thread.currentThread().setContextClassLoader(contextClassLoader);
} }
}); });
}
// Set stylesheets and initialize stage: private void setupStylesheets() {
Font.loadFont(getClass().getResourceAsStream("/css/ionicons.ttf"), 12.0); Font.loadFont(getClass().getResourceAsStream("/css/ionicons.ttf"), 12.0);
chooseNativeStylesheet(); chooseNativeStylesheet();
}
private void initializeStage(Stage primaryStage, MainController mainCtrl) {
mainCtrl.initStage(primaryStage); mainCtrl.initStage(primaryStage);
primaryStage.titleProperty().bind(mainCtrl.windowTitle()); primaryStage.titleProperty().bind(mainCtrl.windowTitle());
primaryStage.setResizable(false); primaryStage.setResizable(false);
if (SystemUtils.IS_OS_WINDOWS) { if (SystemUtils.IS_OS_WINDOWS) {
primaryStage.getIcons().add(new Image(MainApplication.class.getResourceAsStream("/window_icon.png"))); primaryStage.getIcons().add(new Image(MainApplication.class.getResourceAsStream("/window_icon.png")));
} }
}
// show window and start observing its focus: private void showWindow(Stage primaryStage) {
primaryStage.show(); primaryStage.show();
ActiveWindowStyleSupport.startObservingFocus(primaryStage); ActiveWindowStyleSupport.startObservingFocus(primaryStage);
comp.exitUtil().initExitHandler(this::quit); }
// open files, if requested during startup: private void registerExitHandler(CryptomatorComponent comp) {
comp.exitUtil().initExitHandler(this::quit);
}
private void openFilesRequestedDuringStartup(Stage primaryStage, final MainController mainCtrl) {
for (String arg : getParameters().getUnnamed()) { for (String arg : getParameters().getUnnamed()) {
handleCommandLineArg(arg, primaryStage, mainCtrl); handleCommandLineArg(arg, primaryStage, mainCtrl);
} }
if (SystemUtils.IS_OS_MAC_OSX) { if (SystemUtils.IS_OS_MAC_OSX) {
Cryptomator.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(file.getAbsolutePath(), primaryStage, mainCtrl)); Cryptomator.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(file.getAbsolutePath(), primaryStage, mainCtrl));
} }
}
// register this application instance as primary application, that other instances can send open file requests to: private void registerApplicationToProcessOpenFileRequests(Stage primaryStage, final CryptomatorComponent comp, final MainController mainCtrl) throws IOException {
LocalInstance cryptomatorGuiInstance = closer.closeLater(SingleInstanceManager.startLocalInstance(APPLICATION_KEY, comp.executorService()), LocalInstance::close).get().get(); LocalInstance cryptomatorGuiInstance = closer.closeLater(SingleInstanceManager.startLocalInstance(APPLICATION_KEY, comp.executorService()), LocalInstance::close).get().get();
cryptomatorGuiInstance.registerListener(arg -> handleCommandLineArg(arg, primaryStage, mainCtrl)); cryptomatorGuiInstance.registerListener(arg -> handleCommandLineArg(arg, primaryStage, mainCtrl));
} }
private void chooseNativeStylesheet() {
if (SystemUtils.IS_OS_MAC_OSX) {
setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString());
} else if (SystemUtils.IS_OS_LINUX) {
setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString());
} else if (SystemUtils.IS_OS_WINDOWS) {
setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
}
}
private void handleCommandLineArg(String arg, Stage primaryStage, MainController mainCtrl) { private void handleCommandLineArg(String arg, Stage primaryStage, MainController mainCtrl) {
// find correct location: // find correct location:
final Path path = FileSystems.getDefault().getPath(arg); final Path path = FileSystems.getDefault().getPath(arg);
@@ -118,16 +166,6 @@ public class MainApplication extends Application {
}); });
} }
private void chooseNativeStylesheet() {
if (SystemUtils.IS_OS_MAC_OSX) {
setUserAgentStylesheet(getClass().getResource("/css/mac_theme.css").toString());
} else if (SystemUtils.IS_OS_LINUX) {
setUserAgentStylesheet(getClass().getResource("/css/linux_theme.css").toString());
} else if (SystemUtils.IS_OS_WINDOWS) {
setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
}
}
private void quit() { private void quit() {
Platform.runLater(() -> { Platform.runLater(() -> {
stop(); stop();
@@ -136,13 +174,4 @@ public class MainApplication extends Application {
}); });
} }
@Override
public void stop() {
try {
closer.close();
} catch (ExecutionException e) {
LOG.error("Error closing ressources", e);
}
}
} }

View File

@@ -59,6 +59,9 @@ public class SettingsController extends LocalizedFXMLViewController {
@FXML @FXML
private ChoiceBox<String> prefGvfsScheme; private ChoiceBox<String> prefGvfsScheme;
@FXML
private CheckBox debugModeCheckbox;
@Override @Override
public void initialize() { public void initialize() {
checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally()); checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally());
@@ -74,11 +77,13 @@ public class SettingsController extends LocalizedFXMLViewController {
prefGvfsScheme.getItems().add("dav"); prefGvfsScheme.getItems().add("dav");
prefGvfsScheme.getItems().add("webdav"); prefGvfsScheme.getItems().add("webdav");
prefGvfsScheme.setValue(settings.getPreferredGvfsScheme()); prefGvfsScheme.setValue(settings.getPreferredGvfsScheme());
debugModeCheckbox.setSelected(settings.getDebugMode());
EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), this::checkForUpdateDidChange); EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), this::checkForUpdateDidChange);
EasyBind.subscribe(portField.textProperty(), this::portDidChange); EasyBind.subscribe(portField.textProperty(), this::portDidChange);
EasyBind.subscribe(useIpv6Checkbox.selectedProperty(), this::useIpv6DidChange); EasyBind.subscribe(useIpv6Checkbox.selectedProperty(), this::useIpv6DidChange);
EasyBind.subscribe(prefGvfsScheme.valueProperty(), this::prefGvfsSchemeDidChange); EasyBind.subscribe(prefGvfsScheme.valueProperty(), this::prefGvfsSchemeDidChange);
EasyBind.subscribe(debugModeCheckbox.selectedProperty(), this::debugModeDidChange);
} }
@Override @Override
@@ -114,6 +119,11 @@ public class SettingsController extends LocalizedFXMLViewController {
settings.save(); settings.save();
} }
private void debugModeDidChange(Boolean newValue) {
settings.setDebugMode(newValue);
settings.save();
}
private void prefGvfsSchemeDidChange(String newValue) { private void prefGvfsSchemeDidChange(String newValue) {
settings.setPreferredGvfsScheme(newValue); settings.setPreferredGvfsScheme(newValue);
settings.save(); settings.save();

View File

@@ -30,6 +30,7 @@ import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.settings.Localization; import org.cryptomator.ui.settings.Localization;
import org.cryptomator.ui.settings.Settings; import org.cryptomator.ui.settings.Settings;
import org.cryptomator.ui.util.AsyncTaskService; import org.cryptomator.ui.util.AsyncTaskService;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -40,7 +41,9 @@ import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox; import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Hyperlink; import javafx.scene.control.Hyperlink;
@@ -276,6 +279,37 @@ public class UnlockController extends LocalizedFXMLViewController {
} }
} }
// ****************************************
// Save password checkbox
// ****************************************
@FXML
private void didClickSavePasswordCheckbox(ActionEvent event) {
if (!savePassword.isSelected() && hasStoredPassword()) {
Alert confirmDialog = DialogBuilderUtil.buildConfirmationDialog( //
localization.getString("unlock.savePassword.delete.confirmation.title"), //
localization.getString("unlock.savePassword.delete.confirmation.header"), //
localization.getString("unlock.savePassword.delete.confirmation.content"), //
SystemUtils.IS_OS_MAC_OSX ? ButtonType.CANCEL : ButtonType.OK);
Optional<ButtonType> choice = confirmDialog.showAndWait();
if (ButtonType.OK.equals(choice.get())) {
keychainAccess.get().deletePassphrase(vault.getId());
} else if (ButtonType.CANCEL.equals(choice.get())) {
savePassword.setSelected(true);
}
}
}
private boolean hasStoredPassword() {
char[] storedPw = keychainAccess.get().loadPassphrase(vault.getId());
boolean hasPw = (storedPw != null);
if (storedPw != null) {
Arrays.fill(storedPw, ' ');
}
return hasPw;
}
// **************************************** // ****************************************
// Unlock button // Unlock button
// **************************************** // ****************************************

View File

@@ -38,6 +38,7 @@ import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series; import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.ContextMenu; import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ToggleButton; import javafx.scene.control.ToggleButton;
import javafx.scene.input.Clipboard; import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent; import javafx.scene.input.ClipboardContent;
@@ -57,15 +58,6 @@ public class UnlockedController extends LocalizedFXMLViewController {
private Optional<LockListener> listener = Optional.empty(); private Optional<LockListener> listener = Optional.empty();
private Timeline ioAnimation; private Timeline ioAnimation;
@Inject
public UnlockedController(Localization localization, Provider<MacWarningsController> macWarningsControllerProvider, AsyncTaskService asyncTaskService) {
super(localization);
this.macWarningsController = macWarningsControllerProvider.get();
this.asyncTaskService = asyncTaskService;
macWarningsController.vault.bind(this.vault);
}
@FXML @FXML
private Label messageLabel; private Label messageLabel;
@@ -81,11 +73,25 @@ public class UnlockedController extends LocalizedFXMLViewController {
@FXML @FXML
private ContextMenu moreOptionsMenu; private ContextMenu moreOptionsMenu;
@FXML
private MenuItem revealVaultMenuItem;
@Inject
public UnlockedController(Localization localization, Provider<MacWarningsController> macWarningsControllerProvider, AsyncTaskService asyncTaskService) {
super(localization);
this.macWarningsController = macWarningsControllerProvider.get();
this.asyncTaskService = asyncTaskService;
macWarningsController.vault.bind(this.vault);
}
@Override @Override
public void initialize() { public void initialize() {
macWarningsController.initStage(macWarningsWindow); macWarningsController.initStage(macWarningsWindow);
ActiveWindowStyleSupport.startObservingFocus(macWarningsWindow); ActiveWindowStyleSupport.startObservingFocus(macWarningsWindow);
revealVaultMenuItem.disableProperty().bind(EasyBind.map(vault, vault -> vault != null && !vault.isMounted()));
EasyBind.subscribe(vault, this::vaultChanged); EasyBind.subscribe(vault, this::vaultChanged);
EasyBind.subscribe(moreOptionsMenu.showingProperty(), moreOptionsButton::setSelected); EasyBind.subscribe(moreOptionsMenu.showingProperty(), moreOptionsButton::setSelected);
} }
@@ -109,6 +115,11 @@ public class UnlockedController extends LocalizedFXMLViewController {
} }
}); });
if (!vault.get().isMounted()) {
// TODO Markus Kreusch #393: hyperlink auf FAQ oder sowas?
messageLabel.setText(localization.getString("unlocked.label.mountFailed"));
}
// (re)start throughput statistics: // (re)start throughput statistics:
stopIoSampling(); stopIoSampling();
startIoSampling(); startIoSampling();

View File

@@ -41,7 +41,10 @@ public class UpgradeController extends LocalizedFXMLViewController {
} }
@FXML @FXML
private Label upgradeLabel; private Label upgradeTitleLabel;
@FXML
private Label upgradeMsgLabel;
@FXML @FXML
private SecPasswordField passwordField; private SecPasswordField passwordField;
@@ -60,8 +63,11 @@ public class UpgradeController extends LocalizedFXMLViewController {
@Override @Override
protected void initialize() { protected void initialize() {
upgradeLabel.textProperty().bind(EasyBind.monadic(strategy).map(instruction -> { upgradeTitleLabel.textProperty().bind(EasyBind.monadic(strategy).map(instruction -> {
return instruction.map(this::upgradeNotification).orElse(""); return instruction.map(this::upgradeTitle).orElse("");
}).orElse(""));
upgradeMsgLabel.textProperty().bind(EasyBind.monadic(strategy).map(instruction -> {
return instruction.map(this::upgradeMessage).orElse("");
}).orElse("")); }).orElse(""));
BooleanExpression passwordProvided = passwordField.textProperty().isNotEmpty().and(passwordField.disabledProperty().not()); BooleanExpression passwordProvided = passwordField.textProperty().isNotEmpty().and(passwordField.disabledProperty().not());
@@ -87,8 +93,12 @@ public class UpgradeController extends LocalizedFXMLViewController {
// Upgrade label // Upgrade label
// **************************************** // ****************************************
private String upgradeNotification(UpgradeStrategy instruction) { private String upgradeTitle(UpgradeStrategy instruction) {
return instruction.getNotification(vault); return instruction.getTitle(vault);
}
private String upgradeMessage(UpgradeStrategy instruction) {
return instruction.getMessage(vault);
} }
// **************************************** // ****************************************

View File

@@ -13,7 +13,6 @@ import java.net.URL;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@@ -29,6 +28,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.settings.Localization; import org.cryptomator.ui.settings.Localization;
import org.cryptomator.ui.settings.Settings; import org.cryptomator.ui.settings.Settings;
import org.cryptomator.ui.util.ApplicationVersion;
import org.cryptomator.ui.util.AsyncTaskService; import org.cryptomator.ui.util.AsyncTaskService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -104,7 +104,7 @@ public class WelcomeController extends LocalizedFXMLViewController {
asyncTaskService.asyncTaskOf(() -> { asyncTaskService.asyncTaskOf(() -> {
final HttpClient client = new HttpClient(); final HttpClient client = new HttpClient();
final HttpMethod method = new GetMethod("https://cryptomator.org/downloads/latestVersion.json"); final HttpMethod method = new GetMethod("https://cryptomator.org/downloads/latestVersion.json");
client.getParams().setParameter(HttpClientParams.USER_AGENT, "Cryptomator VersionChecker/" + applicationVersion().orElse("SNAPSHOT")); client.getParams().setParameter(HttpClientParams.USER_AGENT, "Cryptomator VersionChecker/" + ApplicationVersion.orElse("SNAPSHOT"));
client.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES); client.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
client.getParams().setConnectionManagerTimeout(5000); client.getParams().setConnectionManagerTimeout(5000);
client.executeMethod(method); client.executeMethod(method);
@@ -124,10 +124,6 @@ public class WelcomeController extends LocalizedFXMLViewController {
}).run(); }).run();
} }
private Optional<String> applicationVersion() {
return Optional.ofNullable(getClass().getPackage().getImplementationVersion());
}
private void compareVersions(final Map<String, String> latestVersions) { private void compareVersions(final Map<String, String> latestVersions) {
final String latestVersion; final String latestVersion;
if (SystemUtils.IS_OS_MAC_OSX) { if (SystemUtils.IS_OS_MAC_OSX) {
@@ -140,7 +136,7 @@ public class WelcomeController extends LocalizedFXMLViewController {
// no version check possible on unsupported OS // no version check possible on unsupported OS
return; return;
} }
final String currentVersion = applicationVersion().orElse(null); final String currentVersion = ApplicationVersion.orElse(null);
LOG.debug("Current version: {}, lastest version: {}", currentVersion, latestVersion); LOG.debug("Current version: {}, lastest version: {}", currentVersion, latestVersion);
if (currentVersion != null && semVerComparator.compare(currentVersion, latestVersion) < 0) { if (currentVersion != null && semVerComparator.compare(currentVersion, latestVersion) < 0) {
final String msg = String.format(localization.getString("welcome.newVersionMessage"), latestVersion, currentVersion); final String msg = String.format(localization.getString("welcome.newVersionMessage"), latestVersion, currentVersion);

View File

@@ -33,9 +33,14 @@ public abstract class UpgradeStrategy {
} }
/** /**
* @return Localized string to display to the user when an upgrade is needed. * @return Localized title string to display to the user when an upgrade is needed.
*/ */
public abstract String getNotification(Vault vault); public abstract String getTitle(Vault vault);
/**
* @return Localized message string to display to the user when an upgrade is needed.
*/
public abstract String getMessage(Vault vault);
/** /**
* Upgrades a vault. Might take a moment, should be run in a background thread. * Upgrades a vault. Might take a moment, should be run in a background thread.

View File

@@ -32,7 +32,12 @@ class UpgradeVersion3DropBundleExtension extends UpgradeStrategy {
} }
@Override @Override
public String getNotification(Vault vault) { public String getTitle(Vault vault) {
return localization.getString("upgrade.version3dropBundleExtension.title");
}
@Override
public String getMessage(Vault vault) {
String fmt = localization.getString("upgrade.version3dropBundleExtension.msg"); String fmt = localization.getString("upgrade.version3dropBundleExtension.msg");
Path path = vault.path().getValue(); Path path = vault.path().getValue();
String oldVaultName = path.getFileName().toString(); String oldVaultName = path.getFileName().toString();

View File

@@ -50,7 +50,12 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
} }
@Override @Override
public String getNotification(Vault vault) { public String getTitle(Vault vault) {
return localization.getString("upgrade.version3to4.title");
}
@Override
public String getMessage(Vault vault) {
return localization.getString("upgrade.version3to4.msg"); return localization.getString("upgrade.version3to4.msg");
} }

View File

@@ -40,8 +40,13 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
} }
@Override @Override
public String getNotification(Vault vault) { public String getTitle(Vault vault) {
return localization.getString("upgrade.version3to4.msg"); return localization.getString("upgrade.version4to5.title");
}
@Override
public String getMessage(Vault vault) {
return localization.getString("upgrade.version4to5.msg");
} }
@Override @Override
@@ -66,7 +71,7 @@ class UpgradeVersion4to5 extends UpgradeStrategy {
}); });
} catch (IOException e) { } catch (IOException e) {
LOG.error("Migration failed.", e); LOG.error("Migration failed.", e);
throw new UpgradeFailedException(localization.getString("upgrade.version3to4.err.io")); throw new UpgradeFailedException(localization.getString("upgrade.version4to5.err.io"));
} }
LOG.info("Migration finished."); LOG.info("Migration finished.");
} }

View File

@@ -50,6 +50,8 @@ import org.cryptomator.ui.util.DeferredClosable;
import org.cryptomator.ui.util.DeferredCloser; import org.cryptomator.ui.util.DeferredCloser;
import org.cryptomator.ui.util.FXThreads; import org.cryptomator.ui.util.FXThreads;
import org.fxmisc.easybind.EasyBind; import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@@ -65,6 +67,8 @@ import javafx.collections.ObservableList;
public class Vault implements CryptoFileSystemDelegate { public class Vault implements CryptoFileSystemDelegate {
private static final Logger LOG = LoggerFactory.getLogger(CryptoFileSystemDelegate.class);
public static final String VAULT_FILE_EXTENSION = ".cryptomator"; public static final String VAULT_FILE_EXTENSION = ".cryptomator";
private final ObjectProperty<Path> path; private final ObjectProperty<Path> path;
@@ -72,6 +76,7 @@ public class Vault implements CryptoFileSystemDelegate {
private final CryptoFileSystemFactory cryptoFileSystemFactory; private final CryptoFileSystemFactory cryptoFileSystemFactory;
private final DeferredCloser closer; private final DeferredCloser closer;
private final BooleanProperty unlocked = new SimpleBooleanProperty(); private final BooleanProperty unlocked = new SimpleBooleanProperty();
private final BooleanProperty mounted = new SimpleBooleanProperty();
private final ObservableList<String> namesOfResourcesWithInvalidMac = FXThreads.observableListOnMainThread(FXCollections.observableArrayList()); private final ObservableList<String> namesOfResourcesWithInvalidMac = FXThreads.observableListOnMainThread(FXCollections.observableArrayList());
private final Set<String> whitelistedResourcesWithInvalidMac = new HashSet<>(); private final Set<String> whitelistedResourcesWithInvalidMac = new HashSet<>();
private final AtomicReference<FileSystem> nioFileSystem = new AtomicReference<>(); private final AtomicReference<FileSystem> nioFileSystem = new AtomicReference<>();
@@ -131,7 +136,8 @@ public class Vault implements CryptoFileSystemDelegate {
} }
public synchronized void activateFrontend(FrontendFactory frontendFactory, Settings settings, CharSequence passphrase) throws FrontendCreationFailedException { public synchronized void activateFrontend(FrontendFactory frontendFactory, Settings settings, CharSequence passphrase) throws FrontendCreationFailedException {
boolean success = false; boolean launchSuccess = false;
boolean mountSuccess = false;
try { try {
FileSystem fs = getNioFileSystem(); FileSystem fs = getNioFileSystem();
FileSystem shorteningFs = shorteningFileSystemFactory.get(fs); FileSystem shorteningFs = shorteningFileSystemFactory.get(fs);
@@ -140,22 +146,32 @@ public class Vault implements CryptoFileSystemDelegate {
StatsFileSystem statsFs = new StatsFileSystem(normalizingFs); StatsFileSystem statsFs = new StatsFileSystem(normalizingFs);
statsFileSystem = Optional.of(statsFs); statsFileSystem = Optional.of(statsFs);
Frontend frontend = frontendFactory.create(statsFs, FrontendId.from(id), stripStart(mountName, "/")); Frontend frontend = frontendFactory.create(statsFs, FrontendId.from(id), stripStart(mountName, "/"));
launchSuccess = true;
filesystemFrontend = closer.closeLater(frontend); filesystemFrontend = closer.closeLater(frontend);
frontend.mount(getMountParams(settings)); frontend.mount(getMountParams(settings));
success = true; mountSuccess = true;
} catch (UncheckedIOException | CommandFailedException e) { } catch (UncheckedIOException e) {
throw new FrontendCreationFailedException(e); throw new FrontendCreationFailedException(e);
} catch (CommandFailedException e) {
LOG.error("Failed to mount vault " + mountName, e);
} finally { } finally {
// unlocked is a observable property and should only be changed by the FX application thread // unlocked is a observable property and should only be changed by the FX application thread
final boolean finalSuccess = success; boolean finalLaunchSuccess = launchSuccess;
Platform.runLater(() -> unlocked.set(finalSuccess)); boolean finalMountSuccess = mountSuccess;
Platform.runLater(() -> {
unlocked.set(finalLaunchSuccess);
mounted.set(finalMountSuccess);
});
} }
} }
public synchronized void deactivateFrontend() throws Exception { public synchronized void deactivateFrontend() throws Exception {
filesystemFrontend.close(); filesystemFrontend.close();
statsFileSystem = Optional.empty(); statsFileSystem = Optional.empty();
Platform.runLater(() -> unlocked.set(false)); Platform.runLater(() -> {
mounted.set(false);
unlocked.set(false);
});
} }
private Map<MountParam, Optional<String>> getMountParams(Settings settings) { private Map<MountParam, Optional<String>> getMountParams(Settings settings) {
@@ -239,10 +255,18 @@ public class Vault implements CryptoFileSystemDelegate {
return unlocked; return unlocked;
} }
public BooleanProperty mountedProperty() {
return mounted;
}
public boolean isUnlocked() { public boolean isUnlocked() {
return unlocked.get(); return unlocked.get();
} }
public boolean isMounted() {
return mounted.get();
}
public ObservableList<String> getNamesOfResourcesWithInvalidMac() { public ObservableList<String> getNamesOfResourcesWithInvalidMac() {
return namesOfResourcesWithInvalidMac; return namesOfResourcesWithInvalidMac;
} }

View File

@@ -28,6 +28,7 @@ public class Settings implements Serializable {
public static final boolean DEFAULT_USE_IPV6 = false; public static final boolean DEFAULT_USE_IPV6 = false;
public static final Integer DEFAULT_NUM_TRAY_NOTIFICATIONS = 3; public static final Integer DEFAULT_NUM_TRAY_NOTIFICATIONS = 3;
public static final String DEFAULT_GVFS_SCHEME = "dav"; public static final String DEFAULT_GVFS_SCHEME = "dav";
public static final boolean DEFAULT_DEBUG_MODE = false;
private final Consumer<Settings> saveCmd; private final Consumer<Settings> saveCmd;
@@ -49,6 +50,9 @@ public class Settings implements Serializable {
@JsonProperty("preferredGvfsScheme") @JsonProperty("preferredGvfsScheme")
private String preferredGvfsScheme; private String preferredGvfsScheme;
@JsonProperty("debugMode")
private Boolean debugMode;
/** /**
* Package-private constructor; use {@link SettingsProvider}. * Package-private constructor; use {@link SettingsProvider}.
*/ */
@@ -125,4 +129,12 @@ public class Settings implements Serializable {
this.preferredGvfsScheme = preferredGvfsScheme; this.preferredGvfsScheme = preferredGvfsScheme;
} }
public boolean getDebugMode() {
return debugMode == null ? DEFAULT_DEBUG_MODE : debugMode;
}
public void setDebugMode(boolean debugMode) {
this.debugMode = debugMode;
}
} }

View File

@@ -0,0 +1,17 @@
package org.cryptomator.ui.util;
import java.util.Optional;
import org.cryptomator.ui.Cryptomator;
public class ApplicationVersion {
public static String orElse(String other) {
return get().orElse(other);
}
public static Optional<String> get() {
return Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion());
}
}

View File

@@ -85,7 +85,7 @@ public class SingleInstanceManager {
return true; return true;
} }
return !buf.hasRemaining(); return !buf.hasRemaining();
} , timeout, 10); }, timeout, 10);
return !buf.hasRemaining(); return !buf.hasRemaining();
} }
@@ -117,13 +117,14 @@ public class SingleInstanceManager {
final String applicationKey; final String applicationKey;
final ServerSocketChannel channel; final ServerSocketChannel channel;
final Selector selector; final Selector selector;
int port = 0; final int port;
public LocalInstance(String applicationKey, ServerSocketChannel channel, Selector selector) { public LocalInstance(String applicationKey, ServerSocketChannel channel, Selector selector, int port) {
Objects.requireNonNull(applicationKey); Objects.requireNonNull(applicationKey);
this.applicationKey = applicationKey; this.applicationKey = applicationKey;
this.channel = channel; this.channel = channel;
this.selector = selector; this.selector = selector;
this.port = port;
} }
/** /**
@@ -317,28 +318,27 @@ public class SingleInstanceManager {
*/ */
public static LocalInstance startLocalInstance(String applicationKey, ExecutorService exec) throws IOException { public static LocalInstance startLocalInstance(String applicationKey, ExecutorService exec) throws IOException {
final ServerSocketChannel channel = ServerSocketChannel.open(); final ServerSocketChannel channel = ServerSocketChannel.open();
channel.configureBlocking(false); boolean success = false;
channel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); try {
channel.configureBlocking(false);
channel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
final int port = ((InetSocketAddress) channel.getLocalAddress()).getPort(); final int port = ((InetSocketAddress) channel.getLocalAddress()).getPort();
Preferences.userNodeForPackage(Cryptomator.class).putInt(applicationKey, port); Preferences.userNodeForPackage(Cryptomator.class).putInt(applicationKey, port);
LOG.debug("InstanceManager bound to port {}", port); LOG.debug("InstanceManager bound to port {}", port);
Selector selector = Selector.open(); Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_ACCEPT); channel.register(selector, SelectionKey.OP_ACCEPT);
LocalInstance instance = new LocalInstance(applicationKey, channel, selector, port);
LocalInstance instance = new LocalInstance(applicationKey, channel, selector); exec.submit(instance::selectionLoop);
exec.submit(() -> {
try {
instance.port = ((InetSocketAddress) channel.getLocalAddress()).getPort();
} catch (IOException e) {
success = true;
return instance;
} finally {
if (!success) {
channel.close();
} }
instance.selectionLoop(); }
});
return instance;
} }
/** /**
@@ -368,7 +368,7 @@ public class SingleInstanceManager {
} }
} }
return !buf.hasRemaining(); return !buf.hasRemaining();
} , timeout, 1); }, timeout, 1);
} }
} }
} }

View File

@@ -46,6 +46,10 @@
<Label GridPane.rowIndex="3" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.prefGvfsScheme.label" cacheShape="true" cache="true" /> <Label GridPane.rowIndex="3" GridPane.columnIndex="0" fx:id="prefGvfsSchemeLabel" text="%settings.prefGvfsScheme.label" cacheShape="true" cache="true" />
<ChoiceBox GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" /> <ChoiceBox GridPane.rowIndex="3" GridPane.columnIndex="1" fx:id="prefGvfsScheme" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
<!-- Row 4 -->
<Label GridPane.rowIndex="4" GridPane.columnIndex="0" fx:id="debugModeLabel" text="%settings.debugMode.label" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="4" GridPane.columnIndex="1" fx:id="debugModeCheckbox" cacheShape="true" cache="true" />
</children> </children>
</GridPane> </GridPane>
<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" /> <Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />

View File

@@ -69,7 +69,7 @@
<!-- Row 3.1 --> <!-- Row 3.1 -->
<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%unlock.label.savePassword" cacheShape="true" cache="true" /> <Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%unlock.label.savePassword" cacheShape="true" cache="true" />
<CheckBox GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="savePassword" cacheShape="true" cache="true" /> <CheckBox GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="savePassword" onAction="#didClickSavePasswordCheckbox" cacheShape="true" cache="true" />
<!-- Row 3.2 --> <!-- Row 3.2 -->
<Label GridPane.rowIndex="2" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" /> <Label GridPane.rowIndex="2" GridPane.columnIndex="0" text="%unlock.label.mountName" cacheShape="true" cache="true" />

View File

@@ -28,7 +28,7 @@
<fx:define> <fx:define>
<ContextMenu fx:id="moreOptionsMenu"> <ContextMenu fx:id="moreOptionsMenu">
<items> <items>
<MenuItem text="%unlocked.moreOptions.reveal" onAction="#didClickRevealVault"> <MenuItem fx:id="revealVaultMenuItem" text="%unlocked.moreOptions.reveal" onAction="#didClickRevealVault">
<graphic><Label text="&#xf133;" styleClass="ionicons"/></graphic> <graphic><Label text="&#xf133;" styleClass="ionicons"/></graphic>
</MenuItem> </MenuItem>
<MenuItem text="%unlocked.moreOptions.copyUrl" onAction="#didClickCopyUrl"> <MenuItem text="%unlocked.moreOptions.copyUrl" onAction="#didClickCopyUrl">

View File

@@ -31,22 +31,24 @@
</columnConstraints> </columnConstraints>
<children> <children>
<Label fx:id="upgradeLabel" wrapText="true" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" /> <Label fx:id="upgradeTitleLabel" wrapText="true" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<Label fx:id="upgradeMsgLabel" wrapText="true" GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<Pane prefHeight="12.0" GridPane.rowIndex="1" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true"> <Pane prefHeight="12.0" GridPane.rowIndex="2" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
</Pane> </Pane>
<Label text="%unlock.label.password" GridPane.rowIndex="2" GridPane.columnIndex="0" cacheShape="true" cache="true" /> <Label text="%unlock.label.password" GridPane.rowIndex="3" GridPane.columnIndex="0" cacheShape="true" cache="true" />
<SecPasswordField fx:id="passwordField" GridPane.rowIndex="2" GridPane.columnIndex="1" cacheShape="true" cache="true" /> <SecPasswordField fx:id="passwordField" GridPane.rowIndex="3" GridPane.columnIndex="1" cacheShape="true" cache="true" />
<CheckBox fx:id="confirmationCheckbox" text="%upgrade.confirmation.label" wrapText="true" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" /> <CheckBox fx:id="confirmationCheckbox" text="%upgrade.confirmation.label" wrapText="true" GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
<HBox alignment="CENTER_RIGHT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true"> <HBox alignment="CENTER_RIGHT" GridPane.hgrow="ALWAYS" GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true">
<Button fx:id="upgradeButton" text="%upgrade.button" prefWidth="150.0" onAction="#didClickUpgradeButton" cacheShape="true" cache="true" /> <Button fx:id="upgradeButton" text="%upgrade.button" prefWidth="150.0" onAction="#didClickUpgradeButton" cacheShape="true" cache="true" />
</HBox> </HBox>
<ProgressIndicator progress="-1" fx:id="progressIndicator" visible="false" GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" cacheHint="SPEED" /> <ProgressIndicator progress="-1" fx:id="progressIndicator" visible="false" GridPane.rowIndex="6" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" cacheHint="SPEED" />
<Label fx:id="errorLabel" wrapText="true" GridPane.rowIndex="6" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" /> <Label fx:id="errorLabel" wrapText="true" GridPane.rowIndex="7" GridPane.columnIndex="0" GridPane.columnSpan="2" cacheShape="true" cache="true" />
</children> </children>
</GridPane> </GridPane>

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Alle Cryptomator Versionen
changePassword.button.change = Passwort ändern changePassword.button.change = Passwort ändern
changePassword.errorMessage.wrongPassword = Falsches Passwort changePassword.errorMessage.wrongPassword = Falsches Passwort
changePassword.errorMessage.decryptionFailed = Entschlüsselung fehlgeschlagen changePassword.errorMessage.decryptionFailed = Entschlüsselung fehlgeschlagen
changePassword.infoMessage.success = Passwort geändert
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Tresor sperren unlocked.button.lock = Tresor sperren
unlocked.moreOptions.reveal = Laufwerk anzeigen unlocked.moreOptions.reveal = Laufwerk anzeigen
@@ -88,4 +87,14 @@ settings.prefGvfsScheme.label = WebDAV Schema
upgrade.confirmation.label = Ja, die Synchronisation ist abgeschlossen upgrade.confirmation.label = Ja, die Synchronisation ist abgeschlossen
initialize.messageLabel.notEmpty = Tresor ist nicht leer initialize.messageLabel.notEmpty = Tresor ist nicht leer
unlock.label.savePassword = Passwort speichern unlock.label.savePassword = Passwort speichern
unlock.errorMessage.unauthenticVersionMac = Versions-MAC konnte nicht authentifiziert werden. unlock.errorMessage.unauthenticVersionMac = Versions-MAC konnte nicht authentifiziert werden.
unlocked.label.mountFailed = Verbinden des Laufwerks fehlgeschlagen
unlock.savePassword.delete.confirmation.title = Gespeichertes Passwort löschen
unlock.savePassword.delete.confirmation.header = Möchten Sie das gespeicherte Passwort von diesem Tresor wirklich löschen?
unlock.savePassword.delete.confirmation.content = Das gespeicherte Passwort von diesem Tresor wird sofort aus Ihrem System-Schlüsselbund gelöscht. Falls Sie das Passwort erneut speichern möchten, müssen Sie den Tresor entsperren und dabei die "Passwort speichern"-Option aktiviert haben.
settings.debugMode.label = Debug-Modus *
upgrade.version3dropBundleExtension.title = Upgrade Tresor-Version 3 (Entfall der Bundle-Extension)
upgrade.version3to4.title = Upgrade Tresor-Version 3 zu 4
upgrade.version4to5.title = Upgrade Tresor-Version 4 zu 5
upgrade.version4to5.msg = Dieser Tresor muss auf ein neueres Format aktualisiert werden.\nVerschlüsselte Dateien werden dabei aktualisiert.\nStellen Sie bitte sicher, dass derzeit keine Synchronisation stattfindet.\n\nHinweis\: Beim Upgrade wird das Änderungsdatum aller Dateien auf das aktuelle Datum geändert.
upgrade.version4to5.err.io = Migration aufgrund eines I/O-Fehlers fehlgeschlagen.\nWeitere Informationen in der Log-Datei.

View File

@@ -9,10 +9,10 @@ app.name=Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions=Click here to add a vault main.emptyListInstructions=Click here to add a vault
main.directoryList.contextMenu.remove=Remove from list main.directoryList.contextMenu.remove=Remove from List
main.directoryList.contextMenu.changePassword=Change password main.directoryList.contextMenu.changePassword=Change Password
main.addDirectory.contextMenu.new=Create new vault main.addDirectory.contextMenu.new=Create New Vault
main.addDirectory.contextMenu.open=Open existing vault main.addDirectory.contextMenu.open=Open Existing Vault
main.directoryList.remove.confirmation.title=Remove Vault main.directoryList.remove.confirmation.title=Remove Vault
main.directoryList.remove.confirmation.header=Do you really want to remove this vault? main.directoryList.remove.confirmation.header=Do you really want to remove this vault?
main.directoryList.remove.confirmation.content=The vault will only be removed from the list. To permanently delete it, please delete the files from your filesystem. main.directoryList.remove.confirmation.content=The vault will only be removed from the list. To permanently delete it, please delete the files from your filesystem.
@@ -23,8 +23,8 @@ welcome.newVersionMessage=Version %1$s can be downloaded.\nThis is %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password=Password initialize.label.password=Password
initialize.label.retypePassword=Retype password initialize.label.retypePassword=Retype Password
initialize.button.ok=Create vault initialize.button.ok=Create Vault
initialize.messageLabel.alreadyInitialized=Vault already initialized initialize.messageLabel.alreadyInitialized=Vault already initialized
initialize.messageLabel.notEmpty=Vault not empty initialize.messageLabel.notEmpty=Vault not empty
initialize.messageLabel.initializationFailed=Could not initialize vault. See log file for details. initialize.messageLabel.initializationFailed=Could not initialize vault. See log file for details.
@@ -40,24 +40,33 @@ notfound.label=Vault couldn't be found. Has it been moved?
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label=Yes, I've made sure that synchronization has finished upgrade.confirmation.label=Yes, I've made sure that synchronization has finished
upgrade.button=Upgrade vault upgrade.button=Upgrade Vault
upgrade.version3dropBundleExtension.title=Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3dropBundleExtension.msg=This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding. upgrade.version3dropBundleExtension.msg=This vault needs to be migrated to a newer format.\n"%1$s" will be renamed to "%2$s".\nPlease make sure synchronization has finished before proceeding.
upgrade.version3dropBundleExtension.err.alreadyExists=Automatic migration failed.\n"%s" already exists. upgrade.version3dropBundleExtension.err.alreadyExists=Automatic migration failed.\n"%s" already exists.
upgrade.version3to4.title=Vault Version 3 to 4 Upgrade
upgrade.version3to4.msg=This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding. upgrade.version3to4.msg=This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io=Migration failed due to an I/O Exception. See log file for details. upgrade.version3to4.err.io=Migration failed due to an I/O Exception. See log file for details.
upgrade.version4to5.title=Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg=This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io=Migration failed due to an I/O Exception. See log file for details.
# unlock.fxml # unlock.fxml
unlock.label.password=Password unlock.label.password=Password
unlock.label.savePassword=Save password unlock.label.savePassword=Save Password
unlock.label.mountName=Drive name unlock.label.mountName=Drive Name
unlock.label.winDriveLetter=Drive letter unlock.label.winDriveLetter=Drive Letter
unlock.label.downloadsPageLink=All Cryptomator versions unlock.label.downloadsPageLink=All Cryptomator versions
unlock.label.advancedHeading=Advanced options unlock.label.advancedHeading=Advanced Options
unlock.button.unlock=Unlock vault unlock.button.unlock=Unlock Vault
unlock.button.advancedOptions.show=More options unlock.button.advancedOptions.show=More Options
unlock.button.advancedOptions.hide=Less options unlock.button.advancedOptions.hide=Less Options
unlock.savePassword.delete.confirmation.title=Delete Saved Password
unlock.savePassword.delete.confirmation.header=Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content=The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
unlock.choicebox.winDriveLetter.auto=Assign automatically unlock.choicebox.winDriveLetter.auto=Assign automatically
unlock.errorMessage.wrongPassword=Wrong password unlock.errorMessage.wrongPassword=Wrong password
unlock.errorMessage.mountingFailed=Mounting failed. See log file for details. unlock.errorMessage.mountingFailed=Mounting failed. See log file for details.
@@ -67,18 +76,19 @@ unlock.errorMessage.unauthenticVersionMac=Could not authenticate version MAC.
unlock.messageLabel.startServerFailed=Starting WebDAV server failed. unlock.messageLabel.startServerFailed=Starting WebDAV server failed.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword=Old password changePassword.label.oldPassword=Old Password
changePassword.label.newPassword=New password changePassword.label.newPassword=New Nassword
changePassword.label.retypePassword=Retype password changePassword.label.retypePassword=Retype Password
changePassword.label.downloadsPageLink=All Cryptomator versions changePassword.label.downloadsPageLink=All Cryptomator versions
changePassword.button.change=Change password changePassword.button.change=Change Password
changePassword.errorMessage.wrongPassword=Wrong password changePassword.errorMessage.wrongPassword=Wrong password
changePassword.errorMessage.decryptionFailed=Decryption failed changePassword.errorMessage.decryptionFailed=Decryption failed
# unlocked.fxml # unlocked.fxml
unlocked.button.lock=Lock vault unlocked.button.lock=Lock Vault
unlocked.moreOptions.reveal=Reveal drive unlocked.moreOptions.reveal=Reveal Drive
unlocked.moreOptions.copyUrl=Copy WebDAV URL unlocked.moreOptions.copyUrl=Copy WebDAV URL
unlocked.label.mountFailed=Connecting drive failed
unlocked.label.revealFailed=Command failed unlocked.label.revealFailed=Command failed
unlocked.label.unmountFailed=Ejecting drive failed unlocked.label.unmountFailed=Ejecting drive failed
unlocked.label.statsEncrypted=encrypted unlocked.label.statsEncrypted=encrypted
@@ -88,21 +98,22 @@ unlocked.ioGraph.yAxis.label=Throughput (MiB/s)
# mac_warnings.fxml # mac_warnings.fxml
macWarnings.windowTitle=Danger - Corrupted file in %s macWarnings.windowTitle=Danger - Corrupted file in %s
macWarnings.message=Cryptomator detected potentially malicious corruptions in the following files: macWarnings.message=Cryptomator detected potentially malicious corruptions in the following files:
macWarnings.moreInformationButton=Learn more macWarnings.moreInformationButton=Learn More
macWarnings.whitelistButton=Decrypt selected anyway macWarnings.whitelistButton=Decrypt Selected Anyway
# settings.fxml # settings.fxml
settings.version.label=Version %s settings.version.label=Version %s
settings.checkForUpdates.label=Check for updates settings.checkForUpdates.label=Check for Updates
settings.port.label=WebDAV Port * settings.port.label=WebDAV Port *
settings.port.prompt=0 = Choose automatically settings.port.prompt=0 = Choose automatically
settings.useipv6.label=Use IPv6 literal settings.useipv6.label=Use IPv6 Literal
settings.prefGvfsScheme.label=WebDAV scheme settings.prefGvfsScheme.label=WebDAV Scheme
settings.debugMode.label=Debug Mode *
settings.requiresRestartLabel=* Cryptomator needs to restart settings.requiresRestartLabel=* Cryptomator needs to restart
# tray icon # tray icon
tray.menu.open=Open tray.menu.open=Open
tray.menu.quit=Quit tray.menu.quit=Quit
tray.infoMsg.title=Still running tray.infoMsg.title=Still Running
tray.infoMsg.msg=Cryptomator is still alive. Quit it from the tray icon. tray.infoMsg.msg=Cryptomator is still alive. Quit it from the tray icon.
tray.infoMsg.msg.osx=Cryptomator is still alive. Quit it from the menu bar icon. tray.infoMsg.msg.osx=Cryptomator is still alive. Quit it from the menu bar icon.

View File

@@ -1,6 +1,6 @@
app.name = Cryptomator app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = Click aquí para añadir una caja fuerte main.emptyListInstructions = Clic aquí para añadir una caja fuerte
# should it be imperative? # should it be imperative?
main.directoryList.contextMenu.remove = Eliminar de la lista main.directoryList.contextMenu.remove = Eliminar de la lista
main.directoryList.contextMenu.changePassword = Cambiar la contraseña main.directoryList.contextMenu.changePassword = Cambiar la contraseña
@@ -45,7 +45,6 @@ changePassword.label.downloadsPageLink = Todas las versiones de Cryptomator
changePassword.button.change = Cambiar contraseña changePassword.button.change = Cambiar contraseña
changePassword.errorMessage.wrongPassword = Contraseña incorrecta changePassword.errorMessage.wrongPassword = Contraseña incorrecta
changePassword.errorMessage.decryptionFailed = Decifración ha fallado changePassword.errorMessage.decryptionFailed = Decifración ha fallado
changePassword.infoMessage.success = Contraseña se ha cambiado
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Encerrar caja fuerte unlocked.button.lock = Encerrar caja fuerte
unlocked.moreOptions.reveal = Mostrar disco unlocked.moreOptions.reveal = Mostrar disco
@@ -78,15 +77,26 @@ initialize.messageLabel.passwordStrength.1 = débil
initialize.messageLabel.passwordStrength.2 = suficiente initialize.messageLabel.passwordStrength.2 = suficiente
initialize.messageLabel.passwordStrength.3 = fuerte initialize.messageLabel.passwordStrength.3 = fuerte
initialize.messageLabel.passwordStrength.4 = muy fuerte initialize.messageLabel.passwordStrength.4 = muy fuerte
initialize.label.doNotForget = IMPORTANTE\: Si olivdes tú contraseña no hay ninguna manera de recuperar tus datos. initialize.label.doNotForget = IMPORTANTE\: Si olivdes tú contraseña, no hay ninguna manera de recuperar tus datos.
main.directoryList.remove.confirmation.title = Borrar caja fuerte main.directoryList.remove.confirmation.title = Borrar caja fuerte
main.directoryList.remove.confirmation.header = ¿Quieres de verdad borrar este caja fuerte? main.directoryList.remove.confirmation.header = ¿Quieres de verdad borrar este caja fuerte?
main.directoryList.remove.confirmation.content = La caja fuerte solo se borra de la lista. Para eliminarla permanente por favor elimina los datos de tú sistema de archivos. main.directoryList.remove.confirmation.content = La caja fuerte solo se borra de la lista. Para eliminarla permanente por favor elimina los datos de tú sistema de archivos.
upgrade.version3to4.msg = Este caja fuerte se debe migrar a un formato más reciente.\nLos nombres de las carpetas cifradas se actualizan.\nPor favor asegurarse de que la sincronización ha terminado antes de seguir. upgrade.version3to4.msg = Este caja fuerte se debe migrar a un formato más reciente.\nLos nombres de las carpetas cifradas se actualizan.\nPor favor asegurarse de que la sincronización ha terminado antes de seguir.
upgrade.version3to4.err.io = Migración ha fallado por causa de una excepción I/O. Para detalles revisa el archivo de registro. upgrade.version3to4.err.io = Migración ha fallado por causa de una excepción I/O. Para detalles revisa el archivo de registro.
settings.prefGvfsScheme.label = WebDAV scheme # or esequema WEBDAV but I think sistema sounds better
settings.prefGvfsScheme.label = sistema WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Sí, me he asegurado de que la sincronización ha terminado
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Caja fuerte no está vacio
unlock.label.savePassword = Save password unlock.label.savePassword = Contraseña segura
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = No se pudo autentificar la version de MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -15,7 +15,7 @@ initialize.button.ok = Créer le coffre
initialize.messageLabel.alreadyInitialized = Coffre déjà initialisé initialize.messageLabel.alreadyInitialized = Coffre déjà initialisé
initialize.messageLabel.initializationFailed = Impossible d'initialiser le coffre. Voir le fichier de log pour plus de détails. initialize.messageLabel.initializationFailed = Impossible d'initialiser le coffre. Voir le fichier de log pour plus de détails.
# notfound.fxml # notfound.fxml
notfound.label = Coffre introuvable. A t'il été déplacé? notfound.label = Coffre introuvable. A-t-il été déplacé?
# upgrade.fxml # upgrade.fxml
upgrade.button = Mettre à niveau upgrade.button = Mettre à niveau
upgrade.version3dropBundleExtension.msg = Ce coffre doit être converti dans un format plus récent.\n"%1$s" sera renommé en "%2$s".\nAssurez-vous que la synchronisation est terminée avant de continuer. upgrade.version3dropBundleExtension.msg = Ce coffre doit être converti dans un format plus récent.\n"%1$s" sera renommé en "%2$s".\nAssurez-vous que la synchronisation est terminée avant de continuer.
@@ -44,7 +44,6 @@ changePassword.button.change = Modification du mot de masse
changePassword.errorMessage.wrongPassword = Mot de passe incorrect changePassword.errorMessage.wrongPassword = Mot de passe incorrect
# En français, on dit déchiffrement lorsque la clé est connue # En français, on dit déchiffrement lorsque la clé est connue
changePassword.errorMessage.decryptionFailed = Echec du déchiffrement changePassword.errorMessage.decryptionFailed = Echec du déchiffrement
changePassword.infoMessage.success = Mot de passe modifié
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Verrouiller le coffre unlocked.button.lock = Verrouiller le coffre
unlocked.moreOptions.reveal = Voir le lecteur unlocked.moreOptions.reveal = Voir le lecteur
@@ -58,7 +57,7 @@ unlocked.label.statsDecrypted = déchiffré
unlocked.ioGraph.yAxis.label = Débit (MiB/s) unlocked.ioGraph.yAxis.label = Débit (MiB/s)
# mac_warnings.fxml # mac_warnings.fxml
macWarnings.windowTitle = Attention - Fichier corrompu dans %s macWarnings.windowTitle = Attention - Fichier corrompu dans %s
macWarnings.message = Cryptomator a détecté des corruptions de données dans les fichiers suivants\: macWarnings.message = Cryptomator a détecté des corruptions de données dans les fichiers suivants \:
macWarnings.moreInformationButton = En savoir plus macWarnings.moreInformationButton = En savoir plus
macWarnings.whitelistButton = Déchiffrer tout de même macWarnings.whitelistButton = Déchiffrer tout de même
# settings.fxml # settings.fxml
@@ -82,12 +81,22 @@ initialize.messageLabel.passwordStrength.4 = Très fort
initialize.label.doNotForget = ATTENTION \: Si vous oubliez votre mot de passe, il n'y aura aucun moyen de récupérer vos données. initialize.label.doNotForget = ATTENTION \: Si vous oubliez votre mot de passe, il n'y aura aucun moyen de récupérer vos données.
main.directoryList.remove.confirmation.title = Retirer un coffre main.directoryList.remove.confirmation.title = Retirer un coffre
main.directoryList.remove.confirmation.header = Voulez-vous vraiment retirer ce coffre ? main.directoryList.remove.confirmation.header = Voulez-vous vraiment retirer ce coffre ?
main.directoryList.remove.confirmation.content = Le coffre sera simplement retiré de la liste. Pour le supprimer complètement, supprimez les fichiers depuis votre système de fichiers. main.directoryList.remove.confirmation.content = Le coffre sera seulement retiré de la liste. Pour le supprimer complètement, supprimez les fichiers depuis votre système de fichiers.
upgrade.version3to4.msg = Ce coffre doit être converti dans un nouveau format. Les noms de dossiers chiffrés seront mis à jour.\nMerci de vous assurer que la procédure de synchronisation est terminée avant de continuer. upgrade.version3to4.msg = Ce coffre doit être converti dans un nouveau format. Les noms de dossiers chiffrés seront mis à jour.\nMerci de vous assurer que la procédure de synchronisation est terminée avant de continuer.
upgrade.version3to4.err.io = La migration a échoué à cause d'une erreur d'entrée/sortie. Référez-vous au fichier log pour plus de détails. upgrade.version3to4.err.io = La migration a échoué à cause d'une erreur d'entrée/sortie. Référez-vous au fichier log pour plus de détails.
settings.prefGvfsScheme.label = Schéma d'URI WebDAV settings.prefGvfsScheme.label = Schéma d'URI WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Oui, je suis certain que la synchronisation est finie upgrade.confirmation.label = Oui, je suis certain que la synchronisation est terminée
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Le coffre n'est pas vide
unlock.label.savePassword = Save password unlock.label.savePassword = Se souvenir du mot de passe
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Impossible d'authentifier la version MAC
unlocked.label.mountFailed = Echec de connexion au lecteur
unlock.savePassword.delete.confirmation.title = supprimer le mot de passe sauvegardé
unlock.savePassword.delete.confirmation.header = voulez vous vraiment supprimer le mot de pase sauvegardé de ce compte ?
unlock.savePassword.delete.confirmation.content = Le mot de passe de ce coffre sera supprimé immédiatement du trousseau.Si vous voulez le sauvegarder à nouveau, vous devrez cocher la case "retenir le mot de passe" lors du déverrouillage du coffre.
settings.debugMode.label = mode debuggage*
upgrade.version3dropBundleExtension.title = mise à jour vers la version 3 du coffre (extension "drop bundle")
upgrade.version3to4.title = metre à jour le coffre de la version 3 à la version 4
upgrade.version4to5.title = metre à jour le coffre de la version 4 à la version 5
upgrade.version4to5.msg = ce coffre doit être mis à jour vers un format plus récent.\nles fichiés chiffrés seront mis à jour.\nVeuillez vérifier que la synchronisation est terminée avant de commencer.\n\nNote \: la date de modification des fichiers sera mise à jour avec la date courante.
upgrade.version4to5.err.io = Migration échouée due à une erreur de lecture. Lisez les logs pour plus de détails.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Összes Cryptomator verzió
changePassword.button.change = Jelszó megváltoztatása changePassword.button.change = Jelszó megváltoztatása
changePassword.errorMessage.wrongPassword = Hibás jelszó changePassword.errorMessage.wrongPassword = Hibás jelszó
changePassword.errorMessage.decryptionFailed = A titkosítás feloldása meghíusúlt changePassword.errorMessage.decryptionFailed = A titkosítás feloldása meghíusúlt
changePassword.infoMessage.success = Jelszó megváltoztatva
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Széf lezárása unlocked.button.lock = Széf lezárása
unlocked.moreOptions.reveal = Meghajtó felfedése unlocked.moreOptions.reveal = Meghajtó felfedése
@@ -84,7 +83,17 @@ upgrade.version3to4.msg = Ennek a széfnek egy újabb formátumra való migráci
upgrade.version3to4.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért. upgrade.version3to4.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.
settings.prefGvfsScheme.label = WebDAV séma settings.prefGvfsScheme.label = WebDAV séma
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Igen, meggyőződtem a szinkronizáció befejeztéről
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = A széf nem üres
unlock.label.savePassword = Save password unlock.label.savePassword = Jelszó mentése
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Meghajtó csatlakoztatása sikertelen
unlock.savePassword.delete.confirmation.title = Mentett jelszó törlése
unlock.savePassword.delete.confirmation.header = Biztosan el akarod távolítani a széfhez tartozó mentett jelszót?
unlock.savePassword.delete.confirmation.content = A széf mentett jelszava rögtön törlése kerül. Ha újra el szeretnéd menteni a jelszavad, a széfet a "Jelszó mentése" opció engedélyezése mellett kell feloldani.
settings.debugMode.label = Hibakeresési mód *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Széf verziófrissítése 3-ról 4-re
upgrade.version4to5.title = Széf verziófrissítése 4-ről 5-re
upgrade.version4to5.msg = Ennek a széfnek egy újabb formátumra való migrációja szükséges. A titkosított könyvtárnevek frissítve lesznek. Kérlek, győződj meg a szinkronizáció befejeztéről mielőtt továbblépnél.\n\nMegjegyzés\: A összes fájl módosításának dátuma az aktuális időre fog módosulni
upgrade.version4to5.err.io = Migráció meghíusúlt egy I/O kivétel miatt. Kérlek nézd meg a naplófájlt a további részletekért.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Tutte le versioni di Cryptomator
changePassword.button.change = Cambia la password changePassword.button.change = Cambia la password
changePassword.errorMessage.wrongPassword = Password errata changePassword.errorMessage.wrongPassword = Password errata
changePassword.errorMessage.decryptionFailed = Decriptaggio fallito changePassword.errorMessage.decryptionFailed = Decriptaggio fallito
changePassword.infoMessage.success = Password cambiata
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Blocca vault unlocked.button.lock = Blocca vault
unlocked.moreOptions.reveal = Apri il disco unlocked.moreOptions.reveal = Apri il disco
@@ -82,9 +81,19 @@ main.directoryList.remove.confirmation.header = Vuoi davvero rimuovere questo va
main.directoryList.remove.confirmation.content = Il vault sarà rimosso solo dalla lista. Per eliminarlo definitivamente, elimina per favore i file dal tuo hard disk. main.directoryList.remove.confirmation.content = Il vault sarà rimosso solo dalla lista. Per eliminarlo definitivamente, elimina per favore i file dal tuo hard disk.
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding. upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details. upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.prefGvfsScheme.label = WebDAV scheme settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -0,0 +1,99 @@
app.name = Cryptomator
# main.fxml
main.emptyListInstructions = ここをクリックして金庫を追加する
main.directoryList.contextMenu.remove = リストから削除する
main.directoryList.contextMenu.changePassword = パスワード変更
main.addDirectory.contextMenu.new = 新しい金庫を作成する
main.addDirectory.contextMenu.open = 既存の金庫を開く
# welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = アップデートを確認中...
welcome.newVersionMessage = バージョン%1$sがダウンロードできます。\n現在のバージョンは%2$sです。
# initialize.fxml
initialize.label.password = パスワード
initialize.label.retypePassword = パスワード再入力
initialize.button.ok = 金庫を作成
initialize.messageLabel.alreadyInitialized = 金庫がすでに初期化されています。
initialize.messageLabel.initializationFailed = 金庫の初期化ができませんでした。詳細はログファイルをご覧ください。
# notfound.fxml
notfound.label = 金庫が見つかりませんでした。動かされたのですか?
# upgrade.fxml
upgrade.button = 金庫をアップグレードする
upgrade.version3dropBundleExtension.msg = この金庫を新しい形式に移行する必要があります。\n"%1$s"は"%2$s"に変更されます。\n続行する前に同期が完了していることをご確認ください。
upgrade.version3dropBundleExtension.err.alreadyExists = 自動移行が失敗しました。\n"%s"はすでに存在します。
# unlock.fxml
unlock.label.password = パスワード
unlock.label.mountName = ドライブ名
unlock.label.winDriveLetter = ドライブ文字
unlock.label.downloadsPageLink = 全てのCryptomatorバージョン
unlock.label.advancedHeading = 詳細オプション
unlock.button.unlock = 金庫を解除する
unlock.button.advancedOptions.show = その他のオプション
unlock.button.advancedOptions.hide = 基本オプション
unlock.choicebox.winDriveLetter.auto = 自動に割り当てる
unlock.errorMessage.wrongPassword = 間違ったパスワード
unlock.errorMessage.mountingFailed = 取り付けに失敗しました。詳細はログファイルをご覧ください。
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = サポートされていない金庫です。この金庫は古いバージョンのCryptomatorから作成されました。
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = サポートされていない金庫です。この金庫は新しいバージョンのCryptomatorから作成されました。
unlock.messageLabel.startServerFailed = WebDAVサーバーの起動失敗
# change_password.fxml
changePassword.label.oldPassword = 古いパスワード
changePassword.label.newPassword = 新しいパスワード
changePassword.label.retypePassword = 二回目のパスワード(確認用)
changePassword.label.downloadsPageLink = 全てのCryptomatorのバージョン
changePassword.button.change = パスワードの変更
changePassword.errorMessage.wrongPassword = 違うパスワード
changePassword.errorMessage.decryptionFailed = 解読不可
# unlocked.fxml
unlocked.button.lock = 金庫の施錠
unlocked.moreOptions.reveal = 金庫ドライブの表示
unlocked.moreOptions.copyUrl = WebDAVのURLのコピー
unlocked.label.revealFailed = 入力エラー
unlocked.label.unmountFailed = 外部出力の排出エラー
unlocked.label.statsEncrypted = 暗号化
unlocked.label.statsDecrypted = 解読
unlocked.ioGraph.yAxis.label = 情報処理量
# mac_warnings.fxml
macWarnings.windowTitle = 危険-有害でフォルダの%s
macWarnings.message = Cryptomatorは、以下のファイルで潜在的に悪意のある改悪されたものを見つけました
macWarnings.moreInformationButton = より習得する
macWarnings.whitelistButton = フォルダを選択、解読してください
# settings.fxml
settings.version.label = バージョンの%s
settings.checkForUpdates.label = 最新版のチェック
settings.port.label = WebDAVの移動
settings.port.prompt = 0自動的に選択します
settings.useipv6.label = IPv6をそのまま使用してください
settings.requiresRestartLabel = Cryptomatorの再起動が必要です
# tray icon
tray.menu.open = 開く
tray.menu.quit = 閉じる
tray.infoMsg.title = バックグラウンドで稼働中
tray.infoMsg.msg = Cryptomatorはまだ稼働しています。終了はトレイアイコンからしてください。
tray.infoMsg.msg.osx = Cryptomatorはまだ稼働しています。終了はメヌーバーアイコンからしてください。
initialize.messageLabel.passwordStrength.0 = 非常に弱い
initialize.messageLabel.passwordStrength.1 = 弱い
initialize.messageLabel.passwordStrength.2 = 普通
initialize.messageLabel.passwordStrength.3 = 強い
initialize.messageLabel.passwordStrength.4 = 非常に強い
initialize.label.doNotForget = 重要:パスワードを忘れましたら、あなたのデータは復旧できません。
main.directoryList.remove.confirmation.title = 金庫の削除
main.directoryList.remove.confirmation.header = 本当にこの金庫を取り除きたいですか?
main.directoryList.remove.confirmation.content = 金庫はリストのみで削除されます。永久に削除するなら、ファイルシステムからファイルを削除してください。
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details.
settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -15,7 +15,7 @@ initialize.button.ok = 보관함 만들기
initialize.messageLabel.alreadyInitialized = 이미 보관함이 초기화되었습니다. initialize.messageLabel.alreadyInitialized = 이미 보관함이 초기화되었습니다.
initialize.messageLabel.initializationFailed = 보관함을 초기화할 수 없습니다. 자세한 사항은 로그 파일을 참조하세요. initialize.messageLabel.initializationFailed = 보관함을 초기화할 수 없습니다. 자세한 사항은 로그 파일을 참조하세요.
# notfound.fxml # notfound.fxml
notfound.label = 보관함을 찾을 수 없습니다. 옮겨진 것은 아닌가요? notfound.label = 보관함을 찾을 수 없습니다. 옮겨졌는지 확인해 주세요.
# upgrade.fxml # upgrade.fxml
upgrade.button = 보관함 업그레이드 upgrade.button = 보관함 업그레이드
upgrade.version3dropBundleExtension.msg = 이 보관함은 새로운 형식으로 다시 바뀔 필요가 있습니다. "%1$s"의 이름은 "%2$s"로 바뀔 것입니다. 진행하기 전에 동기화가 완료되었는지 다시 한 번 확인해주시기 바랍니다. upgrade.version3dropBundleExtension.msg = 이 보관함은 새로운 형식으로 다시 바뀔 필요가 있습니다. "%1$s"의 이름은 "%2$s"로 바뀔 것입니다. 진행하기 전에 동기화가 완료되었는지 다시 한 번 확인해주시기 바랍니다.
@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = 모든 Cryptomator 버전
changePassword.button.change = 비밀번호 변경 changePassword.button.change = 비밀번호 변경
changePassword.errorMessage.wrongPassword = 틀린 비밀번호 changePassword.errorMessage.wrongPassword = 틀린 비밀번호
changePassword.errorMessage.decryptionFailed = 복호화 실패 changePassword.errorMessage.decryptionFailed = 복호화 실패
changePassword.infoMessage.success = 비밀번호 변경
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = 보관함 잠그기 unlocked.button.lock = 보관함 잠그기
unlocked.moreOptions.reveal = 드라이브 표시 unlocked.moreOptions.reveal = 드라이브 표시
@@ -85,6 +84,16 @@ upgrade.version3to4.err.io = 입출력 예외 문제로 마이그레이션이
settings.prefGvfsScheme.label = WebDAV sceme settings.prefGvfsScheme.label = WebDAV sceme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = 네. 동기화가 완료되었음을 확인하였습니다. upgrade.confirmation.label = 네. 동기화가 완료되었음을 확인하였습니다.
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = 보관함이 비어있지 않음
unlock.label.savePassword = Save password unlock.label.savePassword = 비밀번호 저장
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = 인증할 수 없는 버전의 맥입니다
unlocked.label.mountFailed = 드라이브 연결 실패
unlock.savePassword.delete.confirmation.title = 저장된 비밀번호 삭제
unlock.savePassword.delete.confirmation.header = 정말로 이 보관함의 저장된 비밀번호를 지우시겠습니까?
unlock.savePassword.delete.confirmation.content = 이 보관함의 저장된 비밀번호는 당신의 시스템 키체인에서 즉시 삭제될 것입니다. 다시 비밀번호를 저장하고 싶으시다면, 보관함을 열 때 "비밀번호 저장" 옵션을 활성화해야 합니다
settings.debugMode.label = 디버그 모드
upgrade.version3dropBundleExtension.title = 버전 3 보관함 업그레이드 (Drop Bundle Extension)
upgrade.version3to4.title = 보관함 버전 3에서 4로 업그레이드
upgrade.version4to5.title = 보관함 버전 4에서 5로 업그레이드
upgrade.version4to5.msg = 이 보관함은 새로운 포맷으로 이전되어야 합니다.\n암호화된 파일들은 업데이트 될 것입니다.\n진행하기 전에 동기화가 완료되었는지 확인해주세요.\n\n참고\: 모든 파일의 수정 날짜는 과정 진행 중에 현재 날짜/시간으로 바뀔 것입니다.
upgrade.version4to5.err.io = I/O 예외에 의해 마이그레이션 실패. 자세한 사항은 로그 파일을 참조하세요.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Visas Cryptomator versijas
changePassword.button.change = Mainīt paroli changePassword.button.change = Mainīt paroli
changePassword.errorMessage.wrongPassword = Nepareiza parole changePassword.errorMessage.wrongPassword = Nepareiza parole
changePassword.errorMessage.decryptionFailed = Atšifrēšana neizdevās changePassword.errorMessage.decryptionFailed = Atšifrēšana neizdevās
changePassword.infoMessage.success = Parole nomainīta
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Aizslēgt glabātuvi unlocked.button.lock = Aizslēgt glabātuvi
unlocked.moreOptions.reveal = Atklāt disku unlocked.moreOptions.reveal = Atklāt disku
@@ -87,5 +86,15 @@ settings.prefGvfsScheme.label = WebDAV shēma
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Jā, esmu pārliecinājies, ka sinhronizācija ir pabeigta. upgrade.confirmation.label = Jā, esmu pārliecinājies, ka sinhronizācija ir pabeigta.
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -2,22 +2,24 @@ app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = Klik hier om een kluis toe te voegen main.emptyListInstructions = Klik hier om een kluis toe te voegen
main.directoryList.contextMenu.remove = Verwijder van lijst main.directoryList.contextMenu.remove = Verwijder van lijst
main.directoryList.contextMenu.changePassword = Verander wachtwoord # The current Dutch translation of this string (and other, similar contexts) is not in accordance with Windows convention, which is to translate options like this with infinitivies and not imperatives, so "Wachtwoord wijzigen," not "Wijzig wachtwoord." MacOS uses imperatives in Dutch, not Windows.
main.addDirectory.contextMenu.new = Creëer nieuwe kluis main.directoryList.contextMenu.changePassword = Verander Wachtwoord
main.addDirectory.contextMenu.open = Open bestaande kluis main.addDirectory.contextMenu.new = Maak Nieuwe Kluis
main.addDirectory.contextMenu.open = Open Bestaande Kluis
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Controleren op updates... welcome.checkForUpdates.label.currentlyChecking = Controleren op updates...
welcome.newVersionMessage = Versie %1$s kan worden gedownload.\nDit is %2$s. welcome.newVersionMessage = Versie %1$s kan worden gedownload.\nDit is %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password = Wachtwoord initialize.label.password = Wachtwoord
initialize.label.retypePassword = Voer wachtwoord opnieuw in initialize.label.retypePassword = Voer wachtwoord opnieuw in
# This is not in accordance with Dutch conventions. Not only does it use an imperative, but 'create' is generally translated as 'maken' or 'aanmaken', not 'creëren'. So "Kluis maken."
initialize.button.ok = Creëer kluis initialize.button.ok = Creëer kluis
initialize.messageLabel.alreadyInitialized = Kluis reeds geïnitialiseerd initialize.messageLabel.alreadyInitialized = Kluis reeds geïnitialiseerd
initialize.messageLabel.initializationFailed = Kon kluis niet initialiseren. Zie logbestand voor details. initialize.messageLabel.initializationFailed = Kon kluis niet initialiseren. Zie logbestand voor details.
# notfound.fxml # notfound.fxml
notfound.label = Kluis kon niet gevonden worden. Is de kluis wellicht verplaatst? notfound.label = Kluis kon niet gevonden worden. Is hij verplaatst?
# upgrade.fxml # upgrade.fxml
upgrade.button = Upgrade kluis upgrade.button = Upgrade Kluis
upgrade.version3dropBundleExtension.msg = Deze kluis dient te worden gemigreerd naar een nieuwer type.\n"%1$s" zal worden hernoemd naar "%2$s".\nZorg ervoor dat de synchronisatie voltooid is alvorens door te gaan. upgrade.version3dropBundleExtension.msg = Deze kluis dient te worden gemigreerd naar een nieuwer type.\n"%1$s" zal worden hernoemd naar "%2$s".\nZorg ervoor dat de synchronisatie voltooid is alvorens door te gaan.
upgrade.version3dropBundleExtension.err.alreadyExists = Automatische migratie mislukt.\n"%s" bestaat al. upgrade.version3dropBundleExtension.err.alreadyExists = Automatische migratie mislukt.\n"%s" bestaat al.
# unlock.fxml # unlock.fxml
@@ -25,22 +27,22 @@ unlock.label.password = Wachtwoord
unlock.label.mountName = Schijfnaam unlock.label.mountName = Schijfnaam
unlock.label.winDriveLetter = Schijfletter unlock.label.winDriveLetter = Schijfletter
unlock.label.downloadsPageLink = Alle Cryptomator versies unlock.label.downloadsPageLink = Alle Cryptomator versies
unlock.label.advancedHeading = Geavanceerde opties unlock.label.advancedHeading = Geavanceerde Opties
unlock.button.unlock = Ontgrendel kluis unlock.button.unlock = Ontgrendel Kluis
unlock.button.advancedOptions.show = Meer opties unlock.button.advancedOptions.show = Meer Opties
unlock.button.advancedOptions.hide = Minder opties unlock.button.advancedOptions.hide = Minder Opties
unlock.choicebox.winDriveLetter.auto = Automatisch toekennen unlock.choicebox.winDriveLetter.auto = Automatisch toekennen
unlock.errorMessage.wrongPassword = Verkeerd wachtwoord unlock.errorMessage.wrongPassword = Verkeerd wachtwoord
unlock.errorMessage.mountingFailed = Mounten mislukt. Zie logbestand voor details. unlock.errorMessage.mountingFailed = Mounten mislukt. Zie logbestand voor details.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Kluis ontoegankelijk. Deze kluis is gecreëerd met een oudere versie van Cryptomator. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Niet ondersteunde kluis. Deze kluis is gemaakt met een nieuwere versie van Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Kluis ontoegankelijk. Deze kluis is gecreëerd met een nieuwere versie van Cryptomator. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Niet ondersteunde kluis. Deze kluis is gemaakt met een nieuwere versie van Cryptomator.
unlock.messageLabel.startServerFailed = WebDAV server starten mislukt. unlock.messageLabel.startServerFailed = WebDAV server starten mislukt.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Huidig wachtwoord changePassword.label.oldPassword = Huidig Wachtwoord
changePassword.label.newPassword = Nieuw wachtwoord changePassword.label.newPassword = Nieuw Wachtwoord
changePassword.label.retypePassword = Herhaal wachtwoord changePassword.label.retypePassword = Herhaal Wachtwoord
changePassword.label.downloadsPageLink = Alle Cryptomator versies changePassword.label.downloadsPageLink = Alle Cryptomator versies
changePassword.button.change = Verander wachtwoord changePassword.button.change = Verander Wachtwoord
changePassword.errorMessage.wrongPassword = Alle Cryptomator versies changePassword.errorMessage.wrongPassword = Alle Cryptomator versies
changePassword.errorMessage.decryptionFailed = Decoderen mislukt changePassword.errorMessage.decryptionFailed = Decoderen mislukt
# unlocked.fxml # unlocked.fxml
@@ -56,7 +58,7 @@ unlocked.ioGraph.yAxis.label = Doorvoer (MiB/s)
macWarnings.windowTitle = Pas op - Corrupt bestand in %s macWarnings.windowTitle = Pas op - Corrupt bestand in %s
macWarnings.message = Cryptomator heeft mogelijk kwaadwillende corrupte items aangetroffen in de volgende bestanden\: macWarnings.message = Cryptomator heeft mogelijk kwaadwillende corrupte items aangetroffen in de volgende bestanden\:
macWarnings.moreInformationButton = Leer meer macWarnings.moreInformationButton = Leer meer
macWarnings.whitelistButton = Desondanks selectie decoderen macWarnings.whitelistButton = Geselecteerde toch Decoderen
# settings.fxml # settings.fxml
settings.version.label = Versie %s settings.version.label = Versie %s
settings.checkForUpdates.label = Controleer op updates settings.checkForUpdates.label = Controleer op updates
@@ -67,9 +69,9 @@ settings.requiresRestartLabel = * Cryptomator dient te worden herstart
# tray icon # tray icon
tray.menu.open = Open tray.menu.open = Open
tray.menu.quit = Afsluiten tray.menu.quit = Afsluiten
tray.infoMsg.title = Nog steeds actief tray.infoMsg.title = Nog Steeds Actief
tray.infoMsg.msg = Cryptomator is nog steeds actief. Sluit het af via het icon in het systeemvak. tray.infoMsg.msg = Cryptomator is nog steeds actief. Sluit af via het icoon in het systeemvak.
tray.infoMsg.msg.osx = Cryptomator is nog steeds actief. Sluit het af via het icon op de menubalk. tray.infoMsg.msg.osx = Cryptomator is nog steeds actief. Sluit af via het icoon op de menubalk.
initialize.messageLabel.passwordStrength.0 = Zeer zwak initialize.messageLabel.passwordStrength.0 = Zeer zwak
initialize.messageLabel.passwordStrength.1 = Zwak initialize.messageLabel.passwordStrength.1 = Zwak
initialize.messageLabel.passwordStrength.2 = Redelijk initialize.messageLabel.passwordStrength.2 = Redelijk
@@ -85,5 +87,15 @@ settings.prefGvfsScheme.label = WebDAV schema
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Ja, ik heb geverifieerd dat de synchronisatie voltooid is upgrade.confirmation.label = Ja, ik heb geverifieerd dat de synchronisatie voltooid is
initialize.messageLabel.notEmpty = Kluis niet leeg initialize.messageLabel.notEmpty = Kluis niet leeg
unlock.label.savePassword = Wachtwoord bewaren unlock.label.savePassword = Wachtwoord Opslaan
unlock.errorMessage.unauthenticVersionMac = MAC authenticatie mislukt unlock.errorMessage.unauthenticVersionMac = MAC authenticatie mislukt
unlocked.label.mountFailed = Verbinden van schijf mislukt
unlock.savePassword.delete.confirmation.title = Verwijder Opgeslagen Wachtwoord
unlock.savePassword.delete.confirmation.header = Ben je zeker dat je het opgeslagen wachtwoord van deze kluis wilt verwijderen?
unlock.savePassword.delete.confirmation.content = Het opgeslagen wachtwoord van deze kluis zal onmiddellijk verwijderd worden van je systeem sleutelhanger. Als je opnieuw je wachtwoord wilt opslaan, zal je je kluis moeten ontgrendelen met de optie "Sla wachtwoord op" aan.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Kluis Versie 3 Upgrade (Drop Bundel Extensie)
upgrade.version3to4.title = Kluis Versie 3 naar 4 Upgrade
upgrade.version4to5.title = Kluis Versie 4 naar 5 Upgrade
upgrade.version4to5.msg = Deze kluis moet gemigreerd worden naar een nieuw formaat.\nVersleutelde bestanden zullen bijgewerkt worden.\nZorg ervoor dat synchronisatie voltooid is alvorens verder te gaan.\n\nLet op\: Tijdens dit proces zal de wijzigingsdatum van alle bestanden gewijzigd worden naar de huidige datum/tijd.
upgrade.version4to5.err.io = Migratie mislukt door een I/O Exception. Bekijk log file voor details.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Wszystkie wersje Cryptomatora
changePassword.button.change = Zmień hasło changePassword.button.change = Zmień hasło
changePassword.errorMessage.wrongPassword = Złe hasło changePassword.errorMessage.wrongPassword = Złe hasło
changePassword.errorMessage.decryptionFailed = Błąd deszyfracji changePassword.errorMessage.decryptionFailed = Błąd deszyfracji
changePassword.infoMessage.success = Hasło zmienione
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Zablokuj kryptę unlocked.button.lock = Zablokuj kryptę
unlocked.moreOptions.reveal = Zwolnij napęd unlocked.moreOptions.reveal = Zwolnij napęd
@@ -85,6 +84,16 @@ upgrade.version3to4.err.io = Błąd migracji I/O Exception. Sprawdź logi
settings.prefGvfsScheme.label = Schemat WebDAV settings.prefGvfsScheme.label = Schemat WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Tak, jestem pewien, że zakończyłem synchronizacje upgrade.confirmation.label = Tak, jestem pewien, że zakończyłem synchronizacje
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Krypta pusta
unlock.label.savePassword = Save password unlock.label.savePassword = Zapisz hasło
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Nie udało się uwierzytelnić wersji MAC
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -1,24 +1,24 @@
app.name = Cryptomator app.name = Cryptomator
# main.fxml # main.fxml
main.emptyListInstructions = Clique aqui para adicionar uma caixa-forte main.emptyListInstructions = Clique aqui para adicionar um cofre
main.directoryList.contextMenu.remove = Remover da lista main.directoryList.contextMenu.remove = Remover da lista
main.directoryList.contextMenu.changePassword = Alterar senha main.directoryList.contextMenu.changePassword = Alterar senha
main.addDirectory.contextMenu.new = Criar nova caixa-forte main.addDirectory.contextMenu.new = Criar um novo cofre
main.addDirectory.contextMenu.open = Abrir caixa-forte existente main.addDirectory.contextMenu.open = Abrir um cofre já existente
# welcome.fxml # welcome.fxml
welcome.checkForUpdates.label.currentlyChecking = Buscando por atualizações... welcome.checkForUpdates.label.currentlyChecking = Buscando por atualizações...
welcome.newVersionMessage = Versão %1$s pode ser abaixada. Esta é a versão %2$s. welcome.newVersionMessage = Versão %1$s pode ser baixada. Esta é a versão %2$s.
# initialize.fxml # initialize.fxml
initialize.label.password = Senha initialize.label.password = Senha
initialize.label.retypePassword = Redigitar senha initialize.label.retypePassword = Redigite a senha
initialize.button.ok = Criar caixa-forte initialize.button.ok = Criar cofre
initialize.messageLabel.alreadyInitialized = Caixa-forte já inicializada initialize.messageLabel.alreadyInitialized = Cofre já inicializado
initialize.messageLabel.initializationFailed = Não pôde inicializar a caixa-forte. Ver arquivo de log para mais detalhes. initialize.messageLabel.initializationFailed = Não pôde inicializar o cofre. Veja o arquivo de log para mais detalhes.
# notfound.fxml # notfound.fxml
notfound.label = A caixa-forte não pode ser encontrada. Ela foi movida? notfound.label = O cofre não pode ser encontrado. Pode ter sido movido?
# upgrade.fxml # upgrade.fxml
upgrade.button = Atualizar caixa-forte upgrade.button = Atualizar cofre
upgrade.version3dropBundleExtension.msg = Esta caixa-forte tem que ser a migrada a um novo formato. "%1$s" será renomeada para "%2$s". Por favor assegure-se de que a sincronização foi finalizada antes de proceder com a migração. upgrade.version3dropBundleExtension.msg = Esse cofre tem que ser migrado paraa um novo formato. "%1$s" será renomeada para "%2$s". Por favor assegure-se de que a sincronização foi finalizada antes de proceder com a migração.
upgrade.version3dropBundleExtension.err.alreadyExists = A migração automática falhou. "%s" já existe. upgrade.version3dropBundleExtension.err.alreadyExists = A migração automática falhou. "%s" já existe.
# unlock.fxml # unlock.fxml
unlock.label.password = Senha unlock.label.password = Senha
@@ -26,45 +26,46 @@ unlock.label.mountName = Nome do drive
unlock.label.winDriveLetter = Letra do drive unlock.label.winDriveLetter = Letra do drive
unlock.label.downloadsPageLink = Todas as versões do Cryptomator unlock.label.downloadsPageLink = Todas as versões do Cryptomator
unlock.label.advancedHeading = Opções avançadas unlock.label.advancedHeading = Opções avançadas
unlock.button.unlock = Abrir caixa-forte unlock.button.unlock = Abrir cofre
unlock.button.advancedOptions.show = Mais opções unlock.button.advancedOptions.show = Mais opções
unlock.button.advancedOptions.hide = Menos opções unlock.button.advancedOptions.hide = Menos opções
unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente unlock.choicebox.winDriveLetter.auto = Atribuir automaticamente
unlock.errorMessage.wrongPassword = Senha errada unlock.errorMessage.wrongPassword = Senha errada
unlock.errorMessage.mountingFailed = Falha ao montar. Ver arquivo de log para mais detalhes. unlock.errorMessage.mountingFailed = Falha ao montar. Veja o arquivo de log para mais detalhes.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Caixa-forte não suportada. Esta caixa-forte foi criada por uma versão antiga do Cryptomator. unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware = Cofre não suportado. Esse cofre foi criado por uma versão antiga do Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Caixa-forte não suportada. Esta caixa-forte foi criada por uma versão mais nova do Cryptomator. unlock.errorMessage.unsupportedVersion.softwareOlderThanVault = Cofre não suportado. Esse cofre foi criado por uma versão mais nova do Cryptomator.
unlock.messageLabel.startServerFailed = Falha ao iniciar servidor WebDAV. unlock.messageLabel.startServerFailed = Falha ao iniciar servidor WebDAV.
# change_password.fxml # change_password.fxml
changePassword.label.oldPassword = Senha anterior changePassword.label.oldPassword = Senha atual
changePassword.label.newPassword = Nova senha changePassword.label.newPassword = Nova senha
changePassword.label.retypePassword = Re-digitar senha changePassword.label.retypePassword = Re-digitar senha
changePassword.label.downloadsPageLink = Todas as versões do Cryptomator changePassword.label.downloadsPageLink = Todas as versões do Cryptomator
changePassword.button.change = Alterar senha changePassword.button.change = Alterar senha
changePassword.errorMessage.wrongPassword = Senha incorreta changePassword.errorMessage.wrongPassword = Senha incorreta
changePassword.errorMessage.decryptionFailed = Falha ao desencriptar changePassword.errorMessage.decryptionFailed = Falha ao desencriptar
changePassword.infoMessage.success = Senha alterada
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Fechar caixa-forte unlocked.button.lock = Fechar cofre
unlocked.moreOptions.reveal = Mostrar drive unlocked.moreOptions.reveal = Mostrar drive
unlocked.moreOptions.copyUrl = Copiar URL WebDAV unlocked.moreOptions.copyUrl = Copiar URL WebDAV
unlocked.label.revealFailed = Falha ao mostrar drive unlocked.label.revealFailed = Falha ao mostrar drive
unlocked.label.unmountFailed = Falha ao ejetar drive unlocked.label.unmountFailed = Falha ao ejetar drive
unlocked.label.statsEncrypted = encriptado unlocked.label.statsEncrypted = Encriptado
unlocked.label.statsDecrypted = desencriptado unlocked.label.statsDecrypted = Desencriptado
unlocked.ioGraph.yAxis.label = Taxa de transferência (MiB/s) unlocked.ioGraph.yAxis.label = Taxa de transferência (MiB/s)
# mac_warnings.fxml # mac_warnings.fxml
macWarnings.windowTitle = Perigo - Arquivo corrompido na %s macWarnings.windowTitle = Perigo - Arquivo corrompido na %s
# Fuzzy
macWarnings.message = Cryptomator detectou potenciais corrupções maliciosas nos seguintes arquivos\: macWarnings.message = Cryptomator detectou potenciais corrupções maliciosas nos seguintes arquivos\:
macWarnings.moreInformationButton = Saiba mais macWarnings.moreInformationButton = Saiba mais
# Fuzzy
macWarnings.whitelistButton = Desencriptar selecionado de qualquer modo macWarnings.whitelistButton = Desencriptar selecionado de qualquer modo
# settings.fxml # settings.fxml
settings.version.label = Versão %s settings.version.label = Versão %s
settings.checkForUpdates.label = Verificar por atualizações settings.checkForUpdates.label = Verificar por atualizações
settings.port.label = Port WebDAV * settings.port.label = Porta WebDAV *
settings.port.prompt = 0 \= Escolher automaticamente settings.port.prompt = 0 \= Escolher automaticamente
settings.useipv6.label = Usar IPv6 literal settings.useipv6.label = Usar IPv6 literal
settings.requiresRestartLabel = * Cryptomator necessita ser reiniciado settings.requiresRestartLabel = * Cryptomator precisa ser reiniciado
# tray icon # tray icon
tray.menu.open = Abrir tray.menu.open = Abrir
tray.menu.quit = Sair tray.menu.quit = Sair
@@ -77,14 +78,24 @@ initialize.messageLabel.passwordStrength.2 = Razoável
initialize.messageLabel.passwordStrength.3 = Forte initialize.messageLabel.passwordStrength.3 = Forte
initialize.messageLabel.passwordStrength.4 = Muito forte initialize.messageLabel.passwordStrength.4 = Muito forte
initialize.label.doNotForget = IMPORTANTE\: se você esquecer a sua senha, não haverá como recuperar os seus dados. initialize.label.doNotForget = IMPORTANTE\: se você esquecer a sua senha, não haverá como recuperar os seus dados.
main.directoryList.remove.confirmation.title = Remover caixa-forte main.directoryList.remove.confirmation.title = Remover cofre
main.directoryList.remove.confirmation.header = Você realmente quer remover esta caixa-forte? main.directoryList.remove.confirmation.header = Você realmente quer remover esse cofre?
main.directoryList.remove.confirmation.content = A caixa-forte somente será removida da lista. Para apagá-la permanentemente, por favor apagar os arquivos do seu sistema de arquivos. main.directoryList.remove.confirmation.content = O cofre somente será removido da lista. Para apagá-lo permanentemente, por favor apagar os arquivos do seu sistema de arquivos.
upgrade.version3to4.msg = Esta caixa-forte tem que ser migrada a um novo formato. Os nomes das pastas encriptadas serão atualizados. Por favor assegure-se de que a sincronização foi finalizada antes de proceder com a migração. upgrade.version3to4.msg = Esse cofre tem que ser migrado a um novo formato. Os nomes das pastas encriptadas serão atualizados. Por favor, assegure-se de que a sincronização do cofre foi finalizada antes de proceder com a sua migração.
upgrade.version3to4.err.io = Falha na migração devido a um erro de E/S. Ver arquivo de log para mais detalhes. upgrade.version3to4.err.io = Falha na migração devido a um erro de E/S. Veja o arquivo de log para mais detalhes.
settings.prefGvfsScheme.label = WebDAV scheme settings.prefGvfsScheme.label = Esquema WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Sim, tenho certeza de que a sincronização foi concluída
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Cofre não vazio
unlock.label.savePassword = Save password unlock.label.savePassword = Armazenar senha
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Não foi possível autenticar a versão do MAC.
unlocked.label.mountFailed = Falha ao conectar o drive
unlock.savePassword.delete.confirmation.title = Apagar a senha armazenada
unlock.savePassword.delete.confirmation.header = Você realmente quer apagar a senha armazenada deste cofre?
unlock.savePassword.delete.confirmation.content = A senha deste cofre que se encontra armazenada será imediatamente apagada do gestor de senhas do seu sistema. Se você quiser armazenar a sua senha novamente, você terá que abrir o seu cofre com a opção "Armazenar Senha" habilitada.
settings.debugMode.label = Modo de Debug *
upgrade.version3dropBundleExtension.title = Atualização para a versão 3 do cofre (Drop Bundle Extension)
upgrade.version3to4.title = Atualização do cofre da versão 3 para 4
upgrade.version4to5.title = Atualização do cofre da versão 4 para 5
upgrade.version4to5.msg = Este cofre precisa ser migrado a um novo formato.\nOs arquivos encriptados serão atualizados.\nPor favor, assegure-se de que a sincronização do cofre foi finalizada antes de proceder com a sua migração.\n\nNota\: A data de modificação de todos os arquivos do cofre será alterada durante o processo para a data e hora corrente.
upgrade.version4to5.err.io = A migração falhou devido a uma exceção de I/O. Ver arquivo de log para mais detalhes.

View File

@@ -44,7 +44,6 @@ changePassword.label.downloadsPageLink = Все версии Cryptomator
changePassword.button.change = Сменить пароль changePassword.button.change = Сменить пароль
changePassword.errorMessage.wrongPassword = Неверный пароль changePassword.errorMessage.wrongPassword = Неверный пароль
changePassword.errorMessage.decryptionFailed = Ошибка дешифрования changePassword.errorMessage.decryptionFailed = Ошибка дешифрования
changePassword.infoMessage.success = Пароль изменён
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Заблокировать хранилище unlocked.button.lock = Заблокировать хранилище
# Does it mean "open" drive? # Does it mean "open" drive?
@@ -87,6 +86,16 @@ upgrade.version3to4.err.io = Преобразование не выполнен
settings.prefGvfsScheme.label = Схема WebDAV settings.prefGvfsScheme.label = Схема WebDAV
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Да, синхронизация точно завершена upgrade.confirmation.label = Да, синхронизация точно завершена
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Хранилище не пусто
unlock.label.savePassword = Save password unlock.label.savePassword = Сохранить пароль
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Не удалось идентифицировать версию MAC.
unlocked.label.mountFailed = Ошибка подключения к диску
unlock.savePassword.delete.confirmation.title = Удалить сохранённый пароль
unlock.savePassword.delete.confirmation.header = Вы действительно хотите удалить сохранённый пароль для этого хранилища?
unlock.savePassword.delete.confirmation.content = Сохранённый пароль от этого хранилища будет немедленно удалён из системной связки ключей. Если вы снова захотите сохранить пароль, вам придётся разблокировать хранилище с включённой опцией "Сохранить пароль".
settings.debugMode.label = Режим отладки *
upgrade.version3dropBundleExtension.title = Обновление хранилища версии 3 (Drop Bundle Extension)
upgrade.version3to4.title = Обновление хранилища с версии 3 на 4
upgrade.version4to5.title = Обновление хранилища с версии 4 на 5
upgrade.version4to5.msg = Это хранилище нужно преобразовать в более новый формат.\nЗашифрованные файлы будут обновлены.\nПрежде чем продолжить, убедитесь, что завершена синхронизация.\n\nПримечание\: даты изменения всех файлов будут изменены на текущие дату и время на момент обработки.
upgrade.version4to5.err.io = Преобразование не выполнено из-за исключения ввода-вывода. См. подробности в отчёте.

View File

@@ -46,7 +46,6 @@ changePassword.label.downloadsPageLink = Všetky verzie Cryptomatoru.
changePassword.button.change = Zmeniť heslo changePassword.button.change = Zmeniť heslo
changePassword.errorMessage.wrongPassword = Nesprávne heslo changePassword.errorMessage.wrongPassword = Nesprávne heslo
changePassword.errorMessage.decryptionFailed = Dešifrovanie zlyhalo. changePassword.errorMessage.decryptionFailed = Dešifrovanie zlyhalo.
changePassword.infoMessage.success = Heslo zmenené
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Zamknúť trezor unlocked.button.lock = Zamknúť trezor
unlocked.moreOptions.reveal = Odhaliť jednotku unlocked.moreOptions.reveal = Odhaliť jednotku
@@ -74,20 +73,30 @@ tray.menu.quit = Vypnúť
tray.infoMsg.title = Stále beží tray.infoMsg.title = Stále beží
tray.infoMsg.msg = Cryptomator je stále spustený. Vypnite ho pomocou ikony v systémovej lište. tray.infoMsg.msg = Cryptomator je stále spustený. Vypnite ho pomocou ikony v systémovej lište.
tray.infoMsg.msg.osx = Cryptomator je stále sputený. Ukončite ho pomocou ikony v menu. tray.infoMsg.msg.osx = Cryptomator je stále sputený. Ukončite ho pomocou ikony v menu.
initialize.messageLabel.passwordStrength.0 = Very weak initialize.messageLabel.passwordStrength.0 = Veľmi slabé
initialize.messageLabel.passwordStrength.1 = Weak initialize.messageLabel.passwordStrength.1 = Slabé
initialize.messageLabel.passwordStrength.2 = Fair initialize.messageLabel.passwordStrength.2 = Dobré
initialize.messageLabel.passwordStrength.3 = Strong initialize.messageLabel.passwordStrength.3 = Silné
initialize.messageLabel.passwordStrength.4 = Very strong initialize.messageLabel.passwordStrength.4 = Veľmi silné
initialize.label.doNotForget = IMPORTANT\: If you forget your password, there is no way to recover your data. initialize.label.doNotForget = DÔLEŽITÉ\: Ak zabudnete heslo, nie je možné získať späť vaše dáta.
main.directoryList.remove.confirmation.title = Remove Vault main.directoryList.remove.confirmation.title = Odstrániť trezor
main.directoryList.remove.confirmation.header = Do you really want to remove this vault? main.directoryList.remove.confirmation.header = Skutočne chcete odstrániť tento trezor?
main.directoryList.remove.confirmation.content = The vault will only be removed from the list. To permanently delete it, please delete the files from your filesystem. main.directoryList.remove.confirmation.content = Trezor bude odstránení zo zoznamu. Pre úplné zmazanie vymažte súbor s trezorom.
upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding. upgrade.version3to4.msg = This vault needs to be migrated to a newer format.\nEncrypted folder names will be updated.\nPlease make sure synchronization has finished before proceeding.
upgrade.version3to4.err.io = Migration failed due to an I/O Exception. See log file for details. upgrade.version3to4.err.io = Migrácia zlyhala kvôli I/O Exception. Skontrolujte log pre viac detailov
settings.prefGvfsScheme.label = WebDAV scheme settings.prefGvfsScheme.label = WebDAV Schéma
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Áno, som si istý že synchronizácia je hotová
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Trezor nie je prázdny
unlock.label.savePassword = Save password unlock.label.savePassword = Uložiť heslo
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Zmazať uložené heslo
unlock.savePassword.delete.confirmation.header = Naozaj chcete zmazať uložené heslo pre tento trezor?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Tüm Cryptomator sürümleri
changePassword.button.change = Şifreyi değiştir changePassword.button.change = Şifreyi değiştir
changePassword.errorMessage.wrongPassword = Yanlış şifre changePassword.errorMessage.wrongPassword = Yanlış şifre
changePassword.errorMessage.decryptionFailed = Şifre çözme başarısız changePassword.errorMessage.decryptionFailed = Şifre çözme başarısız
changePassword.infoMessage.success = Şifre değiştirildi.
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Kasayı kilitle unlocked.button.lock = Kasayı kilitle
unlocked.moreOptions.reveal = Sürücüyü göster unlocked.moreOptions.reveal = Sürücüyü göster
@@ -82,9 +81,19 @@ main.directoryList.remove.confirmation.header = Kasayı silmek istediğinize emi
main.directoryList.remove.confirmation.content = Kasa yalnızca listeden silinecek. Tamamen silmek için dosya sisteminizden dosyaları elle siliniz. main.directoryList.remove.confirmation.content = Kasa yalnızca listeden silinecek. Tamamen silmek için dosya sisteminizden dosyaları elle siliniz.
upgrade.version3to4.msg = Bu kasanın yeni formata geçirilmesi gerekmekte. Şifreli klasör isimleri güncellenecek. Devam etmeden önce senkronizasyonun bittiğine emin olun. upgrade.version3to4.msg = Bu kasanın yeni formata geçirilmesi gerekmekte. Şifreli klasör isimleri güncellenecek. Devam etmeden önce senkronizasyonun bittiğine emin olun.
upgrade.version3to4.err.io = Format değiştirme işlemi I/O Hatası dolayısı ile başarısız oldu. Detaylar için log dosyasına bakın upgrade.version3to4.err.io = Format değiştirme işlemi I/O Hatası dolayısı ile başarısız oldu. Detaylar için log dosyasına bakın
settings.prefGvfsScheme.label = WebDAV scheme settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -43,7 +43,6 @@ changePassword.label.downloadsPageLink = Всі версії Cryptomator
changePassword.button.change = Змінити пароль changePassword.button.change = Змінити пароль
changePassword.errorMessage.wrongPassword = Пароль невірний changePassword.errorMessage.wrongPassword = Пароль невірний
changePassword.errorMessage.decryptionFailed = Розшифрування невдале changePassword.errorMessage.decryptionFailed = Розшифрування невдале
changePassword.infoMessage.success = Пароль змінений
# unlocked.fxml # unlocked.fxml
unlocked.button.lock = Заблокувати сховище unlocked.button.lock = Заблокувати сховище
unlocked.moreOptions.reveal = Відкрити накопичувач unlocked.moreOptions.reveal = Відкрити накопичувач
@@ -82,9 +81,19 @@ main.directoryList.remove.confirmation.header = Ви дійсно хочете
main.directoryList.remove.confirmation.content = Сховище буде видалене тільки зі списку. Щоб стерти його остаточно, видаліть файли із файлової системи. main.directoryList.remove.confirmation.content = Сховище буде видалене тільки зі списку. Щоб стерти його остаточно, видаліть файли із файлової системи.
upgrade.version3to4.msg = Це сховище необхідно перетворити в новий формат. Зашифровані імена папок будуть оновлені. Перш ніж продовжити, виконайте синхронізацію. upgrade.version3to4.msg = Це сховище необхідно перетворити в новий формат. Зашифровані імена папок будуть оновлені. Перш ніж продовжити, виконайте синхронізацію.
upgrade.version3to4.err.io = Перетворення невдале через помилку введення-виведення. Дивіться деталі в файлі-звіті. upgrade.version3to4.err.io = Перетворення невдале через помилку введення-виведення. Дивіться деталі в файлі-звіті.
settings.prefGvfsScheme.label = WebDAV scheme settings.prefGvfsScheme.label = WebDAV Scheme
# upgrade.fxml # upgrade.fxml
upgrade.confirmation.label = Yes, I've made sure that synchronization has finished upgrade.confirmation.label = Yes, I've made sure that synchronization has finished
initialize.messageLabel.notEmpty = Vault not empty initialize.messageLabel.notEmpty = Vault not empty
unlock.label.savePassword = Save password unlock.label.savePassword = Save Password
unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC. unlock.errorMessage.unauthenticVersionMac = Could not authenticate version MAC.
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -88,4 +88,14 @@ upgrade.confirmation.label = 是的,我确保同步已完成
initialize.messageLabel.notEmpty = 保险柜非空 initialize.messageLabel.notEmpty = 保险柜非空
unlock.label.savePassword = 保存密码 unlock.label.savePassword = 保存密码
# This Mac means Mac(Apple) or Mac address? # This Mac means Mac(Apple) or Mac address?
unlock.errorMessage.unauthenticVersionMac = 无法验证消息验证代码的版本。 unlock.errorMessage.unauthenticVersionMac = 无法验证消息验证代码的版本。
unlocked.label.mountFailed = 连接设备失败
unlock.savePassword.delete.confirmation.title = 删除已保存的密码
unlock.savePassword.delete.confirmation.header = 您真的要删除此密码库已保存的密码吗?
unlock.savePassword.delete.confirmation.content = 此密码库保存的密码将立即从系统钥匙串中删除。如果您想再次保存密码,则必须通过启用“保存密码”选项启用您的密码库。
settings.debugMode.label = 调试模式 *
upgrade.version3dropBundleExtension.title = 升级Vault版本3Drop Bundle Extension
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -86,4 +86,14 @@ settings.prefGvfsScheme.label = WebDAV的格式
upgrade.confirmation.label = 是的,請確認同步已完成。 upgrade.confirmation.label = 是的,請確認同步已完成。
initialize.messageLabel.notEmpty = 檔案庫不是空的 initialize.messageLabel.notEmpty = 檔案庫不是空的
unlock.label.savePassword = 儲存密碼 unlock.label.savePassword = 儲存密碼
unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。 unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -86,4 +86,14 @@ settings.prefGvfsScheme.label = WebDAV 格式
upgrade.confirmation.label = 是的,請確認同步已完成。 upgrade.confirmation.label = 是的,請確認同步已完成。
initialize.messageLabel.notEmpty = 檔案庫不是空的 initialize.messageLabel.notEmpty = 檔案庫不是空的
unlock.label.savePassword = 儲存密碼 unlock.label.savePassword = 儲存密碼
unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。 unlock.errorMessage.unauthenticVersionMac = 無法認證消息驗證碼版本。
unlocked.label.mountFailed = Connecting drive failed
unlock.savePassword.delete.confirmation.title = Delete Saved Password
unlock.savePassword.delete.confirmation.header = Do you really want to delete the saved password of this vault?
unlock.savePassword.delete.confirmation.content = The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save password" option enabled.
settings.debugMode.label = Debug Mode *
upgrade.version3dropBundleExtension.title = Vault Version 3 Upgrade (Drop Bundle Extension)
upgrade.version3to4.title = Vault Version 3 to 4 Upgrade
upgrade.version4to5.title = Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg = This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote\: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io = Migration failed due to an I/O Exception. See log file for details.

View File

@@ -27,9 +27,13 @@
</Appenders> </Appenders>
<Loggers> <Loggers>
<!-- package-specific config: --> <!--
<Logger name="org.cryptomator" level="DEBUG" /> = NOTE =
<Logger name="org.eclipse.jetty.server.Server" level="DEBUG" /> All loggers below are set to info.
This is required to allow changing the levels of the loggers programmatically.
-->
<Logger name="org.cryptomator" level="INFO" />
<Logger name="org.eclipse.jetty.server.Server" level="INFO" />
<Logger name="org.cryptomator.ui.model" level="INFO"> <Logger name="org.cryptomator.ui.model" level="INFO">
<AppenderRef ref="UpgradeLog" /> <AppenderRef ref="UpgradeLog" />
</Logger> </Logger>

View File

@@ -31,8 +31,8 @@ public class LocalizationTest {
private static final Logger LOG = LoggerFactory.getLogger(LocalizationTest.class); private static final Logger LOG = LoggerFactory.getLogger(LocalizationTest.class);
private static final String RESOURCE_FOLDER_PATH = "/localization/"; private static final String RESOURCE_FOLDER_PATH = "/localization/";
private static final String REF_FILE_NAME = "en.txt"; private static final String REF_FILE_NAME = "en.txt";
private static final String[] LANG_FILE_NAMES = {"de.txt", "es.txt", "fr.txt", "hu.txt", "it.txt", "kr.txt", "lv.txt", "nl.txt", "pl.txt", "pt.txt", "ru.txt", "sk.txt", "tr.txt", "uk.txt", "zh_HK.txt", "zh_TW.txt", private static final String[] LANG_FILE_NAMES = {"de.txt", "es.txt", "fr.txt", "hu.txt", "it.txt", "ja.txt", "kr.txt", "lv.txt", "nl.txt", "pl.txt", "pt.txt", "ru.txt", "sk.txt", "tr.txt", "uk.txt", "zh_HK.txt",
"zh.txt"}; "zh_TW.txt", "zh.txt"};
/* /*
* @see Formatter * @see Formatter