mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-09-23 08:24:52 +00:00
Compare commits
89
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a0c03eacc | ||
|
|
ab10a139a7 | ||
|
|
1184ba6748 | ||
|
|
b1bf84a332 | ||
|
|
9397cbf18a | ||
|
|
354225bf1e | ||
|
|
0d4f373311 | ||
|
|
1da535e89c | ||
|
|
941b4e3652 | ||
|
|
dd1af8cd78 | ||
|
|
27ea29ab9d | ||
|
|
a699a794a9 | ||
|
|
cd6b1cf129 | ||
|
|
7d2c4992af | ||
|
|
6a21d24687 | ||
|
|
cba6ed9875 | ||
|
|
72fdc8f536 | ||
|
|
41336cca13 | ||
|
|
322907bbcd | ||
|
|
1f8df6fead | ||
|
|
6e085b783d | ||
|
|
59dddd3f4c | ||
|
|
d6bbcfbbc1 | ||
|
|
7260d7f9f8 | ||
|
|
c39c4be1cd | ||
|
|
565ab4a09b | ||
|
|
f797491a17 | ||
|
|
cff83b6ac6 | ||
|
|
6f9b3e31e7 | ||
|
|
0a0dde3f47 | ||
|
|
e27e303c01 | ||
|
|
ef54b685f6 | ||
|
|
0370fd5848 | ||
|
|
119d18d699 | ||
|
|
8322633b14 | ||
|
|
2f32fc5c16 | ||
|
|
7c44c4f194 | ||
|
|
bbb663f9d2 | ||
|
|
fdb4a2fb5c | ||
|
|
0a4684133d | ||
|
|
0d5e518af3 | ||
|
|
d47ab43fcf | ||
|
|
19a711d12b | ||
|
|
bf2db55d00 | ||
|
|
885975e099 | ||
|
|
85c2901484 | ||
|
|
434030b139 | ||
|
|
e43bb37758 | ||
|
|
2eb9f0fca8 | ||
|
|
9503feb9c4 | ||
|
|
08e9f130e4 | ||
|
|
4e39eaa1f1 | ||
|
|
eaca95e8dc | ||
|
|
cf32e794c8 | ||
|
|
b5b221a5c7 | ||
|
|
d7cb99a12d | ||
|
|
b1893c63d4 | ||
|
|
79b3274074 | ||
|
|
7c86e5e39a | ||
|
|
b50cc703b6 | ||
|
|
9dc4a1dc5a | ||
|
|
f1a63a1679 | ||
|
|
d53d4e3452 | ||
|
|
b7fa1ae6d8 | ||
|
|
3f192a587c | ||
|
|
3a1b0b17d6 | ||
|
|
5d2a243c55 | ||
|
|
008a2a3301 | ||
|
|
0680437004 | ||
|
|
db6cf5459e | ||
|
|
1d8466a9e3 | ||
|
|
dcbcd692e7 | ||
|
|
87fd6c712a | ||
|
|
958505559f | ||
|
|
4736e5e7e7 | ||
|
|
55d217887a | ||
|
|
34ccd3ff73 | ||
|
|
989c349331 | ||
|
|
b9df56a6de | ||
|
|
38dbefff0b | ||
|
|
4cbe45919b | ||
|
|
b7ccf7986d | ||
|
|
40d632a489 | ||
|
|
800aca5207 | ||
|
|
6a26d95c15 | ||
|
|
439d3d7529 | ||
|
|
7476e192a3 | ||
|
|
c6193bc259 | ||
|
|
7446c69cd8 |
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
- Suggest your change by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new/choose) and start writing code.
|
- Suggest your change by [submitting a new issue](https://github.com/cryptomator/cryptomator/issues/new/choose) and start writing code.
|
||||||
|
|
||||||
|
## Do you intend to add a new translation or change an existing one?
|
||||||
|
|
||||||
|
Translations are not managed directly in this repository. Instead, we use [Crowdin](https://translate.cryptomator.org/), which automatically synchronizes translations with this repository. If you want to help us with translations, please visit our translation project on Crowdin.
|
||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
|
|
||||||
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md).
|
Help us keep Cryptomator open and inclusive. Please read and follow our [Code of Conduct](https://github.com/cryptomator/cryptomator/blob/develop/.github/CODE_OF_CONDUCT.md).
|
||||||
|
|||||||
@@ -8,16 +8,24 @@ on:
|
|||||||
version:
|
version:
|
||||||
description: 'Version'
|
description: 'Version'
|
||||||
required: false
|
required: false
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/appimage.yml'
|
||||||
|
- 'dist/linux/appimage/**'
|
||||||
|
- 'dist/linux/common/**'
|
||||||
|
- 'dist/linux/resources/**'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'temurin'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: '23.0.1+11'
|
JAVA_VERSION: '24.0.1+9'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-version:
|
get-version:
|
||||||
uses: ./.github/workflows/get-version.yml
|
uses: ./.github/workflows/get-version.yml
|
||||||
with:
|
with:
|
||||||
version: ${{ inputs.version }}
|
version: ${{ inputs.version }} #okay if not defined
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build AppImage
|
name: Build AppImage
|
||||||
@@ -29,12 +37,12 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
appimage-suffix: x86_64
|
appimage-suffix: x86_64
|
||||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_linux-x64_bin-jmods.zip'
|
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-x64_bin-jmods.zip'
|
||||||
openjfx-sha: '2164bca470bf70a5e2764645e2078ba7f787b274e5be3d7df30d87c5bb62bba6'
|
openjfx-sha: '425fac742b9fbd095b2ce868cff82d1024620f747c94a7144d0a4879e756146c'
|
||||||
- os: ubuntu-24.04-arm
|
- os: ubuntu-24.04-arm
|
||||||
appimage-suffix: aarch64
|
appimage-suffix: aarch64
|
||||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_linux-aarch64_bin-jmods.zip'
|
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-aarch64_bin-jmods.zip'
|
||||||
openjfx-sha: '09c92fa9fa0b82adefd88640a14ebb2a49e5f3f733a57d1542f5590d060ffe1b'
|
openjfx-sha: '7e02edd0f4ee5527a27c94b0bbba66fcaaff41009119e45d0eca0f96ddfb6e7b'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
@@ -61,7 +69,7 @@ jobs:
|
|||||||
POM_JFX_VERSION=${POM_JFX_VERSION#*@}
|
POM_JFX_VERSION=${POM_JFX_VERSION#*@}
|
||||||
POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
|
POM_JFX_VERSION=${POM_JFX_VERSION%%.*}
|
||||||
|
|
||||||
if [ $POM_JFX_VERSION -ne $JMOD_VERSION_AMD64 ]; then
|
if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then
|
||||||
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION})"
|
>&2 echo "Major JavaFX version in pom.xml (${POM_JFX_VERSION}) != amd64 jmod version (${JMOD_VERSION})"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -73,13 +81,21 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cp LICENSE.txt target
|
cp LICENSE.txt target
|
||||||
cp target/cryptomator-*.jar target/mods
|
cp target/cryptomator-*.jar target/mods
|
||||||
|
- name: Run jlink with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
- name: Run jlink
|
- name: Run jlink
|
||||||
#Remark: no compression is applied for improved build compression later (here appimage)
|
#Remark: no compression is applied for improved build compression later (here appimage)
|
||||||
run: >
|
run: >
|
||||||
${JAVA_HOME}/bin/jlink
|
${JAVA_HOME}/bin/jlink
|
||||||
--verbose
|
--verbose
|
||||||
--output runtime
|
--output runtime
|
||||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods"
|
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler
|
||||||
--strip-native-commands
|
--strip-native-commands
|
||||||
--no-header-files
|
--no-header-files
|
||||||
@@ -101,7 +117,7 @@ jobs:
|
|||||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||||
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
||||||
--java-options "--enable-preview"
|
--java-options "--enable-preview"
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator"
|
||||||
--java-options "-Xss5m"
|
--java-options "-Xss5m"
|
||||||
--java-options "-Xmx256m"
|
--java-options "-Xmx256m"
|
||||||
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
|
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
|
||||||
|
|||||||
@@ -13,15 +13,48 @@ on:
|
|||||||
description: "Url to the file to upload"
|
description: "Url to the file to upload"
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
avast:
|
||||||
|
description: "Upload to Avast"
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
kaspersky:
|
||||||
|
description: "Upload to Kaspersky"
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
allowlist:
|
download-file:
|
||||||
name: Anti Virus Allowlisting
|
name: Downloads the file into the VM
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
fileName: ${{ steps.extractName.outputs.fileName}}
|
||||||
steps:
|
steps:
|
||||||
- name: Download file
|
- name: Extract file name
|
||||||
|
id: extractName
|
||||||
run: |
|
run: |
|
||||||
curl --remote-name ${{ inputs.url }} -L
|
url="${{ inputs.url }}"
|
||||||
|
echo "fileName=${url##*/}" >> $GITHUB_OUTPUT
|
||||||
|
- name: Download file
|
||||||
|
run: curl --remote-name ${{ inputs.url }} -L -o ${{steps.extractName.outputs.fileName}}
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ steps.extractName.outputs.fileName }}
|
||||||
|
path: ${{ steps.extractName.outputs.fileName }}
|
||||||
|
if-no-files-found: error
|
||||||
|
allowlist-kaspersky:
|
||||||
|
name: Anti Virus Allowlisting Kaspersky
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: download-file
|
||||||
|
if: github.event_name == 'workflow_call' || inputs.kaspersky
|
||||||
|
steps:
|
||||||
|
- name: Download artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ needs.download-file.outputs.fileName }}
|
||||||
|
path: upload
|
||||||
- name: Upload to Kaspersky
|
- name: Upload to Kaspersky
|
||||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
||||||
with:
|
with:
|
||||||
@@ -30,11 +63,26 @@ jobs:
|
|||||||
port: 990
|
port: 990
|
||||||
username: ${{ secrets.ALLOWLIST_KASPERSKY_USERNAME }}
|
username: ${{ secrets.ALLOWLIST_KASPERSKY_USERNAME }}
|
||||||
password: ${{ secrets.ALLOWLIST_KASPERSKY_PASSWORD }}
|
password: ${{ secrets.ALLOWLIST_KASPERSKY_PASSWORD }}
|
||||||
|
local-dir: ./upload/
|
||||||
|
allowlist-avast:
|
||||||
|
name: Anti Virus Allowlisting Avast
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: download-file
|
||||||
|
if: github.event_name == 'workflow_call' || inputs.avast
|
||||||
|
steps:
|
||||||
|
- name: Download artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ needs.download-file.outputs.fileName }}
|
||||||
|
path: upload
|
||||||
- name: Upload to Avast
|
- name: Upload to Avast
|
||||||
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
uses: wlixcc/SFTP-Deploy-Action@v1.2.5
|
||||||
with:
|
with:
|
||||||
protocol: ftp
|
|
||||||
server: whitelisting.avast.com
|
server: whitelisting.avast.com
|
||||||
port: 21
|
port: 22
|
||||||
username: ${{ secrets.ALLOWLIST_AVAST_USERNAME }}
|
username: ${{ secrets.ALLOWLIST_AVAST_USERNAME }}
|
||||||
password: ${{ secrets.ALLOWLIST_AVAST_PASSWORD }}
|
password: ${{ secrets.ALLOWLIST_AVAST_PASSWORD }}
|
||||||
|
ssh_private_key: ''
|
||||||
|
sftp_only: true
|
||||||
|
local_path: './upload/*'
|
||||||
|
remote_path: '/data'
|
||||||
@@ -2,12 +2,16 @@ name: Build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/build.yml'
|
||||||
|
- 'pom.xml'
|
||||||
|
- 'src/**'
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [labeled]
|
types: [labeled]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'temurin'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: 23
|
JAVA_VERSION: 24
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JDK_VERSION: '23.0.1+11'
|
JDK_VERSION: '24.0.1+9'
|
||||||
JDK_VENDOR: temurin
|
JDK_VENDOR: temurin
|
||||||
RUNTIME_VERSION_HELPER: >
|
RUNTIME_VERSION_HELPER: >
|
||||||
public class Test {
|
public class Test {
|
||||||
|
|||||||
@@ -5,41 +5,52 @@ on:
|
|||||||
inputs:
|
inputs:
|
||||||
semver:
|
semver:
|
||||||
description: 'SemVer String (e.g. 1.7.0-beta1)'
|
description: 'SemVer String (e.g. 1.7.0-beta1)'
|
||||||
required: true
|
|
||||||
ppaver:
|
ppaver:
|
||||||
description: 'Base PPA Version String (e.g. 1.6.16+1.7.0~beta1) without -0ppa1'
|
description: 'Base PPA Version String (e.g. 1.6.16+1.7.0~beta1) without -0ppa1'
|
||||||
required: true
|
|
||||||
dput:
|
dput:
|
||||||
description: 'Upload to PPA'
|
description: 'Upload to PPA'
|
||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/debian.yml'
|
||||||
|
- 'dist/linux/debian/**'
|
||||||
|
- 'dist/linux/common/**'
|
||||||
|
- 'dist/linux/resources/**'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'temurin'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: '23.0.1+11'
|
JAVA_VERSION: '24.0.1+9'
|
||||||
COFFEELIBS_JDK: 23
|
COFFEELIBS_JDK: 24
|
||||||
COFFEELIBS_JDK_VERSION: '23.0.1+11-0ppa1'
|
COFFEELIBS_JDK_VERSION: '24.0.1+9-0ppa3'
|
||||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_linux-x64_bin-jmods.zip'
|
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-x64_bin-jmods.zip'
|
||||||
OPENJFX_JMODS_AMD64_HASH: '2164bca470bf70a5e2764645e2078ba7f787b274e5be3d7df30d87c5bb62bba6'
|
OPENJFX_JMODS_AMD64_HASH: '425fac742b9fbd095b2ce868cff82d1024620f747c94a7144d0a4879e756146c'
|
||||||
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_linux-aarch64_bin-jmods.zip'
|
OPENJFX_JMODS_AARCH64: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_linux-aarch64_bin-jmods.zip'
|
||||||
OPENJFX_JMODS_AARCH64_HASH: '09c92fa9fa0b82adefd88640a14ebb2a49e5f3f733a57d1542f5590d060ffe1b'
|
OPENJFX_JMODS_AARCH64_HASH: '7e02edd0f4ee5527a27c94b0bbba66fcaaff41009119e45d0eca0f96ddfb6e7b'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
get-version:
|
||||||
|
uses: ./.github/workflows/get-version.yml
|
||||||
|
with:
|
||||||
|
version: ${{ inputs.semver }} #okay if not defined
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: Build Debian Package
|
name: Build Debian Package
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
needs: [get-version]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- id: versions
|
- id: deb-version
|
||||||
name: Get version information
|
name: Determine deb-version
|
||||||
run: |
|
run: |
|
||||||
SEM_VER_STR="${{ inputs.semver }}"
|
if [ -n "${{inputs.ppaver}}" ]; then
|
||||||
SEM_VER_NUM=`echo ${SEM_VER_STR} | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+).*/\1/'`
|
echo "debVersion=${{inputs.ppaver }}" >> "$GITHUB_OUTPUT"
|
||||||
REVCOUNT=`git rev-list --count HEAD`
|
else
|
||||||
echo "semVerStr=${SEM_VER_STR}" >> $GITHUB_OUTPUT
|
echo "debVersion=${{needs.get-version.outputs.semVerStr}}" >> "$GITHUB_OUTPUT"
|
||||||
echo "semVerNum=${SEM_VER_NUM}" >> $GITHUB_OUTPUT
|
fi
|
||||||
echo "revNum=${REVCOUNT}" >> $GITHUB_OUTPUT
|
|
||||||
- name: Install build tools
|
- name: Install build tools
|
||||||
run: |
|
run: |
|
||||||
sudo add-apt-repository ppa:coffeelibs/openjdk
|
sudo add-apt-repository ppa:coffeelibs/openjdk
|
||||||
@@ -94,7 +105,7 @@ jobs:
|
|||||||
cp -r jmods pkgdir
|
cp -r jmods pkgdir
|
||||||
cp -r dist/linux/common/ pkgdir
|
cp -r dist/linux/common/ pkgdir
|
||||||
cp target/cryptomator-*.jar pkgdir/mods
|
cp target/cryptomator-*.jar pkgdir/mods
|
||||||
tar -cJf cryptomator_${{ inputs.ppaver }}.orig.tar.xz -C pkgdir .
|
tar -cJf cryptomator_${{ steps.deb-version.outputs.debVersion }}.orig.tar.xz -C pkgdir .
|
||||||
- name: Patch and rename pkgdir
|
- name: Patch and rename pkgdir
|
||||||
run: |
|
run: |
|
||||||
cp -r dist/linux/debian/ pkgdir
|
cp -r dist/linux/debian/ pkgdir
|
||||||
@@ -103,12 +114,12 @@ jobs:
|
|||||||
envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM} ${DISABLE_UPDATE_CHECK}' < dist/linux/debian/rules > pkgdir/debian/rules
|
envsubst '${SEMVER_STR} ${VERSION_NUM} ${REVISION_NUM} ${DISABLE_UPDATE_CHECK}' < dist/linux/debian/rules > pkgdir/debian/rules
|
||||||
envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog
|
envsubst '${PPA_VERSION} ${RFC2822_TIMESTAMP}' < dist/linux/debian/changelog > pkgdir/debian/changelog
|
||||||
find . -name "*.jar" >> pkgdir/debian/source/include-binaries
|
find . -name "*.jar" >> pkgdir/debian/source/include-binaries
|
||||||
mv pkgdir cryptomator_${{ inputs.ppaver }}
|
mv pkgdir cryptomator_${{ steps.deb-version.outputs.debVersion }}
|
||||||
env:
|
env:
|
||||||
SEMVER_STR: ${{ steps.versions.outputs.semVerStr }}
|
SEMVER_STR: ${{ needs.get-version.outputs.semVerStr }}
|
||||||
VERSION_NUM: ${{ steps.versions.outputs.semVerNum }}
|
VERSION_NUM: ${{ needs.get-version.outputs.semVerNum }}
|
||||||
REVISION_NUM: ${{ steps.versions.outputs.revNum }}
|
REVISION_NUM: ${{ needs.get-version.outputs.revNum }}
|
||||||
PPA_VERSION: ${{ inputs.ppaver }}-0ppa1
|
PPA_VERSION: ${{ steps.deb-version.outputs.debVersion }}-0ppa1
|
||||||
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
|
- name: Prepare GPG-Agent for signing with key 615D449FE6E6A235
|
||||||
run: |
|
run: |
|
||||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
@@ -118,12 +129,13 @@ jobs:
|
|||||||
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
|
||||||
- name: debuild
|
- name: debuild
|
||||||
run: |
|
run: |
|
||||||
|
(sleep 8m; gpg --batch --quiet --pinentry-mode loopback -u 615D449FE6E6A235 --dry-run --sign README.md) &
|
||||||
debuild -S -sa -d
|
debuild -S -sa -d
|
||||||
debuild -b -sa -d
|
debuild -b -sa -d
|
||||||
env:
|
env:
|
||||||
DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
|
DEBSIGN_PROGRAM: gpg --batch --pinentry-mode loopback
|
||||||
DEBSIGN_KEYID: 615D449FE6E6A235
|
DEBSIGN_KEYID: 615D449FE6E6A235
|
||||||
working-directory: cryptomator_${{ inputs.ppaver }}
|
working-directory: cryptomator_${{ steps.deb-version.outputs.debVersion }}
|
||||||
- name: Create detached GPG signatures
|
- name: Create detached GPG signatures
|
||||||
run: |
|
run: |
|
||||||
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb
|
gpg --batch --quiet --passphrase-fd 0 --pinentry-mode loopback -u 615D449FE6E6A235 --detach-sign -a cryptomator_*_amd64.deb
|
||||||
@@ -140,7 +152,7 @@ jobs:
|
|||||||
cryptomator_*_amd64.deb
|
cryptomator_*_amd64.deb
|
||||||
cryptomator_*.asc
|
cryptomator_*.asc
|
||||||
- name: Publish on PPA
|
- name: Publish on PPA
|
||||||
if: inputs.dput
|
if: inputs.dput && inputs.ppaver != ''
|
||||||
run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
|
run: dput ppa:sebastian-stenzel/cryptomator-beta cryptomator_*_source.changes
|
||||||
# If ref is a tag, also upload to GitHub Releases:
|
# If ref is a tag, also upload to GitHub Releases:
|
||||||
- name: Publish Debian package on GitHub Releases
|
- name: Publish Debian package on GitHub Releases
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
runner-os: 'ubuntu-latest'
|
runner-os: 'ubuntu-latest'
|
||||||
java-distribution: 'temurin'
|
java-distribution: 'temurin'
|
||||||
java-version: 23
|
java-version: 24
|
||||||
check-command: 'mvn -B validate -Pdependency-check -Djavafx.platform=linux'
|
check-command: 'mvn -B validate -Pdependency-check -Djavafx.platform=linux'
|
||||||
secrets:
|
secrets:
|
||||||
nvd-api-key: ${{ secrets.NVD_API_KEY }}
|
nvd-api-key: ${{ secrets.NVD_API_KEY }}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'temurin'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: 23
|
JAVA_VERSION: 24
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
determine-version:
|
determine-version:
|
||||||
|
|||||||
@@ -5,17 +5,26 @@ name: Build macOS .dmg for x64
|
|||||||
#
|
#
|
||||||
# It is a copy of mac-dmg.yml with tiny adjustements (mainly lines 42 to 47)
|
# It is a copy of mac-dmg.yml with tiny adjustements (mainly lines 42 to 47)
|
||||||
# It was made necessary, since Github does not offer free macos intel runners for macos 15 and above.
|
# It was made necessary, since Github does not offer free macos intel runners for macos 15 and above.
|
||||||
# This workflow can only be triggered by a release.
|
|
||||||
#
|
#
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'Version'
|
||||||
|
required: false
|
||||||
|
notarize:
|
||||||
|
description: 'Notarize'
|
||||||
|
required: true
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'temurin'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: '23.0.1+11'
|
JAVA_VERSION: '24.0.1+9'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-version:
|
get-version:
|
||||||
@@ -35,8 +44,8 @@ jobs:
|
|||||||
architecture: x64
|
architecture: x64
|
||||||
output-suffix: x64
|
output-suffix: x64
|
||||||
fuse-lib: macFUSE
|
fuse-lib: macFUSE
|
||||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_osx-x64_bin-jmods.zip'
|
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_osx-x64_bin-jmods.zip'
|
||||||
openjfx-sha: '8857965975c464a0e5d57709292ce357d0ebb39f6168c41d5ca38301e42c3c8e'
|
openjfx-sha: '6e62a426d43c168a488521f904a523f3dd6ee2cf103e08136f2fd465c828a105'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
@@ -75,13 +84,21 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cp LICENSE.txt target
|
cp LICENSE.txt target
|
||||||
cp target/cryptomator-*.jar target/mods
|
cp target/cryptomator-*.jar target/mods
|
||||||
|
- name: Run jlink with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
- name: Run jlink
|
- name: Run jlink
|
||||||
#Remark: no compression is applied for improved build compression later (here dmg)
|
#Remark: no compression is applied for improved build compression later (here dmg)
|
||||||
run: >
|
run: >
|
||||||
${JAVA_HOME}/bin/jlink
|
${JAVA_HOME}/bin/jlink
|
||||||
--verbose
|
--verbose
|
||||||
--output runtime
|
--output runtime
|
||||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods"
|
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||||
--strip-native-commands
|
--strip-native-commands
|
||||||
--no-header-files
|
--no-header-files
|
||||||
@@ -103,7 +120,7 @@ jobs:
|
|||||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||||
--app-version "${{ needs.get-version.outputs.semVerNum }}"
|
--app-version "${{ needs.get-version.outputs.semVerNum }}"
|
||||||
--java-options "--enable-preview"
|
--java-options "--enable-preview"
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.mac"
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac"
|
||||||
--java-options "-Xss5m"
|
--java-options "-Xss5m"
|
||||||
--java-options "-Xmx256m"
|
--java-options "-Xmx256m"
|
||||||
--java-options "-Dfile.encoding=\"utf-8\""
|
--java-options "-Dfile.encoding=\"utf-8\""
|
||||||
|
|||||||
@@ -13,10 +13,16 @@ on:
|
|||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/mac-dmg.yml'
|
||||||
|
- 'dist/mac/**'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'temurin'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: '23.0.1+11'
|
JAVA_VERSION: '24.0.1+9'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
get-version:
|
get-version:
|
||||||
@@ -36,8 +42,8 @@ jobs:
|
|||||||
architecture: aarch64
|
architecture: aarch64
|
||||||
output-suffix: arm64
|
output-suffix: arm64
|
||||||
fuse-lib: FUSE-T
|
fuse-lib: FUSE-T
|
||||||
openjfx-url: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_osx-aarch64_bin-jmods.zip'
|
openjfx-url: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_osx-aarch64_bin-jmods.zip'
|
||||||
openjfx-sha: 'a800724a1f3e6757ecfa0bd5bf7ed64d2e6a7a3f5b3522650a70b8cfc7782fb6'
|
openjfx-sha: 'b5a94a13077507003fa852512bfa33f4fb680bc8076d8002e4227a84c85171d4'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
@@ -76,13 +82,21 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cp LICENSE.txt target
|
cp LICENSE.txt target
|
||||||
cp target/cryptomator-*.jar target/mods
|
cp target/cryptomator-*.jar target/mods
|
||||||
|
- name: Run jlink with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
- name: Run jlink
|
- name: Run jlink
|
||||||
#Remark: no compression is applied for improved build compression later (here dmg)
|
#Remark: no compression is applied for improved build compression later (here dmg)
|
||||||
run: >
|
run: >
|
||||||
${JAVA_HOME}/bin/jlink
|
${JAVA_HOME}/bin/jlink
|
||||||
--verbose
|
--verbose
|
||||||
--output runtime
|
--output runtime
|
||||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods"
|
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||||
--strip-native-commands
|
--strip-native-commands
|
||||||
--no-header-files
|
--no-header-files
|
||||||
@@ -104,7 +118,7 @@ jobs:
|
|||||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||||
--app-version "${{ needs.get-version.outputs.semVerNum }}"
|
--app-version "${{ needs.get-version.outputs.semVerNum }}"
|
||||||
--java-options "--enable-preview"
|
--java-options "--enable-preview"
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.mac"
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac"
|
||||||
--java-options "-Xss5m"
|
--java-options "-Xss5m"
|
||||||
--java-options "-Xmx256m"
|
--java-options "-Xmx256m"
|
||||||
--java-options "-Dfile.encoding=\"utf-8\""
|
--java-options "-Dfile.encoding=\"utf-8\""
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'temurin'
|
JAVA_DIST: 'temurin'
|
||||||
JAVA_VERSION: 23
|
JAVA_VERSION: 24
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -15,7 +15,6 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
name: Compile and Test
|
name: Compile and Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-java@v4
|
- uses: actions/setup-java@v4
|
||||||
|
|||||||
+129
-67
@@ -12,13 +12,17 @@ on:
|
|||||||
description: 'Build debug version with console output'
|
description: 'Build debug version with console output'
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/win-exe.yml'
|
||||||
|
- 'dist/win/**'
|
||||||
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_DIST: 'zulu'
|
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/24.0.1/openjfx-24.0.1_windows-x64_bin-jmods.zip'
|
||||||
JAVA_VERSION: '23.0.1+11'
|
OPENJFX_JMODS_AMD64_HASH: 'f13d17c7caf88654fc835f1b4e75a9b0f34a888eb8abef381796c0002e63b03f'
|
||||||
OPENJFX_JMODS_AMD64: 'https://download2.gluonhq.com/openjfx/23.0.1/openjfx-23.0.1_windows-x64_bin-jmods.zip'
|
|
||||||
OPENJFX_JMODS_AMD64_HASH: 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
|
|
||||||
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
|
WINFSP_MSI: 'https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi'
|
||||||
WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
|
WINFSP_UNINSTALLER: 'https://github.com/cryptomator/winfsp-uninstaller/releases/latest/download/winfsp-uninstaller.exe'
|
||||||
|
|
||||||
@@ -34,36 +38,54 @@ jobs:
|
|||||||
|
|
||||||
build-msi:
|
build-msi:
|
||||||
name: Build .msi Installer
|
name: Build .msi Installer
|
||||||
runs-on: windows-latest
|
runs-on: ${{ matrix.os }}
|
||||||
needs: [get-version]
|
needs: [ get-version ]
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: x64
|
||||||
|
os: windows-latest
|
||||||
|
java-dist: 'zulu'
|
||||||
|
java-version: '24.0.1+9'
|
||||||
|
java-package: 'jdk'
|
||||||
|
- arch: arm64
|
||||||
|
os: windows-11-arm
|
||||||
|
java-dist: 'liberica'
|
||||||
|
java-version: '24.0.1+11'
|
||||||
|
java-package: 'jdk+fx' #This is needed, as liberica contains JFX 24 Jmods for Windows ARM64
|
||||||
env:
|
env:
|
||||||
LOOPBACK_ALIAS: 'cryptomator-vault'
|
LOOPBACK_ALIAS: 'cryptomator-vault'
|
||||||
WIN_CONSOLE_FLAG: ''
|
WIN_CONSOLE_FLAG: ''
|
||||||
steps:
|
steps:
|
||||||
- name: Upgrade WIX to latest version
|
|
||||||
run: choco install wixtoolset --version 3.14.1
|
|
||||||
shell: pwsh
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ matrix.java-dist }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ matrix.java-version }}
|
||||||
|
java-package: ${{ matrix.java-package }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: 'maven'
|
cache: 'maven'
|
||||||
|
- name: Install wix and extensions
|
||||||
|
run: |
|
||||||
|
dotnet tool install --global wix --version 6.0.0
|
||||||
|
wix.exe extension add WixToolset.UI.wixext/6.0.0 --global
|
||||||
|
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
|
||||||
- name: Download and extract JavaFX jmods from Gluon
|
- name: Download and extract JavaFX jmods from Gluon
|
||||||
|
if: matrix.arch == 'x64'
|
||||||
#In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
|
#In the last step we move all jmods files a dir level up because jmods are placed inside a directory in the zip
|
||||||
run: |
|
run: |
|
||||||
curl --output jfxjmods.zip -L "${{ env.OPENJFX_JMODS_AMD64 }}"
|
curl --output openjfx-jmods.zip -L "${{ env.OPENJFX_JMODS_AMD64 }}"
|
||||||
if(!(Get-FileHash -Path jfxjmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.OPENJFX_JMODS_AMD64_HASH }}")) {
|
if(!(Get-FileHash -Path openjfx-jmods.zip -Algorithm SHA256).Hash.ToLower().equals("${{ env.OPENJFX_JMODS_AMD64_HASH }}")) {
|
||||||
throw "Wrong checksum of JMOD archive downloaded from ${{ env.OPENJFX_JMODS_AMD64 }}.";
|
throw "Wrong checksum of JMOD archive downloaded from ${{ env.OPENJFX_JMODS_AMD64 }}.";
|
||||||
}
|
}
|
||||||
Expand-Archive -Path jfxjmods.zip -DestinationPath jfxjmods
|
Expand-Archive -Path openjfx-jmods.zip -DestinationPath openjfx-jmods
|
||||||
Get-ChildItem -Path jfxjmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
|
Get-ChildItem -Path openjfx-jmods -Recurse -Filter "*.jmod" | ForEach-Object { Move-Item -Path $_ -Destination $_.Directory.Parent}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
- name: Ensure major jfx version in pom and in jmods is the same
|
- name: Ensure major jfx version in pom and in jmods is the same
|
||||||
|
if: matrix.arch == 'x64'
|
||||||
run: |
|
run: |
|
||||||
JMOD_VERSION_AMD64=$(jmod describe jfxjmods/javafx.base.jmod | head -1)
|
JMOD_VERSION_AMD64=$(jmod describe openjfx-jmods/javafx.base.jmod | head -1)
|
||||||
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
|
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64#*@}
|
||||||
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
|
JMOD_VERSION_AMD64=${JMOD_VERSION_AMD64%%.*}
|
||||||
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
|
POM_JFX_VERSION=$(mvn help:evaluate "-Dexpression=javafx.version" -q -DforceStdout)
|
||||||
@@ -75,20 +97,28 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
- name: Set version
|
- name: Set version
|
||||||
run : mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
|
run: mvn versions:set -DnewVersion=${{ needs.get-version.outputs.semVerStr }}
|
||||||
- name: Run maven
|
- name: Run maven
|
||||||
run: mvn -B clean package -Pwin -DskipTests -Djavafx.platform=win
|
run: mvn -B clean package -Pwin -DskipTests -Djavafx.platform=win
|
||||||
- name: Patch target dir
|
- name: Patch target dir
|
||||||
run: |
|
run: |
|
||||||
cp LICENSE.txt target
|
cp LICENSE.txt target
|
||||||
cp target/cryptomator-*.jar target/mods
|
cp target/cryptomator-*.jar target/mods
|
||||||
|
- name: Run jlink with help option
|
||||||
|
id: jep-493-check
|
||||||
|
run: |
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! $(${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"); then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods;${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
echo "jmod_paths=${JMOD_PATHS}" >> "$GITHUB_OUTPUT"
|
||||||
- name: Run jlink
|
- name: Run jlink
|
||||||
#Remark: no compression is applied for improved build compression later (here msi)
|
# Remark: no compression is applied for improved build compression later (here msi)
|
||||||
run: >
|
run: >
|
||||||
${JAVA_HOME}/bin/jlink
|
${JAVA_HOME}/bin/jlink
|
||||||
--verbose
|
--verbose
|
||||||
--output runtime
|
--output runtime
|
||||||
--module-path "jfxjmods;${JAVA_HOME}/jmods"
|
--module-path "${{ steps.jep-493-check.outputs.jmod_paths }}"
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.mscapi,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.crypto.mscapi,jdk.unsupported,jdk.accessibility,jdk.management.jfr,java.compiler
|
||||||
--strip-native-commands
|
--strip-native-commands
|
||||||
--no-header-files
|
--no-header-files
|
||||||
@@ -113,7 +143,7 @@ jobs:
|
|||||||
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
--copyright "(C) 2016 - 2025 Skymatic GmbH"
|
||||||
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
--app-version "${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
||||||
--java-options "--enable-preview"
|
--java-options "--enable-preview"
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win"
|
||||||
--java-options "-Xss5m"
|
--java-options "-Xss5m"
|
||||||
--java-options "-Xmx256m"
|
--java-options "-Xmx256m"
|
||||||
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
|
--java-options "-Dcryptomator.appVersion=\"${{ needs.get-version.outputs.semVerStr }}\""
|
||||||
@@ -130,6 +160,7 @@ jobs:
|
|||||||
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
|
--java-options "-Dcryptomator.buildNumber=\"msi-${{ needs.get-version.outputs.revNum }}\""
|
||||||
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
|
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=\"Cryptomator\""
|
||||||
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\""
|
--java-options "-Dcryptomator.integrationsWin.keychainPaths=\"@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json\""
|
||||||
|
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=\"@{appdata}/Cryptomator/windowsHelloKeychain.json\""
|
||||||
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
|
--java-options "-Djavafx.verbose=${{ inputs.isDebug }}"
|
||||||
--resource-dir dist/win/resources
|
--resource-dir dist/win/resources
|
||||||
--icon dist/win/resources/Cryptomator.ico
|
--icon dist/win/resources/Cryptomator.ico
|
||||||
@@ -240,8 +271,8 @@ jobs:
|
|||||||
description: Cryptomator Installer
|
description: Cryptomator Installer
|
||||||
timestampUrl: 'http://timestamp.digicert.com'
|
timestampUrl: 'http://timestamp.digicert.com'
|
||||||
folder: installer
|
folder: installer
|
||||||
- name: Add possible alpha/beta tags to installer name
|
- name: Add possible alpha/beta tags and architecture to installer name
|
||||||
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.msi
|
run: mv installer/Cryptomator-*.msi Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.arch }}.msi
|
||||||
- name: Create detached GPG signature with key 615D449FE6E6A235
|
- name: Create detached GPG signature with key 615D449FE6E6A235
|
||||||
run: |
|
run: |
|
||||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
@@ -252,7 +283,7 @@ jobs:
|
|||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: msi
|
name: msi-${{ matrix.arch }}
|
||||||
path: |
|
path: |
|
||||||
Cryptomator-*.msi
|
Cryptomator-*.msi
|
||||||
Cryptomator-*.asc
|
Cryptomator-*.asc
|
||||||
@@ -260,21 +291,43 @@ jobs:
|
|||||||
|
|
||||||
build-exe:
|
build-exe:
|
||||||
name: Build .exe installer
|
name: Build .exe installer
|
||||||
runs-on: windows-latest
|
runs-on: ${{ matrix.os }}
|
||||||
needs: [get-version, build-msi]
|
needs: [ get-version, build-msi ]
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: x64
|
||||||
|
os: windows-latest
|
||||||
|
executable-suffix: x64
|
||||||
|
java-dist: 'zulu'
|
||||||
|
java-version: '24.0.1+9'
|
||||||
|
java-package: 'jdk'
|
||||||
|
- arch: arm64
|
||||||
|
os: windows-11-arm
|
||||||
|
executable-suffix: arm64
|
||||||
|
java-dist: 'liberica'
|
||||||
|
java-version: '24.0.1+11'
|
||||||
|
java-package: 'jdk+fx' #This is needed, as liberica contains JFX 24 Jmods for Windows ARM64
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install wix and extensions
|
||||||
|
run: |
|
||||||
|
dotnet tool install --global wix --version 6.0.0
|
||||||
|
wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global
|
||||||
|
wix.exe extension add WixToolset.Util.wixext/6.0.0 --global
|
||||||
- name: Download .msi
|
- name: Download .msi
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: msi
|
name: msi-${{ matrix.arch }}
|
||||||
path: dist/win/bundle/resources
|
path: dist/win/bundle/resources
|
||||||
- name: Strip version info from msi file name
|
- name: Strip version info from msi file name
|
||||||
run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
|
run: mv dist/win/bundle/resources/Cryptomator*.msi dist/win/bundle/resources/Cryptomator.msi
|
||||||
- uses: actions/setup-java@v4
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: ${{ env.JAVA_DIST }}
|
distribution: ${{ matrix.java-dist }}
|
||||||
java-version: ${{ env.JAVA_VERSION }}
|
java-version: ${{ matrix.java-version }}
|
||||||
|
java-package: ${{ matrix.java-package }}
|
||||||
check-latest: true
|
check-latest: true
|
||||||
cache: 'maven'
|
cache: 'maven'
|
||||||
- name: Generate license for exe
|
- name: Generate license for exe
|
||||||
@@ -296,29 +349,24 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
curl --output dist/win/bundle/resources/winfsp-uninstaller.exe -L ${{ env.WINFSP_UNINSTALLER }}
|
curl --output dist/win/bundle/resources/winfsp-uninstaller.exe -L ${{ env.WINFSP_UNINSTALLER }}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
- name: Compile to wixObj file
|
- name: Create Wix Burn bundle
|
||||||
|
working-directory: dist/win
|
||||||
run: >
|
run: >
|
||||||
"${WIX}/bin/candle.exe" dist/win/bundle/bundleWithWinfsp.wxs
|
wix build
|
||||||
-ext WixBalExtension
|
-define BundleName="Cryptomator"
|
||||||
-ext WixUtilExtension
|
-define BundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum}}"
|
||||||
-out dist/win/bundle/
|
-define BundleVendor="Skymatic GmbH"
|
||||||
-dBundleVersion="${{ needs.get-version.outputs.semVerNum }}.${{ needs.get-version.outputs.revNum }}"
|
-define BundleCopyright="(C) 2016 - 2025 Skymatic GmbH"
|
||||||
-dBundleVendor="Skymatic GmbH"
|
-define AboutUrl="https://cryptomator.org"
|
||||||
-dBundleCopyright="(C) 2016 - 2025 Skymatic GmbH"
|
-define HelpUrl="https://cryptomator.org/contact"
|
||||||
-dAboutUrl="https://cryptomator.org"
|
-define UpdateUrl="https://cryptomator.org/downloads/"
|
||||||
-dHelpUrl="https://cryptomator.org/contact"
|
-ext "WixToolset.Util.wixext"
|
||||||
-dUpdateUrl="https://cryptomator.org/downloads/"
|
-ext "WixToolset.BootstrapperApplications.wixext"
|
||||||
- name: Create executable with linker
|
./bundle/bundleWithWinfsp.wxs
|
||||||
run: >
|
-out "../../installer/unsigned/Cryptomator-Installer.exe"
|
||||||
"${WIX}/bin/light.exe" -b dist/win/ dist/win/bundle/bundleWithWinfsp.wixobj
|
|
||||||
-ext WixBalExtension
|
|
||||||
-ext WixUtilExtension
|
|
||||||
-out installer/unsigned/Cryptomator-Installer.exe
|
|
||||||
- name: Detach burn engine in preparation to sign
|
- name: Detach burn engine in preparation to sign
|
||||||
run: >
|
run: >
|
||||||
"${WIX}/bin/insignia.exe"
|
wix burn detach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe
|
||||||
-ib installer/unsigned/Cryptomator-Installer.exe
|
|
||||||
-o tmp/engine.exe
|
|
||||||
- name: Codesign burn engine
|
- name: Codesign burn engine
|
||||||
uses: skymatic/code-sign-action@v3
|
uses: skymatic/code-sign-action@v3
|
||||||
with:
|
with:
|
||||||
@@ -329,10 +377,8 @@ jobs:
|
|||||||
timestampUrl: 'http://timestamp.digicert.com'
|
timestampUrl: 'http://timestamp.digicert.com'
|
||||||
folder: tmp
|
folder: tmp
|
||||||
- name: Reattach signed burn engine to installer
|
- name: Reattach signed burn engine to installer
|
||||||
run : >
|
run: >
|
||||||
"${WIX}/bin/insignia.exe"
|
wix burn reattach installer/unsigned/Cryptomator-Installer.exe -engine tmp/engine.exe -o installer/Cryptomator-Installer.exe
|
||||||
-ab tmp/engine.exe installer/unsigned/Cryptomator-Installer.exe
|
|
||||||
-o installer/Cryptomator-Installer.exe
|
|
||||||
- name: Codesign EXE
|
- name: Codesign EXE
|
||||||
uses: skymatic/code-sign-action@v3
|
uses: skymatic/code-sign-action@v3
|
||||||
with:
|
with:
|
||||||
@@ -343,7 +389,7 @@ jobs:
|
|||||||
timestampUrl: 'http://timestamp.digicert.com'
|
timestampUrl: 'http://timestamp.digicert.com'
|
||||||
folder: installer
|
folder: installer
|
||||||
- name: Add possible alpha/beta tags to installer name
|
- name: Add possible alpha/beta tags to installer name
|
||||||
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-x64.exe
|
run: mv installer/Cryptomator-Installer.exe Cryptomator-${{ needs.get-version.outputs.semVerStr }}-${{ matrix.executable-suffix }}.exe
|
||||||
- name: Create detached GPG signature with key 615D449FE6E6A235
|
- name: Create detached GPG signature with key 615D449FE6E6A235
|
||||||
run: |
|
run: |
|
||||||
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
echo "${GPG_PRIVATE_KEY}" | gpg --batch --quiet --import
|
||||||
@@ -354,7 +400,7 @@ jobs:
|
|||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: exe
|
name: exe-${{ matrix.executable-suffix }}
|
||||||
path: |
|
path: |
|
||||||
Cryptomator-*.exe
|
Cryptomator-*.exe
|
||||||
Cryptomator-*.asc
|
Cryptomator-*.asc
|
||||||
@@ -364,16 +410,18 @@ jobs:
|
|||||||
name: Publish installers to the github release
|
name: Publish installers to the github release
|
||||||
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
if: startsWith(github.ref, 'refs/tags/') && github.event.action == 'published'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-msi, build-exe]
|
needs: [ build-msi, build-exe ]
|
||||||
outputs:
|
outputs:
|
||||||
download-url-msi: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
|
download-url-msi-x64: ${{ fromJSON(steps.publish.outputs.assets)[0].browser_download_url }}
|
||||||
download-url-exe: ${{ fromJSON(steps.publish.outputs.assets)[1].browser_download_url }}
|
download-url-msi-arm64: ${{ fromJSON(steps.publish.outputs.assets)[1].browser_download_url }}
|
||||||
|
download-url-exe-x64: ${{ fromJSON(steps.publish.outputs.assets)[2].browser_download_url }}
|
||||||
|
download-url-exe-arm64: ${{ fromJSON(steps.publish.outputs.assets)[3].browser_download_url }}
|
||||||
steps:
|
steps:
|
||||||
- name: Download installers
|
- name: Download installers
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
- name: Publish .msi on GitHub Releases
|
- name: Publish installers on GitHub Releases
|
||||||
id: publish
|
id: publish
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
@@ -385,18 +433,32 @@ jobs:
|
|||||||
*.exe
|
*.exe
|
||||||
*.asc
|
*.asc
|
||||||
|
|
||||||
allowlist-msi:
|
allowlist-msi-x64:
|
||||||
uses: ./.github/workflows/av-whitelist.yml
|
uses: ./.github/workflows/av-whitelist.yml
|
||||||
needs: [publish]
|
needs: [ publish ]
|
||||||
with:
|
with:
|
||||||
url: ${{ needs.publish.outputs.download-url-msi }}
|
url: ${{ needs.publish.outputs.download-url-msi-x64 }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
allowlist-exe:
|
allowlist-msi-arm64:
|
||||||
uses: ./.github/workflows/av-whitelist.yml
|
uses: ./.github/workflows/av-whitelist.yml
|
||||||
needs: [publish]
|
needs: [ publish ]
|
||||||
with:
|
with:
|
||||||
url: ${{ needs.publish.outputs.download-url-exe }}
|
url: ${{ needs.publish.outputs.download-url-msi-arm64 }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
allowlist-exe-x64:
|
||||||
|
uses: ./.github/workflows/av-whitelist.yml
|
||||||
|
needs: [ publish, allowlist-msi-x64 ]
|
||||||
|
with:
|
||||||
|
url: ${{ needs.publish.outputs.download-url-exe-x64 }}
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
allowlist-exe-arm64:
|
||||||
|
uses: ./.github/workflows/av-whitelist.yml
|
||||||
|
needs: [ publish, allowlist-msi-arm64 ]
|
||||||
|
with:
|
||||||
|
url: ${{ needs.publish.outputs.download-url-exe-arm64 }}
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
notify-winget:
|
notify-winget:
|
||||||
@@ -413,7 +475,7 @@ jobs:
|
|||||||
SLACK_ICON: false
|
SLACK_ICON: false
|
||||||
SLACK_ICON_EMOJI: ':bot:'
|
SLACK_ICON_EMOJI: ':bot:'
|
||||||
SLACK_CHANNEL: 'cryptomator-desktop'
|
SLACK_CHANNEL: 'cryptomator-desktop'
|
||||||
SLACK_TITLE: "MSI of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
|
SLACK_TITLE: "MSI packages of ${{ github.event.repository.name }} ${{ github.event.release.tag_name }} published."
|
||||||
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release to winget>."
|
SLACK_MESSAGE: "Ready to <https://github.com/${{ github.repository }}/actions/workflows/winget.yml| release them to winget>."
|
||||||
SLACK_FOOTER: false
|
SLACK_FOOTER: false
|
||||||
MSG_MINIMAL: true
|
MSG_MINIMAL: true
|
||||||
@@ -23,5 +23,5 @@ jobs:
|
|||||||
identifier: Cryptomator.Cryptomator
|
identifier: Cryptomator.Cryptomator
|
||||||
version: ${{ inputs.tag }}
|
version: ${{ inputs.tag }}
|
||||||
release-tag: ${{ inputs.tag }}
|
release-tag: ${{ inputs.tag }}
|
||||||
installers-regex: '\.msi$'
|
installers-regex: '-x64\.msi$'
|
||||||
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
token: ${{ secrets.CRYPTOBOT_WINGET_TOKEN }}
|
||||||
Generated
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="23" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_24" project-jdk-name="24" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Cryptomator Linux" type="Application" factoryName="Application">
|
<configuration default="false" name="Cryptomator Linux" type="Application" factoryName="Application">
|
||||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
<module name="cryptomator" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator/mnt" -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator/mnt" -Dcryptomator.showTrayIcon=true -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Cryptomator Linux Dev" type="Application" factoryName="Application">
|
<configuration default="false" name="Cryptomator Linux Dev" type="Application" factoryName="Application">
|
||||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
<module name="cryptomator" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator-Dev/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator-Dev/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dfuse.experimental="true" -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{userhome}/.config/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/.config/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/.config/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/.local/share/Cryptomator-Dev/logs" -Dcryptomator.pluginDir="@{userhome}/.local/share/Cryptomator-Dev/plugins" -Dcryptomator.mountPointsDir="@{userhome}/.local/share/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dfuse.experimental="true" -Xss20m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
|
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
|
||||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
<module name="cryptomator" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator" -Dcryptomator.pluginDir="@{appdata}/Cryptomator/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator/settings.json;@{userhome}/AppData/Roaming/Cryptomator/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator" -Dcryptomator.pluginDir="@{appdata}/Cryptomator/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator/keychain.json;@{userhome}/AppData/Roaming/Cryptomator/keychain.json" -Dcryptomator.integrationsWin.windowsHelloKeychainPaths="@{appdata}/Cryptomator/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator/windowsHelloKeychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator/key.p12;@{userhome}/AppData/Roaming/Cryptomator/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application">
|
<configuration default="false" name="Cryptomator Windows Dev" type="Application" factoryName="Application">
|
||||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
<module name="cryptomator" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator-Dev" -Dcryptomator.pluginDir="@{appdata}/Cryptomator-Dev/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator-Dev" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" />
|
<option name="VM_PARAMETERS" value="-Dcryptomator.settingsPath="@{appdata}/Cryptomator-Dev/settings.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/settings.json" -Dcryptomator.ipcSocketPath="@{localappdata}/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{localappdata}/Cryptomator-Dev" -Dcryptomator.pluginDir="@{appdata}/Cryptomator-Dev/Plugins" -Dcryptomator.integrationsWin.keychainPaths="@{appdata}/Cryptomator-Dev/keychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/keychain.json" -Dcryptomator.integrationsWin.windowsHelloKeychainPaths="@{appdata}/Cryptomator-Dev/windowsHelloKeychain.json;@{userhome}/AppData/Roaming/Cryptomator-Dev/windowsHelloKeychain.json" -Dcryptomator.p12Path="@{appdata}/Cryptomator-Dev/key.p12;@{userhome}/AppData/Roaming/Cryptomator-Dev/key.p12" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator-Dev" -Dcryptomator.showTrayIcon=true -Xss2m -Xmx512m --enable-preview --enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
</envs>
|
</envs>
|
||||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
<module name="cryptomator" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
|
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Cryptomator" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
</envs>
|
</envs>
|
||||||
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
|
||||||
<module name="cryptomator" />
|
<module name="cryptomator" />
|
||||||
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator-Dev" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Library/Application Support/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac" />
|
<option name="VM_PARAMETERS" value="-Dapple.awt.enableTemplateImages=true -Dcryptomator.settingsPath="@{userhome}/Library/Application Support/Cryptomator-Dev/settings.json" -Dcryptomator.p12Path="@{userhome}/Library/Application Support/Cryptomator-Dev/key.p12" -Dcryptomator.ipcSocketPath="@{userhome}/Library/Application Support/Cryptomator-Dev/ipc.socket" -Dcryptomator.logDir="@{userhome}/Library/Logs/Cryptomator-Dev" -Dcryptomator.pluginDir="@{userhome}/Library/Application Support/Cryptomator-Dev/Plugins" -Dcryptomator.mountPointsDir="@{userhome}/Library/Application Support/Cryptomator-Dev/mnt" -Dcryptomator.showTrayIcon=true -Dcryptomator.integrationsMac.keychainServiceName=Cryptomator -Xss2m -Xmx512m -ea --enable-preview --enable-native-access=org.cryptomator.jfuse.mac,javafx.graphics" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ For more information on the security details visit [cryptomator.org](https://doc
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
* JDK 23 (e.g. temurin, zulu)
|
* JDK 24 (e.g. temurin, zulu)
|
||||||
* Maven 3
|
* Maven 3
|
||||||
|
|
||||||
### Run Maven
|
### Run Maven
|
||||||
|
|||||||
Vendored
+12
-6
@@ -23,12 +23,12 @@ mvn -B -f ../../../pom.xml clean package -Plinux -DskipTests -Djavafx.platform=l
|
|||||||
cp ../../../LICENSE.txt ../../../target
|
cp ../../../LICENSE.txt ../../../target
|
||||||
cp ../../../target/cryptomator-*.jar ../../../target/mods
|
cp ../../../target/cryptomator-*.jar ../../../target/mods
|
||||||
|
|
||||||
JAVAFX_VERSION=22.0.2
|
JAVAFX_VERSION=24.0.1
|
||||||
JAVAFX_ARCH="x64"
|
JAVAFX_ARCH="x64"
|
||||||
JAVAFX_JMODS_SHA256='2164bca470bf70a5e2764645e2078ba7f787b274e5be3d7df30d87c5bb62bba6'
|
JAVAFX_JMODS_SHA256='425fac742b9fbd095b2ce868cff82d1024620f747c94a7144d0a4879e756146c'
|
||||||
if [ "${CPU_ARCH}" = "aarch64" ]; then
|
if [ "${CPU_ARCH}" = "aarch64" ]; then
|
||||||
JAVAFX_ARCH="aarch64"
|
JAVAFX_ARCH="aarch64"
|
||||||
JAVAFX_JMODS_SHA256='09c92fa9fa0b82adefd88640a14ebb2a49e5f3f733a57d1542f5590d060ffe1b'
|
JAVAFX_JMODS_SHA256='7e02edd0f4ee5527a27c94b0bbba66fcaaff41009119e45d0eca0f96ddfb6e7b'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# download javaFX jmods
|
# download javaFX jmods
|
||||||
@@ -51,11 +51,17 @@ if [ $POM_JFX_VERSION -ne $JMOD_VERSION ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# add runtime
|
# create runtime
|
||||||
|
## check for JEP 493
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
## create runtime image
|
||||||
${JAVA_HOME}/bin/jlink \
|
${JAVA_HOME}/bin/jlink \
|
||||||
--verbose \
|
--verbose \
|
||||||
--output runtime \
|
--output runtime \
|
||||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
|
--module-path "${JMOD_PATHS}" \
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,jdk.net,java.compiler \
|
||||||
--strip-native-commands \
|
--strip-native-commands \
|
||||||
--no-header-files \
|
--no-header-files \
|
||||||
@@ -75,7 +81,7 @@ ${JAVA_HOME}/bin/jpackage \
|
|||||||
--name Cryptomator \
|
--name Cryptomator \
|
||||||
--vendor "Skymatic GmbH" \
|
--vendor "Skymatic GmbH" \
|
||||||
--java-options "--enable-preview" \
|
--java-options "--enable-preview" \
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||||
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
|
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
|
||||||
--java-options "-Xss5m" \
|
--java-options "-Xss5m" \
|
||||||
--java-options "-Xmx256m" \
|
--java-options "-Xmx256m" \
|
||||||
|
|||||||
@@ -83,6 +83,21 @@
|
|||||||
</content_rating>
|
</content_rating>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
|
<release date="2025-05-15" version="1.16.2">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.2</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-30" version="1.16.1">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.1</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-29" version="1.16.0">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.16.0</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-09" version="1.15.3">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.3</url>
|
||||||
|
</release>
|
||||||
|
<release date="2025-04-04" version="1.15.2">
|
||||||
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.2</url>
|
||||||
|
</release>
|
||||||
<release date="2025-02-05" version="1.15.1">
|
<release date="2025-02-05" version="1.15.1">
|
||||||
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.1</url>
|
<url type="details">https://github.com/cryptomator/cryptomator/releases/1.15.1</url>
|
||||||
</release>
|
</release>
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
cryptomator (${PPA_VERSION}) focal; urgency=low
|
cryptomator (${PPA_VERSION}) jammy; urgency=low
|
||||||
|
|
||||||
* Full changelog can be found on https://github.com/cryptomator/cryptomator/releases
|
* Full changelog can be found on https://github.com/cryptomator/cryptomator/releases
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -2,7 +2,7 @@ Source: cryptomator
|
|||||||
Maintainer: Cryptobot <releases@cryptomator.org>
|
Maintainer: Cryptobot <releases@cryptomator.org>
|
||||||
Section: utils
|
Section: utils
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Build-Depends: debhelper (>=10), coffeelibs-jdk-23 (>= 23.0.1+11-0ppa1), libgtk-3-0, libxxf86vm1, libgl1
|
Build-Depends: debhelper (>=10), coffeelibs-jdk-24 (>= 24.0.1+9-0ppa3), libgtk-3-0, libxxf86vm1, libgl1
|
||||||
Standards-Version: 4.5.0
|
Standards-Version: 4.5.0
|
||||||
Homepage: https://cryptomator.org
|
Homepage: https://cryptomator.org
|
||||||
Vcs-Git: https://github.com/cryptomator/cryptomator.git
|
Vcs-Git: https://github.com/cryptomator/cryptomator.git
|
||||||
|
|||||||
Vendored
+2
-2
@@ -4,7 +4,7 @@
|
|||||||
# Uncomment this to turn on verbose mode.
|
# Uncomment this to turn on verbose mode.
|
||||||
#export DH_VERBOSE=1
|
#export DH_VERBOSE=1
|
||||||
|
|
||||||
JAVA_HOME = /usr/lib/jvm/java-23-coffeelibs
|
JAVA_HOME = /usr/lib/jvm/java-24-coffeelibs
|
||||||
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
|
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
|
||||||
ifeq ($(DEB_BUILD_ARCH),amd64)
|
ifeq ($(DEB_BUILD_ARCH),amd64)
|
||||||
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
|
JMODS_PATH = jmods/amd64:${JAVA_HOME}/jmods
|
||||||
@@ -44,7 +44,7 @@ override_dh_auto_build:
|
|||||||
--name cryptomator \
|
--name cryptomator \
|
||||||
--vendor "Skymatic GmbH" \
|
--vendor "Skymatic GmbH" \
|
||||||
--java-options "--enable-preview" \
|
--java-options "--enable-preview" \
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.linux.amd64,org.cryptomator.jfuse.linux.aarch64,org.purejava.appindicator" \
|
||||||
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
|
--copyright "(C) 2016 - 2025 Skymatic GmbH" \
|
||||||
--java-options "-Xss5m" \
|
--java-options "-Xss5m" \
|
||||||
--java-options "-Xmx256m" \
|
--java-options "-Xmx256m" \
|
||||||
|
|||||||
Vendored
+12
-6
@@ -32,15 +32,15 @@ REVISION_NO=`git rev-list --count HEAD`
|
|||||||
VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'`
|
VERSION_NO=`mvn -f../../../pom.xml help:evaluate -Dexpression=project.version -q -DforceStdout | sed -rn 's/.*([0-9]+\.[0-9]+\.[0-9]+).*/\1/p'`
|
||||||
FUSE_LIB="FUSE-T"
|
FUSE_LIB="FUSE-T"
|
||||||
|
|
||||||
JAVAFX_VERSION=23.0.1
|
JAVAFX_VERSION=24.0.1
|
||||||
JAVAFX_ARCH="undefined"
|
JAVAFX_ARCH="undefined"
|
||||||
JAVAFX_JMODS_SHA256="undefined"
|
JAVAFX_JMODS_SHA256="undefined"
|
||||||
if [ "$(machine)" = "arm64e" ]; then
|
if [ "$(machine)" = "arm64e" ]; then
|
||||||
JAVAFX_ARCH="aarch64"
|
JAVAFX_ARCH="aarch64"
|
||||||
JAVAFX_JMODS_SHA256="a800724a1f3e6757ecfa0bd5bf7ed64d2e6a7a3f5b3522650a70b8cfc7782fb6"
|
JAVAFX_JMODS_SHA256="b5a94a13077507003fa852512bfa33f4fb680bc8076d8002e4227a84c85171d4"
|
||||||
else
|
else
|
||||||
JAVAFX_ARCH="x64"
|
JAVAFX_ARCH="x64"
|
||||||
JAVAFX_JMODS_SHA256="8857965975c464a0e5d57709292ce357d0ebb39f6168c41d5ca38301e42c3c8e"
|
JAVAFX_JMODS_SHA256="6e62a426d43c168a488521f904a523f3dd6ee2cf103e08136f2fd465c828a105"
|
||||||
fi
|
fi
|
||||||
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
|
JAVAFX_JMODS_URL="https://download2.gluonhq.com/openjfx/${JAVAFX_VERSION}/openjfx-${JAVAFX_VERSION}_osx-${JAVAFX_ARCH}_bin-jmods.zip"
|
||||||
|
|
||||||
@@ -75,10 +75,16 @@ mvn -B -Djavafx.platform=mac -f../../../pom.xml clean package -DskipTests -Pmac
|
|||||||
cp ../../../LICENSE.txt ../../../target
|
cp ../../../LICENSE.txt ../../../target
|
||||||
cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
|
cp ../../../target/${MAIN_JAR_GLOB} ../../../target/mods
|
||||||
|
|
||||||
# add runtime
|
# create runtime
|
||||||
|
## check for JEP 493
|
||||||
|
JMOD_PATHS="openjfx-jmods"
|
||||||
|
if ! ${JAVA_HOME}/bin/jlink --help | grep -q "Linking from run-time image enabled"; then
|
||||||
|
JMOD_PATHS="${JAVA_HOME}/jmods:${JMOD_PATHS}"
|
||||||
|
fi
|
||||||
|
## create custom runtime
|
||||||
${JAVA_HOME}/bin/jlink \
|
${JAVA_HOME}/bin/jlink \
|
||||||
--output runtime \
|
--output runtime \
|
||||||
--module-path "${JAVA_HOME}/jmods:openjfx-jmods" \
|
--module-path "${JMOD_PATHS}" \
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,java.compiler \
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,javafx.base,javafx.graphics,javafx.controls,javafx.fxml,jdk.unsupported,jdk.security.auth,jdk.accessibility,jdk.management.jfr,java.compiler \
|
||||||
--strip-native-commands \
|
--strip-native-commands \
|
||||||
--no-header-files \
|
--no-header-files \
|
||||||
@@ -100,7 +106,7 @@ ${JAVA_HOME}/bin/jpackage \
|
|||||||
--copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
|
--copyright "(C) ${COPYRIGHT_YEARS} ${VENDOR}" \
|
||||||
--app-version "${VERSION_NO}" \
|
--app-version "${VERSION_NO}" \
|
||||||
--java-options "--enable-preview" \
|
--java-options "--enable-preview" \
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.mac" \
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.mac" \
|
||||||
--java-options "-Xss5m" \
|
--java-options "-Xss5m" \
|
||||||
--java-options "-Xmx256m" \
|
--java-options "-Xmx256m" \
|
||||||
--java-options "-Dfile.encoding=\"utf-8\"" \
|
--java-options "-Dfile.encoding=\"utf-8\"" \
|
||||||
|
|||||||
Vendored
+94
-30
@@ -18,14 +18,32 @@ $ProgressPreference = 'SilentlyContinue' # disables Invoke-WebRequest's progress
|
|||||||
# check preconditions
|
# check preconditions
|
||||||
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
|
if ((Get-Command "git" -ErrorAction SilentlyContinue) -eq $null)
|
||||||
{
|
{
|
||||||
Write-Host "Unable to find git.exe in your PATH (try: choco install git)"
|
Write-Error "Unable to find git.exe in your PATH (try: choco install git)"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null)
|
if ((Get-Command "mvn" -ErrorAction SilentlyContinue) -eq $null)
|
||||||
{
|
{
|
||||||
Write-Host "Unable to find mvn.cmd in your PATH (try: choco install maven)"
|
Write-Error "Unable to find mvn.cmd in your PATH (try: choco install maven)"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
if ((Get-Command 'wix' -ErrorAction SilentlyContinue) -eq $null)
|
||||||
|
{
|
||||||
|
Write-Error 'Unable to find wix in your PATH (try: dotnet tool install --global wix --version 6.0.0)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
$wixExtensions = & wix.exe extension list --global | Out-String
|
||||||
|
if ($wixExtensions -notmatch 'WixToolset.UI.wixext') {
|
||||||
|
Write-Error 'Wix UI extension missing. Please install it with: wix.exe extension add WixToolset.UI.wixext/6.0.0 --global)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if ($wixExtensions -notmatch 'WixToolset.Util.wixext') {
|
||||||
|
Write-Error 'Wix Util extension missing. Please install it with: wix.exe extension add WixToolset.Util.wixext/6.0.0 --global)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
if ($wixExtensions -notmatch 'WixToolset.BootstrapperApplications.wixext') {
|
||||||
|
Write-Error 'Wix Bootstrapper extension missing. Please install it with: wix.exe extension add WixToolset.BootstrapperApplications.wixext/6.0.0 --global)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
$buildDir = Split-Path -Parent $PSCommandPath
|
$buildDir = Split-Path -Parent $PSCommandPath
|
||||||
$version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout)
|
$version = $(mvn -f $buildDir/../../pom.xml help:evaluate -Dexpression="project.version" -q -DforceStdout)
|
||||||
@@ -50,37 +68,71 @@ if ($clean -and (Test-Path -Path $runtimeImagePath)) {
|
|||||||
Remove-Item -Path $runtimeImagePath -Force -Recurse
|
Remove-Item -Path $runtimeImagePath -Force -Recurse
|
||||||
}
|
}
|
||||||
|
|
||||||
## download jfx jmods
|
## download jfx jmods for X64, while they are part of the Arm64 JDK
|
||||||
$javaFxVersion='23.0.1'
|
$archCode = (Get-CimInstance Win32_Processor).Architecture
|
||||||
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
|
$archName = switch ($archCode) {
|
||||||
$javaFxJmodsSHA256 = 'ee176dcee3bd78bde7910735bd67f67c792882f5b89626796ae06f7a1c0119d3'
|
9 { "x64 (AMD64)" }
|
||||||
$javaFxJmods = '.\resources\jfxJmods.zip'
|
12 { "ARM64" }
|
||||||
if( !(Test-Path -Path $javaFxJmods) ) {
|
default { "WMI Win32_Processor.Architecture code ($archCode)" }
|
||||||
Write-Output "Downloading ${javaFxJmodsUrl}..."
|
|
||||||
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
|
switch ($archName) {
|
||||||
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
|
'ARM64' {
|
||||||
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
|
$javafxBaseJmod = Join-Path $Env:JAVA_HOME "jmods\javafx.base.jmod"
|
||||||
, actual: $jmodsChecksumActual"
|
if (!(Test-Path $javafxBaseJmod)) {
|
||||||
exit 1;
|
Write-Error "JavaFX module not found in JDK. Please ensure full JDK (including jmods) is installed."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$jmodPaths = "$Env:JAVA_HOME/jmods"
|
||||||
|
}
|
||||||
|
'x64 (AMD64)' {
|
||||||
|
$javaFxVersion='24.0.1'
|
||||||
|
$javaFxJmodsUrl = "https://download2.gluonhq.com/openjfx/${javaFxVersion}/openjfx-${javaFxVersion}_windows-x64_bin-jmods.zip"
|
||||||
|
$javaFxJmodsSHA256 = 'f13d17c7caf88654fc835f1b4e75a9b0f34a888eb8abef381796c0002e63b03f'
|
||||||
|
$javaFxJmods = '.\resources\jfxJmods.zip'
|
||||||
|
|
||||||
|
if( !(Test-Path -Path $javaFxJmods) ) {
|
||||||
|
Write-Output "Downloading ${javaFxJmodsUrl}..."
|
||||||
|
Invoke-WebRequest $javaFxJmodsUrl -OutFile $javaFxJmods # redirects are followed by default
|
||||||
|
}
|
||||||
|
|
||||||
|
$jmodsChecksumActual = $(Get-FileHash -Path $javaFxJmods -Algorithm SHA256).Hash.ToLower()
|
||||||
|
if( $jmodsChecksumActual -ne $javaFxJmodsSHA256 ) {
|
||||||
|
Write-Error "Checksum mismatch for jfxJmods.zip. Expected: $javaFxJmodsSHA256
|
||||||
|
, actual: $jmodsChecksumActual"
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
|
||||||
|
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
|
||||||
|
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
|
||||||
|
|
||||||
|
$jmodPaths="$buildDir/resources/javafx-jmods";
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
Write-Error "Unsupported architecture: $arch"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Expand-Archive -Path $javaFxJmods -Force -DestinationPath ".\resources\"
|
|
||||||
Remove-Item -Recurse -Force -Path ".\resources\javafx-jmods" -ErrorAction Ignore
|
|
||||||
Move-Item -Force -Path ".\resources\javafx-jmods-*" -Destination ".\resources\javafx-jmods" -ErrorAction Stop
|
|
||||||
|
|
||||||
## create custom runtime
|
## create custom runtime
|
||||||
|
### check for JEP 493
|
||||||
|
if ((& "$Env:JAVA_HOME\bin\jlink" --help | Select-String -Pattern "Linking from run-time image enabled" -SimpleMatch | Measure-Object).Count -eq 0 ) {
|
||||||
|
$jmodPaths="$Env:JAVA_HOME/jmods;" + $jmodPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
### create runtime
|
||||||
& "$Env:JAVA_HOME\bin\jlink" `
|
& "$Env:JAVA_HOME\bin\jlink" `
|
||||||
--verbose `
|
--verbose `
|
||||||
--output runtime `
|
--output runtime `
|
||||||
--module-path "$Env:JAVA_HOME/jmods;$buildDir/resources/javafx-jmods" `
|
--module-path $jmodPaths `
|
||||||
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,jdk.crypto.mscapi,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
|
--add-modules java.base,java.desktop,java.instrument,java.logging,java.naming,java.net.http,java.scripting,java.sql,java.xml,jdk.unsupported,jdk.accessibility,jdk.management.jfr,jdk.crypto.mscapi,java.compiler,javafx.base,javafx.graphics,javafx.controls,javafx.fxml `
|
||||||
--strip-native-commands `
|
--strip-native-commands `
|
||||||
--no-header-files `
|
--no-header-files `
|
||||||
--no-man-pages `
|
--no-man-pages `
|
||||||
--strip-debug `
|
--strip-debug `
|
||||||
--compress "zip-0" #do not compress to have improved msi compression
|
--compress "zip-0" #do not compress and use msi compression
|
||||||
|
|
||||||
$appPath = ".\$AppName"
|
$appPath = ".\$AppName"
|
||||||
if ($clean -and (Test-Path -Path $appPath)) {
|
if ($clean -and (Test-Path -Path $appPath)) {
|
||||||
@@ -100,7 +152,7 @@ if ($clean -and (Test-Path -Path $appPath)) {
|
|||||||
--vendor $Vendor `
|
--vendor $Vendor `
|
||||||
--copyright $copyright `
|
--copyright $copyright `
|
||||||
--java-options "--enable-preview" `
|
--java-options "--enable-preview" `
|
||||||
--java-options "--enable-native-access=org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
|
--java-options "--enable-native-access=javafx.graphics,org.cryptomator.jfuse.win,org.cryptomator.integrations.win" `
|
||||||
--java-options "-Xss5m" `
|
--java-options "-Xss5m" `
|
||||||
--java-options "-Xmx256m" `
|
--java-options "-Xmx256m" `
|
||||||
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
|
--java-options "-Dcryptomator.appVersion=`"$semVerNo`"" `
|
||||||
@@ -116,6 +168,7 @@ if ($clean -and (Test-Path -Path $appPath)) {
|
|||||||
--java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
|
--java-options "-Dcryptomator.loopbackAlias=`"$LoopbackAlias`"" `
|
||||||
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
|
--java-options "-Dcryptomator.integrationsWin.autoStartShellLinkName=`"$AppName`"" `
|
||||||
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
|
--java-options "-Dcryptomator.integrationsWin.keychainPaths=`"@{appdata}/$AppName/keychain.json;@{userhome}/AppData/Roaming/$AppName/keychain.json`"" `
|
||||||
|
--java-options "-Dcryptomator.integrationsWin.windowsHelloKeychainPaths=`"@{appdata}/$AppName/windowsHelloKeychain.json`"" `
|
||||||
--java-options "-Dcryptomator.showTrayIcon=true" `
|
--java-options "-Dcryptomator.showTrayIcon=true" `
|
||||||
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
|
--java-options "-Dcryptomator.buildNumber=`"msi-$revisionNo`"" `
|
||||||
--resource-dir resources `
|
--resource-dir resources `
|
||||||
@@ -166,6 +219,11 @@ $Env:JP_WIXHELPER_DIR = "."
|
|||||||
--about-url $AboutUrl `
|
--about-url $AboutUrl `
|
||||||
--file-associations resources/FAvaultFile.properties
|
--file-associations resources/FAvaultFile.properties
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "jpackage MSI failed with exit code $LASTEXITCODE"
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#Create RTF license for bundle
|
#Create RTF license for bundle
|
||||||
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
|
&mvn -B -f $buildDir/../../pom.xml license:add-third-party "-Djavafx.platform=win" `
|
||||||
"-Dlicense.thirdPartyFilename=license.rtf" `
|
"-Dlicense.thirdPartyFilename=license.rtf" `
|
||||||
@@ -187,14 +245,20 @@ Write-Output "Downloading ${winfspUninstaller}..."
|
|||||||
Invoke-WebRequest $winfspUninstaller -OutFile ".\bundle\resources\winfsp-uninstaller.exe" # redirects are followed by default
|
Invoke-WebRequest $winfspUninstaller -OutFile ".\bundle\resources\winfsp-uninstaller.exe" # redirects are followed by default
|
||||||
|
|
||||||
# copy MSI to bundle resources
|
# copy MSI to bundle resources
|
||||||
Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi"
|
Copy-Item ".\installer\$AppName-*.msi" -Destination ".\bundle\resources\$AppName.msi" -Force
|
||||||
|
|
||||||
# create bundle including winfsp
|
# create bundle including winfsp
|
||||||
& "$env:WIX\bin\candle.exe" .\bundle\bundleWithWinfsp.wxs -ext WixBalExtension -ext WixUtilextension -out bundle\ `
|
& wix build `
|
||||||
-dBundleVersion="$semVerNo.$revisionNo" `
|
-define BundleName="$AppName" `
|
||||||
-dBundleVendor="$Vendor" `
|
-define BundleVersion="$semVerNo.$revisionNo" `
|
||||||
-dBundleCopyright="$copyright" `
|
-define BundleVendor="$Vendor" `
|
||||||
-dAboutUrl="$AboutUrl" `
|
-define BundleCopyright="$copyright" `
|
||||||
-dHelpUrl="$HelpUrl" `
|
-define AboutUrl="$AboutUrl" `
|
||||||
-dUpdateUrl="$UpdateUrl"
|
-define HelpUrl="$HelpUrl" `
|
||||||
& "$env:WIX\bin\light.exe" -b . .\bundle\BundlewithWinfsp.wixobj -ext WixBalExtension -ext WixUtilextension -out installer\$AppName-Installer.exe
|
-define UpdateUrl="$UpdateUrl" `
|
||||||
|
-ext "WixToolset.Util.wixext" `
|
||||||
|
-ext "WixToolset.BootstrapperApplications.wixext" `
|
||||||
|
.\bundle\bundleWithWinfsp.wxs `
|
||||||
|
-out "installer\$AppName-Installer.exe"
|
||||||
|
|
||||||
|
Write-Output "Created EXE installer .\installer\$AppName-Installer.exe"
|
||||||
|
|||||||
Vendored
+41
-59
@@ -1,66 +1,48 @@
|
|||||||
<?xml version="1.0"?>
|
<!-- For Built in variables, see https://wixtoolset.org/docs/tools/burn/builtin-variables/-->
|
||||||
|
<ns0:Wix xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
|
||||||
<!-- For Built in variables, see https://wixtoolset.org/docs/tools/burn/builtin-variables/-->
|
<ns0:Bundle Name="$(var.BundleName)"
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
UpgradeCode="29eea626-2e5b-4449-b5f8-4602925ddf7b"
|
||||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/bundle.html-->
|
Version="$(var.BundleVersion)"
|
||||||
<!-- Attributes explicitly not used:
|
Manufacturer="$(var.BundleVendor)"
|
||||||
Condition - the single msi files have their own install conditions, no need to copy them here
|
AboutUrl="$(var.AboutUrl)"
|
||||||
-->
|
HelpUrl="$(var.HelpUrl)"
|
||||||
|
UpdateUrl="$(var.UpdateUrl)"
|
||||||
<Bundle Name="Cryptomator" UpgradeCode="29eea626-2e5b-4449-b5f8-4602925ddf7b" Version="$(var.BundleVersion)" Manufacturer="$(var.BundleVendor)"
|
Copyright="$(var.BundleCopyright)"
|
||||||
AboutUrl="$(var.AboutUrl)" HelpUrl="$(var.HelpUrl)" UpdateUrl="$(var.UpdateUrl)" Copyright="$(var.BundleCopyright)" IconSourceFile="bundle\resources\Cryptomator.ico">
|
IconSourceFile="bundle\resources\Cryptomator.ico">
|
||||||
|
|
||||||
<!-- detect outdated WinFsp installations -->
|
<!-- detect outdated WinFsp installations -->
|
||||||
<util:ProductSearch
|
<util:ProductSearch Variable="InstalledLegacyWinFspVersion" Result="version" UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B" />
|
||||||
Variable="InstalledLegacyWinFspVersion"
|
|
||||||
Result="version"
|
|
||||||
UpgradeCode="82F812D9-4083-4EF1-8BC8-0F1EDA05B46B"/>
|
|
||||||
|
|
||||||
<!-- for definition of the standard themes, see https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/-->
|
<ns0:BootstrapperApplication>
|
||||||
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLargeLicense">
|
<bal:WixStandardBootstrapperApplication LicenseFile="bundle\resources\license.rtf" ShowVersion="yes"
|
||||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/bal/wixstandardbootstrapperapplication.html -->
|
SuppressOptionsUI="yes"
|
||||||
<!-- Possible Attributes: LaunchTarget -->
|
Theme="rtfLargeLicense"
|
||||||
<bal:WixStandardBootstrapperApplication
|
ThemeFile="bundle\resources\customBootstrapperTheme.xml"
|
||||||
LicenseFile="bundle\resources\license.rtf"
|
LocalizationFile="bundle\resources\customBootstrapperTheme.wxl"
|
||||||
ShowVersion="yes"
|
LogoSideFile="bundle\resources\logoSide.png"
|
||||||
SuppressOptionsUI="yes"
|
LogoFile="bundle\resources\logo.png"
|
||||||
ThemeFile="bundle\customBootstrapperTheme.xml"
|
LaunchTarget="[ProgramFiles64Folder]\$(var.BundleName)\$(var.BundleName).exe" />
|
||||||
LocalizationFile="bundle\customBootstrapperTheme.wxl"
|
<ns0:Payload SourceFile="bundle\resources\logoSide.png"/>
|
||||||
LogoFile="bundle\resources\logo.png"/>
|
<!-- Required due to https://github.com/wixtoolset/issues/issues/8104 -->
|
||||||
<Payload SourceFile="bundle\resources\logoSide.png" />
|
<ns0:Payload Name="Cryptobot.ico" SourceFile="bundle\resources\Cryptomator.ico"/>
|
||||||
</BootstrapperApplicationRef>
|
</ns0:BootstrapperApplication>
|
||||||
|
|
||||||
<Chain>
|
<ns0:Chain>
|
||||||
<ExePackage Cache="yes" PerMachine="yes" Permanent="no"
|
<ns0:ExePackage Cache="keep" PerMachine="yes" Permanent="no" SourceFile="bundle\resources\winfsp-uninstaller.exe" DisplayName="Removing outdated WinFsp Driver" Description="Executable to remove old winfsp" DetectCondition="false" InstallCondition="(InstalledLegacyWinFspVersion <> v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))" UninstallArguments="">
|
||||||
SourceFile="resources\winfsp-uninstaller.exe"
|
<ns0:CommandLine Condition="WixBundleUILevel <= 3" InstallArgument="-q -l "[WixBundleLog].winfsp-uninstaller.log"" RepairArgument="-q" UninstallArgument="-s" />
|
||||||
DisplayName="Removing outdated WinFsp Driver"
|
|
||||||
Description="Executable to remove old winfsp"
|
|
||||||
DetectCondition="false"
|
|
||||||
InstallCondition="(InstalledLegacyWinFspVersion <> v0.0.0.0) AND ((WixBundleAction = 7) OR (WixBundleAction = 5))">
|
|
||||||
<CommandLine Condition="WixBundleUILevel <= 3" InstallArgument="-q -l "[WixBundleLog].winfsp-uninstaller.log"" RepairArgument="-q" UninstallArgument="-s" />
|
|
||||||
<!-- XML allows line breaks in attributes, hence keep the line breaks here -->
|
<!-- XML allows line breaks in attributes, hence keep the line breaks here -->
|
||||||
<CommandLine Condition="WixBundleUILevel > 3" InstallArgument="-l "[WixBundleLog].winfsp-uninstaller.log" -t "Cryptomator Installer" -m "Cryptomator requires a newer version of the WinFsp driver. The installer will now uninstall WinFsp, possibly reboot, and afterwards proceed with the installation.
|
<ns0:CommandLine Condition="WixBundleUILevel > 3" InstallArgument="-l "[WixBundleLog].winfsp-uninstaller.log" -t "Cryptomator Installer" -m "Cryptomator requires a newer version of the WinFsp driver. The installer will now uninstall WinFsp, possibly reboot, and afterwards proceed with the installation.
|
||||||
|
|
||||||
Do you want to continue?"" RepairArgument="-q" UninstallArgument="-s" />
|
Do you want to continue?"" RepairArgument="-q" UninstallArgument="-s" />
|
||||||
<ExitCode Behavior="success" Value="0"/>
|
<ns0:ExitCode Behavior="success" Value="0" />
|
||||||
<ExitCode Behavior="success" Value="1"/>
|
<ns0:ExitCode Behavior="success" Value="1" />
|
||||||
<ExitCode Behavior="error" Value="2"/>
|
<ns0:ExitCode Behavior="error" Value="2" />
|
||||||
<ExitCode Behavior="error" Value="3"/>
|
<ns0:ExitCode Behavior="error" Value="3" />
|
||||||
<ExitCode Behavior="forceReboot" Value="4"/>
|
<ns0:ExitCode Behavior="forceReboot" Value="4" />
|
||||||
<ExitCode Behavior="success" Value="5"/>
|
<ns0:ExitCode Behavior="success" Value="5" />
|
||||||
</ExePackage>
|
</ns0:ExePackage>
|
||||||
<!-- see https://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html-->
|
<ns0:MsiPackage SourceFile="bundle\resources\Cryptomator.msi" CacheId="cryptomator-bundle-cryptomator" Visible="no" />
|
||||||
<MsiPackage
|
<ns0:MsiPackage SourceFile="bundle\resources\winfsp.msi" CacheId="cryptomator-bundle-winfsp" Visible="yes" Permanent="yes" />
|
||||||
SourceFile="resources\Cryptomator.msi"
|
</ns0:Chain>
|
||||||
CacheId="cryptomator-bundle-cryptomator"
|
</ns0:Bundle>
|
||||||
DisplayInternalUI="no"
|
</ns0:Wix>
|
||||||
Visible="no"/>
|
|
||||||
<MsiPackage
|
|
||||||
SourceFile="resources\winfsp.msi"
|
|
||||||
CacheId="cryptomator-bundle-winfsp"
|
|
||||||
Visible="yes"
|
|
||||||
DisplayInternalUI="no"
|
|
||||||
Permanent="yes"/>
|
|
||||||
</Chain>
|
|
||||||
</Bundle>
|
|
||||||
</Wix>
|
|
||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
|
||||||
|
|
||||||
|
|
||||||
<WixLocalization Culture="en-us" Language="1033" xmlns="http://schemas.microsoft.com/wix/2006/localization">
|
|
||||||
<String Id="Caption">[WixBundleName] Setup</String>
|
|
||||||
<String Id="Title">[WixBundleName]</String>
|
|
||||||
<String Id="InstallHeader">Welcome</String>
|
|
||||||
<String Id="InstallMessage">This Setup will install [WixBundleName] and additional dependencies on your computer.</String>
|
|
||||||
<String Id="InstallVersion">Version [WixBundleVersion]</String>
|
|
||||||
<String Id="ConfirmCancelMessage">Are you sure you want to cancel?</String>
|
|
||||||
<String Id="ExecuteUpgradeRelatedBundleMessage">Previous version</String>
|
|
||||||
<String Id="HelpHeader">Setup Help</String>
|
|
||||||
<String Id="HelpText">/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
|
|
||||||
creates a complete local copy of the bundle in directory. Install is the default.
|
|
||||||
|
|
||||||
/passive | /quiet - displays minimal UI with no prompts or displays no UI and
|
|
||||||
no prompts. By default UI and all prompts are displayed.
|
|
||||||
|
|
||||||
/norestart - suppress any attempts to restart. By default UI will prompt before restart.
|
|
||||||
/log log.txt - logs to a specific file. By default a log file is created in %TEMP%.</String>
|
|
||||||
<String Id="HelpCloseButton">&Close</String>
|
|
||||||
<String Id="InstallLicenseLinkText">[WixBundleName] <a href="#">license terms</a>.</String>
|
|
||||||
<String Id="InstallAcceptCheckbox">I &agree to the license terms and conditions</String>
|
|
||||||
<String Id="InstallOptionsButton">&Options</String>
|
|
||||||
<String Id="InstallInstallButton">&Install</String>
|
|
||||||
<String Id="InstallCloseButton">&Close</String>
|
|
||||||
<String Id="OptionsHeader">Setup Options</String>
|
|
||||||
<String Id="OptionsLocationLabel">Install location:</String>
|
|
||||||
<String Id="OptionsBrowseButton">&Browse</String>
|
|
||||||
<String Id="OptionsOkButton">&OK</String>
|
|
||||||
<String Id="OptionsCancelButton">&Cancel</String>
|
|
||||||
<String Id="ProgressHeader">Setup Progress</String>
|
|
||||||
<String Id="ProgressLabel">Processing:</String>
|
|
||||||
<String Id="OverallProgressPackageText">Initializing...</String>
|
|
||||||
<String Id="ProgressCancelButton">&Cancel</String>
|
|
||||||
<String Id="ModifyHeader">Modify Setup</String>
|
|
||||||
<String Id="ModifyRepairButton">&Repair</String>
|
|
||||||
<String Id="ModifyUninstallButton">&Uninstall</String>
|
|
||||||
<String Id="ModifyCloseButton">&Close</String>
|
|
||||||
<String Id="SuccessRepairHeader">Repair Successfully Completed</String>
|
|
||||||
<String Id="SuccessUninstallHeader">Uninstall Successfully Completed</String>
|
|
||||||
<String Id="SuccessInstallHeader">Installation Successfully Completed</String>
|
|
||||||
<String Id="SuccessHeader">Setup Successful</String>
|
|
||||||
<String Id="SuccessLaunchButton">&Launch</String>
|
|
||||||
<String Id="SuccessRestartText">You must restart your computer before you can use the software.</String>
|
|
||||||
<String Id="SuccessRestartButton">&Restart</String>
|
|
||||||
<String Id="SuccessCloseButton">&Close</String>
|
|
||||||
<String Id="FailureHeader">Setup Failed</String>
|
|
||||||
<String Id="FailureInstallHeader">Setup Failed</String>
|
|
||||||
<String Id="FailureUninstallHeader">Uninstall Failed</String>
|
|
||||||
<String Id="FailureRepairHeader">Repair Failed</String>
|
|
||||||
<String Id="FailureHyperlinkLogText">One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>.</String>
|
|
||||||
<String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String>
|
|
||||||
<String Id="FailureRestartButton">&Restart</String>
|
|
||||||
<String Id="FailureCloseButton">&Close</String>
|
|
||||||
<String Id="FilesInUseHeader">Files In Use</String>
|
|
||||||
<String Id="FilesInUseLabel">The following applications are using files that need to be updated:</String>
|
|
||||||
<String Id="FilesInUseCloseRadioButton">Close the &applications and attempt to restart them.</String>
|
|
||||||
<String Id="FilesInUseDontCloseRadioButton">&Do not close applications. A reboot will be required.</String>
|
|
||||||
<String Id="FilesInUseOkButton">&OK</String>
|
|
||||||
<String Id="FilesInUseCancelButton">&Cancel</String>
|
|
||||||
<String Id="ErrorFailNoActionReboot">No action was taken as a system reboot is required.</String>
|
|
||||||
</WixLocalization>
|
|
||||||
-91
@@ -1,91 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
|
||||||
<!-- adjusted theme based on https://github.com/wixtoolset/wix3/blob/master/src/ext/BalExtension/wixstdba/Resources/HyperlinkSidebarTheme.xml -->
|
|
||||||
|
|
||||||
|
|
||||||
<Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010">
|
|
||||||
<Window Width="600" Height="450" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window>
|
|
||||||
<Font Id="0" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
|
||||||
<Font Id="1" Height="-24" Weight="500" Foreground="000000">Segoe UI</Font>
|
|
||||||
<Font Id="2" Height="-22" Weight="500" Foreground="666666">Segoe UI</Font>
|
|
||||||
<Font Id="3" Height="-12" Weight="500" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
|
||||||
<Font Id="4" Height="-12" Weight="500" Foreground="ff0000" Background="FFFFFF" Underline="yes">Segoe UI</Font>
|
|
||||||
<Font Id="5" Height="-12" Weight="700" Foreground="000000" Background="FFFFFF">Segoe UI</Font>
|
|
||||||
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
|
|
||||||
<Page Name="Help">
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Text>
|
|
||||||
<Text X="11" Y="112" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Text>
|
|
||||||
<Button Name="HelpCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.HelpCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Install">
|
|
||||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
|
||||||
<Text X="185" Y="50" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.InstallHeader)</Text>
|
|
||||||
<Text X="185" Y="91" Width="-11" Height="64" FontId="3" DisablePrefix="yes">#(loc.InstallMessage)</Text>
|
|
||||||
<Richedit Name="EulaRichedit" X="185" Y="131" Width="-12" Height="-65" HexStyle="0x00800000" TabStop="yes" FontId="0" />
|
|
||||||
<Checkbox Name="EulaAcceptCheckbox" X="185" Y="-46" Width="-11" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox>
|
|
||||||
<Text Name="InstallVersion" X="185" Y="-11" Width="-11" Height="17" FontId="3" DisablePrefix="yes" HideWhenDisabled="yes">#(loc.InstallVersion)</Text>
|
|
||||||
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
|
|
||||||
<Button Name="WelcomeCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="FilesInUse">
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.FilesInUseHeader)</Text>
|
|
||||||
<Text X="11" Y="121" Width="-11" Height="34" FontId="3" DisablePrefix="yes">#(loc.FilesInUseLabel)</Text>
|
|
||||||
<Text Name="FilesInUseText" X="11" Y="150" Width="-11" Height="-86" FontId="3" DisablePrefix="yes" HexStyle="0x0000000C">A</Text>
|
|
||||||
|
|
||||||
<Button Name="FilesInUseCloseRadioButton" X="11" Y="-60" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseCloseRadioButton)</Button>
|
|
||||||
<Button Name="FilesInUseDontCloseRadioButton" X="11" Y="-40" Width="-11" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes" HexStyle="0x000009">#(loc.FilesInUseDontCloseRadioButton)</Button>
|
|
||||||
|
|
||||||
<Button Name="FilesInUseOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FilesInUseOkButton)</Button>
|
|
||||||
<Button Name="FilesInUseCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FilesInUseCancelButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Progress">
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
|
|
||||||
<Text X="11" Y="141" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Text>
|
|
||||||
<Text Name="OverallProgressPackageText" X="85" Y="141" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
|
|
||||||
<Progressbar Name="OverallCalculatedProgressbar" X="11" Y="163" Width="-11" Height="20" />
|
|
||||||
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Modify">
|
|
||||||
<Image X="11" Y="11" Width="64" Height="64" ImageFile="logo.png" />
|
|
||||||
<Text X="80" Y="11" Width="-11" Height="64" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Text>
|
|
||||||
<Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
|
|
||||||
<Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
|
|
||||||
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Success">
|
|
||||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
|
||||||
<Text Name="SuccessHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessHeader)</Text>
|
|
||||||
<Text Name="SuccessInstallHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessInstallHeader)</Text>
|
|
||||||
<Text Name="SuccessRepairHeader" X="185" Y="50" Width="-11" Height="100" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRepairHeader)</Text>
|
|
||||||
<Text Name="SuccessUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessUninstallHeader)</Text>
|
|
||||||
<Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
|
|
||||||
<Text Name="SuccessRestartText" X="185" Y="-51" Width="400" Height="34" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.SuccessRestartText)</Text>
|
|
||||||
<Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
|
|
||||||
<Button Name="SuccessCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.SuccessCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
<Page Name="Failure">
|
|
||||||
<Text X="185" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Text>
|
|
||||||
<Image X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
|
||||||
<Text Name="FailureHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureHeader)</Text>
|
|
||||||
<Text Name="FailureInstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureInstallHeader)</Text>
|
|
||||||
<Text Name="FailureUninstallHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureUninstallHeader)</Text>
|
|
||||||
<Text Name="FailureRepairHeader" X="185" Y="50" Width="-11" Height="30" FontId="2" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRepairHeader)</Text>
|
|
||||||
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
|
|
||||||
<Hypertext Name="FailureMessageText" X="185" Y="-80" Width="-11" Height="140" FontId="5" TabStop="yes" HideWhenDisabled="yes" />
|
|
||||||
<Text Name="FailureRestartText" X="185" Y="-57" Width="-11" Height="80" FontId="3" HideWhenDisabled="yes" DisablePrefix="yes">#(loc.FailureRestartText)</Text>
|
|
||||||
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
|
|
||||||
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.FailureCloseButton)</Button>
|
|
||||||
</Page>
|
|
||||||
</Theme>
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||||
|
|
||||||
|
|
||||||
|
<WixLocalization Culture="en-us" Language="1033" xmlns="http://wixtoolset.org/schemas/v4/wxl">
|
||||||
|
<String Id="Caption" Value="[WixBundleName] Setup" />
|
||||||
|
<String Id="Title" Value="[WixBundleName]" />
|
||||||
|
<String Id="InstallHeader" Value="Welcome" />
|
||||||
|
<String Id="InstallMessage" Value="Setup will install [WixBundleName] on your computer." />
|
||||||
|
<String Id="InstallVersion" Value="Version [WixBundleVersion]" />
|
||||||
|
<String Id="CheckingForUpdatesLabel" Value="Checking for updates" />
|
||||||
|
<String Id="UpdateButton" Value="&Update to version [WixStdBAUpdateAvailable]" />
|
||||||
|
<String Id="InstallVersion" Value="Version [WixBundleVersion]" />
|
||||||
|
<String Id="ConfirmCancelMessage" Value="Are you sure you want to cancel?" />
|
||||||
|
<String Id="ExecuteUpgradeRelatedBundleMessage" Value="Previous version" />
|
||||||
|
<String Id="HelpHeader" Value="Setup Help" />
|
||||||
|
<String Id="HelpText" Value="/install | /repair | /uninstall | /layout [directory] - installs, repairs, uninstalls or
 creates a complete local copy of the bundle in directory. Install is the default.

/passive | /quiet - displays minimal UI with no prompts or displays no UI and
 no prompts. By default UI and all prompts are displayed.

/norestart - suppress any attempts to restart. By default UI will prompt before restart.
/log log.txt - logs to a specific file. By default a log file is created in %TEMP%." />
|
||||||
|
<String Id="HelpCloseButton" Value="&Close" />
|
||||||
|
<String Id="InstallAcceptCheckbox" Value="I &agree to the license terms and conditions" />
|
||||||
|
<String Id="InstallOptionsButton" Value="&Options" />
|
||||||
|
<String Id="InstallInstallButton" Value="&Install" />
|
||||||
|
<String Id="InstallCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="OptionsHeader" Value="Setup Options" />
|
||||||
|
<String Id="OptionsLocationLabel" Value="Install location:" />
|
||||||
|
<String Id="OptionsBrowseButton" Value="&Browse" />
|
||||||
|
<String Id="OptionsOkButton" Value="&OK" />
|
||||||
|
<String Id="OptionsCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="ProgressHeader" Value="Setup Progress" />
|
||||||
|
<String Id="ProgressLabel" Value="Processing:" />
|
||||||
|
<String Id="OverallProgressPackageText" Value="Initializing..." />
|
||||||
|
<String Id="ProgressCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="ModifyHeader" Value="Modify Setup" />
|
||||||
|
<String Id="ModifyRepairButton" Value="&Repair" />
|
||||||
|
<String Id="ModifyUninstallButton" Value="&Uninstall" />
|
||||||
|
<String Id="ModifyCancelButton" Value="&Cancel" />
|
||||||
|
<String Id="SuccessHeader" Value="Setup Successful" />
|
||||||
|
<String Id="SuccessCacheHeader" Value="Cache Successfully Completed" />
|
||||||
|
<String Id="SuccessInstallHeader" Value="Installation Successfully Completed" />
|
||||||
|
<String Id="SuccessLayoutHeader" Value="Layout Successfully Completed" />
|
||||||
|
<String Id="SuccessModifyHeader" Value="Modify Successfully Completed" />
|
||||||
|
<String Id="SuccessRepairHeader" Value="Repair Successfully Completed" />
|
||||||
|
<String Id="SuccessUninstallHeader" Value="Uninstall Successfully Completed" />
|
||||||
|
<String Id="SuccessUnsafeUninstallHeader" Value="Uninstall Successfully Completed" />
|
||||||
|
<String Id="SuccessLaunchButton" Value="&Launch" />
|
||||||
|
<String Id="SuccessRestartText" Value="You must restart your computer before you can use the software." />
|
||||||
|
<String Id="SuccessUninstallRestartText" Value="You must restart your computer to complete the removal of the software." />
|
||||||
|
<String Id="SuccessRestartButton" Value="&Restart" />
|
||||||
|
<String Id="SuccessCloseButton" Value="&Close" />
|
||||||
|
<String Id="FailureHeader" Value="Setup Failed" />
|
||||||
|
<String Id="FailureCacheHeader" Value="Cache Failed" />
|
||||||
|
<String Id="FailureInstallHeader" Value="Setup Failed" />
|
||||||
|
<String Id="FailureLayoutHeader" Value="Layout Failed" />
|
||||||
|
<String Id="FailureModifyHeader" Value="Modify Failed" />
|
||||||
|
<String Id="FailureRepairHeader" Value="Repair Failed" />
|
||||||
|
<String Id="FailureUninstallHeader" Value="Uninstall Failed" />
|
||||||
|
<String Id="FailureUnsafeUninstallHeader" Value="Uninstall Failed" />
|
||||||
|
<String Id="FailureHyperlinkLogText" Value="One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>." />
|
||||||
|
<String Id="FailureRestartText" Value="You must restart your computer to complete the rollback of the software." />
|
||||||
|
<String Id="FailureRestartButton" Value="&Restart" />
|
||||||
|
<String Id="FailureCloseButton" Value="&Close" />
|
||||||
|
<String Id="FilesInUseTitle" Value="Files In Use" />
|
||||||
|
<String Id="FilesInUseLabel" Value="The following applications are using files that need to be updated:" />
|
||||||
|
<String Id="FilesInUseNetfxCloseRadioButton" Value="Close the &applications." />
|
||||||
|
<String Id="FilesInUseCloseRadioButton" Value="Close the &applications and attempt to restart them." />
|
||||||
|
<String Id="FilesInUseDontCloseRadioButton" Value="&Do not close applications. A reboot will be required." />
|
||||||
|
<String Id="FilesInUseRetryButton" Value="&Retry" />
|
||||||
|
<String Id="FilesInUseIgnoreButton" Value="&Ignore" />
|
||||||
|
<String Id="FilesInUseExitButton" Value="E&xit" />
|
||||||
|
</WixLocalization>
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
|
||||||
|
|
||||||
|
|
||||||
|
<Theme xmlns="http://wixtoolset.org/schemas/v4/thmutil">
|
||||||
|
<Font Id="0" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font>
|
||||||
|
<Font Id="1" Height="-24" Weight="500" Foreground="windowtext">Segoe UI</Font>
|
||||||
|
<Font Id="2" Height="-22" Weight="500" Foreground="graytext">Segoe UI</Font>
|
||||||
|
<Font Id="3" Height="-12" Weight="500" Foreground="windowtext" Background="window">Segoe UI</Font>
|
||||||
|
|
||||||
|
<Window Width="600" Height="450" HexStyle="100a0000" FontId="0" Caption="#(loc.Caption)" IconFile="Cryptobot.ico">
|
||||||
|
<Page Name="Help">
|
||||||
|
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||||
|
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||||
|
<Label X="11" Y="80" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.HelpHeader)</Label>
|
||||||
|
<Label X="11" Y="121" Width="-11" Height="-35" FontId="3" DisablePrefix="yes">#(loc.HelpText)</Label>
|
||||||
|
<Button Name="HelpCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.HelpCloseButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Loading">
|
||||||
|
<Label X="185" Y="50" Width="-11" Height="30" FontId="2" DisablePrefix="yes" Visible="no" Name="CheckingForUpdatesLabel" />
|
||||||
|
</Page>
|
||||||
|
<Page Name="Install">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.InstallHeader)</Label>
|
||||||
|
<Label X="185" Y="50" Width="-11" Height="64" FontId="3" DisablePrefix="yes">
|
||||||
|
<Text Condition="WixStdBASuppressOptionsUI">#(loc.InstallMessage)</Text>
|
||||||
|
<Text Condition="NOT WixStdBASuppressOptionsUI">#(loc.InstallMessageOptions)</Text>
|
||||||
|
</Label>
|
||||||
|
<Richedit Name="EulaRichedit" X="185" Y="91" Width="-12" Height="-64" HexStyle="0x00800000" TabStop="yes" FontId="0" />
|
||||||
|
<Checkbox Name="EulaAcceptCheckbox" X="185" Y="-39" Width="-11" Height="17" TabStop="yes" FontId="3" HideWhenDisabled="yes">#(loc.InstallAcceptCheckbox)</Checkbox>
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Button Name="InstallUpdateButton" X="11" Y="-11" Width="200" Height="23" TabStop="yes" FontId="0" EnableCondition="WixStdBAUpdateAvailable" HideWhenDisabled="yes">#(loc.UpdateButton)</Button>
|
||||||
|
<Button Name="OptionsButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" VisibleCondition="NOT WixStdBASuppressOptionsUI">
|
||||||
|
<Text>#(loc.InstallOptionsButton)</Text>
|
||||||
|
<ChangePageAction Page="Options" />
|
||||||
|
</Button>
|
||||||
|
<Button Name="InstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.InstallInstallButton)</Button>
|
||||||
|
<Button Name="InstallCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.InstallCancelButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Options">
|
||||||
|
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||||
|
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||||
|
<Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.OptionsHeader)</Label>
|
||||||
|
<Label X="11" Y="121" Width="-11" Height="17" FontId="3">#(loc.OptionsLocationLabel)</Label>
|
||||||
|
<Editbox Name="InstallFolder" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes" />
|
||||||
|
<Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3">
|
||||||
|
<Text>#(loc.OptionsBrowseButton)</Text>
|
||||||
|
<BrowseDirectoryAction VariableName="InstallFolder" />
|
||||||
|
</Button>
|
||||||
|
<Button Name="OptionsOkButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.OptionsOkButton)</Text>
|
||||||
|
<ChangePageAction Page="Install" />
|
||||||
|
</Button>
|
||||||
|
<Button Name="OptionsCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.OptionsCancelButton)</Text>
|
||||||
|
<ChangePageAction Page="Install" Cancel="yes" />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Progress">
|
||||||
|
<Label X="80" Y="11" Width="-11" Height="32" FontId="1" DisablePrefix="yes">#(loc.Title)</Label>
|
||||||
|
<ImageControl X="11" Y="11" Width="64" Height="64" ImageFile="logo.png"/>
|
||||||
|
<Label X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Label>
|
||||||
|
<Label X="11" Y="141" Width="70" Height="17" FontId="3" DisablePrefix="yes">#(loc.ProgressLabel)</Label>
|
||||||
|
<Label Name="OverallProgressPackageText" X="85" Y="141" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Label>
|
||||||
|
<Progressbar Name="OverallCalculatedProgressbar" X="11" Y="163" Width="-11" Height="20" />
|
||||||
|
<Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Modify">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">#(loc.ModifyHeader)</Label>
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="-11" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Button Name="ModifyUpdateButton" X="11" Y="-11" Width="200" Height="23" TabStop="yes" FontId="0" EnableCondition="WixStdBAUpdateAvailable" HideWhenDisabled="yes">#(loc.UpdateButton)</Button>
|
||||||
|
<Button Name="RepairButton" X="-171" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.ModifyRepairButton)</Button>
|
||||||
|
<Button Name="UninstallButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ModifyUninstallButton)</Button>
|
||||||
|
<Button Name="ModifyCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.ModifyCancelButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Success">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">
|
||||||
|
<Text>#(loc.SuccessHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 2">#(loc.SuccessLayoutHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 3">#(loc.SuccessUnsafeUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 4">#(loc.SuccessUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 5">#(loc.SuccessCacheHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 6">#(loc.SuccessInstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 7">#(loc.SuccessModifyHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 8">#(loc.SuccessRepairHeader)</Text>
|
||||||
|
</Label>
|
||||||
|
<Button Name="LaunchButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessLaunchButton)</Button>
|
||||||
|
<Label X="185" Y="-51" Width="400" Height="34" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired">
|
||||||
|
<Text>#(loc.SuccessRestartText)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 3">#(loc.SuccessUninstallRestartText)</Text>
|
||||||
|
</Label>
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Button Name="SuccessRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.SuccessRestartButton)</Button>
|
||||||
|
<Button Name="SuccessCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.SuccessCloseButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
<Page Name="Failure">
|
||||||
|
<ImageControl X="11" Y="11" Width="165" Height="400" ImageFile="logoside.png"/>
|
||||||
|
<Label X="185" Y="11" Width="-11" Height="32" FontId="2" DisablePrefix="yes">
|
||||||
|
<Text>#(loc.FailureHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 2">#(loc.FailureLayoutHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 3">#(loc.FailureUnsafeUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 4">#(loc.FailureUninstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 5">#(loc.FailureCacheHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 6">#(loc.FailureInstallHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 7">#(loc.FailureModifyHeader)</Text>
|
||||||
|
<Text Condition="WixBundleAction = 8">#(loc.FailureRepairHeader)</Text>
|
||||||
|
</Label>
|
||||||
|
<Hypertext Name="FailureLogFileLink" X="185" Y="121" Width="-11" Height="68" FontId="3" TabStop="yes" HideWhenDisabled="yes">#(loc.FailureHyperlinkLogText)</Hypertext>
|
||||||
|
<Hypertext Name="FailureMessageText" X="185" Y="-115" Width="-11" Height="80" FontId="3" TabStop="yes" HideWhenDisabled="yes" />
|
||||||
|
<Label Name="InstallVersion" X="11" Y="-11" Width="165" Height="17" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBAShowVersion">#(loc.InstallVersion)</Label>
|
||||||
|
<Label X="185" Y="-57" Width="-11" Height="80" FontId="3" DisablePrefix="yes" VisibleCondition="WixStdBARestartRequired">#(loc.FailureRestartText)</Label>
|
||||||
|
<Button Name="FailureRestartButton" X="-91" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0" HideWhenDisabled="yes">#(loc.FailureRestartButton)</Button>
|
||||||
|
<Button Name="FailureCloseButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">
|
||||||
|
<Text>#(loc.FailureCloseButton)</Text>
|
||||||
|
<CloseWindowAction />
|
||||||
|
</Button>
|
||||||
|
</Page>
|
||||||
|
</Window>
|
||||||
|
</Theme>
|
||||||
Vendored
+2
-1
@@ -6,7 +6,8 @@ java ^
|
|||||||
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
|
-Dcryptomator.ipcSocketPath="~/AppData/Roaming/Cryptomator/ipc.socket" ^
|
||||||
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
|
-Dcryptomator.logDir="~/AppData/Roaming/Cryptomator" ^
|
||||||
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
|
-Dcryptomator.mountPointsDir="~/Cryptomator" ^
|
||||||
-Dcryptomator.keychainPath="~/AppData/Roaming/Cryptomator/keychain.json" ^
|
-Dcryptomator.integrationsWin.keychainPaths="~/AppData/Roaming/Cryptomator/keychain.json" ^
|
||||||
|
-Dcryptomator.integrationsWin.windowsHelloKeychainPaths="~/AppData/Roaming/Cryptomator/windowsHelloKeychain.json" ^
|
||||||
-Xss20m ^
|
-Xss20m ^
|
||||||
-Xmx512m ^
|
-Xmx512m ^
|
||||||
--enable-preview `
|
--enable-preview `
|
||||||
|
|||||||
Vendored
-109
@@ -1,109 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Include>
|
|
||||||
<Fragment>
|
|
||||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/WixUI_InstallDir.wxs with custom exit dialog-->
|
|
||||||
<UI Id="CustomWizard">
|
|
||||||
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
|
|
||||||
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
|
|
||||||
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
|
|
||||||
|
|
||||||
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
|
|
||||||
<Property Id="WixUI_Mode" Value="InstallDir" />
|
|
||||||
|
|
||||||
<DialogRef Id="BrowseDlg" />
|
|
||||||
<DialogRef Id="DiskCostDlg" />
|
|
||||||
<DialogRef Id="ErrorDlg" />
|
|
||||||
<DialogRef Id="FilesInUse" />
|
|
||||||
<DialogRef Id="MsiRMFilesInUse" />
|
|
||||||
<DialogRef Id="PrepareDlg" />
|
|
||||||
<DialogRef Id="ProgressDlg" />
|
|
||||||
<DialogRef Id="ResumeDlg" />
|
|
||||||
<DialogRef Id="UserExit" />
|
|
||||||
|
|
||||||
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3">1</Publish>
|
|
||||||
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
|
||||||
|
|
||||||
<!-- custom end dialogs -->
|
|
||||||
<Publish Dialog="MyExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>
|
|
||||||
<Publish Dialog="MyFatalErrorDlg" Control="Finish" Event="EndDialog" Value="Return" Order="998">1</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
|
|
||||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
|
|
||||||
<Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg">LicenseAccepted = "1"</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg">1</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2">NOT WIXUI_DONTVALIDATEPATH</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3"><![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"]]></Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4">WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
|
|
||||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1">NOT Installed</Publish>
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2">Installed AND PATCH</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>
|
|
||||||
|
|
||||||
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
|
||||||
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
|
||||||
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
|
|
||||||
|
|
||||||
<Property Id="ARPNOMODIFY" Value="1" />
|
|
||||||
|
|
||||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/ExitDialog.wxs with adjustments-->
|
|
||||||
<Dialog Id="MyExitDialog" Width="370" Height="270" Title="!(loc.ExitDialog_Title)">
|
|
||||||
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)" />
|
|
||||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
|
|
||||||
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.ExitDialogBitmap)" />
|
|
||||||
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
|
|
||||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
|
||||||
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogDescription)" />
|
|
||||||
|
|
||||||
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.ExitDialogTitle)" />
|
|
||||||
<!-- TODO: localize? -->
|
|
||||||
<Control Id="Suggestion" Type="Text" X="135" Y="100" Width="220" Height="60" Transparent="yes" NoPrefix="yes">
|
|
||||||
<Text>We recommend for the best user experience to download and install the following third party Windows driver:</Text>
|
|
||||||
</Control>
|
|
||||||
<Control Id="WinFsp" Type="Hyperlink" X="140" Y="125" Width="220" Height="60" Transparent="yes">
|
|
||||||
<Text><![CDATA[WinFsp (<a href="https://winfsp.dev/">Homepage</a>)]]></Text>
|
|
||||||
</Control>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
<!-- copy pasta from https://github.com/wixtoolset/wix3/blob/develop/src/ext/UIExtension/wixlib/FatalError.wxs with adjustments-->
|
|
||||||
<Dialog Id="MyFatalErrorDlg" Width="370" Height="270" Title="!(loc.FatalError_Title)">
|
|
||||||
<Control Id="Finish" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Cancel="yes" Text="!(loc.WixUIFinish)">
|
|
||||||
<Publish Event="EndDialog" Value="Exit">1</Publish>
|
|
||||||
</Control>
|
|
||||||
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUICancel)" />
|
|
||||||
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.FatalErrorBitmap)" />
|
|
||||||
<Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Disabled="yes" Text="!(loc.WixUIBack)" />
|
|
||||||
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
|
|
||||||
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.FatalErrorTitle)" />
|
|
||||||
<Control Id="Description" Type="Text" X="135" Y="70" Width="220" Height="80" Transparent="yes" NoPrefix="yes" Text="!(loc.FatalErrorDescription1) !(loc.FatalErrorDescription2)" />
|
|
||||||
<Control Id="DescriptionReason1" Type="Text" X="135" Y="160" Width="220" Height="20" Transparent="yes" NoPrefix="yes" Hidden="yes" >
|
|
||||||
<Text>Reason:</Text>
|
|
||||||
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
|
|
||||||
</Control>
|
|
||||||
<Control Id="DescriptionReason2" Type="Text" X="135" Y="170" Width="220" Height="40" Transparent="yes" NoPrefix="yes" Hidden="yes" >
|
|
||||||
<Text>Application to update was still running during installation.</Text>
|
|
||||||
<Condition Action="show">FOUNDRUNNINGAPP</Condition>
|
|
||||||
</Control>
|
|
||||||
</Dialog>
|
|
||||||
|
|
||||||
<InstallUISequence>
|
|
||||||
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
|
|
||||||
<Show Dialog="MyFatalErrorDlg" Overridable="yes" OnExit="error"/>
|
|
||||||
</InstallUISequence>
|
|
||||||
<AdminUISequence>
|
|
||||||
<Show Dialog="MyExitDialog" Overridable="yes" OnExit="success"/>
|
|
||||||
<Show Dialog="MyFatalErrorDlg" Overridable="yes" OnExit="error"/>
|
|
||||||
</AdminUISequence>
|
|
||||||
|
|
||||||
</UI>
|
|
||||||
|
|
||||||
<UIRef Id="WixUI_Common" />
|
|
||||||
</Fragment>
|
|
||||||
</Include>
|
|
||||||
Vendored
+105
-115
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
<ns0:Wix xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util" >
|
||||||
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
|
||||||
|
|
||||||
<?ifdef JpIsSystemWide ?>
|
<?ifdef JpIsSystemWide ?>
|
||||||
<?define JpInstallScope="perMachine"?>
|
<?define JpInstallScope="perMachine"?>
|
||||||
@@ -30,174 +29,165 @@
|
|||||||
|
|
||||||
<?include $(var.JpConfigDir)/overrides.wxi ?>
|
<?include $(var.JpConfigDir)/overrides.wxi ?>
|
||||||
|
|
||||||
<Product
|
<ns0:Package
|
||||||
Id="$(var.JpProductCode)"
|
Name="$(var.JpAppName)"
|
||||||
Name="$(var.JpAppName)"
|
Language="$(var.JpProductLanguage)"
|
||||||
Language="$(var.JpProductLanguage)"
|
Version="$(var.JpAppVersion)"
|
||||||
Version="$(var.JpAppVersion)"
|
Manufacturer="$(var.JpAppVendor)"
|
||||||
Manufacturer="$(var.JpAppVendor)"
|
UpgradeCode="$(var.JpProductUpgradeCode)"
|
||||||
UpgradeCode="$(var.JpProductUpgradeCode)">
|
InstallerVersion="$(var.JpInstallerVersion)"
|
||||||
|
Compressed="$(var.JpCompressedMsi)"
|
||||||
|
ProductCode="$(var.JpProductCode)"
|
||||||
|
Scope="$(var.JpInstallScope)">
|
||||||
|
|
||||||
<Package
|
<ns0:SummaryInformation Manufacturer="$(var.JpAppVendor)" Description="$(var.JpAppDescription)"/>
|
||||||
Description="$(var.JpAppDescription)"
|
<ns0:Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
|
||||||
Manufacturer="$(var.JpAppVendor)"
|
|
||||||
InstallerVersion="$(var.JpInstallerVersion)"
|
|
||||||
Compressed="$(var.JpCompressedMsi)"
|
|
||||||
InstallScope="$(var.JpInstallScope)" Platform="x64"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
|
|
||||||
|
|
||||||
<Upgrade Id="$(var.JpProductUpgradeCode)">
|
<ns0:Upgrade Id="$(var.JpProductUpgradeCode)">
|
||||||
<UpgradeVersion
|
<ns0:UpgradeVersion
|
||||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)"
|
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)"
|
||||||
Property="JP_UPGRADABLE_FOUND"
|
Property="JP_UPGRADABLE_FOUND"
|
||||||
Maximum="$(var.JpAppVersion)"
|
Maximum="$(var.JpAppVersion)"
|
||||||
MigrateFeatures="yes"
|
MigrateFeatures="yes"
|
||||||
IncludeMaximum="yes" /> <!-- TODO: check if this needs to be set to yes-->
|
IncludeMaximum="$(var.JpUpgradeVersionOnlyDetectUpgrade)"/> <!-- TODO in earlier versions, this was set to yes-->
|
||||||
<UpgradeVersion
|
<ns0:UpgradeVersion
|
||||||
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
|
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
|
||||||
Property="JP_DOWNGRADABLE_FOUND"
|
Property="JP_DOWNGRADABLE_FOUND"
|
||||||
Minimum="$(var.JpAppVersion)"
|
Minimum="$(var.JpAppVersion)"
|
||||||
MigrateFeatures="yes"
|
MigrateFeatures="yes"
|
||||||
IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
|
IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
|
||||||
</Upgrade>
|
</ns0:Upgrade>
|
||||||
|
|
||||||
<?ifndef JpAllowUpgrades ?>
|
<?ifndef JpAllowUpgrades ?>
|
||||||
<CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
|
<ns0:CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifndef JpAllowDowngrades ?>
|
<?ifndef JpAllowDowngrades ?>
|
||||||
<CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
|
<ns0:CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<Binary Id="JpCaDll" SourceFile="$(env.JP_WIXHELPER_DIR)\wixhelper.dll"/>
|
<!-- TODO: how does this work again? -->
|
||||||
<CustomAction Id="JpFindRelatedProducts" BinaryKey="JpCaDll" DllEntry="FindRelatedProductsEx" />
|
<ns0:Binary Id="JpCaDll" SourceFile="$(env.JP_WIXHELPER_DIR)\wixhelper.dll" />
|
||||||
|
<ns0:CustomAction Id="JpFindRelatedProducts" BinaryRef="JpCaDll" DllEntry="FindRelatedProductsEx" />
|
||||||
|
|
||||||
<?ifndef SkipCryptomatorLegacyCheck ?>
|
<?ifndef SkipCryptomatorLegacyCheck ?>
|
||||||
<!-- Block installation if innosetup entry of Cryptomator is found -->
|
<!-- Block installation if innosetup entry of Cryptomator is found -->
|
||||||
<Property Id="OLDEXEINSTALLER">
|
<ns0:Property Id="OLDEXEINSTALLER">
|
||||||
<RegistrySearch Id="InnoSetupInstallation" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Cryptomator_is1" Type="raw" Name="DisplayName" />
|
<ns0:RegistrySearch Id="InnoSetupInstallation" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Cryptomator_is1" Type="raw" Name="DisplayName" />
|
||||||
</Property>
|
</ns0:Property>
|
||||||
<!-- TODO: localize -->
|
<!-- TODO: localize -->
|
||||||
<Condition Message="A lower version of [ProductName] is already installed. Uninstall it first and then start the setup again. Setup will now exit.">
|
<ns0:Launch Message="A lower version of [ProductName] is already installed. Uninstall it first and then start the setup again. Setup will now exit." Condition="Installed OR NOT OLDEXEINSTALLER" />
|
||||||
<![CDATA[Installed OR NOT OLDEXEINSTALLER]]>
|
|
||||||
</Condition>
|
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<!-- Cryptomator uses UNIX Sockets, which are supported starting with Windows 10 v1803-->
|
<!-- Cryptomator uses UNIX Sockets, which are supported starting with Windows 10 v1803-->
|
||||||
<Property Id="WINDOWSBUILDNUMBER" Secure="yes">
|
<ns0:Property Id="WINDOWSBUILDNUMBER" Secure="yes">
|
||||||
<RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
|
<ns0:RegistrySearch Id="BuildNumberSearch" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion" Name="CurrentBuildNumber" Type="raw" />
|
||||||
</Property>
|
</ns0:Property>
|
||||||
<Condition Message="This application requires Windows 10 version 1803 (build 17134) or newer.">
|
<ns0:Launch Message="This application requires Windows 10 version 1803 (build 17134) or newer." Condition="Installed OR (WINDOWSBUILDNUMBER >= 17134)" />
|
||||||
<![CDATA[Installed OR (WINDOWSBUILDNUMBER >= 17134)]]>
|
|
||||||
</Condition>
|
|
||||||
|
|
||||||
<!-- Non-Opening ProgID -->
|
<!-- Non-Opening ProgID -->
|
||||||
<DirectoryRef Id="INSTALLDIR">
|
<ns0:DirectoryRef Id="INSTALLDIR">
|
||||||
<Component Win64="yes" Id="nonStartingProgID" >
|
<ns0:Component Bitness="always64" Id="nonStartingProgID" >
|
||||||
<File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\$(var.IconFileEncryptedData)" Name="$(var.IconFileEncryptedData)"></File>
|
<ns0:File Id="IconFileForEncryptedData" KeyPath="yes" Source="$(env.JP_WIXWIZARD_RESOURCES)\$(var.IconFileEncryptedData)" Name="$(var.IconFileEncryptedData)"/>
|
||||||
<ProgId Id="$(var.JpAppName).Encrypted.1" Description="$(var.JpAppName) Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
|
<ns0:ProgId Id="$(var.JpAppName).Encrypted.1" Description="$(var.JpAppName) Encrypted Data" Icon="IconFileForEncryptedData" IconIndex="0">
|
||||||
<Extension Id="c9r" Advertise="no" ContentType="$(var.ProgIdContentType)">
|
<ns0:Extension Id="c9r" Advertise="no" ContentType="$(var.ProgIdContentType)">
|
||||||
<MIME ContentType="$(var.ProgIdContentType)" Default="yes"></MIME>
|
<ns0:MIME ContentType="$(var.ProgIdContentType)" Default="yes"/>
|
||||||
</Extension>
|
</ns0:Extension>
|
||||||
<Extension Id="c9s" Advertise="no" ContentType="$(var.ProgIdContentType)"/>
|
<ns0:Extension Id="c9s" Advertise="no" ContentType="$(var.ProgIdContentType)"/>
|
||||||
</ProgId>
|
</ns0:ProgId>
|
||||||
</Component>
|
</ns0:Component>
|
||||||
</DirectoryRef>
|
</ns0:DirectoryRef>
|
||||||
|
|
||||||
<!-- Standard required root -->
|
<!-- Standard required root -->
|
||||||
<Directory Id="TARGETDIR" Name="SourceDir"/>
|
|
||||||
|
|
||||||
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
|
<ns0:Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
|
||||||
<ComponentGroupRef Id="Shortcuts"/>
|
<ns0:ComponentGroupRef Id="Shortcuts"/>
|
||||||
<ComponentGroupRef Id="Files"/>
|
<ns0:ComponentGroupRef Id="Files"/>
|
||||||
<ComponentGroupRef Id="FileAssociations"/>
|
<ns0:ComponentGroupRef Id="FileAssociations"/>
|
||||||
<!-- Ref to additional ProgIDs -->
|
<!-- Ref to additional ProgIDs -->
|
||||||
<ComponentRef Id="nonStartingProgID" />
|
<ns0:ComponentRef Id="nonStartingProgID" />
|
||||||
</Feature>
|
</ns0:Feature>
|
||||||
|
|
||||||
<CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
|
<ns0:CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
|
||||||
<CustomAction Id="JpSetARPCOMMENTS" Property="ARPCOMMENTS" Value="$(var.JpAppDescription)" />
|
<ns0:CustomAction Id="JpSetARPCOMMENTS" Property="ARPCOMMENTS" Value="$(var.JpAppDescription)" />
|
||||||
<CustomAction Id="JpSetARPCONTACT" Property="ARPCONTACT" Value="$(var.JpAppVendor)" />
|
<ns0:CustomAction Id="JpSetARPCONTACT" Property="ARPCONTACT" Value="$(var.JpAppVendor)" />
|
||||||
<CustomAction Id="JpSetARPSIZE" Property="ARPSIZE" Value="$(var.JpAppSizeKb)" />
|
<ns0:CustomAction Id="JpSetARPSIZE" Property="ARPSIZE" Value="$(var.JpAppSizeKb)" />
|
||||||
|
|
||||||
<?ifdef JpHelpURL ?>
|
<?ifdef JpHelpURL ?>
|
||||||
<CustomAction Id="JpSetARPHELPLINK" Property="ARPHELPLINK" Value="$(var.JpHelpURL)" />
|
<ns0:CustomAction Id="JpSetARPHELPLINK" Property="ARPHELPLINK" Value="$(var.JpHelpURL)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<?ifdef JpAboutURL ?>
|
<?ifdef JpAboutURL ?>
|
||||||
<CustomAction Id="JpSetARPURLINFOABOUT" Property="ARPURLINFOABOUT" Value="$(var.JpAboutURL)" />
|
<ns0:CustomAction Id="JpSetARPURLINFOABOUT" Property="ARPURLINFOABOUT" Value="$(var.JpAboutURL)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<?ifdef JpUpdateURL ?>
|
<?ifdef JpUpdateURL ?>
|
||||||
<CustomAction Id="JpSetARPURLUPDATEINFO" Property="ARPURLUPDATEINFO" Value="$(var.JpUpdateURL)" />
|
<ns0:CustomAction Id="JpSetARPURLUPDATEINFO" Property="ARPURLUPDATEINFO" Value="$(var.JpUpdateURL)" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<Property Id="WixQuietExec64CmdTimeout" Value="20" />
|
<ns0:Property Id="WixQuietExec64CmdTimeout" Value="20" />
|
||||||
<!-- Note for custom actions: Immediate CAs run BEFORE the files are installed, hence if you depend on installed files, the CAs must be deferred.-->
|
<!-- Note for custom actions: Immediate CAs run BEFORE the files are installed, hence if you depend on installed files, the CAs must be deferred.-->
|
||||||
<!-- WebDAV patches -->
|
<!-- WebDAV patches -->
|
||||||
<SetProperty Id="PatchWebDAV" Value=""[INSTALLDIR]patchWebDAV.bat""
|
<ns0:SetProperty Id="PatchWebDAV" Value=""[INSTALLDIR]patchWebDAV.bat"" Sequence="execute" Before="PatchWebDAV" />
|
||||||
Sequence="execute" Before="PatchWebDAV" />
|
<ns0:CustomAction Id="PatchWebDAV" BinaryRef="Wix4UtilCA_$(sys.BUILDARCHSHORT)" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no"/>
|
||||||
<CustomAction Id="PatchWebDAV" BinaryKey="WixCA" DllEntry="WixQuietExec64" Execute="deferred" Return="ignore" Impersonate="no"/>
|
|
||||||
|
|
||||||
<!-- Running App detection and exit -->
|
<!-- Running App detection and exit -->
|
||||||
<Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
|
<ns0:Property Id="FOUNDRUNNINGAPP" Admin="yes"/>
|
||||||
<util:CloseApplication
|
<util:CloseApplication
|
||||||
Target="$(var.CloseApplicationTarget)"
|
Target="$(var.CloseApplicationTarget)"
|
||||||
Id="Close$(var.JpAppName)"
|
Id="Close$(var.JpAppName)"
|
||||||
CloseMessage="no"
|
CloseMessage="no"
|
||||||
RebootPrompt="no"
|
RebootPrompt="no"
|
||||||
PromptToContinue="yes"
|
PromptToContinue="yes"
|
||||||
Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
|
Description="A running instance of $(var.JpAppName) is found, using files marked for update. Please close it to continue."
|
||||||
Property="FOUNDRUNNINGAPP"
|
Property="FOUNDRUNNINGAPP"
|
||||||
>
|
/>
|
||||||
</util:CloseApplication>
|
<ns0:CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
|
||||||
<CustomAction Id="FailOnRunningApp" Error="Installation aborted, because files marked for update are used by a running instance of $(var.JpAppName)."/>
|
|
||||||
|
|
||||||
<?ifdef JpIcon ?>
|
<?ifdef JpIcon ?>
|
||||||
<Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
|
<ns0:Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
|
||||||
<Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
|
<ns0:Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<UIRef Id="JpUI"/>
|
<ns0:UIRef Id="JpUI"/>
|
||||||
|
|
||||||
<InstallExecuteSequence>
|
<ns0:InstallExecuteSequence>
|
||||||
<Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize" Condition="Not Installed" />
|
||||||
<Custom Action="JpSetARPCOMMENTS" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPCOMMENTS" After="CostFinalize" Condition="Not Installed" />
|
||||||
<Custom Action="JpSetARPCONTACT" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPCONTACT" After="CostFinalize" Condition="Not Installed" />
|
||||||
<Custom Action="JpSetARPSIZE" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPSIZE" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?ifdef JpHelpURL ?>
|
<?ifdef JpHelpURL ?>
|
||||||
<Custom Action="JpSetARPHELPLINK" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPHELPLINK" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifdef JpAboutURL ?>
|
<?ifdef JpAboutURL ?>
|
||||||
<Custom Action="JpSetARPURLINFOABOUT" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPURLINFOABOUT" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifdef JpUpdateURL ?>
|
<?ifdef JpUpdateURL ?>
|
||||||
<Custom Action="JpSetARPURLUPDATEINFO" After="CostFinalize">Not Installed</Custom>
|
<ns0:Custom Action="JpSetARPURLUPDATEINFO" After="CostFinalize" Condition="Not Installed" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
|
|
||||||
<?ifndef JpAllowUpgrades ?>
|
<?ifndef JpAllowUpgrades ?>
|
||||||
<Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts">JP_UPGRADABLE_FOUND</Custom>
|
<ns0:Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts" Condition="JP_UPGRADABLE_FOUND"/>
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<?ifndef JpAllowDowngrades ?>
|
<?ifndef JpAllowDowngrades ?>
|
||||||
<Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
|
<ns0:Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts" Condition="JP_DOWNGRADABLE_FOUND" />
|
||||||
<?endif?>
|
<?endif?>
|
||||||
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
<ns0:Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||||
|
|
||||||
<!-- Check and fail if Cryptomator is running -->
|
<!-- Check and fail if Cryptomator is running -->
|
||||||
<Custom Action="WixCloseApplications" Before="InstallValidate"></Custom>
|
<ns0:Custom Action="override Wix4CloseApplications_$(sys.BUILDARCHSHORT)" Before="InstallValidate" />
|
||||||
<Custom Action="FailOnRunningApp" After="WixCloseApplications" >FOUNDRUNNINGAPP</Custom>
|
<ns0:Custom Action="FailOnRunningApp" After="Wix4CloseApplications_$(sys.BUILDARCHSHORT)" Condition="FOUNDRUNNINGAPP" />
|
||||||
|
|
||||||
<RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to WixCloseApplications -->
|
<ns0:RemoveExistingProducts After="InstallValidate"/> <!-- Moved from CostInitialize, due to Wix4CloseApplications_* -->
|
||||||
|
<!-- Skip action on uninstall -->
|
||||||
|
<!-- TODO: don't skip action, but remove cryptomator alias from hosts file -->
|
||||||
|
<ns0:Custom Action="PatchWebDAV" After="InstallFiles" Condition="NOT (Installed AND (NOT REINSTALL) AND (NOT UPGRADINGPRODUCTCODE) AND REMOVE)"/>
|
||||||
|
</ns0:InstallExecuteSequence>
|
||||||
|
|
||||||
<Custom Action="PatchWebDAV" After="InstallFiles">NOT Installed OR REINSTALL</Custom>
|
<ns0:InstallUISequence>
|
||||||
</InstallExecuteSequence>
|
<ns0:Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
||||||
|
</ns0:InstallUISequence>
|
||||||
|
|
||||||
<InstallUISequence>
|
<ns0:WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
|
||||||
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
|
<ns0:WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
|
||||||
</InstallUISequence>
|
</ns0:Package>
|
||||||
|
</ns0:Wix>
|
||||||
<WixVariable Id="WixUIBannerBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\banner.bmp" />
|
|
||||||
<WixVariable Id="WixUIDialogBmp" Value="$(env.JP_WIXWIZARD_RESOURCES)\background.bmp" />
|
|
||||||
</Product>
|
|
||||||
|
|
||||||
</Wix>
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -47,4 +47,4 @@ Legacy Installation settings:
|
|||||||
- SkipCryptomatorLegacyCheck
|
- SkipCryptomatorLegacyCheck
|
||||||
Should be defined to disable checking for the inno setup installation of Cryptomator and undefined, to enable it.
|
Should be defined to disable checking for the inno setup installation of Cryptomator and undefined, to enable it.
|
||||||
-->
|
-->
|
||||||
<Include/>
|
<ns0:Include xmlns:ns0="http://wixtoolset.org/schemas/v4/wxs"></ns0:Include>
|
||||||
|
|||||||
Vendored
-16
@@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" ?>
|
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
|
||||||
<Fragment>
|
|
||||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR"></Property>
|
|
||||||
<WixVariable Id="WixUILicenseRtf" Value="$(var.JpLicenseRtf)"></WixVariable>
|
|
||||||
<UI Id="JpUI">
|
|
||||||
<UIRef Id="CustomWizard" />
|
|
||||||
<DialogRef Id="InstallDirNotEmptyDlg"></DialogRef>
|
|
||||||
<Publish Dialog="ShortcutPromptDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg">1</Publish>
|
|
||||||
<Publish Dialog="ShortcutPromptDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
|
|
||||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="ShortcutPromptDlg" Order="6">NOT Installed</Publish>
|
|
||||||
<UIRef Id="CustomWizard" />
|
|
||||||
</UI>
|
|
||||||
</Fragment>
|
|
||||||
<?include $(env.JP_WIXWIZARD_RESOURCES)\customWizard.wxi ?>
|
|
||||||
</Wix>
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.cryptomator</groupId>
|
<groupId>org.cryptomator</groupId>
|
||||||
<artifactId>cryptomator</artifactId>
|
<artifactId>cryptomator</artifactId>
|
||||||
<version>1.16.0</version>
|
<version>1.17.0-SNAPSHOT</version>
|
||||||
<name>Cryptomator Desktop App</name>
|
<name>Cryptomator Desktop App</name>
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
@@ -26,55 +26,66 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.jdk.version>23</project.jdk.version>
|
<project.jdk.version>24</project.jdk.version>
|
||||||
|
|
||||||
<!-- Group IDs of jars that need to stay on the class path for now -->
|
<!-- Group IDs of jars that need to stay on the class path for now -->
|
||||||
<!-- remove them, as soon they got modularized or support is dropped (i.e., WebDAV) -->
|
<!-- remove them, as soon they got modularized or support is dropped (i.e., WebDAV) -->
|
||||||
<nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents</nonModularGroupIds>
|
<nonModularGroupIds>org.ow2.asm,org.apache.jackrabbit,org.apache.httpcomponents</nonModularGroupIds>
|
||||||
|
|
||||||
<!-- cryptomator dependencies -->
|
<!-- cryptomator dependencies -->
|
||||||
<cryptomator.cryptofs.version>2.9.0-beta2</cryptomator.cryptofs.version>
|
<cryptomator.cryptofs.version>2.9.0</cryptomator.cryptofs.version>
|
||||||
<cryptomator.integrations.version>1.5.1</cryptomator.integrations.version>
|
<cryptomator.integrations.version>1.6.0</cryptomator.integrations.version>
|
||||||
<cryptomator.integrations.win.version>1.3.0</cryptomator.integrations.win.version>
|
<cryptomator.integrations.win.version>1.5.0</cryptomator.integrations.win.version>
|
||||||
<cryptomator.integrations.mac.version>1.3.0</cryptomator.integrations.mac.version>
|
<cryptomator.integrations.mac.version>1.4.0</cryptomator.integrations.mac.version>
|
||||||
<cryptomator.integrations.linux.version>1.5.3</cryptomator.integrations.linux.version>
|
<cryptomator.integrations.linux.version>1.6.0</cryptomator.integrations.linux.version>
|
||||||
<cryptomator.fuse.version>5.0.3</cryptomator.fuse.version>
|
<cryptomator.fuse.version>5.0.5</cryptomator.fuse.version>
|
||||||
<cryptomator.webdav.version>2.0.8</cryptomator.webdav.version>
|
<cryptomator.webdav.version>2.0.10</cryptomator.webdav.version>
|
||||||
|
|
||||||
<!-- 3rd party dependencies -->
|
<!-- 3rd party dependencies -->
|
||||||
<commons-lang3.version>3.17.0</commons-lang3.version>
|
<commons-lang3.version>3.17.0</commons-lang3.version>
|
||||||
<dagger.version>2.55</dagger.version>
|
<dagger.version>2.56.1</dagger.version>
|
||||||
<easybind.version>2.2</easybind.version>
|
<easybind.version>2.2</easybind.version>
|
||||||
<jackson.version>2.18.3</jackson.version>
|
<jackson.version>2.18.3</jackson.version>
|
||||||
<javafx.version>23.0.2</javafx.version>
|
<javafx.version>24.0.1</javafx.version>
|
||||||
<jwt.version>4.5.0</jwt.version>
|
<jwt.version>4.5.0</jwt.version>
|
||||||
<nimbus-jose.version>9.37.3</nimbus-jose.version>
|
<nimbus-jose.version>9.37.3</nimbus-jose.version>
|
||||||
<logback.version>1.5.17</logback.version>
|
<logback.version>1.5.18</logback.version>
|
||||||
<slf4j.version>2.0.17</slf4j.version>
|
<slf4j.version>2.0.17</slf4j.version>
|
||||||
<tinyoauth2.version>0.8.1</tinyoauth2.version>
|
<tinyoauth2.version>0.8.1</tinyoauth2.version>
|
||||||
<zxcvbn.version>1.9.0</zxcvbn.version>
|
<zxcvbn.version>1.9.0</zxcvbn.version>
|
||||||
|
|
||||||
<!-- test dependencies -->
|
<!-- test dependencies -->
|
||||||
<junit.jupiter.version>5.11.4</junit.jupiter.version>
|
<junit.jupiter.version>5.12.2</junit.jupiter.version>
|
||||||
<mockito.version>5.15.2</mockito.version>
|
<mockito.version>5.17.0</mockito.version>
|
||||||
<hamcrest.version>3.0</hamcrest.version>
|
<hamcrest.version>3.0</hamcrest.version>
|
||||||
|
|
||||||
<!-- build-time dependencies -->
|
<!-- build-time dependencies -->
|
||||||
<jetbrains.annotations.version>26.0.2</jetbrains.annotations.version>
|
<jetbrains.annotations.version>26.0.2</jetbrains.annotations.version>
|
||||||
<dependency-check.version>12.1.0</dependency-check.version>
|
<dependency-check.version>12.1.1</dependency-check.version>
|
||||||
<jacoco.version>0.8.12</jacoco.version>
|
<jacoco.version>0.8.13</jacoco.version>
|
||||||
<license-generator.version>2.5.0</license-generator.version>
|
<license-generator.version>2.5.0</license-generator.version>
|
||||||
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
|
<junit-tree-reporter.version>1.4.0</junit-tree-reporter.version>
|
||||||
<mvn-compiler.version>3.13.0</mvn-compiler.version>
|
<mvn-compiler.version>3.14.0</mvn-compiler.version>
|
||||||
<mvn-resources.version>3.3.1</mvn-resources.version>
|
<mvn-resources.version>3.3.1</mvn-resources.version>
|
||||||
<mvn-dependency.version>3.8.1</mvn-dependency.version>
|
<mvn-dependency.version>3.8.1</mvn-dependency.version>
|
||||||
<mvn-surefire.version>3.5.2</mvn-surefire.version>
|
<mvn-surefire.version>3.5.3</mvn-surefire.version>
|
||||||
<mvn-jar.version>3.4.2</mvn-jar.version>
|
<mvn-jar.version>3.4.2</mvn-jar.version>
|
||||||
|
|
||||||
<!-- Property used by surefire to determine jacoco engine -->
|
<!-- Property used by surefire to determine jacoco engine -->
|
||||||
<surefire.jacoco.args></surefire.jacoco.args>
|
<surefire.jacoco.args></surefire.jacoco.args>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<!-- TODO: Remove once webdav version 2.0.11 is released -->
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.cryptomator</groupId>
|
||||||
|
<artifactId>webdav-nio-adapter-servlet</artifactId>
|
||||||
|
<version>1.2.9</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Cryptomator Libs -->
|
<!-- Cryptomator Libs -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -347,7 +358,7 @@
|
|||||||
<consoleOutputReporter>
|
<consoleOutputReporter>
|
||||||
<disable>true</disable>
|
<disable>true</disable>
|
||||||
</consoleOutputReporter>
|
</consoleOutputReporter>
|
||||||
<argLine>@{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar}</argLine>
|
<argLine>@{surefire.jacoco.args} -javaagent:${org.mockito:mockito-core:jar} --enable-native-access=javafx.graphics</argLine>
|
||||||
<statelessTestsetInfoReporter
|
<statelessTestsetInfoReporter
|
||||||
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
|
implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoTreeReporter">
|
||||||
</statelessTestsetInfoReporter>
|
</statelessTestsetInfoReporter>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public class Environment {
|
|||||||
private static final String SETTINGS_PATH_PROP_NAME = "cryptomator.settingsPath";
|
private static final String SETTINGS_PATH_PROP_NAME = "cryptomator.settingsPath";
|
||||||
private static final String IPC_SOCKET_PATH_PROP_NAME = "cryptomator.ipcSocketPath";
|
private static final String IPC_SOCKET_PATH_PROP_NAME = "cryptomator.ipcSocketPath";
|
||||||
private static final String KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.keychainPaths";
|
private static final String KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.keychainPaths";
|
||||||
|
private static final String WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME = "cryptomator.integrationsWin.windowsHelloKeychainPaths";
|
||||||
private static final String P12_PATH_PROP_NAME = "cryptomator.p12Path";
|
private static final String P12_PATH_PROP_NAME = "cryptomator.p12Path";
|
||||||
private static final String LOG_DIR_PROP_NAME = "cryptomator.logDir";
|
private static final String LOG_DIR_PROP_NAME = "cryptomator.logDir";
|
||||||
private static final String LOOPBACK_ALIAS_PROP_NAME = "cryptomator.loopbackAlias";
|
private static final String LOOPBACK_ALIAS_PROP_NAME = "cryptomator.loopbackAlias";
|
||||||
@@ -45,6 +46,7 @@ public class Environment {
|
|||||||
logCryptomatorSystemProperty(SETTINGS_PATH_PROP_NAME);
|
logCryptomatorSystemProperty(SETTINGS_PATH_PROP_NAME);
|
||||||
logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME);
|
logCryptomatorSystemProperty(IPC_SOCKET_PATH_PROP_NAME);
|
||||||
logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME);
|
logCryptomatorSystemProperty(KEYCHAIN_PATHS_PROP_NAME);
|
||||||
|
logCryptomatorSystemProperty(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
|
||||||
logCryptomatorSystemProperty(P12_PATH_PROP_NAME);
|
logCryptomatorSystemProperty(P12_PATH_PROP_NAME);
|
||||||
logCryptomatorSystemProperty(LOG_DIR_PROP_NAME);
|
logCryptomatorSystemProperty(LOG_DIR_PROP_NAME);
|
||||||
logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME);
|
logCryptomatorSystemProperty(LOOPBACK_ALIAS_PROP_NAME);
|
||||||
@@ -85,6 +87,10 @@ public class Environment {
|
|||||||
return getPaths(KEYCHAIN_PATHS_PROP_NAME);
|
return getPaths(KEYCHAIN_PATHS_PROP_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Stream<Path> getWindowsHelloKeychainPath() {
|
||||||
|
return getPaths(WINDOWS_HELLO_KEYCHAIN_PATHS_PROP_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
public Stream<Path> getP12Path() {
|
public Stream<Path> getP12Path() {
|
||||||
return getPaths(P12_PATH_PROP_NAME);
|
return getPaths(P12_PATH_PROP_NAME);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,25 +42,11 @@ public class KeychainManager implements KeychainAccessProvider {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String displayName() {
|
|
||||||
return getClass().getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException {
|
public void storePassphrase(String key, String displayName, CharSequence passphrase) throws KeychainAccessException {
|
||||||
storePassphrase(key, displayName, passphrase, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: remove ignored parameter once the API is fixed
|
|
||||||
@Override
|
|
||||||
public void storePassphrase(String key, String displayName, CharSequence passphrase, boolean ignored) throws KeychainAccessException {
|
|
||||||
try {
|
try {
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
var kc = getKeychainOrFail();
|
getKeychainOrFail().storePassphrase(key, displayName, passphrase);
|
||||||
//this is the only keychain actually using the parameter
|
|
||||||
var usesOSAuth = (kc.getClass().getName().equals("org.cryptomator.macos.keychain.TouchIdKeychainAccess"));
|
|
||||||
kc.storePassphrase(key, displayName, passphrase, usesOSAuth);
|
|
||||||
} finally {
|
} finally {
|
||||||
lock.writeLock().unlock();
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class Settings {
|
|||||||
@Deprecated // to be changed to "whatever is available" eventually
|
@Deprecated // to be changed to "whatever is available" eventually
|
||||||
static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : //
|
static final String DEFAULT_KEYCHAIN_PROVIDER = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess" : //
|
||||||
SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : //
|
SystemUtils.IS_OS_MAC ? "org.cryptomator.macos.keychain.MacSystemKeychainAccess" : //
|
||||||
"org.cryptomator.linux.keychain.SecretServiceKeychainAccess";
|
"org.cryptomator.linux.keychain.GnomeKeyringKeychainAccess";
|
||||||
static final String DEFAULT_QUICKACCESS_SERVICE = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.quickaccess.ExplorerQuickAccessService" : //
|
static final String DEFAULT_QUICKACCESS_SERVICE = SystemUtils.IS_OS_WINDOWS ? "org.cryptomator.windows.quickaccess.ExplorerQuickAccessService" : //
|
||||||
SystemUtils.IS_OS_LINUX ? "org.cryptomator.linux.quickaccess.NautilusBookmarks" : null;
|
SystemUtils.IS_OS_LINUX ? "org.cryptomator.linux.quickaccess.NautilusBookmarks" : null;
|
||||||
|
|
||||||
@@ -147,6 +147,11 @@ public class Settings {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private void migrateLegacySettings(SettingsJson json) {
|
private void migrateLegacySettings(SettingsJson json) {
|
||||||
|
// migrate renamed keychainAccess
|
||||||
|
if(this.keychainProvider.getValueSafe().equals("org.cryptomator.linux.SecretServiceKeychainAccess")) {
|
||||||
|
this.keychainProvider.setValue("org.cryptomator.linux.GnomeKeyringKeychainAccess");
|
||||||
|
}
|
||||||
|
|
||||||
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
|
// implicit migration of 1.6.x legacy setting "preferredVolumeImpl":
|
||||||
if (this.mountService.get() == null && json.preferredVolumeImpl != null) {
|
if (this.mountService.get() == null && json.preferredVolumeImpl != null) {
|
||||||
this.mountService.set(switch (json.preferredVolumeImpl) {
|
this.mountService.set(switch (json.preferredVolumeImpl) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ package org.cryptomator.common.vaults;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
import org.cryptomator.common.Constants;
|
import org.cryptomator.common.Constants;
|
||||||
import org.cryptomator.common.EventMap;
|
import org.cryptomator.event.FileSystemEventAggregator;
|
||||||
import org.cryptomator.common.mount.Mounter;
|
import org.cryptomator.common.mount.Mounter;
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.cryptomator.common.settings.VaultSettings;
|
import org.cryptomator.common.settings.VaultSettings;
|
||||||
@@ -78,7 +78,7 @@ public class Vault {
|
|||||||
private final ObjectBinding<Mountpoint> mountPoint;
|
private final ObjectBinding<Mountpoint> mountPoint;
|
||||||
private final Mounter mounter;
|
private final Mounter mounter;
|
||||||
private final Settings settings;
|
private final Settings settings;
|
||||||
private final EventMap eventMap;
|
private final FileSystemEventAggregator fileSystemEventAggregator;
|
||||||
private final BooleanProperty showingStats;
|
private final BooleanProperty showingStats;
|
||||||
|
|
||||||
private final AtomicReference<Mounter.MountHandle> mountHandle = new AtomicReference<>(null);
|
private final AtomicReference<Mounter.MountHandle> mountHandle = new AtomicReference<>(null);
|
||||||
@@ -91,7 +91,7 @@ public class Vault {
|
|||||||
@Named("lastKnownException") ObjectProperty<Exception> lastKnownException, //
|
@Named("lastKnownException") ObjectProperty<Exception> lastKnownException, //
|
||||||
VaultStats stats, //
|
VaultStats stats, //
|
||||||
Mounter mounter, Settings settings, //
|
Mounter mounter, Settings settings, //
|
||||||
EventMap eventMap) {
|
FileSystemEventAggregator fileSystemEventAggregator) {
|
||||||
this.vaultSettings = vaultSettings;
|
this.vaultSettings = vaultSettings;
|
||||||
this.configCache = configCache;
|
this.configCache = configCache;
|
||||||
this.cryptoFileSystem = cryptoFileSystem;
|
this.cryptoFileSystem = cryptoFileSystem;
|
||||||
@@ -108,7 +108,7 @@ public class Vault {
|
|||||||
this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state);
|
this.mountPoint = Bindings.createObjectBinding(this::getMountPoint, state);
|
||||||
this.mounter = mounter;
|
this.mounter = mounter;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.eventMap = eventMap;
|
this.fileSystemEventAggregator = fileSystemEventAggregator;
|
||||||
this.showingStats = new SimpleBooleanProperty(false);
|
this.showingStats = new SimpleBooleanProperty(false);
|
||||||
this.quickAccessEntry = new AtomicReference<>(null);
|
this.quickAccessEntry = new AtomicReference<>(null);
|
||||||
}
|
}
|
||||||
@@ -261,10 +261,7 @@ public class Vault {
|
|||||||
|
|
||||||
|
|
||||||
private void consumeVaultEvent(FilesystemEvent e) {
|
private void consumeVaultEvent(FilesystemEvent e) {
|
||||||
var wrapper = new VaultEvent(this, e);
|
fileSystemEventAggregator.put(this, e);
|
||||||
Platform.runLater(() -> {
|
|
||||||
eventMap.put(wrapper);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************************
|
// ******************************************************************************
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package org.cryptomator.common.vaults;
|
package org.cryptomator.common.vaults;
|
||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import org.cryptomator.common.Constants;
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.cryptomator.common.settings.VaultSettings;
|
import org.cryptomator.common.settings.VaultSettings;
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||||
@@ -35,6 +36,7 @@ import static org.cryptomator.common.Constants.MASTERKEY_FILENAME;
|
|||||||
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
import static org.cryptomator.common.Constants.VAULTCONFIG_FILENAME;
|
||||||
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
import static org.cryptomator.common.vaults.VaultState.Value.ERROR;
|
||||||
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
import static org.cryptomator.common.vaults.VaultState.Value.LOCKED;
|
||||||
|
import static org.cryptomator.common.vaults.VaultState.Value.NEEDS_MIGRATION;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class VaultListManager {
|
public class VaultListManager {
|
||||||
@@ -115,13 +117,15 @@ public class VaultListManager {
|
|||||||
private Vault create(VaultSettings vaultSettings) {
|
private Vault create(VaultSettings vaultSettings) {
|
||||||
var wrapper = new VaultConfigCache(vaultSettings);
|
var wrapper = new VaultConfigCache(vaultSettings);
|
||||||
try {
|
try {
|
||||||
if (Objects.isNull(vaultSettings.lastKnownKeyLoader.get())) {
|
|
||||||
var keyIdScheme = wrapper.get().getKeyId().getScheme();
|
|
||||||
vaultSettings.lastKnownKeyLoader.set(keyIdScheme);
|
|
||||||
}
|
|
||||||
var vaultState = determineVaultState(vaultSettings.path.get());
|
var vaultState = determineVaultState(vaultSettings.path.get());
|
||||||
if (vaultState == LOCKED) { //for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
if (vaultState == LOCKED) { //for legacy reasons: pre v8 vault do not have a config, but they are in the NEEDS_MIGRATION state
|
||||||
wrapper.reloadConfig();
|
wrapper.reloadConfig();
|
||||||
|
if (Objects.isNull(vaultSettings.lastKnownKeyLoader.get())) {
|
||||||
|
var keyIdScheme = wrapper.get().getKeyId().getScheme();
|
||||||
|
vaultSettings.lastKnownKeyLoader.set(keyIdScheme);
|
||||||
|
}
|
||||||
|
} else if (vaultState == NEEDS_MIGRATION) {
|
||||||
|
vaultSettings.lastKnownKeyLoader.set(Constants.DEFAULT_KEY_ID.toString());
|
||||||
}
|
}
|
||||||
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
|
return vaultComponentFactory.create(vaultSettings, wrapper, vaultState, null).vault();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.cryptomator.event;
|
||||||
|
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public record FSEventBucket(Vault vault, Path idPath, Class<? extends FilesystemEvent> c) {}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package org.cryptomator.event;
|
||||||
|
|
||||||
|
import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||||
|
|
||||||
|
public record FSEventBucketContent(FilesystemEvent mostRecentEvent, int count) {}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package org.cryptomator.event;
|
||||||
|
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.cryptofs.event.BrokenDirFileEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.BrokenFileNodeEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.ConflictResolutionFailedEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.ConflictResolvedEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.DecryptionFailedEvent;
|
||||||
|
import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggregator for {@link FilesystemEvent}s.
|
||||||
|
* <p>
|
||||||
|
* The aggregator groups filesystem events by the vault where the event occurred, an identifying path (clear- or ciphertext) and the event class (aka type).
|
||||||
|
* A group is called an {@link FSEventBucket}, its {@link FSEventBucketContent} is the most recent event object and a count of how often the event already occurred.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class FileSystemEventAggregator {
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<FSEventBucket, FSEventBucketContent> map;
|
||||||
|
private final AtomicBoolean hasUpdates;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FileSystemEventAggregator() {
|
||||||
|
this.map = new ConcurrentHashMap<>();
|
||||||
|
this.hasUpdates = new AtomicBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given event to the map. If a bucket for this event already exists, only the count is updated and the event set as the most recent one.
|
||||||
|
*
|
||||||
|
* @param v Vault where the event occurred
|
||||||
|
* @param e Actual {@link FilesystemEvent}
|
||||||
|
*/
|
||||||
|
public void put(Vault v, FilesystemEvent e) {
|
||||||
|
var key = computeKey(v, e);
|
||||||
|
map.compute(key, (k, val) -> {
|
||||||
|
if (val == null) {
|
||||||
|
return new FSEventBucketContent(e, 1);
|
||||||
|
} else {
|
||||||
|
return new FSEventBucketContent(e, val.count() + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hasUpdates.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an event bucket from the map.
|
||||||
|
*/
|
||||||
|
public FSEventBucketContent remove(FSEventBucket key) {
|
||||||
|
var content = map.remove(key);
|
||||||
|
hasUpdates.set(true);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the event map.
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
hasUpdates.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean hasMaybeUpdates() {
|
||||||
|
return hasUpdates.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones the map entries into a collection.
|
||||||
|
* <p>
|
||||||
|
* The collection is first cleared, then all map entries are added in one bulk operation. Cleans the hasUpdates status.
|
||||||
|
*
|
||||||
|
* @param target collection which is first cleared and then the EntrySet copied to.
|
||||||
|
*/
|
||||||
|
public void cloneTo(Collection<Map.Entry<FSEventBucket, FSEventBucketContent>> target) {
|
||||||
|
hasUpdates.set(false);
|
||||||
|
target.clear();
|
||||||
|
target.addAll(map.entrySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to compute the identifying key for a given filesystem event
|
||||||
|
*
|
||||||
|
* @param v Vault where the event occurred
|
||||||
|
* @param event Actual {@link FilesystemEvent}
|
||||||
|
* @return a {@link FSEventBucket} used in the map and lru cache
|
||||||
|
*/
|
||||||
|
private static FSEventBucket computeKey(Vault v, FilesystemEvent event) {
|
||||||
|
var p = switch (event) {
|
||||||
|
case DecryptionFailedEvent(_, Path ciphertextPath, _) -> ciphertextPath;
|
||||||
|
case ConflictResolvedEvent(_, _, _, _, Path resolvedCiphertext) -> resolvedCiphertext;
|
||||||
|
case ConflictResolutionFailedEvent(_, _, Path conflictingCiphertext, _) -> conflictingCiphertext;
|
||||||
|
case BrokenDirFileEvent(_, Path ciphertext) -> ciphertext;
|
||||||
|
case BrokenFileNodeEvent(_, _, Path ciphertext) -> ciphertext;
|
||||||
|
};
|
||||||
|
return new FSEventBucket(v, p, event.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
package org.cryptomator.networking;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.KeyStoreSpi;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.UnrecoverableKeyException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class CombinedKeyStoreSpi extends KeyStoreSpi {
|
||||||
|
|
||||||
|
private final KeyStore primary;
|
||||||
|
private final KeyStore fallback;
|
||||||
|
|
||||||
|
public static CombinedKeyStoreSpi create(KeyStore primary, KeyStore fallback) {
|
||||||
|
checkIfLoaded(primary);
|
||||||
|
checkIfLoaded(fallback);
|
||||||
|
return new CombinedKeyStoreSpi(primary, fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkIfLoaded(KeyStore s) {
|
||||||
|
try {
|
||||||
|
s.aliases();
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalArgumentException("Keystore %s is not loaded.".formatted(s.getType()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CombinedKeyStoreSpi(KeyStore primary, KeyStore fallback) {
|
||||||
|
this.primary = primary;
|
||||||
|
this.fallback = fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
|
||||||
|
try {
|
||||||
|
Key key = primary.getKey(alias, password);
|
||||||
|
if (key == null) {
|
||||||
|
key = fallback.getKey(alias, password);
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate[] engineGetCertificateChain(String alias) {
|
||||||
|
try {
|
||||||
|
Certificate[] chain = primary.getCertificateChain(alias);
|
||||||
|
if (chain == null) {
|
||||||
|
chain = fallback.getCertificateChain(alias);
|
||||||
|
}
|
||||||
|
return chain;
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Certificate engineGetCertificate(String alias) {
|
||||||
|
try {
|
||||||
|
Certificate cert = primary.getCertificate(alias);
|
||||||
|
if (cert == null) {
|
||||||
|
cert = fallback.getCertificate(alias);
|
||||||
|
}
|
||||||
|
return cert;
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Date engineGetCreationDate(String alias) {
|
||||||
|
try {
|
||||||
|
Date date = primary.getCreationDate(alias);
|
||||||
|
if (date == null) {
|
||||||
|
date = fallback.getCreationDate(alias);
|
||||||
|
}
|
||||||
|
return date;
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException {
|
||||||
|
throw new UnsupportedOperationException("Read-only KeyStore");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException {
|
||||||
|
throw new UnsupportedOperationException("Read-only KeyStore");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
|
||||||
|
throw new UnsupportedOperationException("Read-only KeyStore");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void engineDeleteEntry(String alias) throws KeyStoreException {
|
||||||
|
throw new UnsupportedOperationException("Read-only KeyStore");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Enumeration<String> engineAliases() {
|
||||||
|
var aliases = new LinkedHashSet<String>();
|
||||||
|
try {
|
||||||
|
primary.aliases().asIterator().forEachRemaining(aliases::add);
|
||||||
|
fallback.aliases().asIterator().forEachRemaining(aliases::add);
|
||||||
|
return Collections.enumeration(aliases);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean engineContainsAlias(String alias) {
|
||||||
|
try {
|
||||||
|
return primary.containsAlias(alias) || fallback.containsAlias(alias);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int engineSize() {
|
||||||
|
var aliases = engineAliases();
|
||||||
|
var i = new AtomicInteger(0);
|
||||||
|
aliases.asIterator().forEachRemaining(_ -> i.incrementAndGet());
|
||||||
|
return i.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean engineIsKeyEntry(String alias) {
|
||||||
|
try {
|
||||||
|
return primary.isKeyEntry(alias) || fallback.isKeyEntry(alias);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean engineIsCertificateEntry(String alias) {
|
||||||
|
try {
|
||||||
|
return primary.isCertificateEntry(alias) || fallback.isCertificateEntry(alias);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String engineGetCertificateAlias(Certificate cert) {
|
||||||
|
try {
|
||||||
|
String alias = primary.getCertificateAlias(cert);
|
||||||
|
if (alias == null) {
|
||||||
|
alias = fallback.getCertificateAlias(cert);
|
||||||
|
}
|
||||||
|
return alias;
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new IllegalStateException("At least one keystore of [%s, %s] is not initialized.".formatted(primary.getType(), fallback.getType()), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {
|
||||||
|
throw new UnsupportedOperationException("Read-only KeyStore");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {
|
||||||
|
// Nothing to do; the real keystores are already loaded.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import java.io.IOException;
|
|||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.Provider;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,6 +17,16 @@ public class SSLContextWithMacKeychain extends SSLContextDifferentTrustStoreBase
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
KeyStore getTruststore() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
|
KeyStore getTruststore() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
|
||||||
return KeyStore.getInstance("KeychainStore-ROOT");
|
var userKeyStore = KeyStore.getInstance("KeychainStore");
|
||||||
|
var systemRootKeyStore = KeyStore.getInstance("KeychainStore-ROOT");
|
||||||
|
userKeyStore.load(null);
|
||||||
|
systemRootKeyStore.load(null);
|
||||||
|
try {
|
||||||
|
CombinedKeyStoreSpi spi = CombinedKeyStoreSpi.create(userKeyStore, systemRootKeyStore);
|
||||||
|
Provider dummyProvider = new Provider("CombinedKeyStoreProvider", "1.0", "Provides a combined, read-only KeyStore") {};
|
||||||
|
return new KeyStore(spi, dummyProvider, "CombinedKeyStoreProvider") {};
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new KeyStoreException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public enum FxmlFile {
|
|||||||
CONVERTVAULT_HUBTOPASSWORD_START("/fxml/convertvault_hubtopassword_start.fxml"), //
|
CONVERTVAULT_HUBTOPASSWORD_START("/fxml/convertvault_hubtopassword_start.fxml"), //
|
||||||
CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), //
|
CONVERTVAULT_HUBTOPASSWORD_CONVERT("/fxml/convertvault_hubtopassword_convert.fxml"), //
|
||||||
CONVERTVAULT_HUBTOPASSWORD_SUCCESS("/fxml/convertvault_hubtopassword_success.fxml"), //
|
CONVERTVAULT_HUBTOPASSWORD_SUCCESS("/fxml/convertvault_hubtopassword_success.fxml"), //
|
||||||
|
DECRYPTNAMES("/fxml/decryptnames.fxml"), //
|
||||||
ERROR("/fxml/error.fxml"), //
|
ERROR("/fxml/error.fxml"), //
|
||||||
EVENT_VIEW("/fxml/eventview.fxml"), //
|
EVENT_VIEW("/fxml/eventview.fxml"), //
|
||||||
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
|
FORGET_PASSWORD("/fxml/forget_password.fxml"), //
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.cryptomator.ui.decryptname;
|
||||||
|
|
||||||
|
import javafx.beans.property.ReadOnlyStringWrapper;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public record CipherAndCleartext(Path ciphertext, String cleartextName) {
|
||||||
|
|
||||||
|
public String getCiphertextFilename() {
|
||||||
|
return ciphertext.getFileName().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue<String> ciphertextFilenameProperty() {
|
||||||
|
return new ReadOnlyStringWrapper(getCiphertextFilename());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCleartextName() {
|
||||||
|
return cleartextName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue<String> cleartextNameProperty() {
|
||||||
|
return new ReadOnlyStringWrapper(getCleartextName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
package org.cryptomator.ui.decryptname;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.cryptofs.common.Constants;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.controls.FontAwesome5Icon;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.ListProperty;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleListProperty;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.beans.property.StringProperty;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.TableColumn;
|
||||||
|
import javafx.scene.control.TableView;
|
||||||
|
import javafx.scene.control.cell.PropertyValueFactory;
|
||||||
|
import javafx.scene.input.Clipboard;
|
||||||
|
import javafx.scene.input.DataFormat;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
|
import javafx.scene.input.TransferMode;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@DecryptNameScoped
|
||||||
|
public class DecryptFileNamesViewController implements FxController {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(DecryptFileNamesViewController.class);
|
||||||
|
private static final KeyCodeCombination COPY_TO_CLIPBOARD_SHORTCUT = new KeyCodeCombination(KeyCode.C, KeyCodeCombination.SHORTCUT_DOWN);
|
||||||
|
private static final String COPY_TO_CLIPBOARD_SHORTCUT_STRING_WIN = "CTRL+C";
|
||||||
|
private static final String COPY_TO_CLIPBOARD_SHORTCUT_STRING_MAC = "⌘C";
|
||||||
|
private static final String COPY_TO_CLIPBOARD_SHORTCUT_STRING_LINUX = "CTRL+C";
|
||||||
|
|
||||||
|
private final ListProperty<CipherAndCleartext> mapping;
|
||||||
|
private final StringProperty dropZoneText = new SimpleStringProperty();
|
||||||
|
private final ObjectProperty<FontAwesome5Icon> dropZoneIcon = new SimpleObjectProperty<>();
|
||||||
|
private final BooleanProperty wrongFilesSelected = new SimpleBooleanProperty(false);
|
||||||
|
private final Stage window;
|
||||||
|
private final Vault vault;
|
||||||
|
private final ResourceBundle resourceBundle;
|
||||||
|
private final List<Path> initialList;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public TableColumn<CipherAndCleartext, String> ciphertextColumn;
|
||||||
|
@FXML
|
||||||
|
public TableColumn<CipherAndCleartext, String> cleartextColumn;
|
||||||
|
@FXML
|
||||||
|
public TableView<CipherAndCleartext> cipherToCleartextTable;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public DecryptFileNamesViewController(@DecryptNameWindow Stage window, @DecryptNameWindow Vault vault, @DecryptNameWindow List<Path> pathsToDecrypt, ResourceBundle resourceBundle) {
|
||||||
|
this.window = window;
|
||||||
|
this.vault = vault;
|
||||||
|
this.resourceBundle = resourceBundle;
|
||||||
|
this.mapping = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||||
|
this.initialList = pathsToDecrypt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void initialize() {
|
||||||
|
cipherToCleartextTable.setItems(mapping);
|
||||||
|
cipherToCleartextTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_ALL_COLUMNS);
|
||||||
|
//DragNDrop
|
||||||
|
cipherToCleartextTable.setOnDragEntered(event -> {
|
||||||
|
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
||||||
|
cipherToCleartextTable.setItems(FXCollections.emptyObservableList());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cipherToCleartextTable.setOnDragOver(event -> {
|
||||||
|
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
||||||
|
if (SystemUtils.IS_OS_WINDOWS || SystemUtils.IS_OS_MAC) {
|
||||||
|
event.acceptTransferModes(TransferMode.LINK);
|
||||||
|
} else {
|
||||||
|
event.acceptTransferModes(TransferMode.ANY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cipherToCleartextTable.setOnDragDropped(event -> {
|
||||||
|
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
||||||
|
checkAndDecrypt(event.getDragboard().getFiles().stream().map(File::toPath).toList());
|
||||||
|
cipherToCleartextTable.setItems(mapping);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cipherToCleartextTable.setOnDragExited(_ -> cipherToCleartextTable.setItems(mapping));
|
||||||
|
//selectionModel and copy-to-clipboard action
|
||||||
|
cipherToCleartextTable.getSelectionModel().setCellSelectionEnabled(true);
|
||||||
|
cipherToCleartextTable.setOnKeyPressed(keyEvent -> {
|
||||||
|
if (COPY_TO_CLIPBOARD_SHORTCUT.match(keyEvent)) {
|
||||||
|
copySingleCelltoClipboard();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ciphertextColumn.setCellValueFactory(new PropertyValueFactory<>("ciphertextFilename"));
|
||||||
|
cleartextColumn.setCellValueFactory(new PropertyValueFactory<>("cleartextName"));
|
||||||
|
|
||||||
|
dropZoneText.setValue(resourceBundle.getString("decryptNames.dropZone.message"));
|
||||||
|
dropZoneIcon.setValue(FontAwesome5Icon.FILE_IMPORT);
|
||||||
|
|
||||||
|
wrongFilesSelected.addListener((_, _, areWrongFiles) -> {
|
||||||
|
if (areWrongFiles) {
|
||||||
|
CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS, Platform::runLater).execute(() -> {
|
||||||
|
dropZoneText.setValue(resourceBundle.getString("decryptNames.dropZone.message"));
|
||||||
|
dropZoneIcon.setValue(FontAwesome5Icon.FILE_IMPORT);
|
||||||
|
wrongFilesSelected.setValue(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!initialList.isEmpty()) {
|
||||||
|
checkAndDecrypt(initialList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copySingleCelltoClipboard() {
|
||||||
|
cipherToCleartextTable.getSelectionModel().getSelectedCells().stream().findFirst().ifPresent(tablePosition -> {
|
||||||
|
var selectedItem = cipherToCleartextTable.getSelectionModel().getSelectedItem();
|
||||||
|
//TODO: give user feedback, if content is copied -> must be done via a custom cell factory to access the actual table cell!
|
||||||
|
if (tablePosition.getTableColumn().equals(ciphertextColumn)) {
|
||||||
|
Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, selectedItem.ciphertext().toString()));
|
||||||
|
} else {
|
||||||
|
Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, selectedItem.cleartextName()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
public void selectFiles() {
|
||||||
|
var fileChooser = new FileChooser();
|
||||||
|
fileChooser.setTitle(resourceBundle.getString("decryptNames.filePicker.title"));
|
||||||
|
fileChooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter(resourceBundle.getString("decryptNames.filePicker.extensionDescription"), List.of("*.c9r")));
|
||||||
|
fileChooser.setInitialDirectory(vault.getPath().toFile());
|
||||||
|
var ciphertextNodes = fileChooser.showOpenMultipleDialog(window);
|
||||||
|
if (ciphertextNodes != null) {
|
||||||
|
checkAndDecrypt(ciphertextNodes.stream().map(File::toPath).toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAndDecrypt(List<Path> pathsToDecrypt) {
|
||||||
|
mapping.clear();
|
||||||
|
//Assumption: All files are in the same directory
|
||||||
|
var testPath = pathsToDecrypt.getFirst();
|
||||||
|
if (!testPath.startsWith(vault.getPath())) {
|
||||||
|
setDropZoneError(resourceBundle.getString("decryptNames.dropZone.error.foreignFiles").formatted(vault.getDisplayName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pathsToDecrypt.size() == 1 && testPath.endsWith(Constants.DIR_ID_BACKUP_FILE_NAME)) {
|
||||||
|
setDropZoneError(resourceBundle.getString("decryptNames.dropZone.error.vaultInternalFiles"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var newMapping = pathsToDecrypt.stream().filter(p -> !p.endsWith(Constants.DIR_ID_BACKUP_FILE_NAME)).map(this::getCleartextName).toList();
|
||||||
|
mapping.addAll(newMapping);
|
||||||
|
} catch (UncheckedIOException e) {
|
||||||
|
setDropZoneError(resourceBundle.getString("decryptNames.dropZone.error.generic"));
|
||||||
|
LOG.info("Failed to decrypt filenames for directory {}", testPath.getParent(), e);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
setDropZoneError(resourceBundle.getString("decryptNames.dropZone.error.vaultInternalFiles"));
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
setDropZoneError(resourceBundle.getString("decryptNames.dropZone.error.noDirIdBackup"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDropZoneError(String text) {
|
||||||
|
dropZoneIcon.setValue(FontAwesome5Icon.TIMES);
|
||||||
|
dropZoneText.setValue(text);
|
||||||
|
wrongFilesSelected.setValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CipherAndCleartext getCleartextName(Path ciphertextNode) {
|
||||||
|
try {
|
||||||
|
var cleartextName = vault.getCleartextName(ciphertextNode);
|
||||||
|
return new CipherAndCleartext(ciphertextNode, cleartextName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//obvservable getter
|
||||||
|
|
||||||
|
public ObservableValue<String> dropZoneTextProperty() {
|
||||||
|
return dropZoneText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDropZoneText() {
|
||||||
|
return dropZoneText.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableValue<FontAwesome5Icon> dropZoneIconProperty() {
|
||||||
|
return dropZoneIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FontAwesome5Icon getDropZoneIcon() {
|
||||||
|
return dropZoneIcon.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearTable() {
|
||||||
|
mapping.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyTableToClipboard() {
|
||||||
|
var csv = mapping.stream().map(cipherAndClear -> "\"" + cipherAndClear.ciphertext() + "\", \"" + cipherAndClear.cleartextName() + "\"").collect(Collectors.joining("\n"));
|
||||||
|
Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, csv));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCopyToClipboardShortcutString() {
|
||||||
|
if (SystemUtils.IS_OS_WINDOWS) {
|
||||||
|
return COPY_TO_CLIPBOARD_SHORTCUT_STRING_WIN;
|
||||||
|
} else if (SystemUtils.IS_OS_MAC) {
|
||||||
|
return COPY_TO_CLIPBOARD_SHORTCUT_STRING_MAC;
|
||||||
|
} else {
|
||||||
|
return COPY_TO_CLIPBOARD_SHORTCUT_STRING_LINUX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package org.cryptomator.ui.decryptname;
|
||||||
|
|
||||||
|
import dagger.BindsInstance;
|
||||||
|
import dagger.Lazy;
|
||||||
|
import dagger.Subcomponent;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.common.vaults.VaultState;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@DecryptNameScoped
|
||||||
|
@Subcomponent(modules = DecryptNameModule.class)
|
||||||
|
public interface DecryptNameComponent {
|
||||||
|
|
||||||
|
Logger LOG = LoggerFactory.getLogger(DecryptNameComponent.class);
|
||||||
|
|
||||||
|
@DecryptNameWindow
|
||||||
|
Stage window();
|
||||||
|
|
||||||
|
@FxmlScene(FxmlFile.DECRYPTNAMES)
|
||||||
|
Lazy<Scene> decryptNamesView();
|
||||||
|
|
||||||
|
@DecryptNameWindow
|
||||||
|
Vault vault();
|
||||||
|
|
||||||
|
default void showDecryptFileNameWindow() {
|
||||||
|
Stage s = window();
|
||||||
|
s.setScene(decryptNamesView().get());
|
||||||
|
s.sizeToScene();
|
||||||
|
if (vault().isUnlocked()) {
|
||||||
|
s.show();
|
||||||
|
} else {
|
||||||
|
LOG.error("Aborted showing DecryptFileName window: vault state is not {}, but {}.", VaultState.Value.UNLOCKED, vault().getState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subcomponent.Factory
|
||||||
|
interface Factory {
|
||||||
|
|
||||||
|
DecryptNameComponent create(@BindsInstance @DecryptNameWindow Vault vault, @BindsInstance @Named("windowOwner") Stage owner, @BindsInstance @DecryptNameWindow List<Path> pathsToDecrypt);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package org.cryptomator.ui.decryptname;
|
||||||
|
|
||||||
|
import dagger.Binds;
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
import dagger.multibindings.IntoMap;
|
||||||
|
import org.cryptomator.common.vaults.Vault;
|
||||||
|
import org.cryptomator.ui.common.DefaultSceneFactory;
|
||||||
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.common.FxControllerKey;
|
||||||
|
import org.cryptomator.ui.common.FxmlFile;
|
||||||
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
|
import org.cryptomator.ui.common.StageFactory;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
public abstract class DecryptNameModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@DecryptNameScoped
|
||||||
|
@DecryptNameWindow
|
||||||
|
static Stage provideStage(StageFactory factory, @Named("windowOwner") Stage owner, @DecryptNameWindow Vault vault, ResourceBundle resourceBundle) {
|
||||||
|
Stage stage = factory.create();
|
||||||
|
stage.setResizable(true);
|
||||||
|
stage.initModality(Modality.WINDOW_MODAL);
|
||||||
|
stage.initOwner(owner);
|
||||||
|
stage.setTitle(resourceBundle.getString("decryptNames.title"));
|
||||||
|
vault.stateProperty().addListener(((_, _, _) -> stage.close())); //as soon as the state changes from unlocked, close the window
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@DecryptNameScoped
|
||||||
|
@DecryptNameWindow
|
||||||
|
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
|
||||||
|
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@FxmlScene(FxmlFile.DECRYPTNAMES)
|
||||||
|
@DecryptNameScoped
|
||||||
|
static Scene provideDecryptNamesViewScene(@DecryptNameWindow FxmlLoaderFactory fxmlLoaders) {
|
||||||
|
return fxmlLoaders.createScene(FxmlFile.DECRYPTNAMES);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@FxControllerKey(DecryptFileNamesViewController.class)
|
||||||
|
abstract FxController bindDecryptNamesViewController(DecryptFileNamesViewController controller);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package org.cryptomator.ui.decryptname;
|
||||||
|
|
||||||
|
import javax.inject.Scope;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
@Scope
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@interface DecryptNameScoped {}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.cryptomator.ui.decryptname;
|
||||||
|
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@Documented
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@interface DecryptNameWindow {}
|
||||||
@@ -20,8 +20,8 @@ public interface ErrorComponent {
|
|||||||
default Stage show() {
|
default Stage show() {
|
||||||
Stage stage = window();
|
Stage stage = window();
|
||||||
stage.setScene(scene());
|
stage.setScene(scene());
|
||||||
stage.setMinWidth(420);
|
stage.setMinWidth(450);
|
||||||
stage.setMinHeight(300);
|
stage.setMinHeight(450);
|
||||||
stage.show();
|
stage.show();
|
||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.cryptomator.ui.eventview;
|
package org.cryptomator.ui.eventview;
|
||||||
|
|
||||||
import org.cryptomator.common.EventMap;
|
import org.cryptomator.event.FSEventBucket;
|
||||||
|
import org.cryptomator.event.FSEventBucketContent;
|
||||||
|
import org.cryptomator.event.FileSystemEventAggregator;
|
||||||
import org.cryptomator.common.Nullable;
|
import org.cryptomator.common.Nullable;
|
||||||
import org.cryptomator.common.ObservableUtil;
|
import org.cryptomator.common.ObservableUtil;
|
||||||
import org.cryptomator.cryptofs.CryptoPath;
|
import org.cryptomator.cryptofs.CryptoPath;
|
||||||
@@ -9,7 +11,6 @@ import org.cryptomator.cryptofs.event.BrokenFileNodeEvent;
|
|||||||
import org.cryptomator.cryptofs.event.ConflictResolutionFailedEvent;
|
import org.cryptomator.cryptofs.event.ConflictResolutionFailedEvent;
|
||||||
import org.cryptomator.cryptofs.event.ConflictResolvedEvent;
|
import org.cryptomator.cryptofs.event.ConflictResolvedEvent;
|
||||||
import org.cryptomator.cryptofs.event.DecryptionFailedEvent;
|
import org.cryptomator.cryptofs.event.DecryptionFailedEvent;
|
||||||
import org.cryptomator.event.VaultEvent;
|
|
||||||
import org.cryptomator.integrations.revealpath.RevealFailedException;
|
import org.cryptomator.integrations.revealpath.RevealFailedException;
|
||||||
import org.cryptomator.integrations.revealpath.RevealPathService;
|
import org.cryptomator.integrations.revealpath.RevealPathService;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
@@ -41,6 +42,7 @@ import java.nio.file.Path;
|
|||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.FormatStyle;
|
import java.time.format.FormatStyle;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -51,11 +53,11 @@ public class EventListCellController implements FxController {
|
|||||||
private static final DateTimeFormatter LOCAL_DATE_FORMATTER = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withZone(ZoneId.systemDefault());
|
private static final DateTimeFormatter LOCAL_DATE_FORMATTER = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).withZone(ZoneId.systemDefault());
|
||||||
private static final DateTimeFormatter LOCAL_TIME_FORMATTER = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).withZone(ZoneId.systemDefault());
|
private static final DateTimeFormatter LOCAL_TIME_FORMATTER = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).withZone(ZoneId.systemDefault());
|
||||||
|
|
||||||
private final EventMap eventMap;
|
private final FileSystemEventAggregator fileSystemEventAggregator;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final RevealPathService revealService;
|
private final RevealPathService revealService;
|
||||||
private final ResourceBundle resourceBundle;
|
private final ResourceBundle resourceBundle;
|
||||||
private final ObjectProperty<VaultEvent> event;
|
private final ObjectProperty<Map.Entry<FSEventBucket, FSEventBucketContent>> eventEntry;
|
||||||
private final StringProperty eventMessage;
|
private final StringProperty eventMessage;
|
||||||
private final StringProperty eventDescription;
|
private final StringProperty eventDescription;
|
||||||
private final ObjectProperty<FontAwesome5Icon> eventIcon;
|
private final ObjectProperty<FontAwesome5Icon> eventIcon;
|
||||||
@@ -77,18 +79,18 @@ public class EventListCellController implements FxController {
|
|||||||
Button eventActionsButton;
|
Button eventActionsButton;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public EventListCellController(EventMap eventMap, Optional<RevealPathService> revealService, ResourceBundle resourceBundle) {
|
public EventListCellController(FileSystemEventAggregator fileSystemEventAggregator, Optional<RevealPathService> revealService, ResourceBundle resourceBundle) {
|
||||||
this.eventMap = eventMap;
|
this.fileSystemEventAggregator = fileSystemEventAggregator;
|
||||||
this.revealService = revealService.orElseGet(() -> null);
|
this.revealService = revealService.orElseGet(() -> null);
|
||||||
this.resourceBundle = resourceBundle;
|
this.resourceBundle = resourceBundle;
|
||||||
this.event = new SimpleObjectProperty<>(null);
|
this.eventEntry = new SimpleObjectProperty<>(null);
|
||||||
this.eventMessage = new SimpleStringProperty();
|
this.eventMessage = new SimpleStringProperty();
|
||||||
this.eventDescription = new SimpleStringProperty();
|
this.eventDescription = new SimpleStringProperty();
|
||||||
this.eventIcon = new SimpleObjectProperty<>();
|
this.eventIcon = new SimpleObjectProperty<>();
|
||||||
this.eventCount = ObservableUtil.mapWithDefault(event, e -> e.count() == 1? "" : "("+ e.count() +")", "");
|
this.eventCount = ObservableUtil.mapWithDefault(eventEntry, e -> e.getValue().count() == 1? "" : "("+ e.getValue().count() +")", "");
|
||||||
this.vaultUnlocked = ObservableUtil.mapWithDefault(event.flatMap(e -> e.v().unlockedProperty()), Function.identity(), false);
|
this.vaultUnlocked = ObservableUtil.mapWithDefault(eventEntry.flatMap(e -> e.getKey().vault().unlockedProperty()), Function.identity(), false);
|
||||||
this.readableTime = ObservableUtil.mapWithDefault(event, e -> LOCAL_TIME_FORMATTER.format(e.actualEvent().getTimestamp()), "");
|
this.readableTime = ObservableUtil.mapWithDefault(eventEntry, e -> LOCAL_TIME_FORMATTER.format(e.getValue().mostRecentEvent().getTimestamp()), "");
|
||||||
this.readableDate = ObservableUtil.mapWithDefault(event, e -> LOCAL_DATE_FORMATTER.format(e.actualEvent().getTimestamp()), "");
|
this.readableDate = ObservableUtil.mapWithDefault(eventEntry, e -> LOCAL_DATE_FORMATTER.format(e.getValue().mostRecentEvent().getTimestamp()), "");
|
||||||
this.message = Bindings.createStringBinding(this::selectMessage, vaultUnlocked, eventMessage);
|
this.message = Bindings.createStringBinding(this::selectMessage, vaultUnlocked, eventMessage);
|
||||||
this.description = Bindings.createStringBinding(this::selectDescription, vaultUnlocked, eventDescription);
|
this.description = Bindings.createStringBinding(this::selectDescription, vaultUnlocked, eventDescription);
|
||||||
this.icon = Bindings.createObjectBinding(this::selectIcon, vaultUnlocked, eventIcon);
|
this.icon = Bindings.createObjectBinding(this::selectIcon, vaultUnlocked, eventIcon);
|
||||||
@@ -108,13 +110,15 @@ public class EventListCellController implements FxController {
|
|||||||
return vaultUnlocked.getValue() && (eventActionsMenu.isShowing() || root.isHover());
|
return vaultUnlocked.getValue() && (eventActionsMenu.isShowing() || root.isHover());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEvent(@NotNull VaultEvent item) {
|
public void setEventEntry(@NotNull Map.Entry<FSEventBucket, FSEventBucketContent> item) {
|
||||||
event.set(item);
|
eventEntry.set(item);
|
||||||
eventActionsMenu.hide();
|
eventActionsMenu.hide();
|
||||||
eventActionsMenu.getItems().clear();
|
eventActionsMenu.getItems().clear();
|
||||||
eventTooltip.setText(item.v().getDisplayName());
|
eventTooltip.setText(item.getKey().vault().getDisplayName());
|
||||||
addAction("generic.action.dismiss", () -> eventMap.remove(item));
|
addAction("generic.action.dismiss", () -> {
|
||||||
switch (item.actualEvent()) {
|
fileSystemEventAggregator.remove(item.getKey());
|
||||||
|
});
|
||||||
|
switch (item.getValue().mostRecentEvent()) {
|
||||||
case ConflictResolvedEvent fse -> this.adjustToConflictResolvedEvent(fse);
|
case ConflictResolvedEvent fse -> this.adjustToConflictResolvedEvent(fse);
|
||||||
case ConflictResolutionFailedEvent fse -> this.adjustToConflictEvent(fse);
|
case ConflictResolutionFailedEvent fse -> this.adjustToConflictEvent(fse);
|
||||||
case DecryptionFailedEvent fse -> this.adjustToDecryptionFailedEvent(fse);
|
case DecryptionFailedEvent fse -> this.adjustToDecryptionFailedEvent(fse);
|
||||||
@@ -129,9 +133,9 @@ public class EventListCellController implements FxController {
|
|||||||
eventMessage.setValue(resourceBundle.getString("eventView.entry.brokenFileNode.message"));
|
eventMessage.setValue(resourceBundle.getString("eventView.entry.brokenFileNode.message"));
|
||||||
eventDescription.setValue(bfe.ciphertextPath().getFileName().toString());
|
eventDescription.setValue(bfe.ciphertextPath().getFileName().toString());
|
||||||
if (revealService != null) {
|
if (revealService != null) {
|
||||||
addAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, convertVaultPathToSystemPath(bfe.ciphertextPath())));
|
addAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, bfe.ciphertextPath()));
|
||||||
} else {
|
} else {
|
||||||
addAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.ciphertextPath()).toString()));
|
addAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(bfe.ciphertextPath().toString()));
|
||||||
}
|
}
|
||||||
addAction("eventView.entry.brokenFileNode.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.cleartextPath()).toString()));
|
addAction("eventView.entry.brokenFileNode.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.cleartextPath()).toString()));
|
||||||
}
|
}
|
||||||
@@ -202,23 +206,25 @@ public class EventListCellController implements FxController {
|
|||||||
if (vaultUnlocked.getValue()) {
|
if (vaultUnlocked.getValue()) {
|
||||||
return eventMessage.getValue();
|
return eventMessage.getValue();
|
||||||
} else {
|
} else {
|
||||||
return resourceBundle.getString("eventView.entry.vaultLocked.message");
|
return "***********";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String selectDescription() {
|
private String selectDescription() {
|
||||||
if (vaultUnlocked.getValue()) {
|
if (vaultUnlocked.getValue()) {
|
||||||
return eventDescription.getValue();
|
return eventDescription.getValue();
|
||||||
|
} else if (eventEntry.getValue() != null) {
|
||||||
|
var e = eventEntry.getValue().getKey();
|
||||||
|
return resourceBundle.getString("eventView.entry.vaultLocked.description").formatted(e != null ? e.vault().getDisplayName() : "");
|
||||||
} else {
|
} else {
|
||||||
var e = event.getValue();
|
return "";
|
||||||
return resourceBundle.getString("eventView.entry.vaultLocked.description").formatted(e != null ? e.v().getDisplayName() : "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void toggleEventActionsMenu() {
|
public void toggleEventActionsMenu() {
|
||||||
var e = event.get();
|
var e = eventEntry.get();
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
if (eventActionsMenu.isShowing()) {
|
if (eventActionsMenu.isShowing()) {
|
||||||
eventActionsMenu.hide();
|
eventActionsMenu.hide();
|
||||||
@@ -232,7 +238,7 @@ public class EventListCellController implements FxController {
|
|||||||
if (!(p instanceof CryptoPath)) {
|
if (!(p instanceof CryptoPath)) {
|
||||||
throw new IllegalArgumentException("Path " + p + " is not a vault path");
|
throw new IllegalArgumentException("Path " + p + " is not a vault path");
|
||||||
}
|
}
|
||||||
var v = event.getValue().v();
|
var v = eventEntry.getValue().getKey().vault();
|
||||||
if (!v.isUnlocked()) {
|
if (!v.isUnlocked()) {
|
||||||
return Path.of(System.getProperty("user.home"));
|
return Path.of(System.getProperty("user.home"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.cryptomator.ui.eventview;
|
package org.cryptomator.ui.eventview;
|
||||||
|
|
||||||
import org.cryptomator.event.VaultEvent;
|
import org.cryptomator.event.FSEventBucket;
|
||||||
|
import org.cryptomator.event.FSEventBucketContent;
|
||||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -12,9 +13,10 @@ import javafx.scene.control.ListView;
|
|||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UncheckedIOException;
|
import java.io.UncheckedIOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@EventViewScoped
|
@EventViewScoped
|
||||||
public class EventListCellFactory implements Callback<ListView<VaultEvent>, ListCell<VaultEvent>> {
|
public class EventListCellFactory implements Callback<ListView<Map.Entry<FSEventBucket, FSEventBucketContent>>, ListCell<Map.Entry<FSEventBucket, FSEventBucketContent>>> {
|
||||||
|
|
||||||
private static final String FXML_PATH = "/fxml/eventview_cell.fxml";
|
private static final String FXML_PATH = "/fxml/eventview_cell.fxml";
|
||||||
|
|
||||||
@@ -27,7 +29,7 @@ public class EventListCellFactory implements Callback<ListView<VaultEvent>, List
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListCell<VaultEvent> call(ListView<VaultEvent> eventListView) {
|
public ListCell<Map.Entry<FSEventBucket, FSEventBucketContent>> call(ListView<Map.Entry<FSEventBucket, FSEventBucketContent>> eventListView) {
|
||||||
try {
|
try {
|
||||||
FXMLLoader fxmlLoader = fxmlLoaders.load(FXML_PATH);
|
FXMLLoader fxmlLoader = fxmlLoaders.load(FXML_PATH);
|
||||||
return new Cell(fxmlLoader.getRoot(), fxmlLoader.getController());
|
return new Cell(fxmlLoader.getRoot(), fxmlLoader.getController());
|
||||||
@@ -36,7 +38,7 @@ public class EventListCellFactory implements Callback<ListView<VaultEvent>, List
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Cell extends ListCell<VaultEvent> {
|
private static class Cell extends ListCell<Map.Entry<FSEventBucket, FSEventBucketContent>> {
|
||||||
|
|
||||||
private final Parent root;
|
private final Parent root;
|
||||||
private final EventListCellController controller;
|
private final EventListCellController controller;
|
||||||
@@ -47,7 +49,7 @@ public class EventListCellFactory implements Callback<ListView<VaultEvent>, List
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateItem(VaultEvent item, boolean empty) {
|
protected void updateItem(Map.Entry<FSEventBucket, FSEventBucketContent> item, boolean empty) {
|
||||||
super.updateItem(item, empty);
|
super.updateItem(item, empty);
|
||||||
|
|
||||||
if (empty || item == null) {
|
if (empty || item == null) {
|
||||||
@@ -57,7 +59,7 @@ public class EventListCellFactory implements Callback<ListView<VaultEvent>, List
|
|||||||
this.getStyleClass().addLast("list-cell");
|
this.getStyleClass().addLast("list-cell");
|
||||||
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
|
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
|
||||||
setGraphic(root);
|
setGraphic(root);
|
||||||
controller.setEvent(item);
|
controller.setEventEntry(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
package org.cryptomator.ui.eventview;
|
package org.cryptomator.ui.eventview;
|
||||||
|
|
||||||
import org.cryptomator.common.EventMap;
|
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.event.VaultEvent;
|
import org.cryptomator.event.FSEventBucket;
|
||||||
|
import org.cryptomator.event.FSEventBucketContent;
|
||||||
|
import org.cryptomator.event.FileSystemEventAggregator;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
|
import org.cryptomator.ui.fxapp.FxFSEventList;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.MapChangeListener;
|
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.collections.transformation.FilteredList;
|
import javafx.collections.transformation.FilteredList;
|
||||||
import javafx.collections.transformation.SortedList;
|
import javafx.collections.transformation.SortedList;
|
||||||
@@ -17,17 +18,16 @@ import javafx.fxml.FXML;
|
|||||||
import javafx.scene.control.ChoiceBox;
|
import javafx.scene.control.ChoiceBox;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
import java.util.Comparator;
|
import java.util.Map;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
@EventViewScoped
|
@EventViewScoped
|
||||||
public class EventViewController implements FxController {
|
public class EventViewController implements FxController {
|
||||||
|
|
||||||
private final EventMap eventMap;
|
private final FilteredList<Map.Entry<FSEventBucket, FSEventBucketContent>> filteredEventList;
|
||||||
private final ObservableList<VaultEvent> eventList;
|
|
||||||
private final FilteredList<VaultEvent> filteredEventList;
|
|
||||||
private final ObservableList<Vault> vaults;
|
private final ObservableList<Vault> vaults;
|
||||||
private final SortedList<VaultEvent> reversedEventList;
|
private final FileSystemEventAggregator aggregator;
|
||||||
|
private final SortedList<Map.Entry<FSEventBucket, FSEventBucketContent>> sortedEventList;
|
||||||
private final ObservableList<Vault> choiceBoxEntries;
|
private final ObservableList<Vault> choiceBoxEntries;
|
||||||
private final ResourceBundle resourceBundle;
|
private final ResourceBundle resourceBundle;
|
||||||
private final EventListCellFactory cellFactory;
|
private final EventListCellFactory cellFactory;
|
||||||
@@ -35,20 +35,45 @@ public class EventViewController implements FxController {
|
|||||||
@FXML
|
@FXML
|
||||||
ChoiceBox<Vault> vaultFilterChoiceBox;
|
ChoiceBox<Vault> vaultFilterChoiceBox;
|
||||||
@FXML
|
@FXML
|
||||||
ListView<VaultEvent> eventListView;
|
ListView<Map.Entry<FSEventBucket, FSEventBucketContent>> eventListView;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public EventViewController(EventMap eventMap, ObservableList<Vault> vaults, ResourceBundle resourceBundle, EventListCellFactory cellFactory) {
|
public EventViewController(FxFSEventList fxFSEventList, ObservableList<Vault> vaults, ResourceBundle resourceBundle, EventListCellFactory cellFactory, FileSystemEventAggregator aggregator) {
|
||||||
this.eventMap = eventMap;
|
this.filteredEventList = fxFSEventList.getObservableList().filtered(_ -> true);
|
||||||
this.eventList = FXCollections.observableArrayList();
|
|
||||||
this.filteredEventList = eventList.filtered(_ -> true);
|
|
||||||
this.vaults = vaults;
|
this.vaults = vaults;
|
||||||
this.reversedEventList = new SortedList<>(filteredEventList, Comparator.reverseOrder());
|
this.aggregator = aggregator;
|
||||||
|
this.sortedEventList = new SortedList<>(filteredEventList, this::compareBuckets);
|
||||||
this.choiceBoxEntries = FXCollections.observableArrayList();
|
this.choiceBoxEntries = FXCollections.observableArrayList();
|
||||||
this.resourceBundle = resourceBundle;
|
this.resourceBundle = resourceBundle;
|
||||||
this.cellFactory = cellFactory;
|
this.cellFactory = cellFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparison method for the lru cache. During comparsion the map is accessed.
|
||||||
|
* First the entries are compared by the event timestamp, then vaultId, then identifying path and lastly by class name.
|
||||||
|
*
|
||||||
|
* @param left an entry of a {@link FSEventBucket} and its content
|
||||||
|
* @param right another entry of a {@link FSEventBucket} plus content, compared to {@code left}
|
||||||
|
* @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
|
||||||
|
*/
|
||||||
|
private int compareBuckets(Map.Entry<FSEventBucket, FSEventBucketContent> left, Map.Entry<FSEventBucket, FSEventBucketContent> right) {
|
||||||
|
var t1 = left.getValue().mostRecentEvent().getTimestamp();
|
||||||
|
var t2 = right.getValue().mostRecentEvent().getTimestamp();
|
||||||
|
var timeComparison = t1.compareTo(t2);
|
||||||
|
if (timeComparison != 0) {
|
||||||
|
return -timeComparison; //we need the reverse timesorting
|
||||||
|
}
|
||||||
|
var vaultIdComparison = left.getKey().vault().getId().compareTo(right.getKey().vault().getId());
|
||||||
|
if (vaultIdComparison != 0) {
|
||||||
|
return vaultIdComparison;
|
||||||
|
}
|
||||||
|
var pathComparison = left.getKey().idPath().compareTo(right.getKey().idPath());
|
||||||
|
if (pathComparison != 0) {
|
||||||
|
return pathComparison;
|
||||||
|
}
|
||||||
|
return left.getKey().c().getName().compareTo(right.getKey().c().getName());
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
choiceBoxEntries.add(null);
|
choiceBoxEntries.add(null);
|
||||||
@@ -60,39 +85,25 @@ public class EventViewController implements FxController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
eventList.addAll(eventMap.values());
|
|
||||||
eventMap.addListener((MapChangeListener<? super EventMap.EventKey, ? super VaultEvent>) this::updateList);
|
|
||||||
eventListView.setCellFactory(cellFactory);
|
eventListView.setCellFactory(cellFactory);
|
||||||
eventListView.setItems(reversedEventList);
|
eventListView.setItems(sortedEventList);
|
||||||
|
|
||||||
vaultFilterChoiceBox.setItems(choiceBoxEntries);
|
vaultFilterChoiceBox.setItems(choiceBoxEntries);
|
||||||
vaultFilterChoiceBox.valueProperty().addListener(this::applyVaultFilter);
|
vaultFilterChoiceBox.valueProperty().addListener(this::applyVaultFilter);
|
||||||
vaultFilterChoiceBox.setConverter(new VaultConverter(resourceBundle));
|
vaultFilterChoiceBox.setConverter(new VaultConverter(resourceBundle));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateList(MapChangeListener.Change<? extends EventMap.EventKey, ? extends VaultEvent> change) {
|
|
||||||
if (change.wasAdded() && change.wasRemoved()) {
|
|
||||||
//entry updated
|
|
||||||
eventList.remove(change.getValueRemoved());
|
|
||||||
eventList.addLast(change.getValueAdded());
|
|
||||||
} else if (change.wasAdded()) {
|
|
||||||
eventList.addLast(change.getValueAdded());
|
|
||||||
} else { //removed
|
|
||||||
eventList.remove(change.getValueRemoved());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyVaultFilter(ObservableValue<? extends Vault> v, Vault oldV, Vault newV) {
|
private void applyVaultFilter(ObservableValue<? extends Vault> v, Vault oldV, Vault newV) {
|
||||||
if (newV == null) {
|
if (newV == null) {
|
||||||
filteredEventList.setPredicate(_ -> true);
|
filteredEventList.setPredicate(_ -> true);
|
||||||
} else {
|
} else {
|
||||||
filteredEventList.setPredicate(e -> e.v().equals(newV));
|
filteredEventList.setPredicate(e -> e.getKey().vault().equals(newV));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void clearEvents() {
|
void clearEvents() {
|
||||||
eventMap.clear();
|
aggregator.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class VaultConverter extends StringConverter<Vault> {
|
private static class VaultConverter extends StringConverter<Vault> {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.cryptomator.ui.common.FxmlFile;
|
|||||||
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
import org.cryptomator.ui.common.FxmlLoaderFactory;
|
||||||
import org.cryptomator.ui.common.FxmlScene;
|
import org.cryptomator.ui.common.FxmlScene;
|
||||||
import org.cryptomator.ui.common.StageFactory;
|
import org.cryptomator.ui.common.StageFactory;
|
||||||
|
import org.cryptomator.ui.fxapp.FxFSEventList;
|
||||||
|
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
@@ -25,12 +26,17 @@ abstract class EventViewModule {
|
|||||||
@Provides
|
@Provides
|
||||||
@EventViewScoped
|
@EventViewScoped
|
||||||
@EventViewWindow
|
@EventViewWindow
|
||||||
static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle) {
|
static Stage provideStage(StageFactory factory, ResourceBundle resourceBundle, FxFSEventList fxFSEventList) {
|
||||||
Stage stage = factory.create();
|
Stage stage = factory.create();
|
||||||
stage.setHeight(498);
|
stage.setHeight(498);
|
||||||
stage.setTitle(resourceBundle.getString("eventView.title"));
|
stage.setTitle(resourceBundle.getString("eventView.title"));
|
||||||
stage.setResizable(true);
|
stage.setResizable(true);
|
||||||
stage.initModality(Modality.NONE);
|
stage.initModality(Modality.NONE);
|
||||||
|
stage.focusedProperty().addListener((_,_,isFocused) -> {
|
||||||
|
if(isFocused) {
|
||||||
|
fxFSEventList.unreadEventsProperty().setValue(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,10 @@ public class FxApplication {
|
|||||||
private final FxApplicationStyle applicationStyle;
|
private final FxApplicationStyle applicationStyle;
|
||||||
private final FxApplicationTerminator applicationTerminator;
|
private final FxApplicationTerminator applicationTerminator;
|
||||||
private final AutoUnlocker autoUnlocker;
|
private final AutoUnlocker autoUnlocker;
|
||||||
|
private final FxFSEventList fxFSEventList;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FxApplication(@Named("startupTime") long startupTime, Environment environment, Settings settings, AppLaunchEventHandler launchEventHandler, Lazy<TrayMenuComponent> trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker) {
|
FxApplication(@Named("startupTime") long startupTime, Environment environment, Settings settings, AppLaunchEventHandler launchEventHandler, Lazy<TrayMenuComponent> trayMenu, FxApplicationWindows appWindows, FxApplicationStyle applicationStyle, FxApplicationTerminator applicationTerminator, AutoUnlocker autoUnlocker, FxFSEventList fxFSEventList) {
|
||||||
this.startupTime = startupTime;
|
this.startupTime = startupTime;
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
@@ -41,6 +42,7 @@ public class FxApplication {
|
|||||||
this.applicationStyle = applicationStyle;
|
this.applicationStyle = applicationStyle;
|
||||||
this.applicationTerminator = applicationTerminator;
|
this.applicationTerminator = applicationTerminator;
|
||||||
this.autoUnlocker = autoUnlocker;
|
this.autoUnlocker = autoUnlocker;
|
||||||
|
this.fxFSEventList = fxFSEventList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
@@ -85,6 +87,7 @@ public class FxApplication {
|
|||||||
migrateAndInformDokanyRemoval();
|
migrateAndInformDokanyRemoval();
|
||||||
|
|
||||||
launchEventHandler.startHandlingLaunchEvents();
|
launchEventHandler.startHandlingLaunchEvents();
|
||||||
|
fxFSEventList.schedulePollForUpdates();
|
||||||
autoUnlocker.tryUnlockForTimespan(2, TimeUnit.MINUTES);
|
autoUnlocker.tryUnlockForTimespan(2, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.cryptomator.ui.fxapp;
|
|||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
import org.cryptomator.ui.decryptname.DecryptNameComponent;
|
||||||
import org.cryptomator.ui.error.ErrorComponent;
|
import org.cryptomator.ui.error.ErrorComponent;
|
||||||
import org.cryptomator.ui.eventview.EventViewComponent;
|
import org.cryptomator.ui.eventview.EventViewComponent;
|
||||||
import org.cryptomator.ui.health.HealthCheckComponent;
|
import org.cryptomator.ui.health.HealthCheckComponent;
|
||||||
@@ -20,11 +21,15 @@ import org.cryptomator.ui.unlock.UnlockComponent;
|
|||||||
import org.cryptomator.ui.updatereminder.UpdateReminderComponent;
|
import org.cryptomator.ui.updatereminder.UpdateReminderComponent;
|
||||||
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
|
import org.cryptomator.ui.vaultoptions.VaultOptionsComponent;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, //
|
@Module(includes = {UpdateCheckerModule.class}, subcomponents = {TrayMenuComponent.class, //
|
||||||
|
DecryptNameComponent.class, //
|
||||||
MainWindowComponent.class, //
|
MainWindowComponent.class, //
|
||||||
PreferencesComponent.class, //
|
PreferencesComponent.class, //
|
||||||
VaultOptionsComponent.class, //
|
VaultOptionsComponent.class, //
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package org.cryptomator.ui.fxapp;
|
||||||
|
|
||||||
|
import org.cryptomator.event.FSEventBucket;
|
||||||
|
import org.cryptomator.event.FSEventBucketContent;
|
||||||
|
import org.cryptomator.event.FileSystemEventAggregator;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all occurred filesystem events.
|
||||||
|
* <p>
|
||||||
|
* The list exposes an observable list and a property to listen for updates. Internally it polls the {@link FileSystemEventAggregator} in a regular interval for updates.
|
||||||
|
* If an update is available, the list from the {@link FileSystemEventAggregator } is cloned to this list on the FX application thread.
|
||||||
|
*/
|
||||||
|
@FxApplicationScoped
|
||||||
|
public class FxFSEventList {
|
||||||
|
|
||||||
|
private final ObservableList<Map.Entry<FSEventBucket, FSEventBucketContent>> events;
|
||||||
|
private final FileSystemEventAggregator eventAggregator;
|
||||||
|
private final ScheduledExecutorService scheduler;
|
||||||
|
private final BooleanProperty unreadEvents;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FxFSEventList(FileSystemEventAggregator fsEventAggregator, ScheduledExecutorService scheduler) {
|
||||||
|
this.events = FXCollections.observableArrayList();
|
||||||
|
this.eventAggregator = fsEventAggregator;
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.unreadEvents = new SimpleBooleanProperty(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void schedulePollForUpdates() {
|
||||||
|
scheduler.schedule(this::checkForEventUpdates, 1000, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for event updates and reschedules.
|
||||||
|
* If updates are available, the aggregated events are copied from back- to the frontend.
|
||||||
|
* Reschedules itself on successful execution
|
||||||
|
*/
|
||||||
|
private void checkForEventUpdates() {
|
||||||
|
if (eventAggregator.hasMaybeUpdates()) {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
eventAggregator.cloneTo(events);
|
||||||
|
unreadEvents.setValue(true);
|
||||||
|
schedulePollForUpdates();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
schedulePollForUpdates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableList<Map.Entry<FSEventBucket, FSEventBucketContent>> getObservableList() {
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty unreadEventsProperty() {
|
||||||
|
return unreadEvents;
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-5
@@ -36,6 +36,7 @@ import javafx.stage.Stage;
|
|||||||
import javafx.stage.WindowEvent;
|
import javafx.stage.WindowEvent;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
@PassphraseEntryScoped
|
@PassphraseEntryScoped
|
||||||
public class PassphraseEntryController implements FxController {
|
public class PassphraseEntryController implements FxController {
|
||||||
@@ -49,6 +50,7 @@ public class PassphraseEntryController implements FxController {
|
|||||||
private final ForgetPasswordComponent.Builder forgetPassword;
|
private final ForgetPasswordComponent.Builder forgetPassword;
|
||||||
private final KeychainManager keychain;
|
private final KeychainManager keychain;
|
||||||
private final StringBinding vaultName;
|
private final StringBinding vaultName;
|
||||||
|
private final ExecutorService backgroundExecutorService;
|
||||||
private final BooleanProperty unlockInProgress = new SimpleBooleanProperty();
|
private final BooleanProperty unlockInProgress = new SimpleBooleanProperty();
|
||||||
private final ObjectBinding<ContentDisplay> unlockButtonContentDisplay = Bindings.when(unlockInProgress).then(ContentDisplay.LEFT).otherwise(ContentDisplay.TEXT_ONLY);
|
private final ObjectBinding<ContentDisplay> unlockButtonContentDisplay = Bindings.when(unlockInProgress).then(ContentDisplay.LEFT).otherwise(ContentDisplay.TEXT_ONLY);
|
||||||
private final BooleanProperty unlockButtonDisabled = new SimpleBooleanProperty();
|
private final BooleanProperty unlockButtonDisabled = new SimpleBooleanProperty();
|
||||||
@@ -64,7 +66,7 @@ public class PassphraseEntryController implements FxController {
|
|||||||
public Animation unlockAnimation;
|
public Animation unlockAnimation;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PassphraseEntryController(@KeyLoading Stage window, @KeyLoading Vault vault, CompletableFuture<PassphraseEntryResult> result, @Nullable @Named("savedPassword") Passphrase savedPassword, ForgetPasswordComponent.Builder forgetPassword, KeychainManager keychain) {
|
public PassphraseEntryController(@KeyLoading Stage window, @KeyLoading Vault vault, CompletableFuture<PassphraseEntryResult> result, @Nullable @Named("savedPassword") Passphrase savedPassword, ForgetPasswordComponent.Builder forgetPassword, KeychainManager keychain, ExecutorService backgroundExecutorService) {
|
||||||
this.window = window;
|
this.window = window;
|
||||||
this.vault = vault;
|
this.vault = vault;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
@@ -72,8 +74,8 @@ public class PassphraseEntryController implements FxController {
|
|||||||
this.forgetPassword = forgetPassword;
|
this.forgetPassword = forgetPassword;
|
||||||
this.keychain = keychain;
|
this.keychain = keychain;
|
||||||
this.vaultName = WeakBindings.bindString(vault.displayNameProperty());
|
this.vaultName = WeakBindings.bindString(vault.displayNameProperty());
|
||||||
|
this.backgroundExecutorService = backgroundExecutorService;
|
||||||
window.setOnHiding(this::windowClosed);
|
window.setOnHiding(this::windowClosed);
|
||||||
result.whenCompleteAsync((r, t) -> unlockInProgress.set(false), Platform::runLater);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -119,8 +121,6 @@ public class PassphraseEntryController implements FxController {
|
|||||||
new KeyFrame(Duration.millis(800), legsExtendedY, legsExtendedX, faceHidden), //
|
new KeyFrame(Duration.millis(800), legsExtendedY, legsExtendedX, faceHidden), //
|
||||||
new KeyFrame(Duration.millis(1000), faceVisible) //
|
new KeyFrame(Duration.millis(1000), faceVisible) //
|
||||||
);
|
);
|
||||||
|
|
||||||
result.whenCompleteAsync((r, t) -> stopUnlockAnimation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -133,6 +133,9 @@ public class PassphraseEntryController implements FxController {
|
|||||||
result.cancel(true);
|
result.cancel(true);
|
||||||
LOG.debug("Unlock canceled by user.");
|
LOG.debug("Unlock canceled by user.");
|
||||||
}
|
}
|
||||||
|
if( passwordField != null) {
|
||||||
|
passwordField.getCharacters().destroy();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +145,7 @@ public class PassphraseEntryController implements FxController {
|
|||||||
unlockInProgress.set(true);
|
unlockInProgress.set(true);
|
||||||
CharSequence pwFieldContents = passwordField.getCharacters();
|
CharSequence pwFieldContents = passwordField.getCharacters();
|
||||||
Passphrase pw = Passphrase.copyOf(pwFieldContents);
|
Passphrase pw = Passphrase.copyOf(pwFieldContents);
|
||||||
result.complete(new PassphraseEntryResult(pw, savePasswordCheckbox.isSelected()));
|
result.completeAsync(() -> new PassphraseEntryResult(pw, savePasswordCheckbox.isSelected()), backgroundExecutorService);
|
||||||
startUnlockAnimation();
|
startUnlockAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.cryptomator.integrations.revealpath.RevealFailedException;
|
|||||||
import org.cryptomator.integrations.revealpath.RevealPathService;
|
import org.cryptomator.integrations.revealpath.RevealPathService;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
import org.cryptomator.ui.common.VaultService;
|
import org.cryptomator.ui.common.VaultService;
|
||||||
|
import org.cryptomator.ui.decryptname.DecryptNameComponent;
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||||
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
import org.cryptomator.ui.stats.VaultStatisticsComponent;
|
||||||
import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
|
import org.cryptomator.ui.wrongfilealert.WrongFileAlertComponent;
|
||||||
@@ -47,7 +48,6 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@MainWindowScoped
|
@MainWindowScoped
|
||||||
public class VaultDetailUnlockedController implements FxController {
|
public class VaultDetailUnlockedController implements FxController {
|
||||||
@@ -61,6 +61,7 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
private final WrongFileAlertComponent.Builder wrongFileAlert;
|
private final WrongFileAlertComponent.Builder wrongFileAlert;
|
||||||
private final Stage mainWindow;
|
private final Stage mainWindow;
|
||||||
private final Optional<RevealPathService> revealPathService;
|
private final Optional<RevealPathService> revealPathService;
|
||||||
|
private final DecryptNameComponent.Factory decryptNameWindowFactory;
|
||||||
private final ResourceBundle resourceBundle;
|
private final ResourceBundle resourceBundle;
|
||||||
private final LoadingCache<Vault, VaultStatisticsComponent> vaultStats;
|
private final LoadingCache<Vault, VaultStatisticsComponent> vaultStats;
|
||||||
private final VaultStatisticsComponent.Builder vaultStatsBuilder;
|
private final VaultStatisticsComponent.Builder vaultStatsBuilder;
|
||||||
@@ -70,7 +71,6 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
private final BooleanProperty draggingOverLocateEncrypted = new SimpleBooleanProperty();
|
private final BooleanProperty draggingOverLocateEncrypted = new SimpleBooleanProperty();
|
||||||
private final BooleanProperty draggingOverDecryptName = new SimpleBooleanProperty();
|
private final BooleanProperty draggingOverDecryptName = new SimpleBooleanProperty();
|
||||||
private final BooleanProperty ciphertextPathsCopied = new SimpleBooleanProperty();
|
private final BooleanProperty ciphertextPathsCopied = new SimpleBooleanProperty();
|
||||||
private final BooleanProperty cleartextNamesCopied = new SimpleBooleanProperty();
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public Button revealEncryptedDropZone;
|
public Button revealEncryptedDropZone;
|
||||||
@@ -78,13 +78,22 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
public Button decryptNameDropZone;
|
public Button decryptNameDropZone;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VaultDetailUnlockedController(ObjectProperty<Vault> vault, FxApplicationWindows appWindows, VaultService vaultService, VaultStatisticsComponent.Builder vaultStatsBuilder, WrongFileAlertComponent.Builder wrongFileAlert, @MainWindow Stage mainWindow, Optional<RevealPathService> revealPathService, ResourceBundle resourceBundle) {
|
public VaultDetailUnlockedController(ObjectProperty<Vault> vault, //
|
||||||
|
FxApplicationWindows appWindows, //
|
||||||
|
VaultService vaultService, //
|
||||||
|
VaultStatisticsComponent.Builder vaultStatsBuilder, //
|
||||||
|
WrongFileAlertComponent.Builder wrongFileAlert, //
|
||||||
|
@MainWindow Stage mainWindow, //
|
||||||
|
Optional<RevealPathService> revealPathService, //
|
||||||
|
DecryptNameComponent.Factory decryptNameWindowFactory, //
|
||||||
|
ResourceBundle resourceBundle) {
|
||||||
this.vault = vault;
|
this.vault = vault;
|
||||||
this.appWindows = appWindows;
|
this.appWindows = appWindows;
|
||||||
this.vaultService = vaultService;
|
this.vaultService = vaultService;
|
||||||
this.wrongFileAlert = wrongFileAlert;
|
this.wrongFileAlert = wrongFileAlert;
|
||||||
this.mainWindow = mainWindow;
|
this.mainWindow = mainWindow;
|
||||||
this.revealPathService = revealPathService;
|
this.revealPathService = revealPathService;
|
||||||
|
this.decryptNameWindowFactory = decryptNameWindowFactory;
|
||||||
this.resourceBundle = resourceBundle;
|
this.resourceBundle = resourceBundle;
|
||||||
this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats));
|
this.vaultStats = CacheBuilder.newBuilder().weakValues().build(CacheLoader.from(this::buildVaultStats));
|
||||||
this.vaultStatsBuilder = vaultStatsBuilder;
|
this.vaultStatsBuilder = vaultStatsBuilder;
|
||||||
@@ -106,7 +115,7 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
revealEncryptedDropZone.setOnDragExited(_ -> draggingOverLocateEncrypted.setValue(false));
|
revealEncryptedDropZone.setOnDragExited(_ -> draggingOverLocateEncrypted.setValue(false));
|
||||||
|
|
||||||
decryptNameDropZone.setOnDragOver(e -> handleDragOver(e, draggingOverDecryptName));
|
decryptNameDropZone.setOnDragOver(e -> handleDragOver(e, draggingOverDecryptName));
|
||||||
decryptNameDropZone.setOnDragDropped(e -> handleDragDropped(e, this::getCleartextName, this::copyDecryptedNamesToClipboard));
|
decryptNameDropZone.setOnDragDropped(e -> showDecryptNameWindow(e.getDragboard().getFiles().stream().map(File::toPath).toList()));
|
||||||
decryptNameDropZone.setOnDragExited(_ -> draggingOverDecryptName.setValue(false));
|
decryptNameDropZone.setOnDragExited(_ -> draggingOverDecryptName.setValue(false));
|
||||||
|
|
||||||
EasyBind.includeWhen(revealEncryptedDropZone.getStyleClass(), ACTIVE_CLASS, draggingOverLocateEncrypted);
|
EasyBind.includeWhen(revealEncryptedDropZone.getStyleClass(), ACTIVE_CLASS, draggingOverLocateEncrypted);
|
||||||
@@ -153,39 +162,12 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void chooseEncryptedFileAndCopyNames() {
|
public void showDecryptNameWindow() {
|
||||||
var fileChooser = new FileChooser();
|
showDecryptNameWindow(List.of());
|
||||||
fileChooser.setTitle(resourceBundle.getString("main.vaultDetail.decryptName.filePickerTitle"));
|
|
||||||
|
|
||||||
fileChooser.setInitialDirectory(vault.getValue().getPath().toFile());
|
|
||||||
var ciphertextNode = fileChooser.showOpenDialog(mainWindow);
|
|
||||||
if (ciphertextNode != null) {
|
|
||||||
var nodeName = getCleartextName(ciphertextNode.toPath());
|
|
||||||
copyDecryptedNamesToClipboard(List.of(nodeName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyDecryptedNamesToClipboard(List<CipherToCleartext> mapping) {
|
private void showDecryptNameWindow(List<Path> pathsToDecrypt) {
|
||||||
if (mapping.size() == 1) {
|
decryptNameWindowFactory.create(vault.get(), mainWindow, pathsToDecrypt).showDecryptFileNameWindow();
|
||||||
Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, mapping.getFirst().cleartext));
|
|
||||||
} else {
|
|
||||||
var content = mapping.stream().map(CipherToCleartext::toString).collect(Collectors.joining("\n"));
|
|
||||||
Clipboard.getSystemClipboard().setContent(Map.of(DataFormat.PLAIN_TEXT, content));
|
|
||||||
}
|
|
||||||
cleartextNamesCopied.setValue(true);
|
|
||||||
CompletableFuture.delayedExecutor(2, TimeUnit.SECONDS, Platform::runLater).execute(() -> {
|
|
||||||
cleartextNamesCopied.set(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private CipherToCleartext getCleartextName(Path ciphertextNode) {
|
|
||||||
try {
|
|
||||||
return new CipherToCleartext(ciphertextNode.getFileName().toString(), vault.get().getCleartextName(ciphertextNode));
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.warn("Failed to decrypt filename for {}", ciphertextNode, e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean startsWithVaultAccessPoint(Path path) {
|
private boolean startsWithVaultAccessPoint(Path path) {
|
||||||
@@ -260,14 +242,6 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
vaultStats.getUnchecked(vault.get()).showVaultStatisticsWindow();
|
vaultStats.getUnchecked(vault.get()).showVaultStatisticsWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
record CipherToCleartext(String ciphertext, String cleartext) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return ciphertext + " > " + cleartext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getter/Setter */
|
/* Getter/Setter */
|
||||||
|
|
||||||
public ReadOnlyObjectProperty<Vault> vaultProperty() {
|
public ReadOnlyObjectProperty<Vault> vaultProperty() {
|
||||||
@@ -310,11 +284,5 @@ public class VaultDetailUnlockedController implements FxController {
|
|||||||
return ciphertextPathsCopied.get();
|
return ciphertextPathsCopied.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BooleanProperty cleartextNamesCopiedProperty() {
|
|
||||||
return cleartextNamesCopied;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCleartextNamesCopied() {
|
|
||||||
return cleartextNamesCopied.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
package org.cryptomator.ui.mainwindow;
|
package org.cryptomator.ui.mainwindow;
|
||||||
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
import org.cryptomator.common.EventMap;
|
|
||||||
import org.cryptomator.common.settings.Settings;
|
import org.cryptomator.common.settings.Settings;
|
||||||
import org.cryptomator.common.vaults.Vault;
|
import org.cryptomator.common.vaults.Vault;
|
||||||
import org.cryptomator.common.vaults.VaultListManager;
|
import org.cryptomator.common.vaults.VaultListManager;
|
||||||
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
|
||||||
import org.cryptomator.cryptofs.DirStructure;
|
import org.cryptomator.cryptofs.DirStructure;
|
||||||
import org.cryptomator.event.VaultEvent;
|
|
||||||
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
|
||||||
import org.cryptomator.ui.common.FxController;
|
import org.cryptomator.ui.common.FxController;
|
||||||
import org.cryptomator.ui.common.VaultService;
|
import org.cryptomator.ui.common.VaultService;
|
||||||
import org.cryptomator.ui.dialogs.Dialogs;
|
import org.cryptomator.ui.dialogs.Dialogs;
|
||||||
|
import org.cryptomator.ui.fxapp.FxFSEventList;
|
||||||
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
import org.cryptomator.ui.fxapp.FxApplicationWindows;
|
||||||
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
|
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -25,7 +24,6 @@ import javafx.beans.property.ObjectProperty;
|
|||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.MapChangeListener;
|
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.geometry.Side;
|
import javafx.geometry.Side;
|
||||||
@@ -69,8 +67,7 @@ public class VaultListController implements FxController {
|
|||||||
private final VaultListCellFactory cellFactory;
|
private final VaultListCellFactory cellFactory;
|
||||||
private final AddVaultWizardComponent.Builder addVaultWizard;
|
private final AddVaultWizardComponent.Builder addVaultWizard;
|
||||||
private final BooleanBinding emptyVaultList;
|
private final BooleanBinding emptyVaultList;
|
||||||
private final EventMap eventMap;
|
private final BooleanProperty unreadEvents;
|
||||||
private final BooleanProperty newEventsPresent;
|
|
||||||
private final VaultListManager vaultListManager;
|
private final VaultListManager vaultListManager;
|
||||||
private final BooleanProperty draggingVaultOver = new SimpleBooleanProperty();
|
private final BooleanProperty draggingVaultOver = new SimpleBooleanProperty();
|
||||||
private final ResourceBundle resourceBundle;
|
private final ResourceBundle resourceBundle;
|
||||||
@@ -97,7 +94,7 @@ public class VaultListController implements FxController {
|
|||||||
FxApplicationWindows appWindows, //
|
FxApplicationWindows appWindows, //
|
||||||
Settings settings, //
|
Settings settings, //
|
||||||
Dialogs dialogs, //
|
Dialogs dialogs, //
|
||||||
EventMap eventMap) {
|
FxFSEventList fxFSEventList) {
|
||||||
this.mainWindow = mainWindow;
|
this.mainWindow = mainWindow;
|
||||||
this.vaults = vaults;
|
this.vaults = vaults;
|
||||||
this.selectedVault = selectedVault;
|
this.selectedVault = selectedVault;
|
||||||
@@ -110,13 +107,7 @@ public class VaultListController implements FxController {
|
|||||||
this.dialogs = dialogs;
|
this.dialogs = dialogs;
|
||||||
|
|
||||||
this.emptyVaultList = Bindings.isEmpty(vaults);
|
this.emptyVaultList = Bindings.isEmpty(vaults);
|
||||||
this.eventMap = eventMap;
|
this.unreadEvents = fxFSEventList.unreadEventsProperty();
|
||||||
this.newEventsPresent = new SimpleBooleanProperty(false);
|
|
||||||
eventMap.addListener((MapChangeListener<? super EventMap.EventKey, ? super VaultEvent>) change -> {
|
|
||||||
if (change.wasAdded()) {
|
|
||||||
newEventsPresent.setValue(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
selectedVault.addListener(this::selectedVaultDidChange);
|
selectedVault.addListener(this::selectedVaultDidChange);
|
||||||
cellSize = settings.compactMode.map(compact -> compact ? 30.0 : 60.0);
|
cellSize = settings.compactMode.map(compact -> compact ? 30.0 : 60.0);
|
||||||
@@ -279,7 +270,6 @@ public class VaultListController implements FxController {
|
|||||||
@FXML
|
@FXML
|
||||||
public void showEventViewer() {
|
public void showEventViewer() {
|
||||||
appWindows.showEventViewer();
|
appWindows.showEventViewer();
|
||||||
newEventsPresent.setValue(false);
|
|
||||||
}
|
}
|
||||||
// Getter and Setter
|
// Getter and Setter
|
||||||
|
|
||||||
@@ -307,11 +297,11 @@ public class VaultListController implements FxController {
|
|||||||
return cellSize.getValue();
|
return cellSize.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObservableValue<Boolean> newEventsPresentProperty() {
|
public ObservableValue<Boolean> unreadEventsPresentProperty() {
|
||||||
return newEventsPresent;
|
return unreadEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getNewEventsPresent() {
|
public boolean getUnreadEventsPresent() {
|
||||||
return newEventsPresent.getValue();
|
return unreadEvents.getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class GeneralPreferencesController implements FxController {
|
|||||||
var keychainSettingsConverter = new ServiceToSettingsConverter<>(keychainAccessProviders);
|
var keychainSettingsConverter = new ServiceToSettingsConverter<>(keychainAccessProviders);
|
||||||
keychainBackendChoiceBox.getItems().addAll(keychainAccessProviders);
|
keychainBackendChoiceBox.getItems().addAll(keychainAccessProviders);
|
||||||
keychainBackendChoiceBox.setValue(keychainSettingsConverter.fromString(settings.keychainProvider.get()));
|
keychainBackendChoiceBox.setValue(keychainSettingsConverter.fromString(settings.keychainProvider.get()));
|
||||||
keychainBackendChoiceBox.setConverter(new KeychainProviderDisplayNameConverter());
|
keychainBackendChoiceBox.setConverter(new NamedServiceConverter<>());
|
||||||
Bindings.bindBidirectional(settings.keychainProvider, keychainBackendChoiceBox.valueProperty(), keychainSettingsConverter);
|
Bindings.bindBidirectional(settings.keychainProvider, keychainBackendChoiceBox.valueProperty(), keychainSettingsConverter);
|
||||||
useKeychainCheckbox.selectedProperty().bindBidirectional(settings.useKeychain);
|
useKeychainCheckbox.selectedProperty().bindBidirectional(settings.useKeychain);
|
||||||
keychainBackendChoiceBox.disableProperty().bind(useKeychainCheckbox.selectedProperty().not());
|
keychainBackendChoiceBox.disableProperty().bind(useKeychainCheckbox.selectedProperty().not());
|
||||||
@@ -106,13 +106,13 @@ public class GeneralPreferencesController implements FxController {
|
|||||||
var idsAndNames = settings.directories.stream().collect(Collectors.toMap(vs -> vs.id, vs -> vs.displayName.getValue()));
|
var idsAndNames = settings.directories.stream().collect(Collectors.toMap(vs -> vs.id, vs -> vs.displayName.getValue()));
|
||||||
if (!idsAndNames.isEmpty()) {
|
if (!idsAndNames.isEmpty()) {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("Migrating keychain entries {} from {} to {}", idsAndNames.keySet(), oldProvider.displayName(), newProvider.displayName());
|
LOG.debug("Migrating keychain entries {} from {} to {}", idsAndNames.keySet(), oldProvider.getName(), newProvider.getName());
|
||||||
}
|
}
|
||||||
keychainMigrations = keychainMigrations.thenRunAsync(() -> {
|
keychainMigrations = keychainMigrations.thenRunAsync(() -> {
|
||||||
try {
|
try {
|
||||||
KeychainManager.migrate(oldProvider, newProvider, idsAndNames);
|
KeychainManager.migrate(oldProvider, newProvider, idsAndNames);
|
||||||
} catch (KeychainAccessException e) {
|
} catch (KeychainAccessException e) {
|
||||||
LOG.warn("Failed to migrate all entries from {} to {}", oldProvider.displayName(), newProvider.displayName(), e);
|
LOG.warn("Failed to migrate all entries from {} to {}", oldProvider.getName(), newProvider.getName(), e);
|
||||||
}
|
}
|
||||||
}, backgroundExecutor);
|
}, backgroundExecutor);
|
||||||
}
|
}
|
||||||
@@ -151,25 +151,6 @@ public class GeneralPreferencesController implements FxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Helper classes */
|
/* Helper classes */
|
||||||
|
|
||||||
private static class KeychainProviderDisplayNameConverter extends StringConverter<KeychainAccessProvider> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(KeychainAccessProvider provider) {
|
|
||||||
if (provider == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return provider.displayName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public KeychainAccessProvider fromString(String string) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class NamedServiceConverter<T extends NamedServiceProvider> extends StringConverter<T> {
|
private static class NamedServiceConverter<T extends NamedServiceProvider> extends StringConverter<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -130,8 +130,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cryptic-text {
|
.cryptic-text {
|
||||||
-fx-background-color: MAIN_BG;
|
-fx-fill: TEXT_FILL;
|
||||||
-fx-text-fill: TEXT_FILL;
|
|
||||||
-fx-font-family: 'Fira Code';
|
-fx-font-family: 'Fira Code';
|
||||||
-fx-font-size: 1.1em;
|
-fx-font-size: 1.1em;
|
||||||
}
|
}
|
||||||
@@ -313,6 +312,10 @@
|
|||||||
-fx-font-size: 1.0em;
|
-fx-font-size: 1.0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-cell .header-misc {
|
||||||
|
-fx-font-size: 1.0em;
|
||||||
|
}
|
||||||
|
|
||||||
.list-cell .detail-label {
|
.list-cell .detail-label {
|
||||||
-fx-text-fill: TEXT_FILL_MUTED;
|
-fx-text-fill: TEXT_FILL_MUTED;
|
||||||
-fx-font-size: 0.8em;
|
-fx-font-size: 0.8em;
|
||||||
@@ -652,11 +655,8 @@
|
|||||||
* *
|
* *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
.update-indicator {
|
.icon-update-indicator {
|
||||||
-fx-background-color: white, RED_5;
|
-fx-fill: RED_5;
|
||||||
-fx-background-insets: 1px, 2px;
|
|
||||||
-fx-background-radius: 6px, 5px;
|
|
||||||
-fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.8), 2, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -1023,3 +1023,166 @@
|
|||||||
-fx-background-insets: 0, 1px;
|
-fx-background-insets: 0, 1px;
|
||||||
-fx-background-radius: 4px;
|
-fx-background-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* *
|
||||||
|
* Decrypt Name Window
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
.decrypt-name-window .button-bar {
|
||||||
|
-fx-min-height:42px;
|
||||||
|
-fx-max-height:42px;
|
||||||
|
-fx-background-color: MAIN_BG;
|
||||||
|
-fx-border-color: transparent transparent CONTROL_BORDER_NORMAL transparent;
|
||||||
|
-fx-border-width: 0 0 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decrypt-name-window .button-bar .button-right {
|
||||||
|
-fx-border-color: transparent transparent transparent CONTROL_BORDER_NORMAL;
|
||||||
|
-fx-border-width: 0 0 0 1px;
|
||||||
|
-fx-background-color: MAIN_BG;
|
||||||
|
-fx-background-radius: 0px;
|
||||||
|
-fx-min-height: 42px;
|
||||||
|
-fx-max-height: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decrypt-name-window .button-bar .button-right:armed {
|
||||||
|
-fx-background-color: CONTROL_BORDER_NORMAL, CONTROL_BG_ARMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decrypt-name-window .table-view {
|
||||||
|
-fx-background-color: CONTROL_BORDER_NORMAL, CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0,1;
|
||||||
|
/* There is some oddness if padding is in em values rather than pixels,
|
||||||
|
in particular, the left border of the control doesn't show. */
|
||||||
|
-fx-padding: 1; /* 0.083333em; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .placeholder {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-background-radius: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .placeholder > .button {
|
||||||
|
-fx-border-width: 0;
|
||||||
|
-fx-border-color: transparent;
|
||||||
|
-fx-background-radius: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view:focused {
|
||||||
|
-fx-background-color: CONTROL_BORDER_FOCUSED, CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0, 1;
|
||||||
|
-fx-background-radius: 0, 0;
|
||||||
|
/* There is some oddness if padding is in em values rather than pixels,
|
||||||
|
in particular, the left border of the control doesn't show. */
|
||||||
|
-fx-padding: 1; /* 0.083333em; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .virtual-flow > .scroll-bar:vertical {
|
||||||
|
-fx-background-insets: 0, 0 0 0 1;
|
||||||
|
-fx-padding: -1 -1 -1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .virtual-flow > .corner {
|
||||||
|
-fx-background-color: CONTROL_BORDER_NORMAL, CONTROL_BG_NORMAL ;
|
||||||
|
-fx-background-insets: 0, 1 0 0 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Each row in the table is a table-row-cell. Inside a table-row-cell is any
|
||||||
|
number of table-cell. */
|
||||||
|
.table-row-cell {
|
||||||
|
-fx-background-color: GRAY_3, CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0, 0 0 1 0;
|
||||||
|
-fx-padding: 0.0em; /* 0 */
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row-cell:odd {
|
||||||
|
-fx-background-color: GRAY_3, GRAY_1;
|
||||||
|
-fx-background-insets: 0, 0 0 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell {
|
||||||
|
-fx-padding: 3px 6px 3px 6px;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-border-color: transparent CONTROL_BORDER_NORMAL transparent transparent;
|
||||||
|
-fx-border-width: 1px;
|
||||||
|
-fx-cell-size: 30px;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
-fx-text-overrun: center-ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view:focused > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled:selected > .table-cell {
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* selected, hover - not specified */
|
||||||
|
|
||||||
|
/* selected, focused, hover */
|
||||||
|
/* selected, focused */
|
||||||
|
/* selected */
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:selected,
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused:selected,
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused:selected:hover {
|
||||||
|
-fx-background-color: CONTROL_PRIMARY_BG_NORMAL, PRIMARY_D1;
|
||||||
|
-fx-background-insets: 0 0 0 0, 1 1 1 3;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
/* focused */
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused {
|
||||||
|
-fx-background-color: CONTROL_PRIMARY_BORDER_FOCUSED, CONTROL_PRIMARY_BG_NORMAL , CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0 1 0 0, 1 2 1 1, 2 3 2 2;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
/* focused, hover */
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused:hover {
|
||||||
|
-fx-background-color: CONTROL_PRIMARY_BORDER_FOCUSED, CONTROL_PRIMARY_BG_NORMAL , PRIMARY_D2;
|
||||||
|
-fx-background-insets: 0 1 0 0, 1 2 1 1, 2 3 2 2;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
/* hover */
|
||||||
|
.table-view:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:hover {
|
||||||
|
-fx-background-color: PRIMARY_D2;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
-fx-background-insets: 0 0 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The column-resize-line is shown when the user is attempting to resize a column. */
|
||||||
|
.table-view .column-resize-line {
|
||||||
|
-fx-background-color: CONTROL_BG_ARMED;
|
||||||
|
-fx-padding: 0.0em 0.0416667em 0.0em 0.0416667em; /* 0 0.571429 0 0.571429 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the area behind the column headers. An ideal place to specify background
|
||||||
|
and border colors for the whole area (not individual column-header's). */
|
||||||
|
.table-view .column-header-background {
|
||||||
|
-fx-background-color: GRAY_2;
|
||||||
|
-fx-padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The column header row is made up of a number of column-header, one for each
|
||||||
|
TableColumn, and a 'filler' area that extends from the right-most column
|
||||||
|
to the edge of the tableview, or up to the 'column control' button. */
|
||||||
|
.table-view .column-header {
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
-fx-font-size: 1.083333em; /* 13pt ; 1 more than the default font */
|
||||||
|
-fx-size: 24;
|
||||||
|
-fx-border-style: solid;
|
||||||
|
-fx-border-color:
|
||||||
|
transparent
|
||||||
|
GRAY_3
|
||||||
|
GRAY_3
|
||||||
|
transparent;
|
||||||
|
-fx-border-insets: 0 0 0 0;
|
||||||
|
-fx-border-width: 0.083333em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view .column-header .label {
|
||||||
|
-fx-alignment: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view .empty-table {
|
||||||
|
-fx-background-color: MAIN_BG;
|
||||||
|
-fx-font-size: 1.166667em; /* 14pt - 2 more than the default font */
|
||||||
|
}
|
||||||
|
|||||||
@@ -83,6 +83,7 @@
|
|||||||
PROGRESS_INDICATOR_END: GRAY_4;
|
PROGRESS_INDICATOR_END: GRAY_4;
|
||||||
PROGRESS_BAR_BG: GRAY_8;
|
PROGRESS_BAR_BG: GRAY_8;
|
||||||
|
|
||||||
|
|
||||||
-fx-background-color: MAIN_BG;
|
-fx-background-color: MAIN_BG;
|
||||||
-fx-text-fill: TEXT_FILL;
|
-fx-text-fill: TEXT_FILL;
|
||||||
-fx-font-family: 'Open Sans';
|
-fx-font-family: 'Open Sans';
|
||||||
@@ -129,8 +130,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cryptic-text {
|
.cryptic-text {
|
||||||
-fx-background-color: MAIN_BG;
|
-fx-fill: TEXT_FILL;
|
||||||
-fx-text-fill: TEXT_FILL;
|
|
||||||
-fx-font-family: 'Fira Code';
|
-fx-font-family: 'Fira Code';
|
||||||
-fx-font-size: 1.1em;
|
-fx-font-size: 1.1em;
|
||||||
}
|
}
|
||||||
@@ -655,11 +655,8 @@
|
|||||||
* *
|
* *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
.update-indicator {
|
.icon-update-indicator {
|
||||||
-fx-background-color: white, RED_5;
|
-fx-fill: RED_5;
|
||||||
-fx-background-insets: 1px, 2px;
|
|
||||||
-fx-background-radius: 6px, 5px;
|
|
||||||
-fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.8), 2, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -1026,3 +1023,166 @@
|
|||||||
-fx-background-insets: 0, 1px;
|
-fx-background-insets: 0, 1px;
|
||||||
-fx-background-radius: 4px;
|
-fx-background-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* *
|
||||||
|
* Decrypt Name Window
|
||||||
|
* *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
.decrypt-name-window .button-bar {
|
||||||
|
-fx-min-height:42px;
|
||||||
|
-fx-max-height:42px;
|
||||||
|
-fx-background-color: MAIN_BG;
|
||||||
|
-fx-border-color: transparent transparent CONTROL_BORDER_NORMAL transparent;
|
||||||
|
-fx-border-width: 0 0 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decrypt-name-window .button-bar .button-right {
|
||||||
|
-fx-border-color: transparent transparent transparent CONTROL_BORDER_NORMAL;
|
||||||
|
-fx-border-width: 0 0 0 1px;
|
||||||
|
-fx-background-color: MAIN_BG;
|
||||||
|
-fx-background-radius: 0px;
|
||||||
|
-fx-min-height: 42px;
|
||||||
|
-fx-max-height: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decrypt-name-window .button-bar .button-right:armed {
|
||||||
|
-fx-background-color: CONTROL_BORDER_NORMAL, CONTROL_BG_ARMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decrypt-name-window .table-view {
|
||||||
|
-fx-background-color: CONTROL_BORDER_NORMAL, CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0,1;
|
||||||
|
/* There is some oddness if padding is in em values rather than pixels,
|
||||||
|
in particular, the left border of the control doesn't show. */
|
||||||
|
-fx-padding: 1; /* 0.083333em; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .placeholder {
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-background-radius: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .placeholder > .button {
|
||||||
|
-fx-border-width: 0;
|
||||||
|
-fx-border-color: transparent;
|
||||||
|
-fx-background-radius: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view:focused {
|
||||||
|
-fx-background-color: CONTROL_BORDER_FOCUSED, CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0, 1;
|
||||||
|
-fx-background-radius: 0, 0;
|
||||||
|
/* There is some oddness if padding is in em values rather than pixels,
|
||||||
|
in particular, the left border of the control doesn't show. */
|
||||||
|
-fx-padding: 1; /* 0.083333em; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .virtual-flow > .scroll-bar:vertical {
|
||||||
|
-fx-background-insets: 0, 0 0 0 1;
|
||||||
|
-fx-padding: -1 -1 -1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view > .virtual-flow > .corner {
|
||||||
|
-fx-background-color: CONTROL_BORDER_NORMAL, CONTROL_BG_NORMAL ;
|
||||||
|
-fx-background-insets: 0, 1 0 0 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Each row in the table is a table-row-cell. Inside a table-row-cell is any
|
||||||
|
number of table-cell. */
|
||||||
|
.table-row-cell {
|
||||||
|
-fx-background-color: GRAY_6, CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0, 0 0 1 0;
|
||||||
|
-fx-padding: 0.0em; /* 0 */
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row-cell:odd {
|
||||||
|
-fx-background-color: GRAY_6, GRAY_9;
|
||||||
|
-fx-background-insets: 0, 0 0 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-cell {
|
||||||
|
-fx-padding: 3px 6px 3px 6px;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
-fx-border-color: transparent CONTROL_BORDER_NORMAL transparent transparent;
|
||||||
|
-fx-border-width: 1px;
|
||||||
|
-fx-cell-size: 30px;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
-fx-text-overrun: center-ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view:focused > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled:selected > .table-cell {
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* selected, hover - not specified */
|
||||||
|
|
||||||
|
/* selected, focused, hover */
|
||||||
|
/* selected, focused */
|
||||||
|
/* selected */
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:selected,
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused:selected,
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused:selected:hover {
|
||||||
|
-fx-background-color: CONTROL_PRIMARY_BG_NORMAL, CONTROL_BG_SELECTED;
|
||||||
|
-fx-background-insets: 0 0 0 0, 1 1 1 3;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
/* focused */
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused {
|
||||||
|
-fx-background-color: CONTROL_PRIMARY_BORDER_FOCUSED, CONTROL_PRIMARY_BG_NORMAL , CONTROL_BG_NORMAL;
|
||||||
|
-fx-background-insets: 0 1 0 0, 1 2 1 1, 2 3 2 2;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
/* focused, hover */
|
||||||
|
.table-view:focused:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:focused:hover {
|
||||||
|
-fx-background-color: CONTROL_PRIMARY_BORDER_FOCUSED, CONTROL_PRIMARY_BG_NORMAL , PRIMARY_L2;
|
||||||
|
-fx-background-insets: 0 1 0 0, 1 2 1 1, 2 3 2 2;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
}
|
||||||
|
/* hover */
|
||||||
|
.table-view:cell-selection > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled > .table-cell:hover {
|
||||||
|
-fx-background-color: PRIMARY_L2;
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
-fx-background-insets: 0 0 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The column-resize-line is shown when the user is attempting to resize a column. */
|
||||||
|
.table-view .column-resize-line {
|
||||||
|
-fx-background-color: CONTROL_BG_ARMED;
|
||||||
|
-fx-padding: 0.0em 0.0416667em 0.0em 0.0416667em; /* 0 0.571429 0 0.571429 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the area behind the column headers. An ideal place to specify background
|
||||||
|
and border colors for the whole area (not individual column-header's). */
|
||||||
|
.table-view .column-header-background {
|
||||||
|
-fx-background-color: GRAY_7;
|
||||||
|
-fx-padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The column header row is made up of a number of column-header, one for each
|
||||||
|
TableColumn, and a 'filler' area that extends from the right-most column
|
||||||
|
to the edge of the tableview, or up to the 'column control' button. */
|
||||||
|
.table-view .column-header {
|
||||||
|
-fx-text-fill: TEXT_FILL;
|
||||||
|
-fx-font-size: 1.083333em; /* 13pt ; 1 more than the default font */
|
||||||
|
-fx-size: 24;
|
||||||
|
-fx-border-style: solid;
|
||||||
|
-fx-border-color:
|
||||||
|
CONTROL_BORDER_NORMAL
|
||||||
|
GRAY_5
|
||||||
|
GRAY_5
|
||||||
|
transparent;
|
||||||
|
-fx-border-insets: 0 0 0 0;
|
||||||
|
-fx-border-width: 0.083333em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view .column-header .label {
|
||||||
|
-fx-alignment: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-view .empty-table {
|
||||||
|
-fx-background-color: MAIN_BG;
|
||||||
|
-fx-font-size: 1.166667em; /* 14pt - 2 more than the default font */
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
|
||||||
|
<?import org.cryptomator.ui.controls.FormattedLabel?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.TableColumn?>
|
||||||
|
<?import javafx.scene.control.TableView?>
|
||||||
|
<?import javafx.scene.control.Tooltip?>
|
||||||
|
<?import javafx.scene.layout.HBox?>
|
||||||
|
<?import javafx.scene.layout.Region?>
|
||||||
|
<?import javafx.scene.layout.VBox?>
|
||||||
|
<VBox xmlns="http://javafx.com/javafx"
|
||||||
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
|
fx:controller="org.cryptomator.ui.decryptname.DecryptFileNamesViewController"
|
||||||
|
styleClass="decrypt-name-window"
|
||||||
|
minWidth="400"
|
||||||
|
maxWidth="400"
|
||||||
|
minHeight="145">
|
||||||
|
<HBox styleClass="button-bar" alignment="CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets left="6"/>
|
||||||
|
</padding>
|
||||||
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
|
<Button styleClass="button-right" contentDisplay="GRAPHIC_ONLY" onAction="#copyTableToClipboard">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="CLIPBOARD" glyphSize="16"/>
|
||||||
|
</graphic>
|
||||||
|
<tooltip>
|
||||||
|
<Tooltip text="%decryptNames.copyTable.tooltip"/>
|
||||||
|
</tooltip>
|
||||||
|
</Button>
|
||||||
|
<Button styleClass="button-right" contentDisplay="GRAPHIC_ONLY" onAction="#clearTable">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="TRASH" glyphSize="16"/>
|
||||||
|
</graphic>
|
||||||
|
<tooltip>
|
||||||
|
<Tooltip text="%decryptNames.clearTable.tooltip"/>
|
||||||
|
</tooltip>
|
||||||
|
</Button>
|
||||||
|
</HBox>
|
||||||
|
<TableView fx:id="cipherToCleartextTable" VBox.vgrow="ALWAYS">
|
||||||
|
<placeholder>
|
||||||
|
<Button alignment="CENTER" onAction="#selectFiles" text="${controller.dropZoneText}" contentDisplay="TOP" maxWidth="Infinity" maxHeight="Infinity">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="${controller.dropZoneIcon}" glyphSize="16"/>
|
||||||
|
</graphic>
|
||||||
|
</Button>
|
||||||
|
</placeholder>
|
||||||
|
<columns>
|
||||||
|
<TableColumn fx:id="ciphertextColumn" prefWidth="${cipherToCleartextTable.width * 0.5}">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="LOCK"/>
|
||||||
|
</graphic>
|
||||||
|
</TableColumn>
|
||||||
|
<TableColumn fx:id="cleartextColumn" prefWidth="${cipherToCleartextTable.width * 0.5}">
|
||||||
|
<graphic>
|
||||||
|
<FontAwesome5IconView glyph="LOCK_OPEN"/>
|
||||||
|
</graphic>
|
||||||
|
</TableColumn>
|
||||||
|
</columns>
|
||||||
|
</TableView>
|
||||||
|
<HBox>
|
||||||
|
<padding>
|
||||||
|
<Insets topRightBottomLeft="6"/>
|
||||||
|
</padding>
|
||||||
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
|
<FormattedLabel styleClass="label-small" format="%decryptNames.copyHint" arg1="${controller.copyToClipboardShortcutString}"/>
|
||||||
|
</HBox>
|
||||||
|
</VBox>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<padding>
|
<padding>
|
||||||
<Insets left="6" />
|
<Insets left="6" />
|
||||||
</padding>
|
</padding>
|
||||||
<ChoiceBox fx:id="vaultFilterChoiceBox"/>
|
<ChoiceBox fx:id="vaultFilterChoiceBox" minWidth="42"/>
|
||||||
<Region HBox.hgrow="ALWAYS"/>
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
<Button styleClass="button-right" onAction="#clearEvents" contentDisplay="GRAPHIC_ONLY">
|
<Button styleClass="button-right" onAction="#clearEvents" contentDisplay="GRAPHIC_ONLY">
|
||||||
<graphic>
|
<graphic>
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
<Tooltip text="%main.vaultDetail.locateEncryptedFileBtn.tooltip"/>
|
<Tooltip text="%main.vaultDetail.locateEncryptedFileBtn.tooltip"/>
|
||||||
</tooltip>
|
</tooltip>
|
||||||
</Button>
|
</Button>
|
||||||
|
<!-- TODO: instead of showing a button, show on error a small dialog and if copied, show a tooltip -->
|
||||||
<Button styleClass="drag-n-drop" text="%main.vaultDetail.encryptedPathsCopied" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#chooseDecryptedFileAndReveal" contentDisplay="TOP" visible="${controller.ciphertextPathsCopied}" managed="${controller.ciphertextPathsCopied}">
|
<Button styleClass="drag-n-drop" text="%main.vaultDetail.encryptedPathsCopied" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#chooseDecryptedFileAndReveal" contentDisplay="TOP" visible="${controller.ciphertextPathsCopied}" managed="${controller.ciphertextPathsCopied}">
|
||||||
<graphic>
|
<graphic>
|
||||||
<FontAwesome5IconView glyph="CHECK" glyphSize="15"/>
|
<FontAwesome5IconView glyph="CHECK" glyphSize="15"/>
|
||||||
@@ -65,25 +66,14 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</StackPane>
|
</StackPane>
|
||||||
<!-- decrypt file name -->
|
<!-- decrypt file name -->
|
||||||
<StackPane>
|
<Button fx:id="decryptNameDropZone" styleClass="drag-n-drop" text="%main.vaultDetail.decryptName.buttonLabel" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#showDecryptNameWindow" contentDisplay="TOP">
|
||||||
<padding>
|
<graphic>
|
||||||
<Insets topRightBottomLeft="0"/>
|
<Text styleClass="cryptic-text" text="101010 → abc"/>
|
||||||
</padding>
|
</graphic>
|
||||||
<Button fx:id="decryptNameDropZone" styleClass="drag-n-drop" text="%main.vaultDetail.decryptName.buttonLabel" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#chooseEncryptedFileAndCopyNames" contentDisplay="TOP" visible="${!controller.cleartextNamesCopied}" managed="${!controller.cleartextNamesCopied}">
|
<tooltip>
|
||||||
<graphic>
|
<Tooltip text="%main.vaultDetail.decryptName.tooltip"/>
|
||||||
<Text styleClass="cryptic-text" text="101010 → abc"/>
|
</tooltip>
|
||||||
</graphic>
|
</Button>
|
||||||
<tooltip>
|
|
||||||
<Tooltip text="%main.vaultDetail.decryptName.tooltip"/>
|
|
||||||
</tooltip>
|
|
||||||
</Button>
|
|
||||||
<Button styleClass="drag-n-drop" text="%main.vaultDetail.decryptName.copied" minWidth="120" maxWidth="180" prefHeight="72" wrapText="true" textAlignment="CENTER" onAction="#chooseEncryptedFileAndCopyNames" contentDisplay="TOP" visible="${controller.cleartextNamesCopied}" managed="${controller.cleartextNamesCopied}">
|
|
||||||
<graphic>
|
|
||||||
<FontAwesome5IconView glyph="CHECK" glyphSize="15"/>
|
|
||||||
</graphic>
|
|
||||||
</Button>
|
|
||||||
</StackPane>
|
|
||||||
|
|
||||||
<Region HBox.hgrow="ALWAYS"/>
|
<Region HBox.hgrow="ALWAYS"/>
|
||||||
|
|
||||||
<Button text="%main.vaultDetail.stats" minWidth="120" onAction="#showVaultStatistics" contentDisplay="BOTTOM" prefHeight="72">
|
<Button text="%main.vaultDetail.stats" minWidth="120" onAction="#showVaultStatistics" contentDisplay="BOTTOM" prefHeight="72">
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
<?import javafx.scene.layout.StackPane?>
|
<?import javafx.scene.layout.StackPane?>
|
||||||
<?import javafx.scene.layout.VBox?>
|
<?import javafx.scene.layout.VBox?>
|
||||||
<?import javafx.scene.shape.Arc?>
|
<?import javafx.scene.shape.Arc?>
|
||||||
|
<?import javafx.scene.shape.Circle?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.shape.Rectangle?>
|
||||||
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
<StackPane xmlns:fx="http://javafx.com/fxml"
|
<StackPane xmlns:fx="http://javafx.com/fxml"
|
||||||
xmlns="http://javafx.com/javafx"
|
xmlns="http://javafx.com/javafx"
|
||||||
fx:id="root"
|
fx:id="root"
|
||||||
@@ -51,7 +55,9 @@
|
|||||||
<Tooltip text="%main.vaultlist.showEventsButton.tooltip"/>
|
<Tooltip text="%main.vaultlist.showEventsButton.tooltip"/>
|
||||||
</tooltip>
|
</tooltip>
|
||||||
</Button>
|
</Button>
|
||||||
<Region styleClass="update-indicator" visible="${controller.newEventsPresent}" mouseTransparent="true" StackPane.alignment="TOP_RIGHT" prefWidth="12" prefHeight="12" maxWidth="-Infinity" maxHeight="-Infinity"/>
|
<AnchorPane mouseTransparent="true" minWidth="12" maxWidth="12" minHeight="12" maxHeight="12" StackPane.alignment="CENTER">
|
||||||
|
<Circle radius="4" styleClass="icon-update-indicator" AnchorPane.topAnchor="-8" AnchorPane.rightAnchor="-6" visible="${controller.unreadEventsPresent}" />
|
||||||
|
</AnchorPane>
|
||||||
</StackPane>
|
</StackPane>
|
||||||
<Button onMouseClicked="#showPreferences" styleClass="button-right" alignment="CENTER" minWidth="20" contentDisplay="GRAPHIC_ONLY">
|
<Button onMouseClicked="#showPreferences" styleClass="button-right" alignment="CENTER" minWidth="20" contentDisplay="GRAPHIC_ONLY">
|
||||||
<graphic>
|
<graphic>
|
||||||
|
|||||||
@@ -427,9 +427,7 @@ main.vaultDetail.locateEncryptedFileBtn.tooltip=Choose a file from your vault to
|
|||||||
main.vaultDetail.encryptedPathsCopied=Paths Copied to Clipboard!
|
main.vaultDetail.encryptedPathsCopied=Paths Copied to Clipboard!
|
||||||
main.vaultDetail.locateEncrypted.filePickerTitle=Select File Inside Vault
|
main.vaultDetail.locateEncrypted.filePickerTitle=Select File Inside Vault
|
||||||
main.vaultDetail.decryptName.buttonLabel=Decrypt File Name
|
main.vaultDetail.decryptName.buttonLabel=Decrypt File Name
|
||||||
main.vaultDetail.decryptName.filePickerTitle=Select encrypted file
|
|
||||||
main.vaultDetail.decryptName.tooltip=Choose an encrypted vault file to decrypt its name
|
main.vaultDetail.decryptName.tooltip=Choose an encrypted vault file to decrypt its name
|
||||||
main.vaultDetail.decryptName.copied=Names copied to clipboard!
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator could not find a vault at this path.
|
main.vaultDetail.missing.info=Cryptomator could not find a vault at this path.
|
||||||
main.vaultDetail.missing.recheck=Recheck
|
main.vaultDetail.missing.recheck=Recheck
|
||||||
@@ -585,12 +583,25 @@ shareVault.hub.instruction.1=1. Share access of the encrypted vault folder via c
|
|||||||
shareVault.hub.instruction.2=2. Grant access to team member in Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Grant access to team member in Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Open Cryptomator Hub
|
shareVault.hub.openHub=Open Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
decryptNames.title=Decrypt File Names
|
||||||
|
decryptNames.filePicker.title=Select encrypted file
|
||||||
|
decryptNames.filePicker.extensionDescription=Cryptomator encrypted file
|
||||||
|
decryptNames.copyTable.tooltip=Copy table
|
||||||
|
decryptNames.clearTable.tooltip=Clear table
|
||||||
|
decryptNames.copyHint=Copy cell content with %s
|
||||||
|
decryptNames.dropZone.message=Drop files or click to select
|
||||||
|
decryptNames.dropZone.error.vaultInternalFiles=Vault internal files with no decrypt-able name selected
|
||||||
|
decryptNames.dropZone.error.foreignFiles=Files do not belong to vault "%s"
|
||||||
|
decryptNames.dropZone.error.noDirIdBackup=Directory of selected files does not contain dirId.c9r file
|
||||||
|
decryptNames.dropZone.error.generic=Failed to decrypt file names
|
||||||
|
|
||||||
|
|
||||||
# Event View
|
# Event View
|
||||||
eventView.title=Events
|
eventView.title=Events
|
||||||
eventView.filter.allVaults=All
|
eventView.filter.allVaults=All
|
||||||
eventView.clearListButton.tooltip=Dismiss all
|
eventView.clearListButton.tooltip=Clear list
|
||||||
## event list entries
|
## event list entries
|
||||||
eventView.entry.vaultLocked.message=***********
|
|
||||||
eventView.entry.vaultLocked.description=Unlock "%s" for details
|
eventView.entry.vaultLocked.description=Unlock "%s" for details
|
||||||
eventView.entry.conflictResolved.message=Resolved conflict
|
eventView.entry.conflictResolved.message=Resolved conflict
|
||||||
eventView.entry.conflictResolved.showDecrypted=Show decrypted file
|
eventView.entry.conflictResolved.showDecrypted=Show decrypted file
|
||||||
|
|||||||
@@ -121,3 +121,10 @@
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=تجاهل
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=تطبيق
|
generic.button.apply=تطبيق
|
||||||
generic.button.back=رجوع
|
generic.button.back=رجوع
|
||||||
@@ -176,6 +177,7 @@ hub.registerFailed.description.generic=حدث خطأ في عملية تسجيل
|
|||||||
hub.registerFailed.description.deviceAlreadyExists=هذا الجهاز مسجل لمستخدم مختلف بالفعل. حاول تغيير حساب المستخدم أو استخدام جهاز مختلف.
|
hub.registerFailed.description.deviceAlreadyExists=هذا الجهاز مسجل لمستخدم مختلف بالفعل. حاول تغيير حساب المستخدم أو استخدام جهاز مختلف.
|
||||||
### Unauthorized
|
### Unauthorized
|
||||||
hub.unauthorized.message=تم رفض الوصول
|
hub.unauthorized.message=تم رفض الوصول
|
||||||
|
hub.unauthorized.description=غير مسموح لك بفتح هذا المستودع. اتصل بمالك المستودع لطلب الوصول.
|
||||||
### Requires Account Initialization
|
### Requires Account Initialization
|
||||||
hub.requireAccountInit.message=مطلوب اتخاذ إجراء
|
hub.requireAccountInit.message=مطلوب اتخاذ إجراء
|
||||||
hub.requireAccountInit.description.0=للمتابعة، يرجى إكمال الخطوات المطلوبة في
|
hub.requireAccountInit.description.0=للمتابعة، يرجى إكمال الخطوات المطلوبة في
|
||||||
@@ -281,7 +283,7 @@ preferences.title=تفضيلات
|
|||||||
## General
|
## General
|
||||||
preferences.general=عام
|
preferences.general=عام
|
||||||
preferences.general.startHidden=إخفاء النافذة عند بدء تشغيل Cryptomator
|
preferences.general.startHidden=إخفاء النافذة عند بدء تشغيل Cryptomator
|
||||||
preferences.general.autoCloseVaults=اقفل الخزانات المفتوحة تلقائياً عند الإقلاع عن التطبيق
|
preferences.general.autoCloseVaults=اقفل المخازن دون السؤال عند الإقلاع عن التطبيق
|
||||||
preferences.general.debugLogging=تمكين سجلات التصحيح
|
preferences.general.debugLogging=تمكين سجلات التصحيح
|
||||||
preferences.general.debugDirectory=عرض ملفات السجل
|
preferences.general.debugDirectory=عرض ملفات السجل
|
||||||
preferences.general.autoStart=تشغيل Cryptomator عند بدء تشغيل النظام
|
preferences.general.autoStart=تشغيل Cryptomator عند بدء تشغيل النظام
|
||||||
@@ -421,7 +423,6 @@ main.vaultDetail.stats=إحصائيات الخزنة
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر
|
main.vaultDetail.locateEncryptedFileBtn=تحديد موقع الملف المشفر
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=اختر ملف من خزانتك لتحديد مكان نظيره المشفر
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=اختر ملف من خزانتك لتحديد مكان نظيره المشفر
|
||||||
main.vaultDetail.encryptedPathsCopied=تم نسخ مسارات الملفات إلى الحافظة!
|
main.vaultDetail.encryptedPathsCopied=تم نسخ مسارات الملفات إلى الحافظة!
|
||||||
main.vaultDetail.filePickerTitle=إختر الملف من الخزنة
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=لم يتمكن Cryptomator من العثور على خزنة في هذا المسار.
|
main.vaultDetail.missing.info=لم يتمكن Cryptomator من العثور على خزنة في هذا المسار.
|
||||||
main.vaultDetail.missing.recheck=إعادة الفحص
|
main.vaultDetail.missing.recheck=إعادة الفحص
|
||||||
@@ -552,6 +553,10 @@ dokanySupportEnd.description=نوع وحدة التخزين Dokany لم يعد
|
|||||||
dokanySupportEnd.preferencesBtn=فتح التفضيلات
|
dokanySupportEnd.preferencesBtn=فتح التفضيلات
|
||||||
|
|
||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
retryIfReadonly.title=الوصول إلى المخزن المقيّد
|
||||||
|
retryIfReadonly.message=لا يوجد وصول للكتابة إلى مجلد المخزن
|
||||||
|
retryIfReadonly.description=Cryptomator لا يمكنه الكتابة إلى دليل المخزن. يمكنك تغيير المخزن ليكون للقراءة فقط وحاول مرة أخرى. يمكن تعطيل هذا الخيار في خيارات المخزن.
|
||||||
|
retryIfReadonly.retry=غيّر وأعد المحاولة
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
shareVault.title=مشاركة الخزانة
|
shareVault.title=مشاركة الخزانة
|
||||||
@@ -572,3 +577,9 @@ shareVault.hub.description=لمشاركة محتوى الخزانة مع عضو
|
|||||||
shareVault.hub.instruction.1=1. شارك الوصول إلى مجلد الخزانة المشفر عبر التخزين السحابي.
|
shareVault.hub.instruction.1=1. شارك الوصول إلى مجلد الخزانة المشفر عبر التخزين السحابي.
|
||||||
shareVault.hub.instruction.2=2. امنح الوصول لعضو الفريق في Cryptomator Hub.
|
shareVault.hub.instruction.2=2. امنح الوصول لعضو الفريق في Cryptomator Hub.
|
||||||
shareVault.hub.openHub=زيارة Cryptomator Hub
|
shareVault.hub.openHub=زيارة Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Кире ҡаҡ
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Ҡуллан
|
generic.button.apply=Ҡуллан
|
||||||
generic.button.back=Артҡа
|
generic.button.back=Артҡа
|
||||||
@@ -269,7 +270,6 @@ preferences.title=Көйләүҙәр
|
|||||||
## General
|
## General
|
||||||
preferences.general=Дөйөм
|
preferences.general=Дөйөм
|
||||||
preferences.general.startHidden=Cryptomator башланған саҡта тәҙрәне йәшерергә
|
preferences.general.startHidden=Cryptomator башланған саҡта тәҙрәне йәшерергә
|
||||||
preferences.general.autoCloseVaults=Ҡушымтанан сыҡҡан ваҡытта һаҡлағыстарҙы автоматик рәүештә бикләргә
|
|
||||||
preferences.general.debugLogging=Төҙөкләндереү журналын асырға
|
preferences.general.debugLogging=Төҙөкләндереү журналын асырға
|
||||||
preferences.general.debugDirectory=Журнал файлдарын күрһәт
|
preferences.general.debugDirectory=Журнал файлдарын күрһәт
|
||||||
preferences.general.autoStart=Система стартында Cryptomator-ҙы эшләтеп ебәрергә
|
preferences.general.autoStart=Система стартында Cryptomator-ҙы эшләтеп ебәрергә
|
||||||
@@ -389,7 +389,6 @@ main.vaultDetail.stats=Һаҡлағыс статистикаһы
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Шифрланған файлды тап
|
main.vaultDetail.locateEncryptedFileBtn=Шифрланған файлды тап
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Шифрланған аналогын табыр өсөн һаҡлағыстан файл һайлағыҙ
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Шифрланған аналогын табыр өсөн һаҡлағыстан файл һайлағыҙ
|
||||||
main.vaultDetail.encryptedPathsCopied=Юлдарҙын Clipboard-ҡа күсермәһе алынды!
|
main.vaultDetail.encryptedPathsCopied=Юлдарҙын Clipboard-ҡа күсермәһе алынды!
|
||||||
main.vaultDetail.filePickerTitle=Һаҡлағыс эсендә файл һайлау
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator был юлдан һаҡлағыс таба алманы.
|
main.vaultDetail.missing.info=Cryptomator был юлдан һаҡлағыс таба алманы.
|
||||||
main.vaultDetail.missing.recheck=Яңынан тикшер
|
main.vaultDetail.missing.recheck=Яңынан тикшер
|
||||||
@@ -518,3 +517,10 @@ dokanySupportEnd.preferencesBtn=Көйләүҙәрҙе ас
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Адхіліць
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Ужыць
|
generic.button.apply=Ужыць
|
||||||
generic.button.back=Назад
|
generic.button.back=Назад
|
||||||
@@ -258,7 +259,6 @@ preferences.title=Налады
|
|||||||
## General
|
## General
|
||||||
preferences.general=Агульныя
|
preferences.general=Агульныя
|
||||||
preferences.general.startHidden=Хаваць акно пры запуску Cryptomator
|
preferences.general.startHidden=Хаваць акно пры запуску Cryptomator
|
||||||
preferences.general.autoCloseVaults=Замыкаць адчыненыя скарбніцы аўтаматычна пры выхадзе з праграмы
|
|
||||||
preferences.general.debugLogging=Уключыць пратакаляванне адладкі
|
preferences.general.debugLogging=Уключыць пратакаляванне адладкі
|
||||||
preferences.general.debugDirectory=Паказаць файлы пратаколу
|
preferences.general.debugDirectory=Паказаць файлы пратаколу
|
||||||
preferences.general.autoStart=Запускаць Cryptomator падчас запуску сістэмы
|
preferences.general.autoStart=Запускаць Cryptomator падчас запуску сістэмы
|
||||||
@@ -376,7 +376,6 @@ main.vaultDetail.stats=Статыстыка скарбніцы
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Знайсці зашыфраваны файл
|
main.vaultDetail.locateEncryptedFileBtn=Знайсці зашыфраваны файл
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Абяры файл у тваёй скрабніцы, каб знайсці ягоны зашыфраваны адпаведнік
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Абяры файл у тваёй скрабніцы, каб знайсці ягоны зашыфраваны адпаведнік
|
||||||
main.vaultDetail.encryptedPathsCopied=Шлях скапіяваны ў буфер абмену!
|
main.vaultDetail.encryptedPathsCopied=Шлях скапіяваны ў буфер абмену!
|
||||||
main.vaultDetail.filePickerTitle=Абраць файл унутры скарбніцы
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator ня змог знайсці скарбніцу па гэтай сцежцы.
|
main.vaultDetail.missing.info=Cryptomator ня змог знайсці скарбніцу па гэтай сцежцы.
|
||||||
main.vaultDetail.missing.recheck=Пераправерыць
|
main.vaultDetail.missing.recheck=Пераправерыць
|
||||||
@@ -498,3 +497,10 @@ dokanySupportEnd.preferencesBtn=Адчыніць налады
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Отхвърляне
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Прилагане
|
generic.button.apply=Прилагане
|
||||||
generic.button.back=Назад
|
generic.button.back=Назад
|
||||||
@@ -269,11 +270,11 @@ preferences.title=Настройки
|
|||||||
## General
|
## General
|
||||||
preferences.general=Общи
|
preferences.general=Общи
|
||||||
preferences.general.startHidden=Скриване на прозореца при отваряне на Криптоматор
|
preferences.general.startHidden=Скриване на прозореца при отваряне на Криптоматор
|
||||||
preferences.general.autoCloseVaults=Заключване на хранилищата при затваряне на приложението
|
|
||||||
preferences.general.debugLogging=Дневник за отстраняване на дефекти
|
preferences.general.debugLogging=Дневник за отстраняване на дефекти
|
||||||
preferences.general.debugDirectory=Файлове на дневниците
|
preferences.general.debugDirectory=Файлове на дневниците
|
||||||
preferences.general.autoStart=Отваряне на Криптоматор при старт на системата
|
preferences.general.autoStart=Отваряне на Криптоматор при старт на системата
|
||||||
preferences.general.keychainBackend=Съхраняванеа паролите в
|
preferences.general.keychainBackend=Съхраняванеа паролите в
|
||||||
|
preferences.general.quickAccessService=Добавяне на отключените хранилища в зоната за бърз достъп
|
||||||
## Interface
|
## Interface
|
||||||
preferences.interface=Външен вид
|
preferences.interface=Външен вид
|
||||||
preferences.interface.theme=Тема
|
preferences.interface.theme=Тема
|
||||||
@@ -389,7 +390,6 @@ main.vaultDetail.stats=Статистики на хранилището
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Намиране на шифровани файлове
|
main.vaultDetail.locateEncryptedFileBtn=Намиране на шифровани файлове
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Изберете файл от хранилището, за да бъде намерено шифрованото му копие
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Изберете файл от хранилището, за да бъде намерено шифрованото му копие
|
||||||
main.vaultDetail.encryptedPathsCopied=Пътищата са копирани!
|
main.vaultDetail.encryptedPathsCopied=Пътищата са копирани!
|
||||||
main.vaultDetail.filePickerTitle=Изберете файл от хранилището
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Криптоматор не намира хранилище на това място.
|
main.vaultDetail.missing.info=Криптоматор не намира хранилище на това място.
|
||||||
main.vaultDetail.missing.recheck=Повторен опит
|
main.vaultDetail.missing.recheck=Повторен опит
|
||||||
@@ -518,3 +518,10 @@ dokanySupportEnd.preferencesBtn=Към настройките
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -185,3 +185,10 @@ vaultOptions.mount.mountPoint.directoryPickerButton=নির্বাচন ক
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -321,3 +321,10 @@ quit.lockAndQuitBtn=Zaključaj i zatvori
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Descartar
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Aplica
|
generic.button.apply=Aplica
|
||||||
generic.button.back=Enrere
|
generic.button.back=Enrere
|
||||||
@@ -176,6 +177,7 @@ hub.registerFailed.description.generic=S'ha produït un error en el procés de r
|
|||||||
hub.registerFailed.description.deviceAlreadyExists=El dispositiu ja ha estat registrat per un altre usuari. Mireu de canviar el compte d'usuari o feu servir un dispositiu diferent.
|
hub.registerFailed.description.deviceAlreadyExists=El dispositiu ja ha estat registrat per un altre usuari. Mireu de canviar el compte d'usuari o feu servir un dispositiu diferent.
|
||||||
### Unauthorized
|
### Unauthorized
|
||||||
hub.unauthorized.message=Accés denegat
|
hub.unauthorized.message=Accés denegat
|
||||||
|
hub.unauthorized.description=No estàs autoritzat a obrir aquesta caixa forta. Contacta amb el seu propietari per obtenir accés.
|
||||||
### Requires Account Initialization
|
### Requires Account Initialization
|
||||||
hub.requireAccountInit.message=Acció necessària
|
hub.requireAccountInit.message=Acció necessària
|
||||||
hub.requireAccountInit.description.0=Per a continuar, si us plau, seguiu els passos necessaris en el vostre
|
hub.requireAccountInit.description.0=Per a continuar, si us plau, seguiu els passos necessaris en el vostre
|
||||||
@@ -281,7 +283,7 @@ preferences.title=Preferències
|
|||||||
## General
|
## General
|
||||||
preferences.general=General
|
preferences.general=General
|
||||||
preferences.general.startHidden=Amaga la finestra quan s'inicia Cryptomator
|
preferences.general.startHidden=Amaga la finestra quan s'inicia Cryptomator
|
||||||
preferences.general.autoCloseVaults=Bloquejar les caixes fortes automàticament quan surti de l'aplicació
|
preferences.general.autoCloseVaults=Bloca les caixes fortes sense preguntar-ho en sortir de l'aplicació
|
||||||
preferences.general.debugLogging=Habilita el registre de depuració
|
preferences.general.debugLogging=Habilita el registre de depuració
|
||||||
preferences.general.debugDirectory=Mostra els fitxers de registres
|
preferences.general.debugDirectory=Mostra els fitxers de registres
|
||||||
preferences.general.autoStart=Executa Cryptomator en engegar el sistema
|
preferences.general.autoStart=Executa Cryptomator en engegar el sistema
|
||||||
@@ -340,6 +342,7 @@ preferences.contribute.sponsor=Patrocinador
|
|||||||
|
|
||||||
### Remove License Key Dialog
|
### Remove License Key Dialog
|
||||||
removeCert.title=Suprimeix certificat
|
removeCert.title=Suprimeix certificat
|
||||||
|
removeCert.message=Eliminar certificat de col·laborador?
|
||||||
removeCert.description=Les característiques principals de Cryptomator no es veuen afectades per això. Ni l'accés a les vostres caixes fortes s'ha restringit ni el nivell de seguretat ha estat rebaixat.
|
removeCert.description=Les característiques principals de Cryptomator no es veuen afectades per això. Ni l'accés a les vostres caixes fortes s'ha restringit ni el nivell de seguretat ha estat rebaixat.
|
||||||
#<-- Add entries for donations and code/translation/documentation contribution -->
|
#<-- Add entries for donations and code/translation/documentation contribution -->
|
||||||
|
|
||||||
@@ -420,7 +423,6 @@ main.vaultDetail.stats=Estadístiques de la caixa forta
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Trobar fitxer xifrat
|
main.vaultDetail.locateEncryptedFileBtn=Trobar fitxer xifrat
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Esculli un fitxer de la caixa forta per trobar el seu homòleg xifrat
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Esculli un fitxer de la caixa forta per trobar el seu homòleg xifrat
|
||||||
main.vaultDetail.encryptedPathsCopied=Rutes copiades al porta-retalls!
|
main.vaultDetail.encryptedPathsCopied=Rutes copiades al porta-retalls!
|
||||||
main.vaultDetail.filePickerTitle=Seleccioni un fitxer dins la caixa forta
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator no ha trobat una caixa forta en aquesta ruta.
|
main.vaultDetail.missing.info=Cryptomator no ha trobat una caixa forta en aquesta ruta.
|
||||||
main.vaultDetail.missing.recheck=Torna a comprovar
|
main.vaultDetail.missing.recheck=Torna a comprovar
|
||||||
@@ -545,6 +547,9 @@ updateReminder.yesOnce=Sí, una vegada
|
|||||||
updateReminder.yesAutomatically=Sí, automàticament
|
updateReminder.yesAutomatically=Sí, automàticament
|
||||||
|
|
||||||
#Dokany Support End
|
#Dokany Support End
|
||||||
|
dokanySupportEnd.title=Avís d'obsolescència
|
||||||
|
dokanySupportEnd.message=Fi de la compatibilitat amb Dokany
|
||||||
|
dokanySupportEnd.description=El tipus de volum Dokany ja no és compatible amb Cryptomator. La teva configuració canviarà al tipus de volum predeterminat. Pots veure el tipus de volum predeterminat en la configuració.
|
||||||
dokanySupportEnd.preferencesBtn=Obrir les Preferències
|
dokanySupportEnd.preferencesBtn=Obrir les Preferències
|
||||||
|
|
||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
@@ -568,3 +573,9 @@ shareVault.hub.description=Per tal de compartir el contingut de la caixa forta a
|
|||||||
shareVault.hub.instruction.1=1. Compartiu l'accés a la carpeta via emmagatzematge en el núvol.
|
shareVault.hub.instruction.1=1. Compartiu l'accés a la carpeta via emmagatzematge en el núvol.
|
||||||
shareVault.hub.instruction.2=2. Doneu accés al membre de l'equip a Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Doneu accés al membre de l'equip a Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Obre Cryptomator Hub
|
shareVault.hub.openHub=Obre Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Zrušit
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Použít
|
generic.button.apply=Použít
|
||||||
generic.button.back=Zpět
|
generic.button.back=Zpět
|
||||||
@@ -272,7 +273,6 @@ preferences.title=Nastavení
|
|||||||
## General
|
## General
|
||||||
preferences.general=Obecné
|
preferences.general=Obecné
|
||||||
preferences.general.startHidden=Skrýt okno Cryptomatoru při spuštění
|
preferences.general.startHidden=Skrýt okno Cryptomatoru při spuštění
|
||||||
preferences.general.autoCloseVaults=Zamknout trezory automaticky při ukončení aplikace
|
|
||||||
preferences.general.debugLogging=Ladicí režim
|
preferences.general.debugLogging=Ladicí režim
|
||||||
preferences.general.debugDirectory=Ukázat soubory se záznamy událostí (log)
|
preferences.general.debugDirectory=Ukázat soubory se záznamy událostí (log)
|
||||||
preferences.general.autoStart=Spustit Cryptomator při spuštění systému
|
preferences.general.autoStart=Spustit Cryptomator při spuštění systému
|
||||||
@@ -390,7 +390,6 @@ main.vaultDetail.stats=Statistiky trezoru
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Najít šifrovaný soubor
|
main.vaultDetail.locateEncryptedFileBtn=Najít šifrovaný soubor
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Vyberte soubor z vašeho trezoru, abyste našli jeho šifrovaný protějšek
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Vyberte soubor z vašeho trezoru, abyste našli jeho šifrovaný protějšek
|
||||||
main.vaultDetail.encryptedPathsCopied=Cesta souboru byla zkopírována do schránky!
|
main.vaultDetail.encryptedPathsCopied=Cesta souboru byla zkopírována do schránky!
|
||||||
main.vaultDetail.filePickerTitle=Vyberte soubor uvnitř trezoru
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator nemohl najít trezor na této cestě.
|
main.vaultDetail.missing.info=Cryptomator nemohl najít trezor na této cestě.
|
||||||
main.vaultDetail.missing.recheck=Znovu zkontrolovat
|
main.vaultDetail.missing.recheck=Znovu zkontrolovat
|
||||||
@@ -535,3 +534,9 @@ shareVault.hub.description=Chcete-li sdílet obsah trezoru s jiným členem tým
|
|||||||
shareVault.hub.instruction.1=1. Sdílejte přístup ke šifrované složce trezoru prostřednictvím cloudového úložiště.
|
shareVault.hub.instruction.1=1. Sdílejte přístup ke šifrované složce trezoru prostřednictvím cloudového úložiště.
|
||||||
shareVault.hub.instruction.2=2. Udělte přístup členovi týmu v Cryptomator Hubu.
|
shareVault.hub.instruction.2=2. Udělte přístup členovi týmu v Cryptomator Hubu.
|
||||||
shareVault.hub.openHub=Otevřít Cryptomator Hub
|
shareVault.hub.openHub=Otevřít Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Luk
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Anvend
|
generic.button.apply=Anvend
|
||||||
generic.button.back=Tilbage
|
generic.button.back=Tilbage
|
||||||
@@ -282,7 +283,6 @@ preferences.title=Præferencer
|
|||||||
## General
|
## General
|
||||||
preferences.general=Generelt
|
preferences.general=Generelt
|
||||||
preferences.general.startHidden=Skjul vinduet når Cryptomator starter
|
preferences.general.startHidden=Skjul vinduet når Cryptomator starter
|
||||||
preferences.general.autoCloseVaults=Lås åbne bokse automatisk, når programmet afsluttes
|
|
||||||
preferences.general.debugLogging=Aktivér fejllogning
|
preferences.general.debugLogging=Aktivér fejllogning
|
||||||
preferences.general.debugDirectory=Vis logfiler
|
preferences.general.debugDirectory=Vis logfiler
|
||||||
preferences.general.autoStart=Start Cryptomator automatisk ved opstart
|
preferences.general.autoStart=Start Cryptomator automatisk ved opstart
|
||||||
@@ -407,7 +407,6 @@ main.vaultDetail.stats=Boks statistik
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Find Krypteret Fil
|
main.vaultDetail.locateEncryptedFileBtn=Find Krypteret Fil
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Vælg en fil fra din boks for at finde dens krypterede modpart
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Vælg en fil fra din boks for at finde dens krypterede modpart
|
||||||
main.vaultDetail.encryptedPathsCopied=Stier kopieret!
|
main.vaultDetail.encryptedPathsCopied=Stier kopieret!
|
||||||
main.vaultDetail.filePickerTitle=Vælg fil inde i boks
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator kunne ikke finde en boks på denne sti.
|
main.vaultDetail.missing.info=Cryptomator kunne ikke finde en boks på denne sti.
|
||||||
main.vaultDetail.missing.recheck=Kontrollér igen
|
main.vaultDetail.missing.recheck=Kontrollér igen
|
||||||
@@ -555,3 +554,9 @@ shareVault.hub.description=For at dele indholdet i boksen med et andet holdmedle
|
|||||||
shareVault.hub.instruction.1=1. Del adgang til den krypterede boks-mappe vha. opbevaring i skyen.
|
shareVault.hub.instruction.1=1. Del adgang til den krypterede boks-mappe vha. opbevaring i skyen.
|
||||||
shareVault.hub.instruction.2=2. Giv adgang til holdmedlem i Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Giv adgang til holdmedlem i Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Åben Cryptomator Hub
|
shareVault.hub.openHub=Åben Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Verwerfen
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Übernehmen
|
generic.button.apply=Übernehmen
|
||||||
generic.button.back=Zurück
|
generic.button.back=Zurück
|
||||||
@@ -176,6 +177,7 @@ hub.registerFailed.description.generic=Im Registrierungsprozess ist ein Fehler a
|
|||||||
hub.registerFailed.description.deviceAlreadyExists=Dieses Gerät ist bereits für einen anderen Benutzer registriert. Ändere das Benutzerkonto oder verwende ein anderes Gerät.
|
hub.registerFailed.description.deviceAlreadyExists=Dieses Gerät ist bereits für einen anderen Benutzer registriert. Ändere das Benutzerkonto oder verwende ein anderes Gerät.
|
||||||
### Unauthorized
|
### Unauthorized
|
||||||
hub.unauthorized.message=Zugriff verweigert
|
hub.unauthorized.message=Zugriff verweigert
|
||||||
|
hub.unauthorized.description=Du bist nicht berechtigt, diesen Tresor zu öffnen. Wende dich an den Tresoreigentümer, um Zugriff zu erhalten.
|
||||||
### Requires Account Initialization
|
### Requires Account Initialization
|
||||||
hub.requireAccountInit.message=Aktion erforderlich
|
hub.requireAccountInit.message=Aktion erforderlich
|
||||||
hub.requireAccountInit.description.0=Um fortzufahren, führe bitte die erforderlichen Schritte in deinem
|
hub.requireAccountInit.description.0=Um fortzufahren, führe bitte die erforderlichen Schritte in deinem
|
||||||
@@ -393,6 +395,7 @@ main.vaultlist.contextMenu.vaultoptions=Tresoroptionen anzeigen
|
|||||||
main.vaultlist.contextMenu.reveal=Laufwerk anzeigen
|
main.vaultlist.contextMenu.reveal=Laufwerk anzeigen
|
||||||
main.vaultlist.addVaultBtn.menuItemNew=Neuen Tresor erstellen...
|
main.vaultlist.addVaultBtn.menuItemNew=Neuen Tresor erstellen...
|
||||||
main.vaultlist.addVaultBtn.menuItemExisting=Bestehenden Tresor öffnen...
|
main.vaultlist.addVaultBtn.menuItemExisting=Bestehenden Tresor öffnen...
|
||||||
|
main.vaultlist.showEventsButton.tooltip=Ereignis-Ansicht öffnen
|
||||||
##Notificaition
|
##Notificaition
|
||||||
main.notification.updateAvailable=Eine neue Version ist verfügbar.
|
main.notification.updateAvailable=Eine neue Version ist verfügbar.
|
||||||
main.notification.support=Unterstütze Cryptomator.
|
main.notification.support=Unterstütze Cryptomator.
|
||||||
@@ -421,7 +424,9 @@ main.vaultDetail.stats=Tresorstatistik
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Verschlüsselte Datei finden
|
main.vaultDetail.locateEncryptedFileBtn=Verschlüsselte Datei finden
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Wähle eine Datei aus deinem Tresor aus, um das verschlüsselte Gegenstück zu finden
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Wähle eine Datei aus deinem Tresor aus, um das verschlüsselte Gegenstück zu finden
|
||||||
main.vaultDetail.encryptedPathsCopied=Pfade in Zwischenablage kopiert!
|
main.vaultDetail.encryptedPathsCopied=Pfade in Zwischenablage kopiert!
|
||||||
main.vaultDetail.filePickerTitle=Datei im Tresor auswählen
|
main.vaultDetail.locateEncrypted.filePickerTitle=Datei im Tresor auswählen
|
||||||
|
main.vaultDetail.decryptName.buttonLabel=Dateiname entschlüsseln
|
||||||
|
main.vaultDetail.decryptName.tooltip=Wählen eine verschlüsselte Tresordatei, um ihren Namen zu entschlüsseln
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator konnte keinen Tresor mit diesem Pfad finden.
|
main.vaultDetail.missing.info=Cryptomator konnte keinen Tresor mit diesem Pfad finden.
|
||||||
main.vaultDetail.missing.recheck=Erneut prüfen
|
main.vaultDetail.missing.recheck=Erneut prüfen
|
||||||
@@ -552,6 +557,10 @@ dokanySupportEnd.description=Der Laufwerkstyp Dokany wird von Cryptomator nicht
|
|||||||
dokanySupportEnd.preferencesBtn=Einstellungen öffnen
|
dokanySupportEnd.preferencesBtn=Einstellungen öffnen
|
||||||
|
|
||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
retryIfReadonly.title=Eingeschränkter Tresorzugriff
|
||||||
|
retryIfReadonly.message=Kein Schreibzugriff auf Tresor
|
||||||
|
retryIfReadonly.description=Cryptomator kann nicht in das Verzeichnis des Tresors schreiben. Du kannst den Tresor auf schreibgeschützt umstellen und es erneut versuchen. Diese Option kann in den Tresoroptionen deaktiviert werden.
|
||||||
|
retryIfReadonly.retry=Ändern und wiederholen
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
shareVault.title=Tresor teilen
|
shareVault.title=Tresor teilen
|
||||||
@@ -572,3 +581,42 @@ shareVault.hub.description=Zur Freigabe des Tresorinhalts für ein anderes Teamm
|
|||||||
shareVault.hub.instruction.1=1. Teile den Zugriff auf den verschlüsselten Tresorordner über den Cloud-Speicher.
|
shareVault.hub.instruction.1=1. Teile den Zugriff auf den verschlüsselten Tresorordner über den Cloud-Speicher.
|
||||||
shareVault.hub.instruction.2=2. Füge das Teammitglied in Cryptomator Hub als Tresormitglied hinzu.
|
shareVault.hub.instruction.2=2. Füge das Teammitglied in Cryptomator Hub als Tresormitglied hinzu.
|
||||||
shareVault.hub.openHub=Cryptomator Hub öffnen
|
shareVault.hub.openHub=Cryptomator Hub öffnen
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
decryptNames.title=Dateinamen entschlüsseln
|
||||||
|
decryptNames.filePicker.title=Verschlüsselte Datei auswählen
|
||||||
|
decryptNames.filePicker.extensionDescription=Cryptomator-verschlüsselte Datei
|
||||||
|
decryptNames.copyTable.tooltip=Tabelle kopieren
|
||||||
|
decryptNames.clearTable.tooltip=Tabelle leeren
|
||||||
|
decryptNames.copyHint=Inhalt der Zelle mit %s kopieren
|
||||||
|
decryptNames.dropZone.message=Dateien ablegen oder zum Auswählen klicken
|
||||||
|
decryptNames.dropZone.error.vaultInternalFiles=Tresor interne Dateien mit nicht-entschlüsselbaren Namen ausgewählt
|
||||||
|
decryptNames.dropZone.error.foreignFiles=Dateien gehören nicht zum Tresor "%s"
|
||||||
|
decryptNames.dropZone.error.noDirIdBackup=Verzeichnis der ausgewählten Dateien enthält keine dirId.c9r Datei
|
||||||
|
decryptNames.dropZone.error.generic=Fehler beim Entschlüsseln der Dateinamen
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
eventView.title=Ereignisse
|
||||||
|
eventView.filter.allVaults=Alle
|
||||||
|
eventView.clearListButton.tooltip=Liste leeren
|
||||||
|
## event list entries
|
||||||
|
eventView.entry.vaultLocked.description=Entsperre "%s" für Details
|
||||||
|
eventView.entry.conflictResolved.message=Konflikt gelöst
|
||||||
|
eventView.entry.conflictResolved.showDecrypted=Entschlüsselte Datei anzeigen
|
||||||
|
eventView.entry.conflictResolved.copyDecrypted=Pfad der entschlüsselten Datei kopieren
|
||||||
|
eventView.entry.conflict.message=Konfliktlösung fehlgeschlagen
|
||||||
|
eventView.entry.conflict.showDecrypted=Entschlüsselte, ursprüngliche Datei anzeigen
|
||||||
|
eventView.entry.conflict.copyDecrypted=Entschlüsselten, ursprünglicher Pfad kopieren
|
||||||
|
eventView.entry.conflict.showEncrypted=Zeige verschlüsselte Konfliktdatei
|
||||||
|
eventView.entry.conflict.copyEncrypted=Verschlüsselten Konfliktpfad kopieren
|
||||||
|
eventView.entry.decryptionFailed.message=Entschlüsselung fehlgeschlagen
|
||||||
|
eventView.entry.decryptionFailed.showEncrypted=Verschlüsselte Datei anzeigen
|
||||||
|
eventView.entry.decryptionFailed.copyEncrypted=Pfad der verschlüsselten Datei kopieren
|
||||||
|
eventView.entry.brokenDirFile.message=Ungültiger Verzeichnislink
|
||||||
|
eventView.entry.brokenDirFile.showEncrypted=Defekten, verschlüsselten Link anzeigen
|
||||||
|
eventView.entry.brokenDirFile.copyEncrypted=Pfad des ungültigen Links kopieren
|
||||||
|
eventView.entry.brokenFileNode.message=Fehlender Dateisystemknoten
|
||||||
|
eventView.entry.brokenFileNode.showEncrypted=Beschädigten, verschlüsselten Knoten anzeigen
|
||||||
|
eventView.entry.brokenFileNode.copyEncrypted=Pfad des kaputten, verschlüsselten Knotens kopieren
|
||||||
|
eventView.entry.brokenFileNode.copyDecrypted=Pfad der entschlüsselten Datei kopieren
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Παράβλεψη
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Εφαρμογή
|
generic.button.apply=Εφαρμογή
|
||||||
generic.button.back=Πίσω
|
generic.button.back=Πίσω
|
||||||
@@ -282,7 +283,7 @@ preferences.title=Προτιμήσεις
|
|||||||
## General
|
## General
|
||||||
preferences.general=Γενικά
|
preferences.general=Γενικά
|
||||||
preferences.general.startHidden=Απόκρυψη παραθύρου όταν ξεκινά το Cryptomator
|
preferences.general.startHidden=Απόκρυψη παραθύρου όταν ξεκινά το Cryptomator
|
||||||
preferences.general.autoCloseVaults=Αυτόματο κλείδωμα ανοιγμένης κρύπτης κατά την έξοδο της εφαρμογής
|
preferences.general.autoCloseVaults=Κλείδωμα κρυπτών χωρίς ερώτηση κατά την έξοδο από την εφαρμογή
|
||||||
preferences.general.debugLogging=Ενεργοποίηση καταγραφής σφαλμάτων
|
preferences.general.debugLogging=Ενεργοποίηση καταγραφής σφαλμάτων
|
||||||
preferences.general.debugDirectory=Αποκάλυψη αρχείων καταγραφής
|
preferences.general.debugDirectory=Αποκάλυψη αρχείων καταγραφής
|
||||||
preferences.general.autoStart=Εκκίνηση Cryptomator στην εκκίνηση του συστήματος
|
preferences.general.autoStart=Εκκίνηση Cryptomator στην εκκίνηση του συστήματος
|
||||||
@@ -422,7 +423,6 @@ main.vaultDetail.stats=Στατιστικά Vault
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Εντοπισμός Κρυπτογραφημένου Αρχείου
|
main.vaultDetail.locateEncryptedFileBtn=Εντοπισμός Κρυπτογραφημένου Αρχείου
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Επιλέξτε ένα αρχείο από την κρύπτη σας για να εντοπίσετε το κρυπτογραφημένο αντίστοιχο
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Επιλέξτε ένα αρχείο από την κρύπτη σας για να εντοπίσετε το κρυπτογραφημένο αντίστοιχο
|
||||||
main.vaultDetail.encryptedPathsCopied=Οι Διαδρομές Αντιγράφηκαν στο Πρόχειρο!
|
main.vaultDetail.encryptedPathsCopied=Οι Διαδρομές Αντιγράφηκαν στο Πρόχειρο!
|
||||||
main.vaultDetail.filePickerTitle=Επιλογή Αρχείου Μέσα Στην Κρύπτη
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator δεν βρήκε vault σε αυτόν τον κατάλογο.
|
main.vaultDetail.missing.info=Cryptomator δεν βρήκε vault σε αυτόν τον κατάλογο.
|
||||||
main.vaultDetail.missing.recheck=Επανέλεγχος
|
main.vaultDetail.missing.recheck=Επανέλεγχος
|
||||||
@@ -577,3 +577,10 @@ shareVault.hub.description=Για να μοιραστείτε το περιεχ
|
|||||||
shareVault.hub.instruction.1=1. Μοιραστείτε την πρόσβαση στον κρυπτογραφημένο φάκελο κρύπτης μέσω του χώρου αποθήκευσης στο cloud.
|
shareVault.hub.instruction.1=1. Μοιραστείτε την πρόσβαση στον κρυπτογραφημένο φάκελο κρύπτης μέσω του χώρου αποθήκευσης στο cloud.
|
||||||
shareVault.hub.instruction.2=2. Παραχωρήστε πρόσβαση σε μέλος της ομάδας στο Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Παραχωρήστε πρόσβαση σε μέλος της ομάδας στο Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Ανοίξτε το Cryptomator Hub
|
shareVault.hub.openHub=Ανοίξτε το Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
eventView.filter.allVaults=Όλες
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Descartar
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Aplicar
|
generic.button.apply=Aplicar
|
||||||
generic.button.back=Volver
|
generic.button.back=Volver
|
||||||
@@ -282,7 +283,7 @@ preferences.title=Preferencias
|
|||||||
## General
|
## General
|
||||||
preferences.general=General
|
preferences.general=General
|
||||||
preferences.general.startHidden=Ocultar ventana al iniciar Cryptomator
|
preferences.general.startHidden=Ocultar ventana al iniciar Cryptomator
|
||||||
preferences.general.autoCloseVaults=Bloquear automáticamente las bóvedas abiertas al salir de la aplicación
|
preferences.general.autoCloseVaults=Bloquear bóvedas sin preguntar al salir de la aplicación
|
||||||
preferences.general.debugLogging=Habilitar registro de depuración
|
preferences.general.debugLogging=Habilitar registro de depuración
|
||||||
preferences.general.debugDirectory=Revelar archivos de registro
|
preferences.general.debugDirectory=Revelar archivos de registro
|
||||||
preferences.general.autoStart=Cargar Cryptomator al iniciar el sistema
|
preferences.general.autoStart=Cargar Cryptomator al iniciar el sistema
|
||||||
@@ -394,6 +395,7 @@ main.vaultlist.contextMenu.vaultoptions=Mostrar opciones de la bóveda
|
|||||||
main.vaultlist.contextMenu.reveal=Revelar unidad
|
main.vaultlist.contextMenu.reveal=Revelar unidad
|
||||||
main.vaultlist.addVaultBtn.menuItemNew=Crear Bóveda Nueva...
|
main.vaultlist.addVaultBtn.menuItemNew=Crear Bóveda Nueva...
|
||||||
main.vaultlist.addVaultBtn.menuItemExisting=Abrir Bóveda Existente...
|
main.vaultlist.addVaultBtn.menuItemExisting=Abrir Bóveda Existente...
|
||||||
|
main.vaultlist.showEventsButton.tooltip=Abrir vista de evento
|
||||||
##Notificaition
|
##Notificaition
|
||||||
main.notification.updateAvailable=Existen actualizaciones disponibles.
|
main.notification.updateAvailable=Existen actualizaciones disponibles.
|
||||||
main.notification.support=Soporte de Cryptomator.
|
main.notification.support=Soporte de Cryptomator.
|
||||||
@@ -422,7 +424,9 @@ main.vaultDetail.stats=Estadísticas de la bóveda
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Ubicar archivo cifrado
|
main.vaultDetail.locateEncryptedFileBtn=Ubicar archivo cifrado
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Elija un archivo de su bóveda para ubicar su contraparte cifrada
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Elija un archivo de su bóveda para ubicar su contraparte cifrada
|
||||||
main.vaultDetail.encryptedPathsCopied=¡Rutas copiadas al portapapeles!
|
main.vaultDetail.encryptedPathsCopied=¡Rutas copiadas al portapapeles!
|
||||||
main.vaultDetail.filePickerTitle=Seleccionar archivo dentro de la bóveda
|
main.vaultDetail.locateEncrypted.filePickerTitle=Seleccionar archivo dentro de la bóveda
|
||||||
|
main.vaultDetail.decryptName.buttonLabel=Descifrar nombre de archivo
|
||||||
|
main.vaultDetail.decryptName.tooltip=Elija un archivo de bóveda cifrado para descifrar su nombre
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator no pudo encontrar una bóveda en esta ruta.
|
main.vaultDetail.missing.info=Cryptomator no pudo encontrar una bóveda en esta ruta.
|
||||||
main.vaultDetail.missing.recheck=Volver a comprobar
|
main.vaultDetail.missing.recheck=Volver a comprobar
|
||||||
@@ -577,3 +581,42 @@ shareVault.hub.description=Para compartir el contenido de la bóveda con otro mi
|
|||||||
shareVault.hub.instruction.1=1. Comparta el acceso a la carpeta de la bóveda cifrada a través del almacenamiento en la nube.
|
shareVault.hub.instruction.1=1. Comparta el acceso a la carpeta de la bóveda cifrada a través del almacenamiento en la nube.
|
||||||
shareVault.hub.instruction.2=2. Conceda el acceso al miembro del equipo en Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Conceda el acceso al miembro del equipo en Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Abrir Cryptomator Hub
|
shareVault.hub.openHub=Abrir Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
decryptNames.title=Descifrar nombre de archivos
|
||||||
|
decryptNames.filePicker.title=Seleccione archivo cifrado
|
||||||
|
decryptNames.filePicker.extensionDescription=Archivo cifrado Cryptomator
|
||||||
|
decryptNames.copyTable.tooltip=Copiar tabla
|
||||||
|
decryptNames.clearTable.tooltip=Limpiar tabla
|
||||||
|
decryptNames.copyHint=Copiar contenido de celda con %s
|
||||||
|
decryptNames.dropZone.message=Soltar archivos o hacer clic para seleccionar
|
||||||
|
decryptNames.dropZone.error.vaultInternalFiles=Archivos internos de la bóveda sin nombre descifrable seleccionado
|
||||||
|
decryptNames.dropZone.error.foreignFiles=Los archivos no pertenecen a la bóveda "%s"
|
||||||
|
decryptNames.dropZone.error.noDirIdBackup=El directorio de los archivos seleccionados no contiene el archivo dirId.c9r
|
||||||
|
decryptNames.dropZone.error.generic=Error al descifrar nombre de archivos
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
eventView.title=Eventos
|
||||||
|
eventView.filter.allVaults=Todos
|
||||||
|
eventView.clearListButton.tooltip=Borrar lista
|
||||||
|
## event list entries
|
||||||
|
eventView.entry.vaultLocked.description=Desbloquear "%s" para más detalles
|
||||||
|
eventView.entry.conflictResolved.message=Conflicto resuelto
|
||||||
|
eventView.entry.conflictResolved.showDecrypted=Mostrar archivo descifrado
|
||||||
|
eventView.entry.conflictResolved.copyDecrypted=Copiar ruta descifrada
|
||||||
|
eventView.entry.conflict.message=Resolución de conflictos fallida
|
||||||
|
eventView.entry.conflict.showDecrypted=Mostrar archivo descifrado, original
|
||||||
|
eventView.entry.conflict.copyDecrypted=Copiar ruta descifrada, original
|
||||||
|
eventView.entry.conflict.showEncrypted=Mostrar archivo en conflicto, cifrado
|
||||||
|
eventView.entry.conflict.copyEncrypted=Copiar ruta en conflicto, cifrada
|
||||||
|
eventView.entry.decryptionFailed.message=Desencriptación fallida
|
||||||
|
eventView.entry.decryptionFailed.showEncrypted=Mostrar archivo cifrado
|
||||||
|
eventView.entry.decryptionFailed.copyEncrypted=Copiar ruta cifrada
|
||||||
|
eventView.entry.brokenDirFile.message=Enlace de directorio roto
|
||||||
|
eventView.entry.brokenDirFile.showEncrypted=Mostrar enlace roto, cifrado
|
||||||
|
eventView.entry.brokenDirFile.copyEncrypted=Copiar ruta del enlace roto
|
||||||
|
eventView.entry.brokenFileNode.message=Nodo de sistema de archivos roto
|
||||||
|
eventView.entry.brokenFileNode.showEncrypted=Mostrar nodo roto, cifrado
|
||||||
|
eventView.entry.brokenFileNode.copyEncrypted=Copiar ruta del enlace roto, encriptado
|
||||||
|
eventView.entry.brokenFileNode.copyDecrypted=Copiar ruta descifrada
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=لغو
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=درخواست
|
generic.button.apply=اعمال
|
||||||
generic.button.back=بازگشت
|
generic.button.back=بازگشت
|
||||||
generic.button.cancel=انصراف
|
generic.button.cancel=انصراف
|
||||||
generic.button.change=تغییر
|
generic.button.change=تغییر
|
||||||
@@ -106,11 +107,14 @@ addvaultwizard.existing.chooseBtn=انتخاب کنید…
|
|||||||
unlock.unlockBtn=بازکردن قفل
|
unlock.unlockBtn=بازکردن قفل
|
||||||
## Select
|
## Select
|
||||||
## Success
|
## Success
|
||||||
|
unlock.success.revealBtn=نمایش درایو
|
||||||
## Failure
|
## Failure
|
||||||
## Hub
|
## Hub
|
||||||
|
hub.noKeychain.openBtn=باز کردن تنظیمات
|
||||||
### Waiting
|
### Waiting
|
||||||
### Receive Key
|
### Receive Key
|
||||||
### Register Device
|
### Register Device
|
||||||
|
hub.register.message=دستگاه جدید
|
||||||
### Register Device Legacy
|
### Register Device Legacy
|
||||||
### Registration Success
|
### Registration Success
|
||||||
hub.registerSuccess.unlockBtn=بازکردن قفل
|
hub.registerSuccess.unlockBtn=بازکردن قفل
|
||||||
@@ -170,11 +174,13 @@ preferences.updates.upToDate=Cryptomator به روز می باشد.
|
|||||||
# Main Window
|
# Main Window
|
||||||
## Vault List
|
## Vault List
|
||||||
main.vaultlist.contextMenu.lock=قفل
|
main.vaultlist.contextMenu.lock=قفل
|
||||||
|
main.vaultlist.contextMenu.reveal=نمایش درایو
|
||||||
##Notificaition
|
##Notificaition
|
||||||
## Vault Detail
|
## Vault Detail
|
||||||
### Welcome
|
### Welcome
|
||||||
### Locked
|
### Locked
|
||||||
### Unlocked
|
### Unlocked
|
||||||
|
main.vaultDetail.revealBtn=نمایش درایو
|
||||||
main.vaultDetail.lockBtn=قفل
|
main.vaultDetail.lockBtn=قفل
|
||||||
### Missing
|
### Missing
|
||||||
### Needs Migration
|
### Needs Migration
|
||||||
@@ -185,6 +191,7 @@ main.vaultDetail.lockBtn=قفل
|
|||||||
# Vault Options
|
# Vault Options
|
||||||
## General
|
## General
|
||||||
vaultOptions.general.vaultName=نام گاوصندوق
|
vaultOptions.general.vaultName=نام گاوصندوق
|
||||||
|
vaultOptions.general.actionAfterUnlock.reveal=نمایش درایو
|
||||||
|
|
||||||
## Mount
|
## Mount
|
||||||
vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
|
vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
|
||||||
@@ -209,7 +216,15 @@ vaultOptions.mount.mountPoint.directoryPickerButton=انتخاب کنید…
|
|||||||
# Update Reminder
|
# Update Reminder
|
||||||
|
|
||||||
#Dokany Support End
|
#Dokany Support End
|
||||||
|
dokanySupportEnd.preferencesBtn=باز کردن تنظیمات
|
||||||
|
|
||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Ohita
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Käytä
|
generic.button.apply=Käytä
|
||||||
generic.button.back=Takaisin
|
generic.button.back=Takaisin
|
||||||
@@ -281,7 +282,6 @@ preferences.title=Asetukset
|
|||||||
## General
|
## General
|
||||||
preferences.general=Yleiset
|
preferences.general=Yleiset
|
||||||
preferences.general.startHidden=Piilota ikkuna kun Cryptomator käynnistyy
|
preferences.general.startHidden=Piilota ikkuna kun Cryptomator käynnistyy
|
||||||
preferences.general.autoCloseVaults=Lukitse avoimet holvit automaattisesti kun ohjelma sammutetaan
|
|
||||||
preferences.general.debugLogging=Ota virheloki käyttöön
|
preferences.general.debugLogging=Ota virheloki käyttöön
|
||||||
preferences.general.debugDirectory=Näytä lokitiedostot
|
preferences.general.debugDirectory=Näytä lokitiedostot
|
||||||
preferences.general.autoStart=Käynnistä Cryptomator järjestelmän käynnistyessä
|
preferences.general.autoStart=Käynnistä Cryptomator järjestelmän käynnistyessä
|
||||||
@@ -419,7 +419,6 @@ main.vaultDetail.stats=Holvin tilastot
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Etsi salattu tiedosto
|
main.vaultDetail.locateEncryptedFileBtn=Etsi salattu tiedosto
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Valitse tiedosto holvistasi löytääksesi sen salatun vastineen
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Valitse tiedosto holvistasi löytääksesi sen salatun vastineen
|
||||||
main.vaultDetail.encryptedPathsCopied=Polut kopioitu leikepöydälle!
|
main.vaultDetail.encryptedPathsCopied=Polut kopioitu leikepöydälle!
|
||||||
main.vaultDetail.filePickerTitle=Valitse tiedosto holvin sisältä
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator ei löytänyt täältä holvia.
|
main.vaultDetail.missing.info=Cryptomator ei löytänyt täältä holvia.
|
||||||
main.vaultDetail.missing.recheck=Tarkista uudelleen
|
main.vaultDetail.missing.recheck=Tarkista uudelleen
|
||||||
@@ -560,3 +559,9 @@ shareVault.visitHub=Käy Cryptomator Hubissa
|
|||||||
shareVault.hub.message=Kuinka jakaa Hub -holvi
|
shareVault.hub.message=Kuinka jakaa Hub -holvi
|
||||||
shareVault.hub.instruction.1=1. Jaa käyttöoikeus salattuun holvikansioon pilvipalvelun kautta.
|
shareVault.hub.instruction.1=1. Jaa käyttöoikeus salattuun holvikansioon pilvipalvelun kautta.
|
||||||
shareVault.hub.openHub=Avaa Cryptomator Hub
|
shareVault.hub.openHub=Avaa Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=I-dismiss
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=I-apply
|
generic.button.apply=I-apply
|
||||||
generic.button.back=Bumalik
|
generic.button.back=Bumalik
|
||||||
@@ -281,7 +282,6 @@ preferences.title=Mga Kagustuhan
|
|||||||
## General
|
## General
|
||||||
preferences.general=Heneral
|
preferences.general=Heneral
|
||||||
preferences.general.startHidden=Itago ang window kapag sinimulan ang Cryptomator
|
preferences.general.startHidden=Itago ang window kapag sinimulan ang Cryptomator
|
||||||
preferences.general.autoCloseVaults=Awtomatikong i-lock ang mga bukas na vault kapag huminto sa aplikasyon
|
|
||||||
preferences.general.debugLogging=Paganahin ang pag-log ng debug
|
preferences.general.debugLogging=Paganahin ang pag-log ng debug
|
||||||
preferences.general.debugDirectory=Magbunyag ng mga log file
|
preferences.general.debugDirectory=Magbunyag ng mga log file
|
||||||
preferences.general.autoStart=Ilunsad ang Cryptomator sa pagsisimula ng system
|
preferences.general.autoStart=Ilunsad ang Cryptomator sa pagsisimula ng system
|
||||||
@@ -410,7 +410,6 @@ main.vaultDetail.stats=Mga Istatistika ng Vault
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Hanapin ang Naka-encrypt na File
|
main.vaultDetail.locateEncryptedFileBtn=Hanapin ang Naka-encrypt na File
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Pumili ng file mula sa iyong vault upang mahanap ang naka-encrypt na katapat nito
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Pumili ng file mula sa iyong vault upang mahanap ang naka-encrypt na katapat nito
|
||||||
main.vaultDetail.encryptedPathsCopied=Mga Path na Nakopya sa Clipboard!
|
main.vaultDetail.encryptedPathsCopied=Mga Path na Nakopya sa Clipboard!
|
||||||
main.vaultDetail.filePickerTitle=Piliin ang File Inside Vault
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Hindi makahanap ng vault ang Cryptomator sa landas na ito.
|
main.vaultDetail.missing.info=Hindi makahanap ng vault ang Cryptomator sa landas na ito.
|
||||||
main.vaultDetail.missing.recheck=Suriin muli
|
main.vaultDetail.missing.recheck=Suriin muli
|
||||||
@@ -561,3 +560,9 @@ shareVault.hub.description=Upang maibahagi ang nilalaman ng vault sa isa pang mi
|
|||||||
shareVault.hub.instruction.1=1. Ibahagi ang access ng naka-encrypt na folder ng vault sa pamamagitan ng cloud storage.
|
shareVault.hub.instruction.1=1. Ibahagi ang access ng naka-encrypt na folder ng vault sa pamamagitan ng cloud storage.
|
||||||
shareVault.hub.instruction.2=2. Magbigay ng access sa miyembro ng team sa Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Magbigay ng access sa miyembro ng team sa Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Buksan ang Cryptomator Hub
|
shareVault.hub.openHub=Buksan ang Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Ignorer
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Appliquer
|
generic.button.apply=Appliquer
|
||||||
generic.button.back=Précédent
|
generic.button.back=Précédent
|
||||||
@@ -282,7 +283,7 @@ preferences.title=Préférences
|
|||||||
## General
|
## General
|
||||||
preferences.general=Général
|
preferences.general=Général
|
||||||
preferences.general.startHidden=Démarrer Cryptomator en mode caché
|
preferences.general.startHidden=Démarrer Cryptomator en mode caché
|
||||||
preferences.general.autoCloseVaults=Verrouiller automatiquement les coffres ouverts en quittant l'application
|
preferences.general.autoCloseVaults=Verrouiller les coffres sans confirmation lors de la fermeture de l'application
|
||||||
preferences.general.debugLogging=Activer les logs debug
|
preferences.general.debugLogging=Activer les logs debug
|
||||||
preferences.general.debugDirectory=Afficher le journal
|
preferences.general.debugDirectory=Afficher le journal
|
||||||
preferences.general.autoStart=Lancer Cryptomator au démarrage du système
|
preferences.general.autoStart=Lancer Cryptomator au démarrage du système
|
||||||
@@ -342,7 +343,7 @@ preferences.contribute.sponsor=Parrain
|
|||||||
### Remove License Key Dialog
|
### Remove License Key Dialog
|
||||||
removeCert.title=Supprimer le certificat
|
removeCert.title=Supprimer le certificat
|
||||||
removeCert.message=Supprimer le certificat de soutien ?
|
removeCert.message=Supprimer le certificat de soutien ?
|
||||||
removeCert.description=
|
removeCert.description=Les fonctionnalités principales de Cryptomator ne sont pas affectées par cela. L'accès à vos coffres n'est pas restreint et le niveau de sécurité n'est pas diminué.
|
||||||
#<-- Add entries for donations and code/translation/documentation contribution -->
|
#<-- Add entries for donations and code/translation/documentation contribution -->
|
||||||
|
|
||||||
## About
|
## About
|
||||||
@@ -394,6 +395,7 @@ main.vaultlist.contextMenu.vaultoptions=Afficher les options du volume chiffré
|
|||||||
main.vaultlist.contextMenu.reveal=Afficher le lecteur
|
main.vaultlist.contextMenu.reveal=Afficher le lecteur
|
||||||
main.vaultlist.addVaultBtn.menuItemNew=Créer un nouveau coffre...
|
main.vaultlist.addVaultBtn.menuItemNew=Créer un nouveau coffre...
|
||||||
main.vaultlist.addVaultBtn.menuItemExisting=Ouvrir un coffre existant...
|
main.vaultlist.addVaultBtn.menuItemExisting=Ouvrir un coffre existant...
|
||||||
|
main.vaultlist.showEventsButton.tooltip=Ouvrir la vue Événements
|
||||||
##Notificaition
|
##Notificaition
|
||||||
main.notification.updateAvailable=Mise à jour disponible.
|
main.notification.updateAvailable=Mise à jour disponible.
|
||||||
main.notification.support=Soutenir Cryptomator.
|
main.notification.support=Soutenir Cryptomator.
|
||||||
@@ -422,7 +424,9 @@ main.vaultDetail.stats=Statistiques du volume chiffré
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Localiser le fichier chiffré
|
main.vaultDetail.locateEncryptedFileBtn=Localiser le fichier chiffré
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Choisissez un fichier dans votre coffre pour localiser sa version chiffrée
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Choisissez un fichier dans votre coffre pour localiser sa version chiffrée
|
||||||
main.vaultDetail.encryptedPathsCopied=Chemins d'accès copiés dans le presse-papier !
|
main.vaultDetail.encryptedPathsCopied=Chemins d'accès copiés dans le presse-papier !
|
||||||
main.vaultDetail.filePickerTitle=Sélectionner le fichier dans le coffre
|
main.vaultDetail.locateEncrypted.filePickerTitle=Sélectionner le fichier dans le coffre
|
||||||
|
main.vaultDetail.decryptName.buttonLabel=Déchiffrer le nom d'un fichier
|
||||||
|
main.vaultDetail.decryptName.tooltip=Choisir un fichier de coffre chiffré pour déchiffrer son nom
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator n'a pas pu trouver de volume chiffré dans ce chemin d'accès.
|
main.vaultDetail.missing.info=Cryptomator n'a pas pu trouver de volume chiffré dans ce chemin d'accès.
|
||||||
main.vaultDetail.missing.recheck=Revérifier
|
main.vaultDetail.missing.recheck=Revérifier
|
||||||
@@ -577,3 +581,41 @@ shareVault.hub.description=Afin de partager le contenu du coffre avec un autre m
|
|||||||
shareVault.hub.instruction.1=1. Partagez l'accès du dossier de coffre chiffré via le stockage cloud.
|
shareVault.hub.instruction.1=1. Partagez l'accès du dossier de coffre chiffré via le stockage cloud.
|
||||||
shareVault.hub.instruction.2=2. Accorder l'accès au membre de l'équipe dans Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Accorder l'accès au membre de l'équipe dans Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Ouvrir le Hub Cryptomator
|
shareVault.hub.openHub=Ouvrir le Hub Cryptomator
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
decryptNames.title=Déchiffrer les noms de fichiers
|
||||||
|
decryptNames.filePicker.title=Sélectionner le fichier chiffré
|
||||||
|
decryptNames.filePicker.extensionDescription=Fichier chiffré Cryptomator
|
||||||
|
decryptNames.copyTable.tooltip=Copier le tableau
|
||||||
|
decryptNames.clearTable.tooltip=Effacer le tableau
|
||||||
|
decryptNames.copyHint=Copier le contenu de la cellule avec %s
|
||||||
|
decryptNames.dropZone.message=Déposer des fichiers ou cliquer pour en sélectionner
|
||||||
|
decryptNames.dropZone.error.foreignFiles=Les fichiers n'appartiennent pas au coffre « %s »
|
||||||
|
decryptNames.dropZone.error.noDirIdBackup=Le répertoire des fichiers sélectionnés ne contient pas de fichier dirId.c9r
|
||||||
|
decryptNames.dropZone.error.generic=Impossible de déchiffrer les noms de fichiers
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
eventView.title=Événements
|
||||||
|
eventView.filter.allVaults=Tous
|
||||||
|
eventView.clearListButton.tooltip=Effacer la liste
|
||||||
|
## event list entries
|
||||||
|
eventView.entry.vaultLocked.description=Déverrouillez "%s" pour plus de détails
|
||||||
|
eventView.entry.conflictResolved.message=Conflit résolu
|
||||||
|
eventView.entry.conflictResolved.showDecrypted=Afficher le fichier déchiffré
|
||||||
|
eventView.entry.conflictResolved.copyDecrypted=Copier le chemin déchiffré
|
||||||
|
eventView.entry.conflict.message=La résolution des conflits a échoué
|
||||||
|
eventView.entry.conflict.showDecrypted=Afficher le fichier original déchiffré
|
||||||
|
eventView.entry.conflict.copyDecrypted=Copier le chemin original déchiffré
|
||||||
|
eventView.entry.conflict.showEncrypted=Afficher le fichier chiffré en conflit
|
||||||
|
eventView.entry.conflict.copyEncrypted=Copier le chemin chiffré en conflit
|
||||||
|
eventView.entry.decryptionFailed.message=Le déchiffrement a échoué
|
||||||
|
eventView.entry.decryptionFailed.showEncrypted=Afficher le fichier chiffré
|
||||||
|
eventView.entry.decryptionFailed.copyEncrypted=Copier le chemin chiffré
|
||||||
|
eventView.entry.brokenDirFile.message=Lien de répertoire cassé
|
||||||
|
eventView.entry.brokenDirFile.showEncrypted=Afficher le lien chiffré cassé
|
||||||
|
eventView.entry.brokenDirFile.copyEncrypted=Copier le chemin du lien cassé
|
||||||
|
eventView.entry.brokenFileNode.message=Nœud de système de fichiers cassé
|
||||||
|
eventView.entry.brokenFileNode.showEncrypted=Afficher le nœud chiffré cassé
|
||||||
|
eventView.entry.brokenFileNode.copyEncrypted=Copier le chemin du nœud chiffré cassé
|
||||||
|
eventView.entry.brokenFileNode.copyDecrypted=Copier le chemin déchiffré
|
||||||
|
|||||||
@@ -135,3 +135,10 @@ lock.forced.retryBtn=Tentar de novo
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=שחרור
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=החל
|
generic.button.apply=החל
|
||||||
generic.button.back=חזור
|
generic.button.back=חזור
|
||||||
@@ -48,6 +49,7 @@ addvaultwizard.new.nameInstruction=בחירת שם עבור הכספת
|
|||||||
addvaultwizard.new.namePrompt=שם הכספת
|
addvaultwizard.new.namePrompt=שם הכספת
|
||||||
### Location
|
### Location
|
||||||
addvaultwizard.new.locationInstruction=היכן Cryptomator צריך לשמור את הקבצים המוצפנים של הכספת שלך?
|
addvaultwizard.new.locationInstruction=היכן Cryptomator צריך לשמור את הקבצים המוצפנים של הכספת שלך?
|
||||||
|
addvaultwizard.new.locationLoading=בודק מערכת קבצים מקומית עבור ספריות ברירת מחדל לאחסון ענן…
|
||||||
addvaultwizard.new.locationLabel=מיקום אחסון
|
addvaultwizard.new.locationLabel=מיקום אחסון
|
||||||
addvaultwizard.new.locationPrompt=…
|
addvaultwizard.new.locationPrompt=…
|
||||||
addvaultwizard.new.directoryPickerLabel=מיקום מותאם אישית
|
addvaultwizard.new.directoryPickerLabel=מיקום מותאם אישית
|
||||||
@@ -260,7 +262,6 @@ preferences.title=העדפות
|
|||||||
## General
|
## General
|
||||||
preferences.general=כללי
|
preferences.general=כללי
|
||||||
preferences.general.startHidden=הסתר את החלון בהפעלת Cryptomator
|
preferences.general.startHidden=הסתר את החלון בהפעלת Cryptomator
|
||||||
preferences.general.autoCloseVaults=נעל vaults פתוחים באופן אוטומטי בעת יציאה מהאפליקציה
|
|
||||||
preferences.general.debugLogging=אפשר רישום יומן באגים
|
preferences.general.debugLogging=אפשר רישום יומן באגים
|
||||||
preferences.general.debugDirectory=הצג קבצי יומן
|
preferences.general.debugDirectory=הצג קבצי יומן
|
||||||
preferences.general.autoStart=הפעלת Cryptomator עם הפעלת המערכת
|
preferences.general.autoStart=הפעלת Cryptomator עם הפעלת המערכת
|
||||||
@@ -378,7 +379,6 @@ main.vaultDetail.stats=סטטיסטיקת הכספת
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=מצא קבצים מוצפנים
|
main.vaultDetail.locateEncryptedFileBtn=מצא קבצים מוצפנים
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=בחר קובץ מהכספת שלך על מנת לאתר את הקובץ התואם המוצפן
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=בחר קובץ מהכספת שלך על מנת לאתר את הקובץ התואם המוצפן
|
||||||
main.vaultDetail.encryptedPathsCopied=הנתיבים הועתקו ללוח!
|
main.vaultDetail.encryptedPathsCopied=הנתיבים הועתקו ללוח!
|
||||||
main.vaultDetail.filePickerTitle=בחר קובץ בתוך הכספת
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator לא הצליח למצוא כספת בנתיב זה.
|
main.vaultDetail.missing.info=Cryptomator לא הצליח למצוא כספת בנתיב זה.
|
||||||
main.vaultDetail.missing.recheck=בדיקה נוספת
|
main.vaultDetail.missing.recheck=בדיקה נוספת
|
||||||
@@ -494,3 +494,10 @@ dokanySupportEnd.preferencesBtn=פתח העדפות
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=खारिज करें
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=लागू करें
|
generic.button.apply=लागू करें
|
||||||
generic.button.back=पीछे जाएं
|
generic.button.back=पीछे जाएं
|
||||||
@@ -199,7 +200,6 @@ health.result.severityFilter.crit=गंभीर
|
|||||||
preferences.title=प्राथमिकताएं
|
preferences.title=प्राथमिकताएं
|
||||||
## General
|
## General
|
||||||
preferences.general=सामान्य
|
preferences.general=सामान्य
|
||||||
preferences.general.autoCloseVaults=एप्लीकेशन बंद करते समय खुली हुई वॉल्ट्स को अपने आप लॉक करें
|
|
||||||
preferences.general.autoStart=क्रिप्टोमेटर को सिस्टम स्टार्ट पे खोले
|
preferences.general.autoStart=क्रिप्टोमेटर को सिस्टम स्टार्ट पे खोले
|
||||||
## Interface
|
## Interface
|
||||||
preferences.interface.theme.automatic=ऑटोमैटिक
|
preferences.interface.theme.automatic=ऑटोमैटिक
|
||||||
@@ -317,3 +317,10 @@ dokanySupportEnd.preferencesBtn=प्राथमिकताएँ खोल
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -384,3 +384,10 @@ quit.lockAndQuitBtn=Zaključaj i napusti
|
|||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
|
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Elvet
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Alkalmaz
|
generic.button.apply=Alkalmaz
|
||||||
generic.button.back=Vissza
|
generic.button.back=Vissza
|
||||||
@@ -176,6 +177,7 @@ hub.registerFailed.description.generic=Hiba történt a regisztrációs folyamat
|
|||||||
hub.registerFailed.description.deviceAlreadyExists=Ez az eszköz már egy másik felhasználóhoz van regisztrálva. Próbáljon meg felhasználói fiókot váltani, vagy használjon egy másik eszközt.
|
hub.registerFailed.description.deviceAlreadyExists=Ez az eszköz már egy másik felhasználóhoz van regisztrálva. Próbáljon meg felhasználói fiókot váltani, vagy használjon egy másik eszközt.
|
||||||
### Unauthorized
|
### Unauthorized
|
||||||
hub.unauthorized.message=Hozzáférés megtagadva
|
hub.unauthorized.message=Hozzáférés megtagadva
|
||||||
|
hub.unauthorized.description=Nincs hozzáférésed a széf megnyitásához. Vedd fel a kapcsolatot a széf tulajdonosával és kérj hozzáférést.
|
||||||
### Requires Account Initialization
|
### Requires Account Initialization
|
||||||
hub.requireAccountInit.message=Beavatkozás szükséges
|
hub.requireAccountInit.message=Beavatkozás szükséges
|
||||||
hub.requireAccountInit.description.0=A folytatáshoz kérlek töltsd ki a szükséges lépéseket a te
|
hub.requireAccountInit.description.0=A folytatáshoz kérlek töltsd ki a szükséges lépéseket a te
|
||||||
@@ -281,7 +283,7 @@ preferences.title=Beállítások
|
|||||||
## General
|
## General
|
||||||
preferences.general=Általános
|
preferences.general=Általános
|
||||||
preferences.general.startHidden=Az ablak elrejtése a Cryptomator indítása után
|
preferences.general.startHidden=Az ablak elrejtése a Cryptomator indítása után
|
||||||
preferences.general.autoCloseVaults=A széfek automatikus lezárása az alkalmazás bezárásakor
|
preferences.general.autoCloseVaults=Széfek lezárása megerősítés nélkül az alkalmazás bezárásakor
|
||||||
preferences.general.debugLogging=Hibakeresési naplózás engedélyezése
|
preferences.general.debugLogging=Hibakeresési naplózás engedélyezése
|
||||||
preferences.general.debugDirectory=Naplófájlok megjelenítése
|
preferences.general.debugDirectory=Naplófájlok megjelenítése
|
||||||
preferences.general.autoStart=Cryptomator indítása a rendszerrel együtt
|
preferences.general.autoStart=Cryptomator indítása a rendszerrel együtt
|
||||||
@@ -421,7 +423,6 @@ main.vaultDetail.stats=Széf statisztika
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Titkosított fájl megkeresése
|
main.vaultDetail.locateEncryptedFileBtn=Titkosított fájl megkeresése
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Válasszon a széfből egy fájlt a titkosított megfelelőjének megkereséséhez
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Válasszon a széfből egy fájlt a titkosított megfelelőjének megkereséséhez
|
||||||
main.vaultDetail.encryptedPathsCopied=Az útvonal a vágólapra került!
|
main.vaultDetail.encryptedPathsCopied=Az útvonal a vágólapra került!
|
||||||
main.vaultDetail.filePickerTitle=Fájl választása a széfben
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=A Cryptomator nem talált széfet ezen az útvonalon.
|
main.vaultDetail.missing.info=A Cryptomator nem talált széfet ezen az útvonalon.
|
||||||
main.vaultDetail.missing.recheck=Ellenőrizze újra
|
main.vaultDetail.missing.recheck=Ellenőrizze újra
|
||||||
@@ -552,6 +553,10 @@ dokanySupportEnd.description=A Cryptomator nem támogatja tovább a Dokany köte
|
|||||||
dokanySupportEnd.preferencesBtn=Beállítások megnyitása
|
dokanySupportEnd.preferencesBtn=Beállítások megnyitása
|
||||||
|
|
||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
retryIfReadonly.title=Korlátozott Széf Hozzáférés
|
||||||
|
retryIfReadonly.message=Nincs írási jogod a széf könyvtárához
|
||||||
|
retryIfReadonly.description=A Cryptomator nem tud a széf könyvtárába írni. Átrakhatod a széfet írásvédettre és megpróbálhatod újra. Ezt az opciót kikapcsolhatod a széf beállításaiban.
|
||||||
|
retryIfReadonly.retry=Változtatás és Újrapróbálás
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
shareVault.title=Széf megosztása
|
shareVault.title=Széf megosztása
|
||||||
@@ -572,3 +577,9 @@ shareVault.hub.description=Ahhoz, hogy megossza a széf tartalmát egy másik cs
|
|||||||
shareVault.hub.instruction.1=Ossza meg a titkosított széf mappájának hozzáférését felhőalapú tárolón keresztül.
|
shareVault.hub.instruction.1=Ossza meg a titkosított széf mappájának hozzáférését felhőalapú tárolón keresztül.
|
||||||
shareVault.hub.instruction.2=2. Adjon hozzáférést a csapattagnak a Cryptomator Hubban.
|
shareVault.hub.instruction.2=2. Adjon hozzáférést a csapattagnak a Cryptomator Hubban.
|
||||||
shareVault.hub.openHub=Nyissa meg a Cryptomator Hubot
|
shareVault.hub.openHub=Nyissa meg a Cryptomator Hubot
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Tutup
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Terapkan
|
generic.button.apply=Terapkan
|
||||||
generic.button.back=Kembali
|
generic.button.back=Kembali
|
||||||
@@ -16,19 +17,19 @@ generic.button.print=Cetak
|
|||||||
generic.button.remove=Hapus
|
generic.button.remove=Hapus
|
||||||
|
|
||||||
# Error
|
# Error
|
||||||
error.message=Terjadi kesalahan %s
|
error.message=Terjadi kesalahan
|
||||||
error.description=Ups! Cryptomator tidak menyangka hal ini terjadi. Anda dapat mencari solusi yang tersedia untuk error ini. Atau jika error ini belum pernah dilaporkan, tidak perlu sungkan untuk melaporkannya.
|
error.description=Ups! Cryptomator tidak menyangka hal ini terjadi. Anda dapat mencari solusi yang tersedia untuk error ini. Atau jika error ini belum pernah dilaporkan, tidak perlu sungkan untuk melaporkannya.
|
||||||
error.hyperlink.lookup=Cari tahu informasi lebih lanjut tentang suatu kesalahan
|
error.hyperlink.lookup=Cari kesalahan ini
|
||||||
error.hyperlink.report=Laporkan error berikut
|
error.hyperlink.report=Laporkan kesalahan ini
|
||||||
error.technicalDetails=Rincian:
|
error.technicalDetails=Rincian:
|
||||||
error.existingSolutionDescription=Maaf, Cryptomator tiba-tiba berhenti. Tapi telah ditemukan sebuah jawaban untuk masalah ini. Lihat tautan berikut.
|
error.existingSolutionDescription=Cryptomator tidak menyangka ini terjadi. Tapi telah ditemukan sebuah solusi untuk kesalahan ini. Lihat tautan berikut.
|
||||||
error.hyperlink.solution=Cari tahu solusi untuk masalah ini
|
error.hyperlink.solution=Cari tahu solusinya
|
||||||
error.lookupPermissionMessage=Cryptomator bisa mencari solusinya secara daring. Ini akan meneruskan pesan ke direktori masalah kami dengan alamat IP Anda.
|
error.lookupPermissionMessage=Cryptomator bisa mencari solusinya secara daring. Ini akan meneruskan pesan ke direktori masalah kami dengan alamat IP Anda.
|
||||||
error.dismiss=Tutup
|
error.dismiss=Tutup
|
||||||
error.lookUpSolution=Cari tahu solusinya
|
error.lookUpSolution=Cari tahu solusinya
|
||||||
|
|
||||||
# Defaults
|
# Defaults
|
||||||
defaults.vault.vaultName=Brangkas
|
defaults.vault.vaultName=Brankas
|
||||||
|
|
||||||
# Tray Menu
|
# Tray Menu
|
||||||
traymenu.showMainWindow=Tampilkan
|
traymenu.showMainWindow=Tampilkan
|
||||||
@@ -44,10 +45,10 @@ addvaultwizard.title=Tambah Brankas
|
|||||||
## New
|
## New
|
||||||
addvaultwizard.new.title=Tambah Brankas Baru
|
addvaultwizard.new.title=Tambah Brankas Baru
|
||||||
### Name
|
### Name
|
||||||
addvaultwizard.new.nameInstruction=Buat sebuah nama untuk brankas
|
addvaultwizard.new.nameInstruction=Pilih sebuah nama untuk brankas
|
||||||
addvaultwizard.new.namePrompt=Nama Brankas
|
addvaultwizard.new.namePrompt=Nama Brankas
|
||||||
### Location
|
### Location
|
||||||
addvaultwizard.new.locationInstruction=Dimana Cryptomator seharusnya menyimpan vault berisi file enkripsi Anda?
|
addvaultwizard.new.locationInstruction=Di mana Cryptomator mesti menyimpan berkas terenkripsi dari brankas Anda?
|
||||||
addvaultwizard.new.locationLoading=Memeriksa sistem file lokal untuk direktori default penyimpanan cloud…
|
addvaultwizard.new.locationLoading=Memeriksa sistem file lokal untuk direktori default penyimpanan cloud…
|
||||||
addvaultwizard.new.locationLabel=Lokasi penyimpanan
|
addvaultwizard.new.locationLabel=Lokasi penyimpanan
|
||||||
addvaultwizard.new.locationPrompt=…
|
addvaultwizard.new.locationPrompt=…
|
||||||
@@ -71,15 +72,15 @@ addvaultwizard.new.expertSettings.shorteningThreshold.tooltip=Buka dokumentasi u
|
|||||||
addvaultwizard.new.expertSettings.shorteningThreshold.title=Panjang maksimum nama file terenkripsi
|
addvaultwizard.new.expertSettings.shorteningThreshold.title=Panjang maksimum nama file terenkripsi
|
||||||
addvaultwizard.new.expertSettings.shorteningThreshold.valid=Valid
|
addvaultwizard.new.expertSettings.shorteningThreshold.valid=Valid
|
||||||
### Password
|
### Password
|
||||||
addvaultwizard.new.createVaultBtn=Buat Brangkas
|
addvaultwizard.new.createVaultBtn=Buat Brankas
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice=Anda tidak dapat mengakses data tanpa kata sandi yang Anda miliki. Apa Anda ingin sebuah kunci pemulihan untuk berjaga-jaga jika seandainya Anda kehilangan kata sandi?
|
addvaultwizard.new.generateRecoveryKeyChoice=Anda tidak dapat mengakses data tanpa kata sandi yang Anda miliki. Apa Anda ingin sebuah kunci pemulihan untuk berjaga-jaga jika seandainya Anda kehilangan kata sandi?
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.yes=Ya tolong, Lebih baik aman daripada menyesal
|
addvaultwizard.new.generateRecoveryKeyChoice.yes=Ya tolong, Lebih baik aman daripada menyesal
|
||||||
addvaultwizard.new.generateRecoveryKeyChoice.no=Tidak terima kasih, Saya tidak akan kehilangan kata sandi saya
|
addvaultwizard.new.generateRecoveryKeyChoice.no=Tidak terima kasih, Saya tidak akan kehilangan kata sandi saya
|
||||||
### Information
|
### Information
|
||||||
addvault.new.readme.storageLocation.fileName=PENTING.rtf
|
addvault.new.readme.storageLocation.fileName=PENTING.rtf
|
||||||
addvault.new.readme.storageLocation.1=⚠️ FILE VAULT ⚠️
|
addvault.new.readme.storageLocation.1=⚠️ BERKAS BRANKAS ⚠️
|
||||||
addvault.new.readme.storageLocation.2=Ini adalah lokasi penyimpanan vault Anda.
|
addvault.new.readme.storageLocation.2=Ini adalah lokasi penyimpanan brankas Anda.
|
||||||
addvault.new.readme.storageLocation.3=DILARANG
|
addvault.new.readme.storageLocation.3=JANGAN
|
||||||
addvault.new.readme.storageLocation.4=• mengubah file apapun di direktori ini, atau
|
addvault.new.readme.storageLocation.4=• mengubah file apapun di direktori ini, atau
|
||||||
addvault.new.readme.storageLocation.5=• menyalin file untuk dienkripsi ke dalam direktori ini.
|
addvault.new.readme.storageLocation.5=• menyalin file untuk dienkripsi ke dalam direktori ini.
|
||||||
addvault.new.readme.storageLocation.6=Jika Anda ingin mengenkripsi file dan melihat isi konten dari vault, lakukan hal berikut:
|
addvault.new.readme.storageLocation.6=Jika Anda ingin mengenkripsi file dan melihat isi konten dari vault, lakukan hal berikut:
|
||||||
@@ -97,15 +98,15 @@ addvaultwizard.existing.title=Tambahkan Vault yang Ada
|
|||||||
addvaultwizard.existing.instruction=Pilih file "vault.cryptomator" Anda dari vault yang ada. Jika hanya ada file bernama "masterkey.cryptomator", pilih file tersebut.
|
addvaultwizard.existing.instruction=Pilih file "vault.cryptomator" Anda dari vault yang ada. Jika hanya ada file bernama "masterkey.cryptomator", pilih file tersebut.
|
||||||
addvaultwizard.existing.chooseBtn=Pilih…
|
addvaultwizard.existing.chooseBtn=Pilih…
|
||||||
addvaultwizard.existing.filePickerTitle=Pilih File Vault
|
addvaultwizard.existing.filePickerTitle=Pilih File Vault
|
||||||
addvaultwizard.existing.filePickerMimeDesc=Vault Cryptomator
|
addvaultwizard.existing.filePickerMimeDesc=Brankas Cryptomator
|
||||||
## Success
|
## Success
|
||||||
addvaultwizard.success.nextStepsInstructions=Vault "%s" telah dibuat.\nAnda harus membuka kunci vault ini untuk mengakses atau menambahkan konten. Anda juga dapat membuka kunci vault ini kapan saja di kemudian hari.
|
addvaultwizard.success.nextStepsInstructions=Vault "%s" telah dibuat.\nAnda harus membuka kunci vault ini untuk mengakses atau menambahkan konten. Anda juga dapat membuka kunci vault ini kapan saja di kemudian hari.
|
||||||
addvaultwizard.success.unlockNow=Buka Kunci Sekarang
|
addvaultwizard.success.unlockNow=Buka Kunci Sekarang
|
||||||
|
|
||||||
# Remove Vault
|
# Remove Vault
|
||||||
removeVault.title=Hapus Vault
|
removeVault.title=Hapus "%s"
|
||||||
removeVault.message=Hapus vault?
|
removeVault.message=Hapus brankas?
|
||||||
removeVault.description=Tindakan ini hanya akan membuat Cryptomator melupakan vault ini. Anda dapat menambahkan vault ini lagi nanti. File yang telah dienkripsi tidak akan dihapus dari hard drive Anda.
|
removeVault.description=Tindakan ini hanya akan membuat Cryptomator melupakan brankas ini. Anda dapat menambahkan brankas ini lagi nanti. Berkas yang telah dienkripsi tidak akan dihapus dari hard drive Anda.
|
||||||
|
|
||||||
# Change Password
|
# Change Password
|
||||||
changepassword.title=Ubah Kata Sandi
|
changepassword.title=Ubah Kata Sandi
|
||||||
@@ -124,14 +125,14 @@ unlock.passwordPrompt=Masukkan kata sandi "%s":
|
|||||||
unlock.savePassword=Ingat Kata Sandi
|
unlock.savePassword=Ingat Kata Sandi
|
||||||
unlock.unlockBtn=Buka Kunci
|
unlock.unlockBtn=Buka Kunci
|
||||||
## Select
|
## Select
|
||||||
unlock.chooseMasterkey.message=File masterkey tidak ditemukan
|
unlock.chooseMasterkey.message=Berkas masterkey tidak ditemukan
|
||||||
unlock.chooseMasterkey.description=Tidak dapat menemukan file masterkey untuk vault ini pada lokasi yang dicari. Mohon pilih file kunci secara manual.
|
unlock.chooseMasterkey.description=Tidak dapat menemukan file masterkey untuk vault ini pada lokasi yang dicari. Mohon pilih file kunci secara manual.
|
||||||
unlock.chooseMasterkey.filePickerTitle=Pilih File Masterkey
|
unlock.chooseMasterkey.filePickerTitle=Pilih File Masterkey
|
||||||
unlock.chooseMasterkey.filePickerMimeDesc=MasterKey Cryptomator
|
unlock.chooseMasterkey.filePickerMimeDesc=MasterKey Cryptomator
|
||||||
## Success
|
## Success
|
||||||
unlock.success.message=Buka kunci berhasil
|
unlock.success.message=Buka kunci berhasil
|
||||||
unlock.success.description="%s" berhasil dibuka! Vault Anda sekarang dapat diakses melalui drive virtual.
|
unlock.success.description="%s" berhasil dibuka! Vault Anda sekarang dapat diakses melalui drive virtual.
|
||||||
unlock.success.rememberChoice=Ingat pilihan saya, jangan perlihatkan lagi
|
unlock.success.rememberChoice=Ingat pilihan saya, jangan tanyakan lagi
|
||||||
unlock.success.revealBtn=Tampilkan Drive
|
unlock.success.revealBtn=Tampilkan Drive
|
||||||
## Failure
|
## Failure
|
||||||
unlock.error.customPath.message=Tidak dapat memasang vault ke path kustom
|
unlock.error.customPath.message=Tidak dapat memasang vault ke path kustom
|
||||||
@@ -142,7 +143,7 @@ unlock.error.customPath.description.hideawayNotDir=File sementara dan tersembuny
|
|||||||
unlock.error.customPath.description.couldNotBeCleaned=Vault Anda tidak dapat dipasang ke path "%s". Silakan coba lagi atau pilih path yang berbeda.
|
unlock.error.customPath.description.couldNotBeCleaned=Vault Anda tidak dapat dipasang ke path "%s". Silakan coba lagi atau pilih path yang berbeda.
|
||||||
unlock.error.customPath.description.notEmptyDir=Path kustom pemasangan "%s" bukan folder kosong. Silakan pilih folder kosong dan coba lagi.
|
unlock.error.customPath.description.notEmptyDir=Path kustom pemasangan "%s" bukan folder kosong. Silakan pilih folder kosong dan coba lagi.
|
||||||
unlock.error.customPath.description.generic=Anda telah memilih kustom path pemasangan untuk vault ini, tetapi gagal menggunakannya dengan pesan:%2$s
|
unlock.error.customPath.description.generic=Anda telah memilih kustom path pemasangan untuk vault ini, tetapi gagal menggunakannya dengan pesan:%2$s
|
||||||
unlock.error.restartRequired.message=Tidak dapat membuka kunci vault
|
unlock.error.restartRequired.message=Tidak dapat membuka kunci brankas
|
||||||
unlock.error.restartRequired.description=Ubah jenis volume di opsi vault atau restart Cryptomator.
|
unlock.error.restartRequired.description=Ubah jenis volume di opsi vault atau restart Cryptomator.
|
||||||
unlock.error.title=Gagal membuka kunci "%s"
|
unlock.error.title=Gagal membuka kunci "%s"
|
||||||
## Hub
|
## Hub
|
||||||
@@ -154,7 +155,7 @@ hub.auth.message=Menunggu otentikasi…
|
|||||||
hub.auth.description=Anda secara otomatis akan diarahkan ke halaman login.
|
hub.auth.description=Anda secara otomatis akan diarahkan ke halaman login.
|
||||||
hub.auth.loginLink=Tidak diarahkan? Klik di sini untuk membukanya.
|
hub.auth.loginLink=Tidak diarahkan? Klik di sini untuk membukanya.
|
||||||
### Receive Key
|
### Receive Key
|
||||||
hub.receive.message=Respons pemrosesan…
|
hub.receive.message=Memroses respons…
|
||||||
hub.receive.description=Cryptomator menerima dan memproses respons dari Hub. Harap tunggu.
|
hub.receive.description=Cryptomator menerima dan memproses respons dari Hub. Harap tunggu.
|
||||||
### Register Device
|
### Register Device
|
||||||
hub.register.message=Perangkat Baru
|
hub.register.message=Perangkat Baru
|
||||||
@@ -176,10 +177,11 @@ hub.registerFailed.description.generic=Kesalahan terjadi dalam proses pendaftara
|
|||||||
hub.registerFailed.description.deviceAlreadyExists=Perangkat ini sudah terdaftar untuk pengguna lain. Cobalah menggunakan akun pengguna atau perangkat yang berbeda.
|
hub.registerFailed.description.deviceAlreadyExists=Perangkat ini sudah terdaftar untuk pengguna lain. Cobalah menggunakan akun pengguna atau perangkat yang berbeda.
|
||||||
### Unauthorized
|
### Unauthorized
|
||||||
hub.unauthorized.message=Akses ditolak
|
hub.unauthorized.message=Akses ditolak
|
||||||
|
hub.unauthorized.description=Anda tidak punya otorisasi untuk membuka brankas ini. Hubungi pemilik brankas untuk meminta akses.
|
||||||
### Requires Account Initialization
|
### Requires Account Initialization
|
||||||
hub.requireAccountInit.message=Tindakan diperlukan
|
hub.requireAccountInit.message=Tindakan diperlukan
|
||||||
hub.requireAccountInit.description.0=Untuk melanjutkan, silakan lengkapi langkah-langkah yang diperlukan
|
hub.requireAccountInit.description.0=Untuk melanjutkan, silakan lengkapi langkah-langkah yang diperlukan dalam
|
||||||
hub.requireAccountInit.description.1=Hub profil pengguna
|
hub.requireAccountInit.description.1=Profil pengguna Hub Anda
|
||||||
hub.requireAccountInit.description.2=.
|
hub.requireAccountInit.description.2=.
|
||||||
### License Exceeded
|
### License Exceeded
|
||||||
hub.invalidLicense.message=Lisensi Hub tidak valid
|
hub.invalidLicense.message=Lisensi Hub tidak valid
|
||||||
@@ -281,7 +283,7 @@ preferences.title=Preferensi
|
|||||||
## General
|
## General
|
||||||
preferences.general=Umum
|
preferences.general=Umum
|
||||||
preferences.general.startHidden=Sembunyikan jendela saat memulai Cryptomator
|
preferences.general.startHidden=Sembunyikan jendela saat memulai Cryptomator
|
||||||
preferences.general.autoCloseVaults=Kunci vault yang terbuka secara otomatis saat aplikasi dihentikan
|
preferences.general.autoCloseVaults=Kunci brankas tanpa bertanya ketika keluar aplikasi
|
||||||
preferences.general.debugLogging=Aktifkan pencatatan debug
|
preferences.general.debugLogging=Aktifkan pencatatan debug
|
||||||
preferences.general.debugDirectory=Perlihatkan file log
|
preferences.general.debugDirectory=Perlihatkan file log
|
||||||
preferences.general.autoStart=Jalankan Cryptomator saat sistem dimulai
|
preferences.general.autoStart=Jalankan Cryptomator saat sistem dimulai
|
||||||
@@ -421,7 +423,6 @@ main.vaultDetail.stats=Statistik Vault
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Temukan File yang Dienkripsi
|
main.vaultDetail.locateEncryptedFileBtn=Temukan File yang Dienkripsi
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Pilih file dari vault Anda untuk menemukan mitra enkripsinya
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Pilih file dari vault Anda untuk menemukan mitra enkripsinya
|
||||||
main.vaultDetail.encryptedPathsCopied=Path Disalin ke Clipboard!
|
main.vaultDetail.encryptedPathsCopied=Path Disalin ke Clipboard!
|
||||||
main.vaultDetail.filePickerTitle=Pilih File Didalam Vault
|
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator tidak dapat menemukan vault di path ini.
|
main.vaultDetail.missing.info=Cryptomator tidak dapat menemukan vault di path ini.
|
||||||
main.vaultDetail.missing.recheck=Periksa kembali
|
main.vaultDetail.missing.recheck=Periksa kembali
|
||||||
@@ -552,6 +553,10 @@ dokanySupportEnd.description=Volume berjenis Dokany sudah tidak didukung oleh Cr
|
|||||||
dokanySupportEnd.preferencesBtn=Buka Preferensi
|
dokanySupportEnd.preferencesBtn=Buka Preferensi
|
||||||
|
|
||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
retryIfReadonly.title=Akses Brankas Dibatasi
|
||||||
|
retryIfReadonly.message=Tidak ada akses tulis ke direktori brankas
|
||||||
|
retryIfReadonly.description=Cryptomator tidak bisa menulis ke direktori brankas. Anda dapat mengubah brankas menjadi hanya-baca dan mencoba lagi. Opsi ini bisa dimatikan dalam opsi brankas.
|
||||||
|
retryIfReadonly.retry=Ubah dan Coba Lagi
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
shareVault.title=Bagikan Vault
|
shareVault.title=Bagikan Vault
|
||||||
@@ -572,3 +577,10 @@ shareVault.hub.description=Untuk berbagi isi vault dengan anggota tim lain, Anda
|
|||||||
shareVault.hub.instruction.1=1. Bagikan akses folder vault terenkripsi melalui penyimpanan cloud.
|
shareVault.hub.instruction.1=1. Bagikan akses folder vault terenkripsi melalui penyimpanan cloud.
|
||||||
shareVault.hub.instruction.2=2. Berikan akses ke anggota tim di Cryptomator Hub.
|
shareVault.hub.instruction.2=2. Berikan akses ke anggota tim di Cryptomator Hub.
|
||||||
shareVault.hub.openHub=Buka Cryptomator Hub
|
shareVault.hub.openHub=Buka Cryptomator Hub
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
eventView.filter.allVaults=Semua
|
||||||
|
## event list entries
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=Ignora
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=Applica
|
generic.button.apply=Applica
|
||||||
generic.button.back=Indietro
|
generic.button.back=Indietro
|
||||||
@@ -282,7 +283,7 @@ preferences.title=Preferenze
|
|||||||
## General
|
## General
|
||||||
preferences.general=Generale
|
preferences.general=Generale
|
||||||
preferences.general.startHidden=Nascondi la finestra avviando Cryptomator
|
preferences.general.startHidden=Nascondi la finestra avviando Cryptomator
|
||||||
preferences.general.autoCloseVaults=Blocca automaticamente le cassaforti aperte all'uscita dell'applicazione
|
preferences.general.autoCloseVaults=Alla chiusura dell'applicazione blocca le casseforti senza chiedere conferma
|
||||||
preferences.general.debugLogging=Abilita la registrazione di debug
|
preferences.general.debugLogging=Abilita la registrazione di debug
|
||||||
preferences.general.debugDirectory=Rivela i file di registro
|
preferences.general.debugDirectory=Rivela i file di registro
|
||||||
preferences.general.autoStart=Avvia Cryptomator all'avvio del sistema
|
preferences.general.autoStart=Avvia Cryptomator all'avvio del sistema
|
||||||
@@ -394,6 +395,7 @@ main.vaultlist.contextMenu.vaultoptions=Mostra le Opzioni della Cassaforte
|
|||||||
main.vaultlist.contextMenu.reveal=Rivela Unità
|
main.vaultlist.contextMenu.reveal=Rivela Unità
|
||||||
main.vaultlist.addVaultBtn.menuItemNew=Crea una nuova cassaforte...
|
main.vaultlist.addVaultBtn.menuItemNew=Crea una nuova cassaforte...
|
||||||
main.vaultlist.addVaultBtn.menuItemExisting=Apri una cassaforte esistente...
|
main.vaultlist.addVaultBtn.menuItemExisting=Apri una cassaforte esistente...
|
||||||
|
main.vaultlist.showEventsButton.tooltip=Apri vista eventi
|
||||||
##Notificaition
|
##Notificaition
|
||||||
main.notification.updateAvailable=Aggiornamento disponibile.
|
main.notification.updateAvailable=Aggiornamento disponibile.
|
||||||
main.notification.support=Supporta Cryptomator.
|
main.notification.support=Supporta Cryptomator.
|
||||||
@@ -422,7 +424,9 @@ main.vaultDetail.stats=Statistiche della Cassaforte
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=Individua File Crittografato
|
main.vaultDetail.locateEncryptedFileBtn=Individua File Crittografato
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=Scegli un file dalla cassaforte per individuare la controparte cifrata
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=Scegli un file dalla cassaforte per individuare la controparte cifrata
|
||||||
main.vaultDetail.encryptedPathsCopied=Percorsi copiati negli Appunti!
|
main.vaultDetail.encryptedPathsCopied=Percorsi copiati negli Appunti!
|
||||||
main.vaultDetail.filePickerTitle=Seleziona File Nella Cassaforte
|
main.vaultDetail.locateEncrypted.filePickerTitle=Seleziona file nella cassaforte
|
||||||
|
main.vaultDetail.decryptName.buttonLabel=Decifra nome file
|
||||||
|
main.vaultDetail.decryptName.tooltip=Seleziona il file di una cassaforte cifrata per decifrarne il nome
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator non è riuscito a trovare una cassaforte in questo percorso.
|
main.vaultDetail.missing.info=Cryptomator non è riuscito a trovare una cassaforte in questo percorso.
|
||||||
main.vaultDetail.missing.recheck=Ricontrolla
|
main.vaultDetail.missing.recheck=Ricontrolla
|
||||||
@@ -577,3 +581,42 @@ shareVault.hub.description=Per condividere il contenuto della cassaforte con un
|
|||||||
shareVault.hub.instruction.1=1. Condividi l'accesso alla cartella della cassaforte crittografata tramite l'archiviazione cloud.
|
shareVault.hub.instruction.1=1. Condividi l'accesso alla cartella della cassaforte crittografata tramite l'archiviazione cloud.
|
||||||
shareVault.hub.instruction.2=2. Concedi l'accesso ai membri del gruppo nell'Hub Cryptomator.
|
shareVault.hub.instruction.2=2. Concedi l'accesso ai membri del gruppo nell'Hub Cryptomator.
|
||||||
shareVault.hub.openHub=Apri l'Hub Cryptomator
|
shareVault.hub.openHub=Apri l'Hub Cryptomator
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
decryptNames.title=Decifra i nomi dei files
|
||||||
|
decryptNames.filePicker.title=Seleziona file criptato
|
||||||
|
decryptNames.filePicker.extensionDescription=File crittografato Cryptomator
|
||||||
|
decryptNames.copyTable.tooltip=Copia tabella
|
||||||
|
decryptNames.clearTable.tooltip=Cancella la tabella
|
||||||
|
decryptNames.copyHint=Copia il contenuto della cella con %s
|
||||||
|
decryptNames.dropZone.message=Trascina i file o fai clic per selezionare
|
||||||
|
decryptNames.dropZone.error.vaultInternalFiles=Hai selezionato file di casseforti con il nome non decifrabile
|
||||||
|
decryptNames.dropZone.error.foreignFiles=I file non appartengono alla cassaforte "%s"
|
||||||
|
decryptNames.dropZone.error.noDirIdBackup=La directory dei file selezionati non contiene il file dirId.c9r
|
||||||
|
decryptNames.dropZone.error.generic=Decifratura nomi file non riuscita
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
eventView.title=Eventi
|
||||||
|
eventView.filter.allVaults=Tutti
|
||||||
|
eventView.clearListButton.tooltip=Cancella elenco
|
||||||
|
## event list entries
|
||||||
|
eventView.entry.vaultLocked.description=Sblocca "%s" per i dettagli
|
||||||
|
eventView.entry.conflictResolved.message=Conflitto risolto
|
||||||
|
eventView.entry.conflictResolved.showDecrypted=Mostra file decifrato
|
||||||
|
eventView.entry.conflictResolved.copyDecrypted=Copia percorso decriptato
|
||||||
|
eventView.entry.conflict.message=Risoluzione dei conflitti fallita
|
||||||
|
eventView.entry.conflict.showDecrypted=Mostra il file originale decifrato
|
||||||
|
eventView.entry.conflict.copyDecrypted=Copia il percorso originale decifrato
|
||||||
|
eventView.entry.conflict.showEncrypted=Mostra file cifrato in conflitto
|
||||||
|
eventView.entry.conflict.copyEncrypted=Copia il percorso cifrato in conflitto
|
||||||
|
eventView.entry.decryptionFailed.message=Decifratura fallita
|
||||||
|
eventView.entry.decryptionFailed.showEncrypted=Mostra file cifrato
|
||||||
|
eventView.entry.decryptionFailed.copyEncrypted=Copia percorso cifrato
|
||||||
|
eventView.entry.brokenDirFile.message=Collegamento directory errato
|
||||||
|
eventView.entry.brokenDirFile.showEncrypted=Visualizza il link cifrato errato
|
||||||
|
eventView.entry.brokenDirFile.copyEncrypted=Copia il percorso errato del file cifrato
|
||||||
|
eventView.entry.brokenFileNode.message=Nodo file errato
|
||||||
|
eventView.entry.brokenFileNode.showEncrypted=Visualizza il nodo file cifrato errato
|
||||||
|
eventView.entry.brokenFileNode.copyEncrypted=Copia il percorso errato del nodo file cifrato
|
||||||
|
eventView.entry.brokenFileNode.copyDecrypted=Copia il percorso decifrato
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Locale Specific CSS files such as CJK, RTL,...
|
# Locale Specific CSS files such as CJK, RTL,...
|
||||||
|
|
||||||
# Generics
|
# Generics
|
||||||
|
generic.action.dismiss=閉じる
|
||||||
## Button
|
## Button
|
||||||
generic.button.apply=適用
|
generic.button.apply=適用
|
||||||
generic.button.back=戻る
|
generic.button.back=戻る
|
||||||
@@ -176,6 +177,7 @@ hub.registerFailed.description.generic=登録中にエラーが発生しまし
|
|||||||
hub.registerFailed.description.deviceAlreadyExists=このデバイスは既に別のユーザーに登録されています。ユーザーアカウントを変更するか、別のデバイスを使用してください。
|
hub.registerFailed.description.deviceAlreadyExists=このデバイスは既に別のユーザーに登録されています。ユーザーアカウントを変更するか、別のデバイスを使用してください。
|
||||||
### Unauthorized
|
### Unauthorized
|
||||||
hub.unauthorized.message=アクセスが拒否されました
|
hub.unauthorized.message=アクセスが拒否されました
|
||||||
|
hub.unauthorized.description=この金庫を開く権限がありません。金庫の所有者からアクセス許可を貰って下さい。
|
||||||
### Requires Account Initialization
|
### Requires Account Initialization
|
||||||
hub.requireAccountInit.message=アクションが必要です
|
hub.requireAccountInit.message=アクションが必要です
|
||||||
hub.requireAccountInit.description.0=続行するには以下のサイトで必要な手順を完了してください
|
hub.requireAccountInit.description.0=続行するには以下のサイトで必要な手順を完了してください
|
||||||
@@ -281,7 +283,7 @@ preferences.title=環境設定
|
|||||||
## General
|
## General
|
||||||
preferences.general=基本設定
|
preferences.general=基本設定
|
||||||
preferences.general.startHidden=Cryptomator を開始したときウィンドウを隠す
|
preferences.general.startHidden=Cryptomator を開始したときウィンドウを隠す
|
||||||
preferences.general.autoCloseVaults=アプリケーションを終了するときに自動的に開いている金庫を施錠する
|
preferences.general.autoCloseVaults=アプリケーション終了時に質問せずに金庫をロックする
|
||||||
preferences.general.debugLogging=ログを有効にする
|
preferences.general.debugLogging=ログを有効にする
|
||||||
preferences.general.debugDirectory=ログ ファイルを表示
|
preferences.general.debugDirectory=ログ ファイルを表示
|
||||||
preferences.general.autoStart=システム開始時に Cryptomator を起動する
|
preferences.general.autoStart=システム開始時に Cryptomator を起動する
|
||||||
@@ -333,8 +335,12 @@ preferences.contribute.registeredFor=サポート証明書 (%s) が登録され
|
|||||||
preferences.contribute.noCertificate=Cryptomator を支援し、サポーター証明書を受け取りましょう。ライセンスキーに似ていますがフリーソフトを使う寄付者向けのキーです。 ;-)
|
preferences.contribute.noCertificate=Cryptomator を支援し、サポーター証明書を受け取りましょう。ライセンスキーに似ていますがフリーソフトを使う寄付者向けのキーです。 ;-)
|
||||||
preferences.contribute.getCertificate=まだ証明書を手に入れていませんか? 詳細はこちらから確認できます。
|
preferences.contribute.getCertificate=まだ証明書を手に入れていませんか? 詳細はこちらから確認できます。
|
||||||
preferences.contribute.promptText=サポーター証明書をここに張り付けてください
|
preferences.contribute.promptText=サポーター証明書をここに張り付けてください
|
||||||
|
preferences.contribute.donate=寄付する
|
||||||
|
preferences.contribute.sponsor=スポンサー
|
||||||
|
|
||||||
### Remove License Key Dialog
|
### Remove License Key Dialog
|
||||||
|
removeCert.title=証明書を削除
|
||||||
|
removeCert.message=サポーター証明書を削除しますか?
|
||||||
#<-- Add entries for donations and code/translation/documentation contribution -->
|
#<-- Add entries for donations and code/translation/documentation contribution -->
|
||||||
|
|
||||||
## About
|
## About
|
||||||
@@ -384,7 +390,11 @@ main.vaultlist.contextMenu.unlock=解錠...
|
|||||||
main.vaultlist.contextMenu.unlockNow=今すぐ解錠
|
main.vaultlist.contextMenu.unlockNow=今すぐ解錠
|
||||||
main.vaultlist.contextMenu.vaultoptions=金庫のオプションを表示
|
main.vaultlist.contextMenu.vaultoptions=金庫のオプションを表示
|
||||||
main.vaultlist.contextMenu.reveal=ドライブを表示
|
main.vaultlist.contextMenu.reveal=ドライブを表示
|
||||||
|
main.vaultlist.addVaultBtn.menuItemNew=新しい金庫を作成…
|
||||||
|
main.vaultlist.addVaultBtn.menuItemExisting=既存の金庫を開く…
|
||||||
##Notificaition
|
##Notificaition
|
||||||
|
main.notification.updateAvailable=アップデートがあります。
|
||||||
|
main.notification.support=Cryptomator を支援する。
|
||||||
## Vault Detail
|
## Vault Detail
|
||||||
### Welcome
|
### Welcome
|
||||||
main.vaultDetail.welcomeOnboarding=ファイルを保護するために Cryptomator を選んでいただきありがとうございます。ヘルプが必要であれば、スタートガイドをご覧ください:
|
main.vaultDetail.welcomeOnboarding=ファイルを保護するために Cryptomator を選んでいただきありがとうございます。ヘルプが必要であれば、スタートガイドをご覧ください:
|
||||||
@@ -410,7 +420,9 @@ main.vaultDetail.stats=金庫の統計情報
|
|||||||
main.vaultDetail.locateEncryptedFileBtn=暗号化されたファイルの場所
|
main.vaultDetail.locateEncryptedFileBtn=暗号化されたファイルの場所
|
||||||
main.vaultDetail.locateEncryptedFileBtn.tooltip=暗号化された金庫のファイルを選択してください
|
main.vaultDetail.locateEncryptedFileBtn.tooltip=暗号化された金庫のファイルを選択してください
|
||||||
main.vaultDetail.encryptedPathsCopied=パスをクリップボードにコピーしました!
|
main.vaultDetail.encryptedPathsCopied=パスをクリップボードにコピーしました!
|
||||||
main.vaultDetail.filePickerTitle=金庫内のファイルを選択
|
main.vaultDetail.locateEncrypted.filePickerTitle=金庫内のファイルを選択
|
||||||
|
main.vaultDetail.decryptName.buttonLabel=ファイル名の復号化
|
||||||
|
main.vaultDetail.decryptName.tooltip=名前を復号化する暗号化金庫を選択してください
|
||||||
### Missing
|
### Missing
|
||||||
main.vaultDetail.missing.info=Cryptomator はこの場所に金庫を見つけることができませんでした。
|
main.vaultDetail.missing.info=Cryptomator はこの場所に金庫を見つけることができませんでした。
|
||||||
main.vaultDetail.missing.recheck=再確認
|
main.vaultDetail.missing.recheck=再確認
|
||||||
@@ -541,6 +553,9 @@ dokanySupportEnd.description=ボリュームタイプ
|
|||||||
dokanySupportEnd.preferencesBtn=環境設定を開く
|
dokanySupportEnd.preferencesBtn=環境設定を開く
|
||||||
|
|
||||||
#Retry If Readonly
|
#Retry If Readonly
|
||||||
|
retryIfReadonly.title=制限された金庫へのアクセス
|
||||||
|
retryIfReadonly.message=金庫のディレクトリに書き込み権限がありません
|
||||||
|
retryIfReadonly.retry=変更して再試行
|
||||||
|
|
||||||
# Share Vault
|
# Share Vault
|
||||||
shareVault.title=保管庫を共有する
|
shareVault.title=保管庫を共有する
|
||||||
@@ -561,3 +576,20 @@ shareVault.hub.description=データ保管庫のコンテンツを他のチー
|
|||||||
shareVault.hub.instruction.1=1. クラウドストレージ経由で暗号化された保管庫フォルダへのアクセスを共有します。
|
shareVault.hub.instruction.1=1. クラウドストレージ経由で暗号化された保管庫フォルダへのアクセスを共有します。
|
||||||
shareVault.hub.instruction.2=2. Cryptomator Hubでチームメンバーにアクセスを許可する。
|
shareVault.hub.instruction.2=2. Cryptomator Hubでチームメンバーにアクセスを許可する。
|
||||||
shareVault.hub.openHub=Cryptomator Hubを開く
|
shareVault.hub.openHub=Cryptomator Hubを開く
|
||||||
|
|
||||||
|
# Decrypt File Names
|
||||||
|
decryptNames.title=ファイル名の復号化
|
||||||
|
decryptNames.filePicker.title=暗号化されたファイルを選択
|
||||||
|
decryptNames.filePicker.extensionDescription=Cryptomator で暗号化したファイル
|
||||||
|
decryptNames.copyTable.tooltip=表をコピー
|
||||||
|
decryptNames.clearTable.tooltip=表をクリア
|
||||||
|
decryptNames.copyHint=%s でセルの内容をコピー
|
||||||
|
decryptNames.dropZone.message=ファイルをドロップまたはクリックして選択
|
||||||
|
decryptNames.dropZone.error.vaultInternalFiles=選択された金庫の内部ファイルに復号化できる名前がありません
|
||||||
|
decryptNames.dropZone.error.foreignFiles=ファイルは金庫 "%s" に属していません
|
||||||
|
decryptNames.dropZone.error.noDirIdBackup=選択したファイルのディレクトリにdirId.c9rファイルが含まれていません
|
||||||
|
decryptNames.dropZone.error.generic=ファイル名の復号化に失敗しました
|
||||||
|
|
||||||
|
|
||||||
|
# Event View
|
||||||
|
## event list entries
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user