From bca32846b596bc1d2869a538b178c1bb5cf02036 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sat, 13 Dec 2025 01:27:48 +0000 Subject: [PATCH] Rework --- .../io/xpipe/app/action/ActionConfigComp.java | 1 - .../xpipe/app/action/ActionShortcutComp.java | 6 +- .../BrowserFileChooserSessionComp.java | 3 +- .../browser/file/BrowserBreadcrumbBar.java | 19 +- .../file/BrowserFileSystemTabComp.java | 2 +- .../file/BrowserFileTransferOperation.java | 15 -- .../browser/file/BrowserHistoryTabComp.java | 2 +- .../browser/menu/impl/JarMenuProvider.java | 6 +- .../browser/menu/impl/JavapMenuProvider.java | 4 + .../impl/compress/BaseUntarMenuProvider.java | 2 +- .../compress/BaseUnzipUnixMenuProvider.java | 2 +- .../io/xpipe/app/comp/base/AppLayoutComp.java | 2 +- .../comp/base/AppMainWindowContentComp.java | 23 ++- .../base/ContextualFileReferenceSync.java | 1 + .../xpipe/app/comp/base/InputGroupComp.java | 12 +- .../xpipe/app/comp/base/MultiContentComp.java | 6 +- .../xpipe/app/comp/base/SecretFieldComp.java | 6 +- .../check/AppDirectoryPermissionsCheck.java | 8 + .../java/io/xpipe/app/ext/FileSystem.java | 28 ++- .../xpipe/app/ext/SelfReferentialStore.java | 12 ++ .../app/hub/action/BatchStoreAction.java | 4 +- .../action/impl/OpenHubMenuLeafProvider.java | 4 + .../action/impl/RefreshHubLeafProvider.java | 44 +++++ .../app/hub/comp/StoreCategoryConfigComp.java | 28 +-- .../app/hub/comp/StoreCategoryWrapper.java | 14 +- .../xpipe/app/hub/comp/StoreChoiceComp.java | 80 ++++---- .../app/hub/comp/StoreChoicePopover.java | 12 +- .../app/hub/comp/StoreComboChoiceComp.java | 17 +- .../app/hub/comp/StoreCreationDialog.java | 8 +- .../app/hub/comp/StoreEntryListComp.java | 2 +- .../app/hub/comp/StoreListChoiceComp.java | 3 +- .../io/xpipe/app/hub/comp/StoreViewState.java | 17 +- .../xpipe/app/issue/ErrorHandlerDialog.java | 4 +- .../io/xpipe/app/issue/GuiErrorHandler.java | 8 +- .../java/io/xpipe/app/prefs/AppPrefs.java | 12 +- .../app/prefs/ExternalApplicationType.java | 10 +- .../io/xpipe/app/prefs/LoggingCategory.java | 2 +- .../io/xpipe/app/prefs/TerminalCategory.java | 1 - .../io/xpipe/app/storage/StandardStorage.java | 1 + .../app/terminal/ExternalTerminalType.java | 2 +- .../io/xpipe/app/terminal/TerminalPrompt.java | 2 +- .../xpipe/app/terminal/WarpTerminalType.java | 2 +- .../java/io/xpipe/app/util/Deobfuscator.java | 8 +- .../java/io/xpipe/app/util/DesktopHelper.java | 24 ++- .../io/xpipe/app/util/DocumentationLink.java | 3 +- .../java/io/xpipe/app/util/RemminaHelper.java | 28 ++- .../xpipe/app/util/ScanSingleDialogComp.java | 3 +- app/src/main/java/module-info.java | 1 + .../xpipe/app/resources/style/choice-comp.css | 4 +- .../io/xpipe/app/resources/style/style.css | 12 ++ dist/changelog/19.3.1_incremental.md | 1 + dist/changelog/19.3_incremental.md | 4 + dist/changelog/19.4_incremental.md | 7 + dist/changelog/19.5_incremental.md | 10 + dist/changelog/19.6_incremental.md | 2 + .../DesktopApplicationStoreProvider.java | 1 - .../base/host/AbstractHostStoreProvider.java | 3 +- .../ext/base/host/HostAddressChoiceComp.java | 10 +- .../ext/base/identity/IdentitySelectComp.java | 16 +- .../base/script/ScriptGroupStoreProvider.java | 1 - .../script/SimpleScriptStoreProvider.java | 1 - .../base/service/AbstractServiceStore.java | 10 +- .../ext/base/service/CustomServiceStore.java | 7 + .../service/CustomServiceStoreProvider.java | 27 ++- .../ext/base/service/FixedServiceStore.java | 6 + .../service/FixedServiceStoreProvider.java | 28 ++- .../service/MappedServiceStoreProvider.java | 25 ++- .../service/ServiceProtocolTypeHelper.java | 8 +- .../incus/IncusContainerStoreProvider.java | 8 +- .../system/lxd/LxdContainerStoreProvider.java | 7 +- .../podman/PodmanContainerStoreProvider.java | 10 +- lang/strings/translations_da.properties | 23 ++- lang/strings/translations_de.properties | 23 ++- lang/strings/translations_en.properties | 28 +-- lang/strings/translations_es.properties | 21 +- lang/strings/translations_fr.properties | 19 +- lang/strings/translations_id.properties | 23 ++- lang/strings/translations_it.properties | 21 +- lang/strings/translations_ja.properties | 17 +- lang/strings/translations_ko.properties | 186 ++++++++++++------ lang/strings/translations_nl.properties | 21 +- lang/strings/translations_pl.properties | 21 +- lang/strings/translations_pt.properties | 21 +- lang/strings/translations_ru.properties | 17 +- lang/strings/translations_sv.properties | 21 +- lang/strings/translations_tr.properties | 21 +- lang/strings/translations_vi.properties | 23 ++- lang/strings/translations_zh-Hans.properties | 9 +- lang/strings/translations_zh-Hant.properties | 19 +- version | 2 +- 90 files changed, 820 insertions(+), 428 deletions(-) create mode 100644 app/src/main/java/io/xpipe/app/hub/action/impl/RefreshHubLeafProvider.java create mode 100644 dist/changelog/19.3.1_incremental.md create mode 100644 dist/changelog/19.3_incremental.md create mode 100644 dist/changelog/19.4_incremental.md create mode 100644 dist/changelog/19.5_incremental.md create mode 100644 dist/changelog/19.6_incremental.md diff --git a/app/src/main/java/io/xpipe/app/action/ActionConfigComp.java b/app/src/main/java/io/xpipe/app/action/ActionConfigComp.java index 54cfa3a51..d6647eee2 100644 --- a/app/src/main/java/io/xpipe/app/action/ActionConfigComp.java +++ b/app/src/main/java/io/xpipe/app/action/ActionConfigComp.java @@ -75,7 +75,6 @@ public class ActionConfigComp extends SimpleComp { }); var choice = new StoreChoiceComp<>( - StoreChoiceComp.Mode.OTHER, null, singleProp, DataStore.class, diff --git a/app/src/main/java/io/xpipe/app/action/ActionShortcutComp.java b/app/src/main/java/io/xpipe/app/action/ActionShortcutComp.java index d9e123c06..eb5dc2a00 100644 --- a/app/src/main/java/io/xpipe/app/action/ActionShortcutComp.java +++ b/app/src/main/java/io/xpipe/app/action/ActionShortcutComp.java @@ -69,7 +69,7 @@ public class ActionShortcutComp extends SimpleComp { field.grow(true, false); field.apply(struc -> struc.get().setEditable(false)); var group = new InputGroupComp(List.of(field, copyButton)); - group.setHeightReference(copyButton); + group.setMainReference(copyButton); group.hide(Bindings.isNull(url)); return group; } @@ -95,7 +95,7 @@ public class ActionShortcutComp extends SimpleComp { var field = new TextFieldComp(name); field.grow(true, false); var group = new InputGroupComp(List.of(field, copyButton)); - group.setHeightReference(copyButton); + group.setMainReference(copyButton); group.hide(BindingsHelper.map(action, v -> !(v instanceof SerializableAction))); return group; } @@ -117,7 +117,7 @@ public class ActionShortcutComp extends SimpleComp { field.grow(true, false); field.apply(struc -> struc.get().setEditable(false)); var group = new InputGroupComp(List.of(field, copyButton)); - group.setHeightReference(copyButton); + group.setMainReference(copyButton); group.hide(BindingsHelper.map(action, v -> !(v instanceof SerializableAction))); return group; } diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFileChooserSessionComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserFileChooserSessionComp.java index cc9cd4904..3ff0d0fa5 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFileChooserSessionComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFileChooserSessionComp.java @@ -83,7 +83,7 @@ public class BrowserFileChooserSessionComp extends ModalOverlayContentComp { modal.addButton(new ModalButton("select", () -> model.finishChooser(), true, true)); modal.show(); ThreadHelper.runAsync(() -> { - model.openFileSystemAsync(store.get(), null, (sc) -> initialPath.get(), null); + model.openFileSystemAsync(store.get(), null, (sc) -> initialPath.get(), model.getBusy()); }); } @@ -167,6 +167,7 @@ public class BrowserFileChooserSessionComp extends ModalOverlayContentComp { struc.getLeft().setMinWidth(200); struc.getLeft().setMaxWidth(500); }); + splitPane.disable(model.getBusy()); return splitPane.prefHeight(2000).createRegion(); } } diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java index 670769f9a..b0fec3488 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserBreadcrumbBar.java @@ -2,6 +2,7 @@ package io.xpipe.app.browser.file; import io.xpipe.app.comp.SimpleComp; import io.xpipe.app.platform.PlatformThread; +import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.GlobalTimer; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.FilePath; @@ -120,14 +121,16 @@ public class BrowserBreadcrumbBar extends SimpleComp { breadcrumbs.selectedCrumbProperty().addListener((obs, old, val) -> { ThreadHelper.runAsync(() -> { - model.cdSync(val != null ? val.getValue().toString() : null); - var now = model.getCurrentPath().getValue(); - // If we initiated a cd from the navbar, but it was rejected, reflect the changes - if (!Objects.equals(now, val != null ? val.getValue() : null)) { - Platform.runLater(() -> { - breadcrumbs.setSelectedCrumb(old); - }); - } + BooleanScope.executeExclusive(model.getBusy(), () -> { + model.cdSync(val != null ? val.getValue().toString() : null); + var now = model.getCurrentPath().getValue(); + // If we initiated a cd from the navbar, but it was rejected, reflect the changes + if (!Objects.equals(now, val != null ? val.getValue() : null)) { + Platform.runLater(() -> { + breadcrumbs.setSelectedCrumb(old); + }); + } + }); }); }); diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabComp.java index 38f9b4983..a0a7adcac 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileSystemTabComp.java @@ -243,7 +243,7 @@ public class BrowserFileSystemTabComp extends SimpleComp { }); var home = new BrowserOverviewComp(model).styleClass("browser-overview"); - var stack = new MultiContentComp(Map.of(home, showOverview, fileList, showOverview.not()), false); + var stack = new MultiContentComp(false, Map.of(home, showOverview, fileList, showOverview.not()), false); var r = stack.styleClass("browser-content-container").createRegion(); r.focusedProperty().addListener((observable, oldValue, newValue) -> { if (newValue) { diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java index 318ae2733..4f05cdcfe 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java @@ -288,21 +288,6 @@ public class BrowserFileTransferOperation { list.add(fileEntry); return true; }); - - for (FileEntry fileEntry : list) { - if (cancelled()) { - return; - } - - var rel = fileEntry.getPath().relativize(baseRelative).toUnix(); - flatFiles.put(fileEntry, rel); - if (fileEntry.getKind() == FileKind.FILE) { - // This one is up-to-date and does not need to be recalculated - // If we don't have a size, it doesn't matter that much as the total size is only for display - totalSize.addAndGet(fileEntry.getFileSizeLong().orElse(0)); - progress.accept(new BrowserTransferProgress(source.getName(), 0, totalSize.get())); - } - } } else { // Source might have been deleted meanwhile var exists = source.getFileSystem().fileExists(source.getPath()); diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserHistoryTabComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserHistoryTabComp.java index d76c46098..0b7b99bee 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserHistoryTabComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserHistoryTabComp.java @@ -61,7 +61,7 @@ public class BrowserHistoryTabComp extends SimpleComp { var map = new LinkedHashMap, ObservableValue>(); map.put(emptyDisplay, empty); map.put(contentDisplay, empty.not()); - var stack = new MultiContentComp(map, false); + var stack = new MultiContentComp(false, map, false); return stack.createRegion(); } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/JarMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/JarMenuProvider.java index 6d63e656c..4e2124bd9 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/JarMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/JarMenuProvider.java @@ -27,7 +27,11 @@ public class JarMenuProvider extends MultiExecuteMenuProvider @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { - return super.isApplicable(model, entries) && FileTypeMenuProvider.super.isApplicable(model, entries); + if (!BrowserApplicationPathMenuProvider.super.isApplicable(model, entries)) { + return false; + } + + return FileTypeMenuProvider.super.isApplicable(model, entries); } @Override diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/JavapMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/JavapMenuProvider.java index 7ec245138..3816a9386 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/JavapMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/JavapMenuProvider.java @@ -33,6 +33,10 @@ public class JavapMenuProvider @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { + if (!BrowserApplicationPathMenuProvider.super.isApplicable(model, entries) || !BrowserMenuLeafProvider.super.isApplicable(model, entries)) { + return false; + } + return FileTypeMenuProvider.super.isApplicable(model, entries); } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUntarMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUntarMenuProvider.java index 4fe616439..0f435d2f1 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUntarMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUntarMenuProvider.java @@ -49,7 +49,7 @@ public class BaseUntarMenuProvider implements BrowserApplicationPathMenuProvider @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { - if (model.getFileSystem().getShell().isEmpty()) { + if (!BrowserApplicationPathMenuProvider.super.isApplicable(model, entries) || !BrowserMenuLeafProvider.super.isApplicable(model, entries)) { return false; } diff --git a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUnzipUnixMenuProvider.java b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUnzipUnixMenuProvider.java index 0729fa726..c4a917ea5 100644 --- a/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUnzipUnixMenuProvider.java +++ b/app/src/main/java/io/xpipe/app/browser/menu/impl/compress/BaseUnzipUnixMenuProvider.java @@ -55,7 +55,7 @@ public abstract class BaseUnzipUnixMenuProvider implements BrowserMenuLeafProvid @Override public boolean isApplicable(BrowserFileSystemTabModel model, List entries) { - if (model.getFileSystem().getShell().isEmpty()) { + if (!BrowserApplicationPathMenuProvider.super.isApplicable(model, entries) || !BrowserMenuLeafProvider.super.isApplicable(model, entries)) { return false; } diff --git a/app/src/main/java/io/xpipe/app/comp/base/AppLayoutComp.java b/app/src/main/java/io/xpipe/app/comp/base/AppLayoutComp.java index d015eb750..78fbc222b 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/AppLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/AppLayoutComp.java @@ -41,7 +41,7 @@ public class AppLayoutComp extends Comp { model.getSelected()), (v1, v2) -> v2, LinkedHashMap::new)); - var multi = new MultiContentComp(map, true); + var multi = new MultiContentComp(true, map, true); multi.styleClass("background"); var pane = new BorderPane(); diff --git a/app/src/main/java/io/xpipe/app/comp/base/AppMainWindowContentComp.java b/app/src/main/java/io/xpipe/app/comp/base/AppMainWindowContentComp.java index df359bad5..3aed448a7 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/AppMainWindowContentComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/AppMainWindowContentComp.java @@ -10,8 +10,12 @@ import io.xpipe.app.platform.ColorHelper; import io.xpipe.app.platform.PlatformThread; import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.util.GlobalTimer; import javafx.animation.*; +import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.beans.property.SimpleStringProperty; import javafx.collections.ListChangeListener; import javafx.css.PseudoClass; import javafx.geometry.Pos; @@ -24,6 +28,8 @@ import javafx.scene.paint.Color; import javafx.stage.Stage; import javafx.stage.Window; +import java.time.Duration; + public class AppMainWindowContentComp extends SimpleComp { private final Stage stage; @@ -93,7 +99,22 @@ public class AppMainWindowContentComp extends SimpleComp { struc.get().setOpacity(0.65); }); - var text = new LabelComp(AppMainWindow.getLoadingText()); + var loadingTextCounter = new SimpleIntegerProperty(); + GlobalTimer.scheduleUntil(Duration.ofMillis(300), false, () -> { + if (loaded.getValue() != null) { + return true; + } + + loadingTextCounter.set((loadingTextCounter.get() + 1) % 4); + return false; + }); + var loadingTextAnimated = Bindings.createStringBinding(() -> { + return AppMainWindow.getLoadingText().getValue() + " " + + (".".repeat(loadingTextCounter.get() + 1)) + + (" ".repeat(3 - loadingTextCounter.get())); + }, AppMainWindow.getLoadingText(), loadingTextCounter); + var text = new LabelComp(loadingTextAnimated); + text.styleClass("loading-text"); text.apply(struc -> { struc.get().setOpacity(0.8); }); diff --git a/app/src/main/java/io/xpipe/app/comp/base/ContextualFileReferenceSync.java b/app/src/main/java/io/xpipe/app/comp/base/ContextualFileReferenceSync.java index 73b57357f..746fc8690 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ContextualFileReferenceSync.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ContextualFileReferenceSync.java @@ -67,6 +67,7 @@ public class ContextualFileReferenceSync { return true; } }); + event.expected(); event.handle(); if (rename.get()) { diff --git a/app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java b/app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java index 9db2828e3..eaaa59c37 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java @@ -17,7 +17,7 @@ public class InputGroupComp extends Comp> { private final List> entries; @Setter - private Comp heightReference; + private Comp mainReference; public InputGroupComp(List> comps) { entries = List.copyOf(comps); @@ -32,8 +32,8 @@ public class InputGroupComp extends Comp> { } b.setAlignment(Pos.CENTER); - if (heightReference != null && entries.contains(heightReference)) { - var refIndex = entries.indexOf(heightReference); + if (mainReference != null && entries.contains(mainReference)) { + var refIndex = entries.indexOf(mainReference); var ref = b.getChildren().get(refIndex); if (ref instanceof Region refR) { for (int i = 0; i < entries.size(); i++) { @@ -51,6 +51,12 @@ public class InputGroupComp extends Comp> { entryR.prefHeightProperty().bind(refR.heightProperty()); } } + + b.focusedProperty().addListener((observable, oldValue, newValue) -> { + if (newValue) { + ref.requestFocus(); + } + }); } return new SimpleCompStructure<>(b); diff --git a/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java b/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java index d138da7d3..7cd87dc22 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/MultiContentComp.java @@ -17,10 +17,12 @@ import java.util.Map; public class MultiContentComp extends SimpleComp { + private final boolean requestFocus; private final boolean log; private final Map, ObservableValue> content; - public MultiContentComp(Map, ObservableValue> content, boolean log) { + public MultiContentComp(boolean requestFocus, Map, ObservableValue> content, boolean log) { + this.requestFocus = requestFocus; this.log = log; this.content = FXCollections.observableMap(content); } @@ -62,7 +64,7 @@ public class MultiContentComp extends SimpleComp { PlatformThread.runLaterIfNeeded(() -> { r.setManaged(val); r.setVisible(val); - if (val) { + if (requestFocus && val) { Platform.runLater(() -> { r.requestFocus(); }); diff --git a/app/src/main/java/io/xpipe/app/comp/base/SecretFieldComp.java b/app/src/main/java/io/xpipe/app/comp/base/SecretFieldComp.java index 7af25f6bc..74b367cf5 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/SecretFieldComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/SecretFieldComp.java @@ -100,7 +100,7 @@ public class SecretFieldComp extends Comp { capsPopover.hide(); return; } - if (!capsPopover.isShowing()) { + if (!capsPopover.isShowing() && field.getScene() != null) { capsPopover.show(field); } }); @@ -114,13 +114,15 @@ public class SecretFieldComp extends Comp { .tooltipKey("copyPassword"); var list = new ArrayList>(); - list.add(Comp.of(() -> field)); + var fieldComp = Comp.of(() -> field); + list.add(fieldComp); if (allowCopy) { list.add(copyButton); } list.addAll(additionalButtons); var ig = new InputGroupComp(list); + ig.setMainReference(fieldComp); ig.styleClass("secret-field-comp"); ig.apply(struc -> { struc.get().focusedProperty().addListener((c, o, n) -> { diff --git a/app/src/main/java/io/xpipe/app/core/check/AppDirectoryPermissionsCheck.java b/app/src/main/java/io/xpipe/app/core/check/AppDirectoryPermissionsCheck.java index 44ca07b5e..f1f43100e 100644 --- a/app/src/main/java/io/xpipe/app/core/check/AppDirectoryPermissionsCheck.java +++ b/app/src/main/java/io/xpipe/app/core/check/AppDirectoryPermissionsCheck.java @@ -20,6 +20,14 @@ public class AppDirectoryPermissionsCheck { throw new IOException("Directory creation in " + dataDirectory + " failed silently"); } Files.delete(testDirectory); + + // For cloud providers like OneDrive, we need another check to guarantee that all files are synced + // The file operation might fail if the directory is designated to sync but the actual file is not downloaded yet + var testFile = dataDirectory.resolve("sync_file"); + if (!Files.exists(testFile)) { + Files.createFile(testFile); + } + Files.readString(testFile); } catch (IOException e) { var message = "Unable to access directory " + dataDirectory + "."; if (OsType.ofLocal() == OsType.WINDOWS) { diff --git a/app/src/main/java/io/xpipe/app/ext/FileSystem.java b/app/src/main/java/io/xpipe/app/ext/FileSystem.java index 41b924d6b..b0a9c683b 100644 --- a/app/src/main/java/io/xpipe/app/ext/FileSystem.java +++ b/app/src/main/java/io/xpipe/app/ext/FileSystem.java @@ -109,17 +109,29 @@ public interface FileSystem extends Closeable, AutoCloseable { base = filesStream.toList(); } - for (FileEntry fileEntry : base) { - if (!visitor.test(fileEntry)) { - return; - } + if (base.size() != 1) { + for (FileEntry fileEntry : base) { + // False will cancel the whole traversal + if (!visitor.test(fileEntry)) { + return; + } - if (fileEntry.getKind() != FileKind.DIRECTORY) { - continue; - } + if (fileEntry.getKind() != FileKind.DIRECTORY) { + continue; + } - traverseFilesRecursively(system, fileEntry.getPath(), visitor); + traverseFilesRecursively(system, fileEntry.getPath(), visitor); + } + return; } + + // Optimize this call to use tail recursion if possible + + if (!visitor.test(base.getFirst()) || base.getFirst().getKind() != FileKind.DIRECTORY) { + return; + } + + traverseFilesRecursively(system, base.getFirst().getPath(), visitor); } List listRoots() throws Exception; diff --git a/app/src/main/java/io/xpipe/app/ext/SelfReferentialStore.java b/app/src/main/java/io/xpipe/app/ext/SelfReferentialStore.java index 862f44d11..615a888d4 100644 --- a/app/src/main/java/io/xpipe/app/ext/SelfReferentialStore.java +++ b/app/src/main/java/io/xpipe/app/ext/SelfReferentialStore.java @@ -11,6 +11,18 @@ public interface SelfReferentialStore extends DataStore { Map FALLBACK = new HashMap<>(); + default boolean hasSelfEntry() { + if (DataStorage.get() == null) { + return false; + } + + return DataStorage.get() + .getStoreEntryIfPresent(this, true) + .or(() -> { + return DataStorage.get().getStoreEntryInProgressIfPresent(this); + }).isPresent(); + } + default DataStoreEntry getSelfEntry() { if (DataStorage.get() == null) { return DataStoreEntry.createTempWrapper(this); diff --git a/app/src/main/java/io/xpipe/app/hub/action/BatchStoreAction.java b/app/src/main/java/io/xpipe/app/hub/action/BatchStoreAction.java index 13a8c581b..423e7dc2e 100644 --- a/app/src/main/java/io/xpipe/app/hub/action/BatchStoreAction.java +++ b/app/src/main/java/io/xpipe/app/hub/action/BatchStoreAction.java @@ -41,7 +41,9 @@ public final class BatchStoreAction extends SerializableAct @Override public void executeImpl() throws Exception { for (AbstractAction action : actions) { - action.executeImpl(); + if (!action.executeSyncImpl(true)) { + break; + } } } diff --git a/app/src/main/java/io/xpipe/app/hub/action/impl/OpenHubMenuLeafProvider.java b/app/src/main/java/io/xpipe/app/hub/action/impl/OpenHubMenuLeafProvider.java index 4673a9172..6c7ca12b7 100644 --- a/app/src/main/java/io/xpipe/app/hub/action/impl/OpenHubMenuLeafProvider.java +++ b/app/src/main/java/io/xpipe/app/hub/action/impl/OpenHubMenuLeafProvider.java @@ -9,6 +9,7 @@ import io.xpipe.app.hub.action.StoreActionCategory; import io.xpipe.app.platform.LabelGraphic; import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.ThreadHelper; import javafx.beans.value.ObservableValue; import lombok.experimental.SuperBuilder; @@ -69,6 +70,9 @@ public class OpenHubMenuLeafProvider implements HubLeafProvider, Batc public void executeImpl() throws Exception { var r = ref.get().getProvider().launch(ref.get()); r.run(); + + // Terminal launching is done async, so to show the busy marker, just wait here + ThreadHelper.sleep(1000); } } } diff --git a/app/src/main/java/io/xpipe/app/hub/action/impl/RefreshHubLeafProvider.java b/app/src/main/java/io/xpipe/app/hub/action/impl/RefreshHubLeafProvider.java new file mode 100644 index 000000000..a779cd4d8 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/hub/action/impl/RefreshHubLeafProvider.java @@ -0,0 +1,44 @@ +package io.xpipe.app.hub.action.impl; + +import io.xpipe.app.action.AbstractAction; +import io.xpipe.app.core.AppI18n; +import io.xpipe.app.ext.ShellStore; +import io.xpipe.app.hub.action.HubLeafProvider; +import io.xpipe.app.hub.action.StoreAction; +import io.xpipe.app.hub.action.StoreActionCategory; +import io.xpipe.app.platform.LabelGraphic; +import io.xpipe.app.process.ShellTtyState; +import io.xpipe.app.process.SystemState; +import io.xpipe.app.storage.DataStoreEntryRef; +import io.xpipe.app.util.ScanDialog; +import javafx.beans.value.ObservableValue; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +public class RefreshHubLeafProvider implements HubLeafProvider { + + @Override + public StoreActionCategory getCategory() { + return StoreActionCategory.CONFIGURATION; + } + + @Override + public ObservableValue getName(DataStoreEntryRef store) { + return AppI18n.observable("refresh"); + } + + @Override + public LabelGraphic getIcon(DataStoreEntryRef store) { + return new LabelGraphic.IconGraphic("mdi2r-refresh"); + } + + @Override + public Class getApplicableClass() { + return ShellStore.class; + } + + @Override + public AbstractAction createAction(DataStoreEntryRef ref) { + return RefreshActionProvider.Action.builder().ref(ref.asNeeded()).build(); + } +} diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryConfigComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryConfigComp.java index 2cbb99f2c..5e632e2dc 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryConfigComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryConfigComp.java @@ -88,27 +88,30 @@ public class StoreCategoryConfigComp extends SimpleComp { }); }); - var options = new OptionsBuilder() - .nameAndDescription("categorySync") + var options = new OptionsBuilder(); + + var specialCategorySync = !wrapper.getCategory().canShare(); + var syncDisable = !DataStorage.get().supportsSync() + || ((sync.getValue() == null || !sync.getValue()) + && !wrapper.getCategory().canShare()); + var syncHide = !DataStorage.get().supportsSync(); + options.name(specialCategorySync ? AppI18n.observable("categorySyncSpecial", wrapper.getName().getValue()) : AppI18n.observable("categorySync")) + .description("categorySyncDescription") .addYesNoToggle(sync) - .hide(!DataStorage.get().supportsSync() - || ((sync.getValue() == null || !sync.getValue()) - && !wrapper.getCategory().canShare())) + .disable(syncDisable) + .hide(syncHide) .nameAndDescription("categoryDontAllowScripts") .addYesNoToggle(scripts) .hide(!connectionsCategory) .nameAndDescription("categoryConfirmAllModifications") .addYesNoToggle(confirm) + .hide(!connectionsCategory) .nameAndDescription("categoryFreeze") .addYesNoToggle(freeze) .hide(!connectionsCategory) .nameAndDescription("categoryDefaultIdentity") .addComp( - StoreChoiceComp.other( - ref, - DataStore.class, - s -> true, - StoreViewState.get().getAllIdentitiesCategory()), + new StoreChoiceComp<>(null, ref, DataStore.class, null, StoreViewState.get().getAllIdentitiesCategory()), ref) .hide(!connectionsCategory) .nameAndDescription("categoryColor") @@ -123,9 +126,8 @@ public class StoreCategoryConfigComp extends SimpleComp { freeze.get(), ref.get() != null ? ref.get().get().getUuid() : null); }, - config) - .buildComp(); - var r = options.createRegion(); + config); + var r = options.build(); var sp = new ScrollPane(r); sp.setFitToWidth(true); sp.prefHeightProperty().bind(r.heightProperty()); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java index 0d4efb570..89dc8b5f7 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java @@ -182,10 +182,18 @@ public class StoreCategoryWrapper { } var directFiltered = directContainedEntries.getList().stream() - .filter(storeEntryWrapper -> storeEntryWrapper.includeInConnectionCount() - && storeEntryWrapper.matchesFilter( - StoreViewState.get().getFilterString().getValue())) + .filter(storeEntryWrapper -> { + var filter = StoreViewState.get().getFilterString().getValue(); + if (filter != null) { + var matches = storeEntryWrapper.matchesFilter(filter); + return matches; + } + + return storeEntryWrapper.includeInConnectionCount(); + }) .count(); + // Due to always including filtered entries, there is the possibility of exceeding the direct count + directFiltered = Math.min(directFiltered, direct); var subFiltered = children.getList().stream() .mapToInt(value -> value.shownContainedEntriesCount.get()) .sum(); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java index ec4e74a5e..027b25786 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java @@ -1,5 +1,6 @@ package io.xpipe.app.hub.comp; +import atlantafx.base.theme.Styles; import io.xpipe.app.comp.Comp; import io.xpipe.app.comp.SimpleComp; import io.xpipe.app.comp.base.*; @@ -17,6 +18,7 @@ import javafx.beans.property.*; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.input.MouseButton; +import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; @@ -28,23 +30,17 @@ import java.util.function.Predicate; @RequiredArgsConstructor public class StoreChoiceComp extends SimpleComp { - private final Mode mode; - private final Property> selected; + private final ObjectProperty> selected; private final StoreChoicePopover popover; public StoreChoiceComp( - Mode mode, DataStoreEntry self, - Property> selected, + ObjectProperty> selected, Class storeClass, Predicate> applicableCheck, StoreCategoryWrapper initialCategory) { - - this.mode = mode; - this.selected = selected; - this.popover = new StoreChoicePopover<>( self, selected, @@ -55,29 +51,12 @@ public class StoreChoiceComp extends SimpleComp { "noCompatibleConnection"); } - public static StoreChoiceComp other( - Property> selected, - Class clazz, - Predicate> filter, - StoreCategoryWrapper initialCategory) { - return new StoreChoiceComp<>(Mode.OTHER, null, selected, clazz, filter, initialCategory); - } - - public static StoreChoiceComp host( - Property> selected, StoreCategoryWrapper initialCategory) { - return new StoreChoiceComp<>(Mode.HOST, null, selected, ShellStore.class, null, initialCategory); - } - private String toName(DataStoreEntry entry) { if (entry == null) { return null; } - if (mode == Mode.PROXY && entry.getStore() instanceof LocalStore) { - return AppI18n.get("none"); - } - - return entry.getName(); + return DataStorage.get().getStoreEntryDisplayName(entry); } @Override @@ -116,37 +95,48 @@ public class StoreChoiceComp extends SimpleComp { return; } - selected.setValue( - mode == Mode.PROXY ? DataStorage.get().local().ref() : null); + selected.setValue(null); event.consume(); }); }) .styleClass("choice-comp"); - var r = button.grow(true, false).accessibleText("Select connection").createRegion(); - var icon = new FontIcon("mdal-keyboard_arrow_down"); - icon.setDisable(true); - icon.setPickOnBounds(false); - icon.visibleProperty().bind(r.disabledProperty().not()); - AppFontSizes.xl(icon); - var pane = new StackPane(r, icon); + var r = button.accessibleText("Select connection").createRegion(); + + var dropdownIcon = new FontIcon("mdal-keyboard_arrow_down"); + dropdownIcon.setDisable(true); + dropdownIcon.setPickOnBounds(false); + dropdownIcon.visibleProperty().bind(r.disabledProperty().not()); + AppFontSizes.xl(dropdownIcon); + + var pane = new AnchorPane(r, dropdownIcon); pane.focusedProperty().addListener((observable, oldValue, newValue) -> { if (newValue) { r.requestFocus(); } }); - StackPane.setMargin(icon, new Insets(10)); + AnchorPane.setTopAnchor(dropdownIcon, 11.0); + AnchorPane.setRightAnchor(dropdownIcon, 7.0); + AnchorPane.setRightAnchor(r, 0.0); + AnchorPane.setLeftAnchor(r, 0.0); pane.setPickOnBounds(false); - StackPane.setAlignment(icon, Pos.CENTER_RIGHT); pane.setMaxWidth(20000); - r.prefWidthProperty().bind(pane.widthProperty()); - r.maxWidthProperty().bind(pane.widthProperty()); + + var clearButton = new IconButtonComp("mdi2c-close", () -> { + selected.setValue(null); + }); + clearButton.styleClass(Styles.FLAT); + clearButton.hide(selected.isNull().or(pane.disabledProperty())); + clearButton.apply(struc -> { + struc.get().setOpacity(0.7); + struc.get().getStyleClass().add("clear-button"); + AppFontSizes.xs(struc.get()); + AnchorPane.setRightAnchor(struc.get(), 30.0); + AnchorPane.setTopAnchor(struc.get(), 3.0); + AnchorPane.setBottomAnchor(struc.get(), 3.0); + }); + pane.getChildren().add(clearButton.createRegion()); + return pane; } - - public enum Mode { - HOST, - OTHER, - PROXY - } } diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java index 763070494..ee659857b 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java @@ -31,6 +31,7 @@ import org.kordamp.ikonli.javafx.FontIcon; import java.util.List; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; @RequiredArgsConstructor @@ -43,8 +44,13 @@ public class StoreChoicePopover { private final StoreCategoryWrapper initialCategory; private final String titleKey; private final String noMatchKey; + private Consumer consumer; private Popover popover; + public void withPopover(Consumer consumer) { + this.consumer = consumer; + } + public void show(Node node) { var p = getPopover(); if (!p.isShowing()) { @@ -60,7 +66,7 @@ public class StoreChoicePopover { } } - public Popover getPopover() { + private Popover getPopover() { // Rebuild popover if we have a non-null condition to allow for the content to be updated in case the condition // changed if (popover == null || applicableCheck != null) { @@ -208,6 +214,10 @@ public class StoreChoicePopover { AppDialog.getModalOverlays().addListener((ListChangeListener) c -> { popover.hide(); }); + + if (consumer != null) { + consumer.accept(popover); + } } return popover; diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java index 90fd7beb0..e7e6817dc 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java @@ -2,6 +2,7 @@ package io.xpipe.app.hub.comp; import io.xpipe.app.comp.SimpleComp; import io.xpipe.app.ext.DataStore; +import io.xpipe.app.issue.ErrorEventFactory; import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.platform.PlatformThread; import io.xpipe.app.storage.DataStoreEntry; @@ -12,6 +13,7 @@ import javafx.beans.property.Property; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.control.ComboBox; +import javafx.scene.control.ComboBoxBase; import javafx.scene.control.skin.ComboBoxListViewSkin; import javafx.scene.layout.Region; @@ -98,7 +100,15 @@ public class StoreComboChoiceComp extends SimpleComp { protected Region createSimple() { var combo = new ComboBox(); - ((Region) popover.getPopover().getContentNode()).setMaxHeight(350); + popover.withPopover(po -> { + ((Region) po.getContentNode()).setMaxHeight(350); + po.showingProperty().addListener((o, oldValue, newValue) -> { + if (!newValue) { + combo.hide(); + } + }); + }); + var skin = new ComboBoxListViewSkin<>(combo) { @Override public void show() { @@ -110,11 +120,6 @@ public class StoreComboChoiceComp extends SimpleComp { popover.hide(); } }; - popover.getPopover().showingProperty().addListener((o, oldValue, newValue) -> { - if (!newValue) { - combo.hide(); - } - }); combo.setSkin(skin); combo.setMaxWidth(20000); combo.setEditable(true); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationDialog.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationDialog.java index edbd527d2..f3abbccd4 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationDialog.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCreationDialog.java @@ -63,9 +63,7 @@ public class StoreCreationDialog { .getStoreCategoryIfPresent(e.getCategoryUuid()) .orElseThrow(); PlatformThread.runLaterIfNeeded(() -> { - StoreViewState.get() - .getActiveCategory() - .setValue(StoreViewState.get().getCategoryWrapper(cat)); + StoreViewState.get().selectCategoryIntoViewIfNeeded(StoreViewState.get().getCategoryWrapper(cat)); }); c.accept(e); @@ -106,9 +104,7 @@ public class StoreCreationDialog { .getStoreCategoryIfPresent(e.getCategoryUuid()) .orElseThrow(); PlatformThread.runLaterIfNeeded(() -> { - StoreViewState.get() - .getActiveCategory() - .setValue(StoreViewState.get().getCategoryWrapper(cat)); + StoreViewState.get().selectCategoryIntoViewIfNeeded(StoreViewState.get().getCategoryWrapper(cat)); }); } } catch (Exception ex) { diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java index b13e56903..20edbfa41 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryListComp.java @@ -162,6 +162,6 @@ public class StoreEntryListComp extends SimpleComp { map.put(new StoreScriptsIntroComp(scriptsIntroShowing), showScriptsIntro); map.put(new StoreIdentitiesIntroComp(), showIdentitiesIntro); - return new MultiContentComp(map, false).createRegion(); + return new MultiContentComp(false, map, false).createRegion(); } } diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreListChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreListChoiceComp.java index 929384a3b..0dfb75964 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreListChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreListChoiceComp.java @@ -101,8 +101,7 @@ public class StoreListChoiceComp extends SimpleComp { .apply(struc -> struc.get().setMinHeight(0)) .apply(struc -> ((VBox) struc.get().getContent()).setSpacing(5)); var selected = new SimpleObjectProperty>(); - var add = new StoreChoiceComp<>( - StoreChoiceComp.Mode.OTHER, null, selected, storeClass, applicableCheck, initialCategory); + var add = new StoreChoiceComp<>(null, selected, storeClass, applicableCheck, initialCategory); selected.addListener((observable, oldValue, newValue) -> { if (newValue != null) { if (!selectedList.contains(newValue) && (applicableCheck == null || applicableCheck.test(newValue))) { diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java index 68a1c6dab..6a759e5e2 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java @@ -12,7 +12,6 @@ import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.StorageListener; -import io.xpipe.app.util.ThreadHelper; import javafx.application.Platform; import javafx.beans.Observable; import javafx.beans.binding.Bindings; @@ -246,7 +245,21 @@ public class StoreViewState { .anyMatch(wrapper -> wrapper.matchesFilter(newValue))) .toList(); if (matchingCats.size() == 1) { - activeCategory.setValue(matchingCats.getFirst()); + var onlyMatch = matchingCats.getFirst(); + selectCategoryIntoViewIfNeeded(onlyMatch); + } + } + + public void selectCategoryIntoViewIfNeeded(StoreCategoryWrapper category) { + StoreCategoryWrapper matchingParent = category; + while ((matchingParent = matchingParent.getParent()) != null) { + if (matchingParent.equals(activeCategory.getValue())) { + break; + } + } + + if (matchingParent == null) { + activeCategory.setValue(category); } } diff --git a/app/src/main/java/io/xpipe/app/issue/ErrorHandlerDialog.java b/app/src/main/java/io/xpipe/app/issue/ErrorHandlerDialog.java index 32b2db119..8d7aa8f68 100644 --- a/app/src/main/java/io/xpipe/app/issue/ErrorHandlerDialog.java +++ b/app/src/main/java/io/xpipe/app/issue/ErrorHandlerDialog.java @@ -46,7 +46,7 @@ public class ErrorHandlerDialog { "stackTrace", () -> { var detailsModal = ModalOverlay.of("errorDetails", Comp.of(() -> { - var content = createStrackTraceContent(event); + var content = createStackTraceContent(event); content.setPrefWidth(650); content.setPrefHeight(750); return content; @@ -86,7 +86,7 @@ public class ErrorHandlerDialog { } } - private static Region createStrackTraceContent(ErrorEvent event) { + private static Region createStackTraceContent(ErrorEvent event) { if (event.getThrowable() != null) { String stackTrace = Deobfuscator.deobfuscateToString(event.getThrowable()); if (event.getThrowable() instanceof ProcessOutputException pex) { diff --git a/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java b/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java index d90fd5f0e..dff7b58b1 100644 --- a/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java +++ b/app/src/main/java/io/xpipe/app/issue/GuiErrorHandler.java @@ -5,6 +5,7 @@ import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.platform.LabelGraphic; import io.xpipe.app.util.LicenseProvider; import io.xpipe.app.util.LicenseRequiredException; +import org.kordamp.ikonli.javafx.FontIcon; import java.time.Duration; import java.util.stream.Stream; @@ -32,7 +33,12 @@ public class GuiErrorHandler extends GuiErrorHandlerBase implements ErrorHandler .showQueueEntry( new AppLayoutModel.QueueEntry( AppI18n.observable("errorOccurred"), - new LabelGraphic.IconGraphic("mdoal-error_outline"), + new LabelGraphic.NodeGraphic(() -> { + var graphic = new FontIcon("mdoal-error_outline"); + graphic.getStyleClass().add("graphic"); + graphic.getStyleClass().add("error"); + return graphic; + }), () -> { handleGui(event); }), diff --git a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java index 5ff03bcf8..93194853b 100644 --- a/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java +++ b/app/src/main/java/io/xpipe/app/prefs/AppPrefs.java @@ -823,14 +823,7 @@ public final class AppPrefs { continue; } - var def = value.getProperty().getValue(); - var r = loadValue(vaultStorageHandler, value); - - // This can be used to facilitate backwards compatibility - var isDefault = Objects.equals(r, def); - if (isDefault) { - loadValue(globalStorageHandler, value); - } + loadValue(vaultStorageHandler, value); } if (OsType.ofLocal() != OsType.WINDOWS) { @@ -853,12 +846,11 @@ public final class AppPrefs { } @SuppressWarnings("unchecked") - private T loadValue(AppPrefsStorageHandler handler, Mapping value) { + private void loadValue(AppPrefsStorageHandler handler, Mapping value) { T def = (T) value.getProperty().getValue(); Property property = (Property) value.getProperty(); var val = handler.loadObject(value.getKey(), value.getValueType(), def, value.isLog()); property.setValue(val); - return val; } public synchronized void save() { diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java index 600a9e054..22ab4eab3 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java @@ -13,6 +13,7 @@ import io.xpipe.core.OsType; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.util.Optional; @@ -160,7 +161,14 @@ public interface ExternalApplicationType extends PrefsValue { String name = getExecutable(); var out = sc.view().findProgram(name); if (out.isPresent()) { - return out.map(filePath -> Path.of(filePath.toString())); + return out.flatMap(filePath -> { + try { + return Optional.of(Path.of(filePath.toString())); + } catch (InvalidPathException ex) { + ErrorEventFactory.fromThrowable(ex).omit().handle(); + return Optional.empty(); + } + }); } } catch (Exception ex) { ErrorEventFactory.fromThrowable(ex).omit().handle(); diff --git a/app/src/main/java/io/xpipe/app/prefs/LoggingCategory.java b/app/src/main/java/io/xpipe/app/prefs/LoggingCategory.java index d1eb4ab62..fc20676dc 100644 --- a/app/src/main/java/io/xpipe/app/prefs/LoggingCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/LoggingCategory.java @@ -31,7 +31,7 @@ public class LoggingCategory extends AppPrefsCategory { .addTitle("sessionLogging") .sub(new OptionsBuilder() .pref(prefs.enableTerminalLogging) - .documentationLink(DocumentationLink.API) + .documentationLink(DocumentationLink.TERMINAL_LOGGING) .addToggle(prefs.enableTerminalLogging) .nameAndDescription("terminalLoggingDirectory") .addComp(new ButtonComp(AppI18n.observable("openSessionLogs"), () -> { diff --git a/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java b/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java index 6122c0609..39dbf43c1 100644 --- a/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java +++ b/app/src/main/java/io/xpipe/app/prefs/TerminalCategory.java @@ -215,7 +215,6 @@ public class TerminalCategory extends AppPrefsCategory { var proxyChoice = new DelayedInitComp( Comp.of(() -> { var comp = new StoreChoiceComp<>( - StoreChoiceComp.Mode.PROXY, null, ref, ShellStore.class, diff --git a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java index e65564c8f..7c6387d38 100644 --- a/app/src/main/java/io/xpipe/app/storage/StandardStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/StandardStorage.java @@ -351,6 +351,7 @@ public class StandardStorage extends DataStorage { // If another save operation is in progress, we have to wait on dispose // Otherwise the application may quit and kill the daemon thread that is performing the other save operation if (dispose && !busyIo.tryLock(1, TimeUnit.MINUTES)) { + disposed = true; return; } } catch (InterruptedException e) { diff --git a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java index 2c23dabbc..919bbe875 100644 --- a/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java +++ b/app/src/main/java/io/xpipe/app/terminal/ExternalTerminalType.java @@ -519,13 +519,13 @@ public interface ExternalTerminalType extends PrefsChoiceValue { TERMIUS, WaveTerminalType.WAVE_LINUX); List MACOS_TERMINALS = List.of( - WarpTerminalType.MACOS, ITERM2, KittyTerminalType.KITTY_MACOS, TabbyTerminalType.TABBY_MAC_OS, AlacrittyTerminalType.ALACRITTY_MAC_OS, WezTerminalType.WEZTERM_MAC_OS, GhosttyTerminalType.GHOSTTY_MACOS, + WarpTerminalType.MACOS, MACOS_TERMINAL, TERMIUS, WaveTerminalType.WAVE_MAC_OS); diff --git a/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java b/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java index e446fe0d5..1a48a41d7 100644 --- a/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java +++ b/app/src/main/java/io/xpipe/app/terminal/TerminalPrompt.java @@ -45,7 +45,7 @@ public interface TerminalPrompt { checkCanInstall(sc); install(sc); } catch (Exception e) { - ErrorEventFactory.fromThrowable(e).omit().handle(); + ErrorEventFactory.fromThrowable(e).omit().description("Prompt installation for " + getId() + " failed on remote system").expected().handle(); return false; } return true; diff --git a/app/src/main/java/io/xpipe/app/terminal/WarpTerminalType.java b/app/src/main/java/io/xpipe/app/terminal/WarpTerminalType.java index 82dd782d8..5a53d3cc3 100644 --- a/app/src/main/java/io/xpipe/app/terminal/WarpTerminalType.java +++ b/app/src/main/java/io/xpipe/app/terminal/WarpTerminalType.java @@ -56,7 +56,7 @@ public interface WarpTerminalType extends ExternalTerminalType, TrackableTermina @Override public int getProcessHierarchyOffset() { - return 1; + return 0; } @Override diff --git a/app/src/main/java/io/xpipe/app/util/Deobfuscator.java b/app/src/main/java/io/xpipe/app/util/Deobfuscator.java index 2a79b4f6e..33837de2c 100644 --- a/app/src/main/java/io/xpipe/app/util/Deobfuscator.java +++ b/app/src/main/java/io/xpipe/app/util/Deobfuscator.java @@ -2,6 +2,7 @@ package io.xpipe.app.util; import io.xpipe.app.core.AppNames; import io.xpipe.core.OsType; +import org.apache.commons.lang3.exception.ExceptionUtils; import java.io.PrintWriter; import java.io.StringWriter; @@ -11,11 +12,8 @@ import java.nio.file.Path; public class Deobfuscator { public static String deobfuscateToString(Throwable t) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - String stackTrace = sw.toString(); - stackTrace = stackTrace.replaceAll("at .+/(.+)", "at $1"); + String stackTrace = ExceptionUtils.getStackTrace(t); + stackTrace = stackTrace.replaceAll("\tat .+/(.+)", "\tat $1"); try { if (!canDeobfuscate()) { diff --git a/app/src/main/java/io/xpipe/app/util/DesktopHelper.java b/app/src/main/java/io/xpipe/app/util/DesktopHelper.java index ccbfc4f02..02eb25070 100644 --- a/app/src/main/java/io/xpipe/app/util/DesktopHelper.java +++ b/app/src/main/java/io/xpipe/app/util/DesktopHelper.java @@ -20,10 +20,6 @@ public class DesktopHelper { return; } - if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { - return; - } - URI parsed; try { parsed = URI.create(uri); @@ -33,6 +29,13 @@ public class DesktopHelper { return; } + if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { + if (OsType.ofLocal() == OsType.LINUX) { + LocalExec.readStdoutIfPossible("xdg-open", parsed.toString()); + return; + } + } + // This can be a blocking operation ThreadHelper.runAsync(() -> { try { @@ -57,6 +60,13 @@ public class DesktopHelper { return; } + if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { + if (OsType.ofLocal() == OsType.LINUX) { + LocalExec.readStdoutIfPossible("xdg-open", file.toString()); + return; + } + } + // This can be a blocking operation ThreadHelper.runAsync(() -> { if (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { @@ -88,11 +98,7 @@ public class DesktopHelper { // Windows does not support Action.BROWSE_FILE_DIR if (OsType.ofLocal() == OsType.WINDOWS) { // Explorer does not support single quotes, so use normal quotes - if (Files.isDirectory(file)) { - LocalExec.readStdoutIfPossible("explorer", "\"" + file + "\""); - } else { - LocalExec.readStdoutIfPossible("explorer", "/select,", "\"" + file + "\""); - } + LocalExec.readStdoutIfPossible("explorer", "/select,", "\"" + file + "\""); return; } diff --git a/app/src/main/java/io/xpipe/app/util/DocumentationLink.java b/app/src/main/java/io/xpipe/app/util/DocumentationLink.java index a5e63d4f7..493a480e5 100644 --- a/app/src/main/java/io/xpipe/app/util/DocumentationLink.java +++ b/app/src/main/java/io/xpipe/app/util/DocumentationLink.java @@ -15,7 +15,7 @@ public enum DocumentationLink { PRIVACY("legal/privacy"), EULA("legal/eula"), WEBTOP_UPDATE("guide/webtop#updating"), - WEBTOP_TUN("guide/webtop##networking-tailscale-and-netbird"), + WEBTOP_TUN("guide/webtop#networking-tailscale-and-netbird"), SYNC("guide/sync"), SYNC_LOCAL("guide/sync#local-repositories"), DESKTOP_APPLICATIONS("guide/desktop-applications"), @@ -72,6 +72,7 @@ public enum DocumentationLink { SSH_MACS("troubleshoot/ssh#no-matching-mac-found"), SSH_JUMP_SERVERS("guide/ssh#gateways-and-jump-servers"), SSH_CUSTOM("guide/ssh-config#custom-ssh-connections"), + SSH_CUSTOM_ORDER("guide/ssh-config#jump-hosts"), KEEPASSXC("guide/password-manager#keepassxc"), PASSWORD_MANAGER("guide/password-manager"), VNC_CLIENTS("guide/vnc#external-clients"), diff --git a/app/src/main/java/io/xpipe/app/util/RemminaHelper.java b/app/src/main/java/io/xpipe/app/util/RemminaHelper.java index 20e63eac5..91848745f 100644 --- a/app/src/main/java/io/xpipe/app/util/RemminaHelper.java +++ b/app/src/main/java/io/xpipe/app/util/RemminaHelper.java @@ -58,9 +58,14 @@ public class RemminaHelper { user = user.split("\\\\")[1]; } + var w = Math.round(AppMainWindow.get().getStage().getWidth()); + // Remmina's height calculation does not take the titlebar into account + var h = Math.round(AppMainWindow.get().getStage().getHeight()) - 38; + // Use window size as remmina's autosize is broken + var maximize = "0"; // AppMainWindow.get().getStage().isMaximized() ? "1" : "0"; + var name = OsFileSystem.ofLocal().makeFileSystemCompatible(configuration.getTitle()); var file = ShellTemp.getLocalTempDataDirectory(null).resolve("xpipe-" + name + ".remmina"); - // Use window size as remmina's autosize is broken var string = """ [remmina] @@ -74,6 +79,7 @@ public class RemminaHelper { scale=2 window_width=%s window_height=%s + window_maximize=%s """ .formatted( configuration.getTitle(), @@ -85,8 +91,9 @@ public class RemminaHelper { .orElseThrow() .getValue(), password != null ? password : "", - Math.round(AppMainWindow.get().getStage().getWidth()), - Math.round(AppMainWindow.get().getStage().getHeight())); + w, + h, + maximize); Files.createDirectories(file.getParent()); Files.writeString(file, string); return file; @@ -95,6 +102,13 @@ public class RemminaHelper { public static Path writeRemminaVncConfigFile(VncLaunchConfig configuration, String password) throws Exception { var name = OsFileSystem.ofLocal().makeFileSystemCompatible(configuration.getTitle()); var file = ShellTemp.getLocalTempDataDirectory(null).resolve("xpipe-" + name + ".remmina"); + + var w = Math.round(AppMainWindow.get().getStage().getWidth()); + // Remmina's height calculation does not take the titlebar into account + var h = Math.round(AppMainWindow.get().getStage().getHeight()) - 38; + // Use window size as remmina's autosize is broken + var maximize = "0"; // AppMainWindow.get().getStage().isMaximized() ? "1" : "0"; + var string = """ [remmina] @@ -104,12 +118,18 @@ public class RemminaHelper { server=%s password=%s colordepth=32 + window_width=%s + window_height=%s + window_maximize=%s """ .formatted( configuration.getTitle(), configuration.retrieveUsername().orElse(""), configuration.getHost() + ":" + configuration.getPort(), - password != null ? password : ""); + password != null ? password : "", + w, + h, + maximize); Files.createDirectories(file.getParent()); Files.writeString(file, string); return file; diff --git a/app/src/main/java/io/xpipe/app/util/ScanSingleDialogComp.java b/app/src/main/java/io/xpipe/app/util/ScanSingleDialogComp.java index 89f636762..6726399f9 100644 --- a/app/src/main/java/io/xpipe/app/util/ScanSingleDialogComp.java +++ b/app/src/main/java/io/xpipe/app/util/ScanSingleDialogComp.java @@ -64,11 +64,10 @@ class ScanSingleDialogComp extends ModalOverlayContentComp { .name("scanAlertChoiceHeader") .description("scanAlertChoiceHeaderDescription") .addComp(new StoreChoiceComp<>( - StoreChoiceComp.Mode.OTHER, null, entry, ShellStore.class, - store1 -> true, + null, StoreViewState.get().getAllConnectionsCategory()) .disable(base.getBusy().or(new SimpleBooleanProperty(initialStore != null)))) .name("scanAlertHeader") diff --git a/app/src/main/java/module-info.java b/app/src/main/java/module-info.java index a795ea60f..dc390d4ee 100644 --- a/app/src/main/java/module-info.java +++ b/app/src/main/java/module-info.java @@ -126,6 +126,7 @@ open module io.xpipe.app { uses CloudSetupProvider; provides ActionProvider with + RefreshHubLeafProvider, SetupToolActionProvider, XPipeUrlProvider, OpenHubMenuLeafProvider, diff --git a/app/src/main/resources/io/xpipe/app/resources/style/choice-comp.css b/app/src/main/resources/io/xpipe/app/resources/style/choice-comp.css index 55e0bdef0..bbc138478 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/choice-comp.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/choice-comp.css @@ -6,11 +6,11 @@ -fx-background-color: -color-accent-fg; } -.identity-select-comp .clear-button:hover .ikonli-font-icon { +.clear-button:hover .ikonli-font-icon { -fx-icon-color: -color-accent-fg; } -.identity-select-comp .clear-button { +.clear-button { -fx-background-color: transparent; } diff --git a/app/src/main/resources/io/xpipe/app/resources/style/style.css b/app/src/main/resources/io/xpipe/app/resources/style/style.css index 79b9301e4..689712b5a 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/style.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/style.css @@ -156,6 +156,13 @@ .toggle-group-comp .toggle-button { -fx-padding: 3 10; +} + +.root .toggle-group-comp:disabled .toggle-button:disabled { + -fx-opacity: 0.6; +} + +.toggle-group-comp .toggle-button:disabled { -fx-opacity: 1.0; } @@ -187,3 +194,8 @@ .creation-menu.menu-button .separator { -fx-padding: 2 0; } + +.loading-text { + -fx-font-family: Roboto; +} + diff --git a/dist/changelog/19.3.1_incremental.md b/dist/changelog/19.3.1_incremental.md new file mode 100644 index 000000000..2763982c7 --- /dev/null +++ b/dist/changelog/19.3.1_incremental.md @@ -0,0 +1 @@ +- Fix SSH failing with bad configuration error when a custom IdentityFile option was used as additional SSH options diff --git a/dist/changelog/19.3_incremental.md b/dist/changelog/19.3_incremental.md new file mode 100644 index 000000000..4de9dcc16 --- /dev/null +++ b/dist/changelog/19.3_incremental.md @@ -0,0 +1,4 @@ +- Fix SSH failing with bad configuration error when a connection had custom SSH options configured +- Fix file browser symlinks to directories not being treated as directories in some cases +- Improve yes/no toggle for category configuration to be less confusing in its neutral state +- Add automatic fallback to Remmina RDP integration to use FreeRDP for RemoteApps when FreeRDP is installed as well diff --git a/dist/changelog/19.4_incremental.md b/dist/changelog/19.4_incremental.md new file mode 100644 index 000000000..7bd3b7891 --- /dev/null +++ b/dist/changelog/19.4_incremental.md @@ -0,0 +1,7 @@ +- Fix URLs not opening in browser on current Debian sid and potentially other Linux systems +- Fix file browser defaulting to SFTP for connections with no saved state, e.g. when they were synced the first time via git +- Fix password field sometimes throwing errors when capslock was active +- Fix connection filter string match count sometimes being wrong +- Fix connection filter always switching category even if it was not necessary +- Fix errors in SFTP session when right-clicking certain files +- Improve Korean translations (Thanks to @nillpoe) diff --git a/dist/changelog/19.5_incremental.md b/dist/changelog/19.5_incremental.md new file mode 100644 index 000000000..faa81ddb1 --- /dev/null +++ b/dist/changelog/19.5_incremental.md @@ -0,0 +1,10 @@ +- Fix file browser transfer size being displayed as twice the actual size for directory transfers +- Fix SSH PKCS11Provider option breaking ssh on Windows 10 LTSC (again) +- Fix various broken documentation links +- Fix potential stack overflow when transferring directory with 100+ layers of nested directories +- Fix MSYS2 shell environment name formatting +- Fix category selection always changing when editing connection configurations +- Fix Remmina window overlapping taskbar in fullscreen +- Show connection name of SSH askpass prompt dialog +- Improve interface for custom SSH connections with multiple hosts to always show target +- Improve category config dialog description for sync option of special categories diff --git a/dist/changelog/19.6_incremental.md b/dist/changelog/19.6_incremental.md new file mode 100644 index 000000000..2141e1878 --- /dev/null +++ b/dist/changelog/19.6_incremental.md @@ -0,0 +1,2 @@ +- Fix Linux executable being linked to a too new GLIBC version, causing it to not run on old Linux systems +- Fix Warp terminal sessions on Windows not registering exit properly diff --git a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java index 3bab7b9b1..6d4011aee 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/desktop/DesktopApplicationStoreProvider.java @@ -72,7 +72,6 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider { .nameAndDescription("desktopBase") .addComp( new StoreChoiceComp<>( - StoreChoiceComp.Mode.HOST, entry, host, DesktopBaseStore.class, diff --git a/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStoreProvider.java index 9d19d24d5..9d79d0633 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/host/AbstractHostStoreProvider.java @@ -82,11 +82,10 @@ public class AbstractHostStoreProvider implements DataStoreProvider { .nameAndDescription("abstractHostGateway") .addComp( new StoreChoiceComp<>( - StoreChoiceComp.Mode.PROXY, entry, gateway, NetworkTunnelStore.class, - ref -> true, + null, StoreViewState.get().getAllConnectionsCategory()), gateway) .bind( diff --git a/ext/base/src/main/java/io/xpipe/ext/base/host/HostAddressChoiceComp.java b/ext/base/src/main/java/io/xpipe/ext/base/host/HostAddressChoiceComp.java index e31864909..705c5c324 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/host/HostAddressChoiceComp.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/host/HostAddressChoiceComp.java @@ -64,13 +64,9 @@ public class HostAddressChoiceComp extends Comp> { nodes.add(addButton); } - var layout = new InputGroupComp(nodes).apply(struc -> struc.get().setFillHeight(true)); - layout.apply(struc -> { - struc.get().focusedProperty().addListener((observable, oldValue, newValue) -> { - struc.get().getChildren().getFirst().requestFocus(); - }); - }); - + var layout = new InputGroupComp(nodes); + layout.setMainReference(combo); + layout.apply(struc -> struc.get().setFillHeight(true)); return new SimpleCompStructure<>(layout.createStructure().get()); } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java index ad1060683..b26eddad0 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java @@ -302,7 +302,16 @@ public class IdentitySelectComp extends Comp> { StoreViewState.get().getAllIdentitiesCategory(), "selectIdentity", "noCompatibleIdentity"); - ((Region) popover.getPopover().getContentNode()).setMaxHeight(350); + + popover.withPopover(po -> { + ((Region) po.getContentNode()).setMaxHeight(350); + po.showingProperty().addListener((o, oldValue, newValue) -> { + if (!newValue) { + struc.get().hide(); + } + }); + }); + var skin = new ComboBoxListViewSkin<>(struc.get()) { @Override public void show() { @@ -314,11 +323,6 @@ public class IdentitySelectComp extends Comp> { popover.hide(); } }; - popover.getPopover().showingProperty().addListener((o, oldValue, newValue) -> { - if (!newValue) { - struc.get().hide(); - } - }); struc.get().setSkin(skin); }); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java index c2ce79b03..69d3ee376 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java @@ -60,7 +60,6 @@ public class ScriptGroupStoreProvider implements EnabledParentStoreProvider, Dat .description("scriptGroupGroupDescription") .addComp( new StoreChoiceComp<>( - StoreChoiceComp.Mode.OTHER, entry, group, ScriptGroupStore.class, diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java index e07f8bc2b..37d09cc60 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java @@ -168,7 +168,6 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da .documentationLink(DocumentationLink.SCRIPTING_GROUPS) .addComp( new StoreChoiceComp<>( - StoreChoiceComp.Mode.OTHER, null, group, ScriptGroupStore.class, diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java index 17ea8b633..ffdf63f95 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/AbstractServiceStore.java @@ -24,6 +24,8 @@ public abstract class AbstractServiceStore private final Integer localPort; private final ServiceProtocolType serviceProtocolType; + public abstract boolean shouldTunnel(); + public abstract String getAddress(); public abstract DataStoreEntryRef getGateway(); @@ -105,9 +107,9 @@ public abstract class AbstractServiceStore return false; } - return nts.requiresTunnel(); + return shouldTunnel() && nts.requiresTunnel(); } else { - return t.requiresTunnel(); + return shouldTunnel() && t.requiresTunnel(); } } @@ -134,6 +136,10 @@ public abstract class AbstractServiceStore return null; } } + + if (!shouldTunnel()) { + return null; + } } else { return null; } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java index 08ee53dc1..5d8fdf7db 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStore.java @@ -7,6 +7,7 @@ import io.xpipe.ext.base.host.AbstractHostStore; import io.xpipe.ext.base.host.AbstractHostTransformStore; import com.fasterxml.jackson.annotation.JsonTypeName; +import javafx.beans.property.BooleanProperty; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; @@ -24,6 +25,7 @@ public final class CustomServiceStore extends AbstractServiceStore implements Ab private final DataStoreEntryRef host; private final String address; private final DataStoreEntryRef gateway; + private final Boolean tunnelToLocalhost; @Override public boolean canConvertToAbstractHost() { @@ -43,4 +45,9 @@ public final class CustomServiceStore extends AbstractServiceStore implements Ab .host(newParent.asNeeded()) .build(); } + + @Override + public boolean shouldTunnel() { + return tunnelToLocalhost == null || tunnelToLocalhost; + } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java index 069b08835..2137cab6e 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/CustomServiceStoreProvider.java @@ -1,9 +1,6 @@ package io.xpipe.ext.base.service; -import io.xpipe.app.ext.DataStore; -import io.xpipe.app.ext.DataStoreCreationCategory; -import io.xpipe.app.ext.GuiDialog; -import io.xpipe.app.ext.NetworkTunnelStore; +import io.xpipe.app.ext.*; import io.xpipe.app.hub.comp.StoreChoiceComp; import io.xpipe.app.hub.comp.StoreComboChoiceComp; import io.xpipe.app.hub.comp.StoreViewState; @@ -14,7 +11,10 @@ import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.ext.base.host.AbstractHostStore; +import io.xpipe.ext.base.host.HostAddressGatewayStore; +import javafx.beans.binding.Bindings; import javafx.beans.property.Property; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import java.util.List; @@ -58,10 +58,23 @@ public class CustomServiceStoreProvider extends AbstractServiceStoreProvider { var comboHost = new SimpleObjectProperty<>(StoreComboChoiceComp.ComboValue.of(st.getAddress(), st.getHost())); var gateway = new SimpleObjectProperty<>(st.getGateway()); var hideGateway = BindingsHelper.map(comboHost, c -> c == null || c.getRef() != null); + comboHost.addListener((obs, o, n) -> { + if (n != null && n.getRef() != null) { + gateway.setValue(null); + } + }); var localPort = new SimpleObjectProperty<>(st.getLocalPort()); var remotePort = new SimpleObjectProperty<>(st.getRemotePort()); var serviceProtocolType = new SimpleObjectProperty<>(st.getServiceProtocolType()); + var tunnelToLocalhost = new SimpleBooleanProperty(st.getTunnelToLocalhost() != null ? st.getTunnelToLocalhost() : true); + var hideTunnelToLocalhost = Bindings.createBooleanBinding(() -> { + return comboHost.get() == null || gateway.get() != null || + (comboHost.get().getRef().getStore() instanceof HostAddressGatewayStore g && g.getGateway() != null && !(g.getGateway().getStore() instanceof LocalStore)); + }, comboHost, gateway); + var hideLocalPort = Bindings.createBooleanBinding(() -> { + return comboHost.get() == null || !tunnelToLocalhost.get(); + }, hideTunnelToLocalhost, tunnelToLocalhost); var hostChoice = new StoreComboChoiceComp<>( hostStore -> hostStore instanceof AbstractHostStore a @@ -74,7 +87,6 @@ public class CustomServiceStoreProvider extends AbstractServiceStoreProvider { || (n.getStore() instanceof NetworkTunnelStore t && t.isLocallyTunnelable()), StoreViewState.get().getAllConnectionsCategory()); var gatewayChoice = new StoreChoiceComp<>( - StoreChoiceComp.Mode.PROXY, entry, gateway, NetworkTunnelStore.class, @@ -93,8 +105,12 @@ public class CustomServiceStoreProvider extends AbstractServiceStoreProvider { .nonNull() .sub(ServiceProtocolTypeHelper.choice(serviceProtocolType), serviceProtocolType) .nonNull() + .nameAndDescription("tunnelToLocalhost") + .addToggle(tunnelToLocalhost) + .hide(hideTunnelToLocalhost) .nameAndDescription("serviceLocalPort") .addInteger(localPort) + .hide(hideLocalPort) .bind( () -> { return CustomServiceStore.builder() @@ -110,6 +126,7 @@ public class CustomServiceStoreProvider extends AbstractServiceStoreProvider { .localPort(localPort.get()) .remotePort(remotePort.get()) .serviceProtocolType(serviceProtocolType.get()) + .tunnelToLocalhost(tunnelToLocalhost.get()) .build(); }, store); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java index 65eb52bf9..e070de72b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStore.java @@ -25,6 +25,7 @@ public class FixedServiceStore extends AbstractServiceStore implements FixedChil private final DataStoreEntryRef host; private final DataStoreEntryRef displayParent; + private final Boolean tunnelToLocalhost; @Override public String getAddress() { @@ -57,4 +58,9 @@ public class FixedServiceStore extends AbstractServiceStore implements FixedChil public OptionalInt getFixedId() { return OptionalInt.of(getRemotePort()); } + + @Override + public boolean shouldTunnel() { + return tunnelToLocalhost == null || tunnelToLocalhost; + } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java index 6fb928c65..4e3156358 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/FixedServiceStoreProvider.java @@ -2,6 +2,7 @@ package io.xpipe.ext.base.service; import io.xpipe.app.ext.DataStore; import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.ext.LocalStore; import io.xpipe.app.ext.NetworkTunnelStore; import io.xpipe.app.hub.comp.StoreChoiceComp; import io.xpipe.app.hub.comp.StoreViewState; @@ -9,7 +10,11 @@ import io.xpipe.app.platform.OptionsBuilder; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.ext.base.host.HostAddressGatewayStore; +import javafx.beans.binding.Bindings; import javafx.beans.property.Property; +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import java.util.List; @@ -31,25 +36,35 @@ public class FixedServiceStoreProvider extends AbstractServiceStoreProvider { @Override public GuiDialog guiDialog(DataStoreEntry entry, Property store) { FixedServiceStore st = store.getValue().asNeeded(); - var host = new SimpleObjectProperty<>(st.getHost()); + var host = new ReadOnlyObjectWrapper<>(st.getHost()); var localPort = new SimpleObjectProperty<>(st.getLocalPort()); var serviceProtocolType = new SimpleObjectProperty<>(st.getServiceProtocolType()); + var tunnelToLocalhost = new SimpleBooleanProperty(st.getTunnelToLocalhost() != null ? st.getTunnelToLocalhost() : true); + var hideTunnelToLocalhost = Bindings.createBooleanBinding(() -> { + return host.get() == null || (host.get().getStore() instanceof HostAddressGatewayStore g && + g.getGateway() != null && !(g.getGateway().getStore() instanceof LocalStore)); + }, host); + var hideLocalPort = Bindings.createBooleanBinding(() -> { + return host.get() == null || !tunnelToLocalhost.get(); + }, hideTunnelToLocalhost, tunnelToLocalhost); + var q = new OptionsBuilder() .nameAndDescription("serviceHost") - .addComp( - StoreChoiceComp.other( - host, - NetworkTunnelStore.class, - n -> n.getStore().isLocallyTunnelable(), + .addComp(new StoreChoiceComp<>(entry, host, NetworkTunnelStore.class, n -> n.getStore().isLocallyTunnelable(), StoreViewState.get().getAllConnectionsCategory()), host) .nonNull() + .disable() .sub(ServiceProtocolTypeHelper.choice(serviceProtocolType), serviceProtocolType) .nonNull() .nameAndDescription("serviceRemotePort") .addStaticString(st.getRemotePort()) + .nameAndDescription("tunnelToLocalhost") + .addToggle(tunnelToLocalhost) + .hide(hideTunnelToLocalhost) .nameAndDescription("serviceLocalPort") .addInteger(localPort) + .hide(hideLocalPort) .bind( () -> { return FixedServiceStore.builder() @@ -58,6 +73,7 @@ public class FixedServiceStoreProvider extends AbstractServiceStoreProvider { .localPort(localPort.get()) .remotePort(st.getRemotePort()) .serviceProtocolType(serviceProtocolType.get()) + .tunnelToLocalhost(tunnelToLocalhost.get()) .build(); }, store); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java index 56214b43f..a7eabfea7 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/MappedServiceStoreProvider.java @@ -2,6 +2,7 @@ package io.xpipe.ext.base.service; import io.xpipe.app.ext.DataStore; import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.ext.LocalStore; import io.xpipe.app.ext.NetworkTunnelStore; import io.xpipe.app.hub.comp.StoreChoiceComp; import io.xpipe.app.hub.comp.StoreViewState; @@ -9,7 +10,10 @@ import io.xpipe.app.platform.OptionsBuilder; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.ext.base.host.HostAddressGatewayStore; +import javafx.beans.binding.Bindings; import javafx.beans.property.Property; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import java.util.List; @@ -35,25 +39,37 @@ public class MappedServiceStoreProvider extends FixedServiceStoreProvider { @Override public GuiDialog guiDialog(DataStoreEntry entry, Property store) { MappedServiceStore st = store.getValue().asNeeded(); + var host = new SimpleObjectProperty<>(st.getHost()); var localPort = new SimpleObjectProperty<>(st.getLocalPort()); var serviceProtocolType = new SimpleObjectProperty<>(st.getServiceProtocolType()); + var tunnelToLocalhost = new SimpleBooleanProperty(st.getTunnelToLocalhost() != null ? st.getTunnelToLocalhost() : true); + var hideTunnelToLocalhost = Bindings.createBooleanBinding(() -> { + return host.get() == null || (host.get().getStore() instanceof HostAddressGatewayStore g && + g.getGateway() != null && !(g.getGateway().getStore() instanceof LocalStore)); + }, host); + var hideLocalPort = Bindings.createBooleanBinding(() -> { + return host.get() == null || !tunnelToLocalhost.get(); + }, hideTunnelToLocalhost, tunnelToLocalhost); + var q = new OptionsBuilder() .nameAndDescription("serviceHost") .addComp( - StoreChoiceComp.other( - host, - NetworkTunnelStore.class, - n -> n.getStore().isLocallyTunnelable(), + new StoreChoiceComp<>(entry, host, NetworkTunnelStore.class, n -> n.getStore().isLocallyTunnelable(), StoreViewState.get().getAllConnectionsCategory()), host) .nonNull() + .disable() .sub(ServiceProtocolTypeHelper.choice(serviceProtocolType), serviceProtocolType) .nonNull() .nameAndDescription("serviceRemotePort") .addStaticString(st.getRemotePort() + " <- " + st.getContainerPort()) + .nameAndDescription("tunnelToLocalhost") + .addToggle(tunnelToLocalhost) + .hide(hideTunnelToLocalhost) .nameAndDescription("serviceLocalPort") .addInteger(localPort) + .hide(hideLocalPort) .bind( () -> { return MappedServiceStore.builder() @@ -63,6 +79,7 @@ public class MappedServiceStoreProvider extends FixedServiceStoreProvider { .remotePort(st.getRemotePort()) .serviceProtocolType(serviceProtocolType.get()) .containerPort(st.getContainerPort()) + .tunnelToLocalhost(tunnelToLocalhost.get()) .build(); }, store); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceProtocolTypeHelper.java b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceProtocolTypeHelper.java index 3c08a0ea9..7f6384f11 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceProtocolTypeHelper.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/service/ServiceProtocolTypeHelper.java @@ -37,7 +37,9 @@ public class ServiceProtocolTypeHelper { var path = new SimpleStringProperty(p.getValue() != null ? p.getValue().getPath() : null); return new OptionsBuilder() .nameAndDescription("servicePath") - .addString(path) + .addComp(new TextFieldComp(path).apply(struc -> { + struc.get().setPromptText("/sub/path"); + }), path) .bind( () -> { return new ServiceProtocolType.Http(path.get()); @@ -49,7 +51,9 @@ public class ServiceProtocolTypeHelper { var path = new SimpleStringProperty(p.getValue() != null ? p.getValue().getPath() : null); return new OptionsBuilder() .nameAndDescription("servicePath") - .addString(path) + .addComp(new TextFieldComp(path).apply(struc -> { + struc.get().setPromptText("/sub/path"); + }), path) .bind( () -> { return new ServiceProtocolType.Https(path.get()); diff --git a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java index 14b4e6815..ff79ba7a4 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/incus/IncusContainerStoreProvider.java @@ -4,6 +4,7 @@ import io.xpipe.app.comp.Comp; import io.xpipe.app.ext.ContainerStoreState; import io.xpipe.app.ext.DataStore; import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.ext.ShellStore; import io.xpipe.app.hub.comp.*; import io.xpipe.app.platform.BindingsHelper; import io.xpipe.app.platform.OptionsBuilder; @@ -13,6 +14,7 @@ import io.xpipe.ext.base.identity.IdentityChoiceBuilder; import io.xpipe.ext.base.store.ShellStoreProvider; import javafx.beans.property.Property; +import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -76,8 +78,10 @@ public class IncusContainerStoreProvider implements ShellStoreProvider { var q = new OptionsBuilder() .name("host") .description("lxdHostDescription") - .addComp(StoreChoiceComp.host( - new SimpleObjectProperty<>(st.getInstall().getStore().getHost()), + .addComp( + new StoreChoiceComp<>(entry, + new ReadOnlyObjectWrapper<>(st.getInstall().getStore().getHost()), ShellStore.class, + null, StoreViewState.get().getAllConnectionsCategory())) .disable() .name("container") diff --git a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java index 381bcafc8..98f97d204 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/lxd/LxdContainerStoreProvider.java @@ -4,6 +4,7 @@ import io.xpipe.app.comp.Comp; import io.xpipe.app.ext.ContainerStoreState; import io.xpipe.app.ext.DataStore; import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.ext.ShellStore; import io.xpipe.app.hub.comp.*; import io.xpipe.app.platform.BindingsHelper; import io.xpipe.app.platform.OptionsBuilder; @@ -13,6 +14,7 @@ import io.xpipe.ext.base.identity.IdentityChoiceBuilder; import io.xpipe.ext.base.store.ShellStoreProvider; import javafx.beans.property.Property; +import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -76,8 +78,9 @@ public class LxdContainerStoreProvider implements ShellStoreProvider { var q = new OptionsBuilder() .name("host") .description("lxdHostDescription") - .addComp(StoreChoiceComp.host( - new SimpleObjectProperty<>(st.getCmd().getStore().getHost()), + .addComp( + new StoreChoiceComp<>(entry, + new ReadOnlyObjectWrapper<>(st.getCmd().getStore().getHost()), ShellStore.class, null, StoreViewState.get().getAllConnectionsCategory())) .disable() .name("container") diff --git a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java index 5f7cd3f7a..45b62f337 100644 --- a/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java +++ b/ext/system/src/main/java/io/xpipe/ext/system/podman/PodmanContainerStoreProvider.java @@ -4,6 +4,7 @@ import io.xpipe.app.comp.Comp; import io.xpipe.app.ext.ContainerStoreState; import io.xpipe.app.ext.DataStore; import io.xpipe.app.ext.GuiDialog; +import io.xpipe.app.ext.ShellStore; import io.xpipe.app.hub.comp.*; import io.xpipe.app.platform.BindingsHelper; import io.xpipe.app.platform.OptionsBuilder; @@ -14,6 +15,7 @@ import io.xpipe.ext.base.service.FixedServiceGroupStore; import io.xpipe.ext.base.store.ShellStoreProvider; import javafx.beans.property.Property; +import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; @@ -60,9 +62,11 @@ public class PodmanContainerStoreProvider implements ShellStoreProvider { return new OptionsBuilder() .name("host") .description("podmanHostDescription") - .addComp(StoreChoiceComp.host( - new SimpleObjectProperty<>( - st.getCmd() != null ? st.getCmd().getStore().getHost() : null), + .addComp( + new StoreChoiceComp<>(entry, + new ReadOnlyObjectWrapper<>( + st.getCmd() != null ? st.getCmd().getStore().getHost() : null), ShellStore.class, + null, StoreViewState.get().getAllConnectionsCategory())) .disable() .name("container") diff --git a/lang/strings/translations_da.properties b/lang/strings/translations_da.properties index 423ba5986..ddfb6a4e0 100644 --- a/lang/strings/translations_da.properties +++ b/lang/strings/translations_da.properties @@ -420,7 +420,7 @@ retry=Forsøg igen retryAll=Prøv igen alle replace=Udskift replaceAll=Erstat alle -copyPassword=copyPassword +copyPassword=Kopier adgangskode hibernateBehaviour=Dvaleadfærd hibernateBehaviourDescription=Styrer, hvordan programmet opfører sig, når dit system sættes i dvale. #custom @@ -579,13 +579,13 @@ browseVaultButton=Gennemse hvælving vaultUsers=Vault-brugere createHeapDump=Opret heap-dump createHeapDumpDescription=Dump hukommelsesindhold til fil for at fejlfinde hukommelsesforbrug -initializingApp=Indlæser forbindelser ... -checkingLicense=Kontrol af licens ... -loadingGit=Synkronisering med git repo ... -loadingGpg=Starter GnuPG-dæmon til git ... -loadingSettings=Indlæser indstillinger ... -loadingConnections=Indlæser forbindelser ... -loadingUserInterface=Indlæsning af brugergrænseflade ... +initializingApp=Indlæsning af forbindelser +checkingLicense=Kontrol af licens +loadingGit=Synkronisering med git repo +loadingGpg=Start af GnuPG-dæmon til git +loadingSettings=Indlæsning af indstillinger +loadingConnections=Indlæsning af forbindelser +loadingUserInterface=Indlæsning af brugergrænseflade ptbNotice=Meddelelse om den offentlige testversion userDeletionTitle=Sletning af brugere userDeletionContent=Vil du slette denne vault-bruger? Dette vil genkryptere alle dine personlige identiteter og forbindelseshemmeligheder ved hjælp af den vault-nøgle, der er tilgængelig for alle brugere. XPipe genstarter for at anvende brugerændringerne. @@ -1416,6 +1416,7 @@ categoryColor=Kategori farve categoryColorDescription=Den standardfarve, der skal bruges til forbindelser inden for denne kategori categorySync=Synkroniser med git-arkiv categorySyncDescription=Synkroniser automatisk alle forbindelser med git-repository. Alle lokale ændringer af forbindelser vil blive skubbet til fjernlageret. +categorySyncSpecial=Synkroniser med git-arkiv\n(Kan ikke konfigureres for specialkategorien "$NAME$") categoryDontAllowScripts=Deaktivering af scripts categoryDontAllowScriptsDescription=Deaktiver oprettelse af scripts på systemer i denne kategori for at forhindre ændringer i filsystemet. Dette vil deaktivere al scripting-funktionalitet, shell-miljøkommandoer, prompter med mere. categoryConfirmAllModifications=Bekræft alle ændringer @@ -1470,7 +1471,7 @@ vncConnections=VNC-forbindelser passwordManagerIdentity=Password manager-identitet passwordManagerIdentity.displayName=Password manager-identitet passwordManagerIdentity.displayDescription=Hent brugernavn og adgangskode til en identitet fra din adgangskodeadministrator -useAsJumpServer=Spring server +useAsJumpServer=Jump-server useAsJumpServerDescription=Dette system er en jump-server, der skal bruges med ProxyJump passwordCopied=Forbindelsesadgangskode kopieret til udklipsholder errorOccurred=Der opstod en fejl @@ -1580,7 +1581,7 @@ enableMcpMutationTools=Aktiver MCP-mutationsværktøjer enableMcpMutationToolsDescription=Som standard er kun skrivebeskyttede værktøjer aktiveret på MCP-serveren. Dette er for at sikre, at der ikke kan foretages utilsigtede handlinger, som potentielt kan ændre et system.\n\nHvis du planlægger at foretage ændringer i systemer via MCP-klienter, skal du sørge for at kontrollere, at din MCP-klient er konfigureret til at bekræfte eventuelle potentielt destruktive handlinger, før du aktiverer denne indstilling. Kræver en genforbindelse af alle MCP-klienter for at gælde. mcpClientConfigurationDetails=Konfiguration af MCP-klient mcpClientConfigurationDetailsDescription=Brug disse konfigurationsdata til at oprette forbindelse til XPipe MCP-serveren fra din valgte MCP-klient. -switchHostAddress=Switch-værtsadresse +switchHostAddress=Skift værtsadresse addAnotherHostName=Tilføj et andet værtsnavn addNetwork=Netværksscanning ... networkScan=Netværksscanning @@ -1668,3 +1669,5 @@ netbirdProfileNameAsktext=Navn på ny netbird-profil openSftp=Åbn i SFTP-session capslockWarning=Du har aktiveret capslock inherit=Arve +sshConfigStringSelected=Målvært +sshConfigStringSelectedDescription=For flere hosts bruges den første som mål. Omorganiser dine værter for at ændre målet diff --git a/lang/strings/translations_de.properties b/lang/strings/translations_de.properties index 05d135894..735e8a054 100644 --- a/lang/strings/translations_de.properties +++ b/lang/strings/translations_de.properties @@ -422,7 +422,7 @@ retry=Wiederholung retryAll=Alle Versuche wiederholen replace=Ersetze replaceAll=Ersetze alle -copyPassword=copyPassword +copyPassword=Passwort kopieren #custom hibernateBehaviour=Verhalten im Ruhezustand hibernateBehaviourDescription=Steuert, wie sich die Anwendung verhält, wenn dein System in den Ruhezustand versetzt wird. @@ -589,13 +589,13 @@ browseVaultButton=Tresor durchsuchen vaultUsers=Tresor-Benutzer createHeapDump=Heap-Dump erstellen createHeapDumpDescription=Speicherinhalte in eine Datei ausgeben, um Fehler bei der Speichernutzung zu beheben -initializingApp=Verbindungen laden ... -checkingLicense=Prüfen der Lizenz ... -loadingGit=Synchronisierung mit git repo ... -loadingGpg=GnuPG-Daemon für Git starten ... -loadingSettings=Einstellungen laden ... -loadingConnections=Verbindungen laden ... -loadingUserInterface=Laden der Benutzeroberfläche ... +initializingApp=Verbindungen laden +checkingLicense=Prüfen der Lizenz +loadingGit=Synchronisierung mit git repo +loadingGpg=GnuPG-Daemon für Git starten +loadingSettings=Einstellungen laden +loadingConnections=Verbindungen laden +loadingUserInterface=Benutzeroberfläche laden ptbNotice=Hinweis für die öffentliche Testversion userDeletionTitle=Benutzerlöschung userDeletionContent=Willst du diesen Tresorbenutzer löschen? Dadurch werden alle deine persönlichen Identitäten und Verbindungsgeheimnisse mit dem Tresorschlüssel, der allen Benutzern zur Verfügung steht, neu verschlüsselt. XPipe wird neu gestartet, um die Benutzeränderungen zu übernehmen. @@ -1408,6 +1408,7 @@ categoryColor=Kategorie Farbe categoryColorDescription=Die Standardfarbe, die für Verbindungen innerhalb dieser Kategorie verwendet wird categorySync=Mit Git-Repository synchronisieren categorySyncDescription=Synchronisiere alle Verbindungen automatisch mit dem git repository. Alle lokalen Änderungen an den Verbindungen werden in das Remote-Repository übertragen. +categorySyncSpecial=Mit Git-Repository synchronisieren\n(Nicht konfigurierbar für die spezielle Kategorie "$NAME$") categoryDontAllowScripts=Skripte deaktivieren categoryDontAllowScriptsDescription=Deaktiviere die Skripterstellung auf Systemen dieser Kategorie, um Änderungen am Dateisystem zu verhindern. Dadurch werden alle Skriptfunktionen, Shell-Umgebungsbefehle, Eingabeaufforderungen und mehr deaktiviert. categoryConfirmAllModifications=Bestätige alle Änderungen @@ -1463,7 +1464,7 @@ vncConnections=VNC-Verbindungen passwordManagerIdentity=Passwort Manager Identität passwordManagerIdentity.displayName=Passwort Manager Identität passwordManagerIdentity.displayDescription=Den Benutzernamen und das Passwort einer Identität aus dem Passwortmanager abrufen -useAsJumpServer=Server springen +useAsJumpServer=Sprungserver useAsJumpServerDescription=Dieses System ist ein Jump Server, der mit ProxyJump verwendet wird passwordCopied=Verbindungskennwort in die Zwischenablage kopiert errorOccurred=Fehler aufgetreten @@ -1575,7 +1576,7 @@ enableMcpMutationTools=MCP-Mutationswerkzeuge einschalten enableMcpMutationToolsDescription=Standardmäßig sind auf dem MCP-Server nur schreibgeschützte Tools aktiviert. Damit soll sichergestellt werden, dass keine versehentlichen Eingriffe vorgenommen werden können, die das System verändern könnten.\n\nWenn du planst, Änderungen an Systemen über MCP-Clients vorzunehmen, solltest du sicherstellen, dass dein MCP-Client so konfiguriert ist, dass er alle potenziell zerstörerischen Aktionen bestätigt, bevor du diese Option aktivierst. Erfordert eine erneute Verbindung aller MCP-Clients zur Anwendung. mcpClientConfigurationDetails=MCP-Client-Konfiguration mcpClientConfigurationDetailsDescription=Verwende diese Konfigurationsdaten, um dich mit dem XPipe MCP-Server von einem MCP-Client deiner Wahl aus zu verbinden. -switchHostAddress=Switch-Host-Adresse +switchHostAddress=Host-Adresse ändern addAnotherHostName=Einen weiteren Hostnamen hinzufügen addNetwork=Netzwerk-Scan ... networkScan=Netzwerk-Scan @@ -1663,3 +1664,5 @@ netbirdProfileNameAsktext=Name des neuen Netbird-Profils openSftp=In SFTP-Sitzung öffnen capslockWarning=Du hast Capslock aktiviert inherit=Erbe +sshConfigStringSelected=Ziel-Host +sshConfigStringSelectedDescription=Bei mehreren Hosts wird der erste als Ziel verwendet. Ordne deine Hosts neu an, um das Ziel zu ändern diff --git a/lang/strings/translations_en.properties b/lang/strings/translations_en.properties index eabeef9b0..860c486b9 100644 --- a/lang/strings/translations_en.properties +++ b/lang/strings/translations_en.properties @@ -433,7 +433,7 @@ retry=Retry retryAll=Retry all replace=Replace replaceAll=Replace all -copyPassword=copyPassword +copyPassword=Copy password hibernateBehaviour=Hibernation behaviour hibernateBehaviourDescription=Controls how the application behaves when your system is put into hibernation/to sleep. overview=Overview @@ -611,13 +611,13 @@ browseVaultButton=Browse vault vaultUsers=Vault users createHeapDump=Create heap dump createHeapDumpDescription=Dump memory contents to file to troubleshoot memory usage -initializingApp=Loading connections ... -checkingLicense=Checking license ... -loadingGit=Syncing with git repo ... -loadingGpg=Starting GnuPG daemon for git ... -loadingSettings=Loading settings ... -loadingConnections=Loading connections ... -loadingUserInterface=Loading user interface ... +initializingApp=Loading connections +checkingLicense=Checking license +loadingGit=Syncing with git repo +loadingGpg=Starting GnuPG daemon for git +loadingSettings=Loading settings +loadingConnections=Loading connections +loadingUserInterface=Loading user interface ptbNotice=Notice for the public test build userDeletionTitle=User deletion userDeletionContent=Do you want to delete this vault user? This will reencrypt all your personal identities and connection secrets using the vault key that is available to all users. XPipe will restart to apply the user changes. @@ -1458,6 +1458,7 @@ categoryColor=Category color categoryColorDescription=The default color to use for connections within this category categorySync=Sync with git repository categorySyncDescription=Sync all connections automatically with git repository. All local changes to connections will be pushed to the remote. +categorySyncSpecial=Sync with git repository\n(Not configurable for special category "$NAME$") categoryDontAllowScripts=Disable scripts categoryDontAllowScriptsDescription=Disable script creation on systems within this category to prevent any file system modifications. This will disable all scripting functionality, shell environment commands, prompts, and more. categoryConfirmAllModifications=Confirm all modifications @@ -1514,8 +1515,6 @@ vncConnections=VNC connections passwordManagerIdentity=Password manager identity passwordManagerIdentity.displayName=Password manager identity passwordManagerIdentity.displayDescription=Retrieve username and password of an identity from your password manager -useAsJumpServer=Jump server -useAsJumpServerDescription=This system is a jump server to be used with ProxyJump passwordCopied=Connection password copied to clipboard errorOccurred=Error occurred actionMacro.displayName=Action macro @@ -1628,7 +1627,7 @@ enableMcpMutationTools=Enable MCP mutation tools enableMcpMutationToolsDescription=By default, only read-only tools are enabled in the MCP server. This is to ensure that no accidental operations can be made that potentially modify a system.\n\nIf you plan to make changes to systems via MCP clients, make sure to check that your MCP client is configured to confirm any potentially destructive actions before enabling this option. Requires a reconnect of any MCP clients to apply. mcpClientConfigurationDetails=MCP client configuration mcpClientConfigurationDetailsDescription=Use this configuration data to connect to the XPipe MCP server from your MCP client of choice. -switchHostAddress=Switch host address +switchHostAddress=Change host address addAnotherHostName=Add another host name addNetwork=Network scan ... networkScan=Network scan @@ -1716,6 +1715,13 @@ netbirdProfileNameAsktext=Name of new netbird profile openSftp=Open in SFTP session capslockWarning=You have capslock enabled inherit=Inherit +sshConfigStringSelected=Target host +sshConfigStringSelectedDescription=For multiple hosts, the first one is used as the target. Reorder your hosts to change the target +tunnelToLocalhost=Tunnel to localhost +tunnelToLocalhostDescription=Automatically tunnel the remote port to localhost +#context: SSH jump server, noun +useGatewayAsJumpServer=Use gateway as jump server +useGatewayAsJumpServerDescription=Use the gateway as a jump server with ProxyJump groupSecretStrategy=Group-based access control groupSecretStrategyDescription=Here you can choose how to retrieve the group secret used for encryption. The retrieval method you choose will be run when a user logs into the vault. Their access level to certain connections is determined by the raw key that the retrieval method returns. fileSecret=File-based secret diff --git a/lang/strings/translations_es.properties b/lang/strings/translations_es.properties index 415a6f24e..fe0041b9b 100644 --- a/lang/strings/translations_es.properties +++ b/lang/strings/translations_es.properties @@ -410,7 +410,7 @@ retry=Reintentar retryAll=Reintentar todo replace=Sustituye replaceAll=Sustituir todo -copyPassword=copyContraseña +copyPassword=Copiar contraseña hibernateBehaviour=Comportamiento de hibernación hibernateBehaviourDescription=Controla cómo se comporta la aplicación cuando tu sistema se pone en hibernación/en reposo. overview=Visión general @@ -568,13 +568,13 @@ browseVaultButton=Navegar por la bóveda vaultUsers=Usuarios de bóvedas createHeapDump=Crear volcado de heap createHeapDumpDescription=Volcar el contenido de la memoria a un archivo para solucionar problemas de uso de memoria -initializingApp=Cargando conexiones ... -checkingLicense=Comprobación de licencia ... -loadingGit=Sincronización con git repo ... -loadingGpg=Iniciando el demonio GnuPG para git ... -loadingSettings=Cargando ajustes ... -loadingConnections=Cargando conexiones ... -loadingUserInterface=Carga de la interfaz de usuario ... +initializingApp=Carga de conexiones +checkingLicense=Comprobación de licencia +loadingGit=Sincronización con git repo +loadingGpg=Iniciar el demonio GnuPG para git +loadingSettings=Configuración de carga +loadingConnections=Carga de conexiones +loadingUserInterface=Carga de la interfaz de usuario ptbNotice=Aviso para la versión de prueba pública userDeletionTitle=Eliminación de usuarios userDeletionContent=¿Quieres eliminar este usuario de la bóveda? Esto volverá a encriptar todas tus identidades personales y secretos de conexión utilizando la clave de la bóveda que está disponible para todos los usuarios. XPipe se reiniciará para aplicar los cambios de usuario. @@ -1375,6 +1375,7 @@ categoryColor=Color de la categoría categoryColorDescription=El color por defecto a utilizar para las conexiones dentro de esta categoría categorySync=Sincronizar con el repositorio git categorySyncDescription=Sincroniza todas las conexiones automáticamente con el repositorio git. Todos los cambios locales en las conexiones serán empujados al remoto. +categorySyncSpecial=Sincronizar con repositorio git\n(No configurable para la categoría especial "$NAME$") categoryDontAllowScripts=Desactivar scripts categoryDontAllowScriptsDescription=Desactiva la creación de scripts en los sistemas de esta categoría para evitar cualquier modificación del sistema de archivos. Esto deshabilitará todas las funciones de creación de scripts, comandos del entorno shell, avisos, etc. categoryConfirmAllModifications=Confirma todas las modificaciones @@ -1539,7 +1540,7 @@ enableMcpMutationTools=Habilitar herramientas de mutación MCP enableMcpMutationToolsDescription=Por defecto, en el servidor MCP sólo están habilitadas las herramientas de sólo lectura. Esto es para garantizar que no se puedan realizar operaciones accidentales que modifiquen potencialmente un sistema.\n\nSi tienes previsto realizar cambios en los sistemas a través de clientes MCP, asegúrate de que tu cliente MCP está configurado para confirmar cualquier acción potencialmente destructiva antes de activar esta opción. Requiere una reconexión de cualquier cliente MCP para aplicarse. mcpClientConfigurationDetails=Configuración del cliente MCP mcpClientConfigurationDetailsDescription=Utiliza estos datos de configuración para conectarte al servidor MCP XPipe desde el cliente MCP que elijas. -switchHostAddress=Dirección del host del conmutador +switchHostAddress=Cambiar la dirección del host addAnotherHostName=Añadir otro nombre de host addNetwork=Escaneado de red ... networkScan=Escaneado de red @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Nombre del nuevo perfil netbird openSftp=Abrir en sesión SFTP capslockWarning=Tienes activado el bloqueo de mayúsculas inherit=Hereda +sshConfigStringSelected=Host de destino +sshConfigStringSelectedDescription=Para múltiples hosts, el primero se utiliza como destino. Reordena tus hosts para cambiar el objetivo diff --git a/lang/strings/translations_fr.properties b/lang/strings/translations_fr.properties index 836b7dafc..589a62ab3 100644 --- a/lang/strings/translations_fr.properties +++ b/lang/strings/translations_fr.properties @@ -584,13 +584,13 @@ browseVaultButton=Parcourir le coffre-fort vaultUsers=Utilisateurs du coffre-fort createHeapDump=Créer un dump du tas createHeapDumpDescription=Vider le contenu de la mémoire dans un fichier pour dépanner l'utilisation de la mémoire -initializingApp=Chargement des connexions ... -checkingLicense=Vérification de la licence ... -loadingGit=Synchronisation avec git repo ... -loadingGpg=Démarrage du démon GnuPG pour git ... -loadingSettings=Chargement des paramètres ... -loadingConnections=Chargement des connexions ... -loadingUserInterface=Chargement de l'interface utilisateur ... +initializingApp=Chargement des connexions +checkingLicense=Vérification de la licence +loadingGit=Synchronisation avec git repo +loadingGpg=Démarrage du démon GnuPG pour git +loadingSettings=Paramètres de chargement +loadingConnections=Chargement des connexions +loadingUserInterface=Chargement de l'interface utilisateur ptbNotice=Avis pour la version de test publique userDeletionTitle=Suppression de l'utilisateur userDeletionContent=Veux-tu supprimer cet utilisateur du coffre-fort ? Cela permettra de recrypter toutes tes identités personnelles et tes secrets de connexion à l'aide de la clé du coffre-fort qui est disponible pour tous les utilisateurs. XPipe va redémarrer pour appliquer les changements d'utilisateur. @@ -1414,6 +1414,7 @@ categoryColor=Couleur de la catégorie categoryColorDescription=La couleur par défaut à utiliser pour les connexions de cette catégorie categorySync=Synchronisation avec le dépôt git categorySyncDescription=Synchronise automatiquement toutes les connexions avec le dépôt git. Toutes les modifications locales apportées aux connexions seront poussées vers le dépôt distant. +categorySyncSpecial=Synchronisation avec le dépôt git\n(Non configurable pour la catégorie spéciale "$NAME$") categoryDontAllowScripts=Désactiver les scripts categoryDontAllowScriptsDescription=Désactive la création de scripts sur les systèmes de cette catégorie pour empêcher toute modification du système de fichiers. Cela désactivera toutes les fonctionnalités de script, les commandes de l'environnement shell, les invites, etc. categoryConfirmAllModifications=Confirme toutes les modifications @@ -1580,7 +1581,7 @@ enableMcpMutationTools=Activer les outils de mutation MCP enableMcpMutationToolsDescription=Par défaut, seuls les outils en lecture seule sont activés dans le serveur MCP. Cela permet de s'assurer qu'aucune opération accidentelle ne peut être effectuée pour modifier potentiellement un système.\n\nSi tu prévois d'apporter des modifications aux systèmes par l'intermédiaire de clients MCP, veille à vérifier que ton client MCP est configuré pour confirmer toute action potentiellement destructrice avant d'activer cette option. Nécessite une reconnexion de tous les clients MCP pour s'appliquer. mcpClientConfigurationDetails=Configuration du client MCP mcpClientConfigurationDetailsDescription=Utilise ces données de configuration pour te connecter au serveur XPipe MCP à partir du client MCP de ton choix. -switchHostAddress=Adresse de l'hôte du commutateur +switchHostAddress=Changer l'adresse de l'hôte addAnotherHostName=Ajouter un autre nom d'hôte addNetwork=Analyse du réseau ... networkScan=Balayage du réseau @@ -1668,3 +1669,5 @@ netbirdProfileNameAsktext=Nom du nouveau profil netbird openSftp=Ouvrir une session SFTP capslockWarning=Tu as activé le verrouillage des caps inherit=Hériter +sshConfigStringSelected=Hôte cible +sshConfigStringSelectedDescription=Pour plusieurs hôtes, le premier est utilisé comme cible. Réorganise tes hôtes pour changer la cible diff --git a/lang/strings/translations_id.properties b/lang/strings/translations_id.properties index 6eaa8d72f..ced21be16 100644 --- a/lang/strings/translations_id.properties +++ b/lang/strings/translations_id.properties @@ -410,7 +410,7 @@ retry=Coba lagi retryAll=Coba lagi semua replace=Menggantikan replaceAll=Ganti semua -copyPassword=salinKata Sandi +copyPassword=Salin kata sandi hibernateBehaviour=Perilaku hibernasi hibernateBehaviourDescription=Mengontrol perilaku aplikasi saat sistem Anda masuk ke mode hibernasi/tidur. overview=Ikhtisar @@ -568,13 +568,13 @@ browseVaultButton=Jelajahi brankas vaultUsers=Pengguna brankas createHeapDump=Membuat tempat pembuangan sampah createHeapDumpDescription=Membuang konten memori ke file untuk memecahkan masalah penggunaan memori -initializingApp=Memuat koneksi ... -checkingLicense=Memeriksa lisensi ... -loadingGit=Menyinkronkan dengan repo git ... -loadingGpg=Memulai daemon GnuPG untuk git ... -loadingSettings=Memuat pengaturan ... -loadingConnections=Memuat koneksi ... -loadingUserInterface=Memuat antarmuka pengguna ... +initializingApp=Memuat koneksi +checkingLicense=Memeriksa lisensi +loadingGit=Menyinkronkan dengan repo git +loadingGpg=Memulai daemon GnuPG untuk git +loadingSettings=Memuat pengaturan +loadingConnections=Memuat koneksi +loadingUserInterface=Memuat antarmuka pengguna ptbNotice=Pemberitahuan untuk uji coba publik userDeletionTitle=Penghapusan pengguna userDeletionContent=Apakah Anda ingin menghapus pengguna brankas ini? Ini akan mengenkripsi ulang semua identitas pribadi dan rahasia koneksi Anda menggunakan kunci brankas yang tersedia untuk semua pengguna. XPipe akan memulai ulang untuk menerapkan perubahan pengguna. @@ -1375,6 +1375,7 @@ categoryColor=Warna kategori categoryColorDescription=Warna default yang digunakan untuk koneksi dalam kategori ini categorySync=Sinkronisasi dengan repositori git categorySyncDescription=Menyinkronkan semua koneksi secara otomatis dengan repositori git. Semua perubahan lokal pada koneksi akan didorong ke remote. +categorySyncSpecial=Sinkronisasi dengan repositori git\n(Tidak dapat dikonfigurasi untuk kategori khusus "$NAME$") categoryDontAllowScripts=Menonaktifkan skrip categoryDontAllowScriptsDescription=Nonaktifkan pembuatan skrip pada sistem dalam kategori ini untuk mencegah modifikasi sistem file. Ini akan menonaktifkan semua fungsionalitas skrip, perintah lingkungan shell, prompt, dan lainnya. categoryConfirmAllModifications=Mengonfirmasi semua modifikasi @@ -1429,7 +1430,7 @@ vncConnections=Koneksi VNC passwordManagerIdentity=Identitas pengelola kata sandi passwordManagerIdentity.displayName=Identitas pengelola kata sandi passwordManagerIdentity.displayDescription=Mengambil nama pengguna dan kata sandi identitas dari pengelola kata sandi Anda -useAsJumpServer=Lompat server +useAsJumpServer=Server lompat useAsJumpServerDescription=Sistem ini adalah server lompatan yang akan digunakan dengan ProxyJump passwordCopied=Kata sandi sambungan disalin ke papan klip errorOccurred=Terjadi kesalahan @@ -1539,7 +1540,7 @@ enableMcpMutationTools=Mengaktifkan alat mutasi MCP enableMcpMutationToolsDescription=Secara default, hanya alat hanya-baca yang diaktifkan di server MCP. Hal ini untuk memastikan bahwa tidak ada operasi yang tidak disengaja yang berpotensi memodifikasi sistem.\n\nJika Anda berencana untuk membuat perubahan pada sistem melalui klien MCP, pastikan untuk memeriksa apakah klien MCP Anda dikonfigurasikan untuk mengonfirmasi tindakan yang berpotensi merusak sebelum mengaktifkan opsi ini. Memerlukan koneksi ulang klien MCP apa pun untuk diterapkan. mcpClientConfigurationDetails=Konfigurasi klien MCP mcpClientConfigurationDetailsDescription=Gunakan data konfigurasi ini untuk menyambung ke server MCP XPipe dari klien MCP pilihan Anda. -switchHostAddress=Mengganti alamat host +switchHostAddress=Mengubah alamat host addAnotherHostName=Menambahkan nama host lain addNetwork=Pemindaian jaringan ... networkScan=Pemindaian jaringan @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Nama profil netbird baru openSftp=Buka dalam sesi SFTP capslockWarning=Anda telah mengaktifkan capslock inherit=Mewarisi +sshConfigStringSelected=Host target +sshConfigStringSelectedDescription=Untuk beberapa host, host pertama digunakan sebagai target. Susun ulang host Anda untuk mengubah target diff --git a/lang/strings/translations_it.properties b/lang/strings/translations_it.properties index f9027f947..97ef77d7b 100644 --- a/lang/strings/translations_it.properties +++ b/lang/strings/translations_it.properties @@ -410,7 +410,7 @@ retry=Riprova retryAll=Riprova tutti replace=Sostituire replaceAll=Sostituisci tutto -copyPassword=copiaPassword +copyPassword=Copia della password hibernateBehaviour=Comportamento di ibernazione hibernateBehaviourDescription=Controlla il comportamento dell'applicazione quando il sistema viene messo in ibernazione o a riposo. overview=Panoramica @@ -568,13 +568,13 @@ browseVaultButton=Sfogliare il caveau vaultUsers=Utenti del caveau createHeapDump=Creare un heap dump createHeapDumpDescription=Dump del contenuto della memoria su file per risolvere i problemi di utilizzo della memoria -initializingApp=Caricamento delle connessioni ... -checkingLicense=Verifica della licenza ... -loadingGit=Sincronizzazione con git repo ... -loadingGpg=Avvio del demone GnuPG per git ... -loadingSettings=Caricamento delle impostazioni ... -loadingConnections=Caricamento delle connessioni ... -loadingUserInterface=Caricamento dell'interfaccia utente ... +initializingApp=Caricamento delle connessioni +checkingLicense=Verifica della licenza +loadingGit=Sincronizzazione con git repo +loadingGpg=Avviare il demone GnuPG per git +loadingSettings=Impostazioni di caricamento +loadingConnections=Caricamento delle connessioni +loadingUserInterface=Interfaccia utente di caricamento ptbNotice=Avviso per la build di prova pubblica userDeletionTitle=Eliminazione di un utente userDeletionContent=Vuoi eliminare questo utente del vault? In questo modo tutte le tue identità personali e i segreti di connessione verranno crittografati utilizzando la chiave del vault disponibile per tutti gli utenti. XPipe si riavvia per applicare le modifiche agli utenti. @@ -1375,6 +1375,7 @@ categoryColor=Categoria colore categoryColorDescription=Il colore predefinito da utilizzare per le connessioni di questa categoria categorySync=Sincronizzazione con il repository git categorySyncDescription=Sincronizza automaticamente tutte le connessioni con il repository git. Tutte le modifiche locali alle connessioni saranno inviate al repository remoto. +categorySyncSpecial=Sincronizzazione con il repository git\n(Non configurabile per la categoria speciale "$NAME$") categoryDontAllowScripts=Disabilita gli script categoryDontAllowScriptsDescription=Disabilita la creazione di script sui sistemi appartenenti a questa categoria per impedire qualsiasi modifica del file system. Questo disabilita tutte le funzionalità di scripting, i comandi dell'ambiente shell, i prompt e altro ancora. categoryConfirmAllModifications=Conferma tutte le modifiche @@ -1539,7 +1540,7 @@ enableMcpMutationTools=Abilita gli strumenti di mutazione MCP enableMcpMutationToolsDescription=Per impostazione predefinita, nel server MCP sono abilitati solo strumenti di sola lettura. Questo per garantire che non vengano effettuate operazioni accidentali che potrebbero modificare il sistema.\n\nSe intendi apportare modifiche ai sistemi tramite i client MCP, assicurati di verificare che il tuo client MCP sia configurato per confermare qualsiasi azione potenzialmente distruttiva prima di abilitare questa opzione. Richiede la riconnessione di tutti i client MCP per essere applicata. mcpClientConfigurationDetails=Configurazione del client MCP mcpClientConfigurationDetailsDescription=Utilizza questi dati di configurazione per connetterti al server XPipe MCP dal tuo client MCP preferito. -switchHostAddress=Indirizzo host dello switch +switchHostAddress=Cambiare l'indirizzo dell'host addAnotherHostName=Aggiungi un altro nome di host addNetwork=Scansione di rete ... networkScan=Scansione di rete @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Nome del nuovo profilo Netbird openSftp=Aprire una sessione SFTP capslockWarning=Hai attivato il capslock inherit=Eredita +sshConfigStringSelected=Host di destinazione +sshConfigStringSelectedDescription=Nel caso di più host, il primo viene utilizzato come destinazione. Riordina gli host per cambiare la destinazione diff --git a/lang/strings/translations_ja.properties b/lang/strings/translations_ja.properties index ac52e1641..988ec602a 100644 --- a/lang/strings/translations_ja.properties +++ b/lang/strings/translations_ja.properties @@ -410,7 +410,7 @@ retry=リトライ retryAll=すべて再試行する replace=置き換える replaceAll=すべて置き換える -copyPassword=コピーパスワード +copyPassword=パスワードをコピーする hibernateBehaviour=ハイバネーションの動作 hibernateBehaviourDescription=システムがハイバネーション/スリープ状態になったときのアプリケーションの動作を制御する。 overview=概要 @@ -568,11 +568,11 @@ browseVaultButton=金庫を閲覧する vaultUsers=金庫のユーザー createHeapDump=ヒープダンプを作成する createHeapDumpDescription=メモリの使用状況をトラブルシューティングするために、メモリの内容をファイルにダンプする -initializingApp=接続をロードする -checkingLicense=ライセンスをチェックする -loadingGit=git リポジトリと同期する... -loadingGpg=git用のGnuPGデーモンを起動する ... -loadingSettings=設定を読み込む +initializingApp=接続を読み込む +checkingLicense=ライセンスの確認 +loadingGit=gitリポジトリと同期する +loadingGpg=git用のGnuPGデーモンを起動する +loadingSettings=設定の読み込み loadingConnections=接続をロードする loadingUserInterface=ユーザーインターフェースの読み込み ptbNotice=公開テストビルドのお知らせ @@ -1375,6 +1375,7 @@ categoryColor=カテゴリーカラー categoryColorDescription=このカテゴリ内の接続に使用するデフォルトの色 categorySync=gitリポジトリと同期する categorySyncDescription=すべての接続をgitリポジトリと自動的に同期する。接続に対するローカルの変更はすべてリモートにプッシュされる。 +categorySyncSpecial=git リポジトリと同期する\n(特別なカテゴリ "$NAME$" では設定できない) categoryDontAllowScripts=スクリプトを無効にする categoryDontAllowScriptsDescription=このカテゴリ内のシステムでスクリプトの作成を無効にし、ファイルシステムの変更を防止する。これにより、すべてのスクリプト機能、シェル環境コマンド、プロンプトなどが無効になる。 categoryConfirmAllModifications=すべての変更を確認する @@ -1539,7 +1540,7 @@ enableMcpMutationTools=MCP変異ツールを有効にする enableMcpMutationToolsDescription=デフォルトでは、MCPサーバーでは読み取り専用ツールだけが有効になっている。これは、システムを変更する可能性のある偶発的な操作が行われないようにするためである。\n\nMCPクライアントを介してシステムに変更を加える予定がある場合は、このオプショ ンを有効にする前に、破壊的な可能性のある操作を確認するようにMCPクライアントが構成さ れていることを確認する。適用するには、MCPクライアントの再接続が必要である。 mcpClientConfigurationDetails=MCPクライアントの設定 mcpClientConfigurationDetailsDescription=この設定データを使用して、MCPクライアントからXPipe MCPサーバーに接続する。 -switchHostAddress=スイッチホストアドレス +switchHostAddress=ホストアドレスを変更する addAnotherHostName=別のホスト名を追加する addNetwork=ネットワークスキャン ... networkScan=ネットワークスキャン @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=新しいネットバードプロファイルの名前 openSftp=SFTPセッションで開く capslockWarning=キャップロックを有効にしている inherit=継承する +sshConfigStringSelected=対象ホスト +sshConfigStringSelectedDescription=複数のホストの場合、最初のホストがターゲットとして使われる。ホストの順番を変えてターゲットを変更する diff --git a/lang/strings/translations_ko.properties b/lang/strings/translations_ko.properties index 40dd49e60..8beb8ec83 100644 --- a/lang/strings/translations_ko.properties +++ b/lang/strings/translations_ko.properties @@ -1,13 +1,20 @@ delete=삭제 properties=속성 -usedDate=사용됨 $DATE$ -openDir=디렉터리 열기 -sortLastUsed=마지막으로 사용한 날짜를 기준으로 정렬 -sortAlphabetical=이름별로 알파벳순 정렬 -sortIndexed=주문 인덱스로 정렬 +#custom +usedDate=$DATE$ 사용됨 +#custom +openDir=폴더 열기 +#custom +sortLastUsed=마지막으로 사용한 날짜로 정렬 +#custom +sortAlphabetical=파일 이름을 알파벳순으로 정렬 +#custom +sortIndexed=인덱스 순으로 정렬 restartDescription=재시작으로 빠르게 해결할 수 있는 경우가 많습니다 -reportIssue=문제 신고하기 -reportIssueDescription=통합 이슈 리포터 열기 +#custom +reportIssue=문제 보고하기 +#custom +reportIssueDescription=통합 오류 보고기 열기 usefulActions=유용한 작업 stored=저장됨 troubleshootingOptions=문제 해결 도구 @@ -17,7 +24,8 @@ addShellStore=셸 추가 ... addShellTitle=셸 연결 추가 savedConnections=저장된 연결 save=저장 -clean=Clean +#custom +clean=청소 moveTo=이동 ... addDatabase=데이터베이스 ... browseInternalStorage=내부 저장소 찾아보기 @@ -55,7 +63,8 @@ color=색상 alwaysConfirmElevation=항상 권한 상승을 확인 alwaysConfirmElevationDescription=시스템에서 명령을 실행하기 위해 상승된 권한이 필요한 경우(예: sudo)를 사용하여 처리하는 방법을 제어합니다.\n\n기본적으로 모든 sudo 자격 증명은 세션 중에 캐시되어 있다가 필요할 때 자동으로 제공됩니다. 이 옵션을 사용 설정하면 매번 상승 권한 액세스를 확인하라는 메시지가 표시됩니다. allow=허용 -ask=Ask +#custom +ask=묻기 deny=거부 share=Git 리포지토리에 추가 unshare=Git 리포지토리에서 제거 @@ -72,21 +81,27 @@ test=테스트 finish=마침 error=오류가 발생했습니다 downloadStageDescription=다운로드한 파일을 시스템 다운로드 디렉터리로 이동하여 엽니다. -ok=Ok +#custom +ok=확인 search=검색 -repeatPassword=반복 비밀번호 +#custom +repeatPassword=비밀번호 확인 askpassAlertTitle=Askpass unsupportedOperation=지원되지 않는 작업입니다: $MSG$ fileConflictAlertTitle=충돌 해결 fileConflictAlertContent=충돌이 발생했습니다. $FILE$ 파일이 대상 시스템에 이미 존재합니다.\n\n어떻게 진행하시겠습니까? fileConflictAlertContentMultiple=충돌이 발생했습니다. $FILE$ 파일이 이미 존재합니다.\n\n어떻게 진행하시겠습니까? 모두에 적용되는 옵션을 선택하여 자동으로 해결할 수 있는 충돌이 더 있을 수 있습니다. moveAlertTitle=이동 확인 -moveAlertHeader=($COUNT$) 선택한 요소를 $TARGET$ 으로 이동하시겠습니까? +#custom +moveAlertHeader=($COUNT$) 개의 요소를 $TARGET$ 으로 이동하시겠습니까? deleteAlertTitle=삭제 확인 -deleteAlertHeader=($COUNT$) 선택한 요소를 삭제하시겠습니까? +#custom +deleteAlertHeader=($COUNT$) 개의 요소를 삭제하시겠습니까? selectedElements=선택된 요소: -mustNotBeEmpty=$VALUE$ 는 비어 있지 않아야 합니다 -valueMustNotBeEmpty=값이 비어 있지 않아야 합니다 +#custom +mustNotBeEmpty=$VALUE$ 는 값을 입력해야 합니다 +#custom +valueMustNotBeEmpty=값을 입력해야 합니다 transferDescription=다운로드하려면 파일을 여기로 드래그하세요 dragLocalFiles=여기에서 다운로드 드래그 null=$VALUE$ 는 널이 아니어야 합니다 @@ -276,7 +291,8 @@ gitSync=Git 동기화 enableGitStorageDescription=이 옵션을 활성화하면 XPipe가 로컬 볼트에 대한 git 리포지토리를 초기화하고 변경 사항을 커밋합니다. 이 경우 git이 설치되어 있어야 하며 로드 및 저장 작업 속도가 느려질 수 있습니다.\n\n동기화해야 하는 모든 카테고리는 명시적으로 동기화됨으로 표시해야 합니다. storageGitRemote=Git 원격 URL storageGitRemoteDescription=설정하면 XPipe는 로드할 때 변경 내용을 자동으로 가져오고 저장할 때 변경 내용을 원격 리포지토리에 푸시합니다.\n\n이를 통해 여러 XPipe 설치 간에 볼트를 공유할 수 있습니다. HTTP와 SSH URL이 모두 지원됩니다.\n\n이 경우 로딩 및 저장 작업이 느려질 수 있습니다. -vault=금고 +#custom +vault=저장소 workspaceLockDescription=XPipe에 저장된 모든 민감한 정보를 암호화하기 위한 사용자 지정 비밀번호를 설정합니다.\n\n이렇게 하면 저장된 민감한 정보에 대한 추가 암호화 계층이 제공되므로 보안이 강화됩니다. 그러면 XPipe가 시작될 때 비밀번호를 입력하라는 메시지가 표시됩니다. useSystemFontDescription=기본 시스템 글꼴을 사용할지 아니면 XPipe에 포함된 Inter 글꼴을 사용할지 제어합니다. tooltipDelay=툴팁 지연 @@ -349,7 +365,8 @@ editorReloadTimeout=편집기 재로드 시간 초과 editorReloadTimeoutDescription=파일이 업데이트된 후 파일을 읽기 전에 대기하는 시간(밀리초)입니다. 이렇게 하면 편집기가 파일 잠금을 쓰거나 해제하는 속도가 느릴 때 발생하는 문제를 방지할 수 있습니다. encryptAllVaultData=모든 볼트 데이터 암호화 encryptAllVaultDataDescription=이 기능을 활성화하면 볼트 연결 데이터의 모든 부분이 해당 데이터 내의 비밀만 암호화되는 것이 아니라 사용자 볼트 암호화 키로 암호화됩니다. 이렇게 하면 볼트에 기본적으로 암호화되지 않는 사용자 이름, 호스트 이름 등과 같은 다른 매개변수에 대한 보안이 한층 더 강화됩니다.\n\n이 옵션을 사용하면 더 이상 원본 변경 내용은 볼 수 없고 바이너리 변경 내용만 볼 수 있으므로 git 볼트 기록과 Diffs는 쓸모가 없게 됩니다. -vaultSecurity=금고 보안 +#custom +vaultSecurity=저장소 보안 developerDisableUpdateVersionCheck=업데이트 버전 확인 비활성화 developerDisableUpdateVersionCheckDescription=업데이트 검사기에서 업데이트를 찾을 때 버전 번호를 무시할지 여부를 제어합니다. developerDisableGuiRestrictions=GUI 제한 비활성화 @@ -404,13 +421,14 @@ size=크기 attributes=속성 modified=수정됨 owner=소유자 -updateReadyTitle=$VERSION$ 로 업데이트 준비 +#custom +updateReadyTitle=$VERSION$ 로 업데이트할 수 있습니다. templates=템플릿 retry=재시도 retryAll=모두 다시 시도 replace=바꾸다 replaceAll=모두 바꾸기 -copyPassword=복사 비밀번호 +copyPassword=비밀번호 복사 hibernateBehaviour=최대 절전 모드 동작 hibernateBehaviourDescription=시스템이 최대 절전 모드/절전 모드로 전환될 때 애플리케이션이 작동하는 방식을 제어합니다. overview=개요 @@ -470,12 +488,15 @@ ttyWarning=연결이 pty/tty를 강제로 할당했으며 별도의 stderr 스 xshellSetup=Xshell 설정 termiusSetup=Termius 설정 tryPtbDescription=XPipe 개발자 빌드에서 새로운 기능을 먼저 사용해 보세요 -confirmVaultUnencryptTitle=금고 암호화 해제 확인 -confirmVaultUnencryptContent=정말 고급 금고 암호화를 비활성화하시겠습니까? 이렇게 하면 저장된 데이터에 대한 추가 암호화가 제거되고 기존 데이터를 덮어쓰게 됩니다. +#custom +confirmVaultUnencryptTitle=저장소 암호화 해제 확인 +#custom +confirmVaultUnencryptContent=정말 고급 저장소 암호화를 비활성화하시겠습니까? 이렇게 하면 저장된 데이터에 대한 추가 암호화가 제거되고 기존 데이터를 덮어쓰게 됩니다. enableHttpApi=HTTP API 사용 enableHttpApiDescription=API를 활성화하여 외부 프로그램에서 XPipe 디먼을 호출하여 관리되는 연결에 대한 작업을 수행할 수 있도록 합니다. chooseCustomIcon=사용자 지정 아이콘 선택 -gitVault=Git 볼트 +#custom +gitVault=Git 저장소 fileBrowser=파일 브라우저 confirmAllDeletions=모든 삭제 확인 confirmAllDeletionsDescription=모든 삭제 작업에 대해 확인 대화 상자를 표시할지 여부입니다. 기본적으로 디렉터리만 확인이 필요합니다. @@ -542,19 +563,27 @@ identitiesIntroButton=ID 만들기 userName=사용자 이름 team=팀 teamSettings=팀 설정 -teamVaults=팀 금고 -vaultTypeNameDefault=기본 금고 -vaultTypeNameLegacy=레거시 개인 금고 -vaultTypeNamePersonal=개인 금고 -vaultTypeNameTeam=팀 금고 +#custom +teamVaults=팀 저장소 +#custom +vaultTypeNameDefault=기본 저장소 +#custom +vaultTypeNameLegacy=레거시 개인 저장소 +#custom +vaultTypeNamePersonal=개인 저장소 +#custom +vaultTypeNameTeam=팀 저장소 teamVaultsDescription=팀 볼트를 사용하면 여러 사용자가 공유 볼트에 안전하게 액세스할 수 있습니다. 연결과 ID를 모든 사용자에게 공유하거나 개인 키로 암호화하여 개인 사용자만 사용할 수 있도록 구성할 수 있습니다. 다른 볼트 사용자는 개인용 연결과 ID에 액세스할 수 없습니다. vaultTypeContentDefault=현재 사용자 및 사용자 지정 암호가 설정되지 않은 기본 볼트를 사용하고 있습니다. 비밀은 로컬 볼트 키로 암호화되어 있습니다. 볼트 사용자 계정을 만들어 개인용 볼트로 업그레이드할 수 있습니다. 이렇게 하면 로그인할 때마다 입력해야 하는 개인용 비밀번호로 볼트 비밀을 암호화하여 볼트를 잠금 해제할 수 있습니다. -vaultTypeContentLegacy=현재 사용자를 위해 레거시 개인 금고를 사용하고 있습니다. 비밀은 개인 비밀번호로 암호화되어 있습니다. 이 레거시 호환성에는 기능이 제한되어 있으며 팀 볼트로 바로 업그레이드할 수 없습니다. -vaultTypeContentPersonal=현재 사용자를 위해 개인 금고를 사용하고 있습니다. 비밀은 개인 비밀번호로 암호화되어 있습니다. 볼트 사용자를 추가하여 팀 볼트로 업그레이드할 수 있습니다. +#custom +vaultTypeContentLegacy=현재 사용자를 위해 레거시 개인 저장소를 사용하고 있습니다. 비밀은 개인 비밀번호로 암호화되어 있습니다. 이 레거시 호환성에는 기능이 제한되어 있으며 팀 볼트로 바로 업그레이드할 수 없습니다. +#custom +vaultTypeContentPersonal=현재 사용자를 위해 개인 저장소를 사용하고 있습니다. 비밀은 개인 비밀번호로 암호화되어 있습니다. 볼트 사용자를 추가하여 팀 볼트로 업그레이드할 수 있습니다. vaultTypeContentTeam=현재 여러 사용자가 공유 볼트에 안전하게 액세스할 수 있는 팀 볼트를 사용하고 있습니다. 연결과 ID를 모든 사용자에게 공유하거나 개인 키로 암호화하여 개인 사용자만 사용할 수 있도록 구성할 수 있습니다. 다른 볼트 사용자는 개인용 연결과 ID에 액세스할 수 없습니다. userManagement=사용자 관리 userManagementDescription=기존 볼트 사용자를 관리하거나 새 사용자를 만듭니다. -userManagementDescriptionEmpty=기존 금고 사용자를 관리하거나 새 사용자를 만드세요. 개인 키로 연결과 신원을 암호화할 수 있는 사용자를 직접 만들 수 있습니다.\n\n커뮤니티 에디션에서는 단일 사용자 계정만 지원됩니다. 프로페셔널 요금제에서는 팀을 위한 여러 사용자 계정이 지원됩니다. +#custom +userManagementDescriptionEmpty=기존 저장소 사용자를 관리하거나 새 사용자를 만드세요. 개인 키로 연결과 신원을 암호화할 수 있는 사용자를 직접 만들 수 있습니다.\n\n커뮤니티 에디션에서는 단일 사용자 계정만 지원됩니다. 프로페셔널 요금제에서는 팀을 위한 여러 사용자 계정이 지원됩니다. userIntroHeader=사용자 관리 userIntroContent=시작하려면 첫 번째 사용자 계정을 직접 만드세요. 이렇게 하면 이 워크스페이스를 비밀번호로 잠글 수 있습니다. addReusableIdentity=재사용 가능한 ID 추가 @@ -568,13 +597,13 @@ browseVaultButton=볼트 찾아보기 vaultUsers=Vault 사용자 createHeapDump=힙 덤프 생성 createHeapDumpDescription=메모리 사용량 문제를 해결하기 위해 메모리 내용을 파일로 덤프합니다 -initializingApp=연결 로드 중 ... -checkingLicense=라이선스 확인 중 ... -loadingGit=Git 리포지토리와 동기화 중 ... -loadingGpg=Git용 GnuPG 데몬 시작 ... -loadingSettings=설정 로드 중 ... -loadingConnections=연결 로드 중 ... -loadingUserInterface=사용자 인터페이스 로드 중 ... +initializingApp=연결 로드 중 +checkingLicense=라이선스 확인 +loadingGit=Git 리포지토리와 동기화 +loadingGpg=Git용 GnuPG 데몬 시작하기 +loadingSettings=로딩 설정 +loadingConnections=연결 로드 중 +loadingUserInterface=사용자 인터페이스 로드 ptbNotice=공개 테스트 빌드에 대한 공지 userDeletionTitle=사용자 삭제 userDeletionContent=이 볼트 사용자를 삭제하시겠습니까? 그러면 모든 사용자가 사용할 수 있는 볼트 키를 사용하여 모든 개인 신원 및 연결 비밀이 다시 암호화됩니다. XPipe가 다시 시작되어 사용자 변경 사항을 적용합니다. @@ -790,7 +819,8 @@ customUsernamePasswordDescription=Sudo 인증이 필요할 때 사용할 사용 showInternalPods=내부 파드 표시 showAllNamespaces=모든 네임스페이스 표시 showInternalContainers=내부 컨테이너 표시 -refresh=새로 고침 +#custom +refresh=새로고침 vmwareGui=시작 GUI monitorVm=VM 모니터 addCluster=클러스터 추가 ... @@ -1162,13 +1192,15 @@ automaticallyDetect=자동 감지 lockCreationAlertTitle=사용자 생성 passphrase=암호 구문 repeatPassphrase=반복 암호 구문 -lockCreationAlertHeader=새 금고 사용자 만들기 +#custom +lockCreationAlertHeader=새 저장소 사용자 만들기 loginAlertTitle=로그인 필요 loginAlertHeader=개인 연결에 액세스할 수 있는 볼트 잠금 해제 vaultUser=Vault 사용자 me=Me addUser=사용자 추가 ... -addUserDescription=이 금고의 새 사용자 만들기 +#custom +addUserDescription=이 저장소의 새 사용자 만들기 skip=건너뛰기 userChangePasswordAlertTitle=비밀번호 변경 userChangePasswordAlertHeader=사용자에 대한 새 비밀번호 설정 @@ -1226,7 +1258,8 @@ activate=활성화 validUntil=다음까지 유효합니다 licenseActivated=활성화된 라이선스 restart=다시 시작 -lockVault=금고 잠금 +#custom +lockVault=저장소 잠금 restartApp=XPipe 다시 시작 free=무료 upgradeInfo=아래에서 라이선스 업그레이드에 대한 정보를 확인할 수 있습니다. @@ -1252,7 +1285,8 @@ downloadingUpdateDescription=릴리스 패키지 다운로드 updateNag=XPipe를 한동안 업데이트하지 않았습니다. 최신 릴리스의 새로운 기능 및 수정 사항을 놓치고 있을 수 있습니다. updateNagTitle=업데이트 알림 updateNagButton=릴리스 보기 -refreshServices=서비스 새로 고침 +#custom +refreshServices=서비스 새로고침 serviceProtocolType=서비스 프로토콜 유형 serviceProtocolTypeDescription=서비스 열기 방법 제어 serviceCommand=서비스가 활성화되면 실행할 명령 @@ -1295,7 +1329,8 @@ icons=아이콘 customIcons=사용자 지정 아이콘 iconSources=아이콘 소스 iconSourcesDescription=여기에서 아이콘 소스를 직접 추가할 수 있습니다. XPipe는 추가된 위치에서 .svg 파일을 선택하여 사용 가능한 아이콘 세트에 추가합니다.\n\n로컬 디렉터리와 원격 git 리포지토리 모두 아이콘 위치로 지원됩니다. -refreshSources=새로 고침 아이콘 +#custom +refreshSources=새로고침 아이콘 refreshSourcesDescription=사용 가능한 소스에서 모든 아이콘 업데이트 addDirectoryIconSource=디렉토리 소스 추가 ... addDirectoryIconSourceDescription=로컬 디렉터리에서 아이콘 추가 @@ -1315,13 +1350,17 @@ runInConnectionHub=연결 허브의 commandOutput=명령 출력 iconSourceDeletionTitle=아이콘 소스 삭제 iconSourceDeletionContent=이 아이콘 소스 및 이와 관련된 모든 아이콘을 삭제하시겠습니까? -refreshIcons=새로 고침 아이콘 +#custom +refreshIcons=새로고침 아이콘 refreshIconsDescription=사용 가능한 모든 1000개 이상의 아이콘을 .png 파일로 검색, 렌더링 및 캐싱합니다. 시간이 좀 걸릴 수 있습니다... -vaultUserLegacy=Vault 사용자(레거시 호환성 모드 제한) -upgradeInstructions=업그레이드 지침 +#custom +vaultUserLegacy=Vault 사용자 (레거시 호환성 모드 제한) +#custom +upgradeInstructions=업그레이드 방법 externalActionTitle=외부 작업 요청 externalActionContent=외부 작업이 요청되었습니다. XPipe 외부에서 작업을 시작하도록 허용하시겠습니까? -noScriptStateAvailable=스크립트 호환성을 확인하려면 새로 고침 ... +#custom +noScriptStateAvailable=스크립트 호환성을 확인하려면 새로고침 ... documentationDescription=문서 확인 customEditorCommandInTerminal=터미널에서 사용자 지정 명령 실행 customEditorCommandInTerminalDescription=편집기가 터미널 기반인 경우 이 옵션을 활성화하면 터미널을 자동으로 열고 대신 터미널 세션에서 명령을 실행할 수 있습니다.\n\nVi, vim, nvim 등의 편집기에 이 옵션을 사용할 수 있습니다. @@ -1353,9 +1392,12 @@ terminalMultiplexerWindowsDescription=터미널에서 탭 대신 사용할 터 terminalAlwaysPauseOnExit=종료 시 항상 일시 중지 terminalAlwaysPauseOnExitDescription=활성화하면 터미널 세션을 종료할 때 항상 세션을 다시 시작하거나 닫으라는 메시지가 표시됩니다. 비활성화하면 XPipe는 오류와 함께 종료되는 실패한 연결에 대해서만 메시지를 표시합니다. querying=쿼리 ... -retrievedPassword=획득했습니다: $PASSWORD$ -refreshOpenpubkey=오픈펍키 ID 새로 고침 -refreshOpenpubkeyDescription=Opkssh 새로 고침을 실행하여 오픈펍키 ID를 다시 유효하게 만듭니다 +#custom +retrievedPassword=비밀번호: $PASSWORD$ +#custom +refreshOpenpubkey=Openpubkey ID 새로고침 +#custom +refreshOpenpubkeyDescription=Opkssh 새로고침을 실행하여 Openpubkey ID를 다시 유효하게 만듭니다 all=모두 terminalPrompt=터미널 프롬프트 terminalPromptDescription=원격 터미널에서 사용할 터미널 프롬프트 도구입니다. 터미널 프롬프트를 활성화하면 터미널 세션을 열 때 대상 시스템에서 프롬프트 도구가 자동으로 설정 및 구성됩니다.\n\n이 경우 시스템의 기존 프롬프트 구성이나 프로필 파일은 수정되지 않습니다. 이렇게 하면 원격 시스템에서 프롬프트를 설정하는 동안 처음으로 터미널을 로딩하는 시간이 늘어납니다. 프롬프트를 올바르게 표시하려면 터미널에 https://github.com/ryanoasis/nerd-fonts 의 특수 글꼴이 필요할 수 있습니다. @@ -1375,6 +1417,7 @@ categoryColor=카테고리 색상 categoryColorDescription=이 카테고리 내의 연결에 사용할 기본 색상입니다 categorySync=Git 리포지토리와 동기화 categorySyncDescription=모든 연결을 git 리포지토리와 자동으로 동기화합니다. 연결에 대한 모든 로컬 변경사항이 원격으로 푸시됩니다. +categorySyncSpecial=Git 리포지토리와 동기화\n(특수 카테고리 "$NAME$"에는 구성할 수 없음) categoryDontAllowScripts=스크립트 비활성화 categoryDontAllowScriptsDescription=이 범주에 속하는 시스템에서 스크립트 생성을 비활성화하여 파일 시스템 수정을 방지합니다. 이렇게 하면 모든 스크립팅 기능, 셸 환경 명령, 프롬프트 등이 비활성화됩니다. categoryConfirmAllModifications=모든 수정 사항 확인 @@ -1391,11 +1434,16 @@ dockerComposeRestricted=이 작성 프로젝트는 $NAME$ 에 의해 제한되 restricted=제한됨 disableSshPinCaching=SSH PIN 캐싱 비활성화 disableSshPinCachingDescription=XPipe는 어떤 형태의 하드웨어 기반 인증을 사용할 때 키에 입력한 모든 PIN을 자동으로 캐시합니다.\n\n이 기능을 비활성화하면 연결을 시도할 때마다 PIN을 다시 입력해야 합니다. -gitSyncPull=당겨서 원격 Git 변경 사항 동기화 -enpassVaultFile=볼트 파일 -enpassVaultFileDescription=로컬 Enpass 볼트 파일입니다. -flat=플랫 -recursive=재귀적 +#custom +gitSyncPull=원격 Git 변경 사항 동기화 (pull) +#custom +enpassVaultFile=저장소 파일 +#custom +enpassVaultFileDescription=로컬 Enpass 저장소 파일입니다. +#custom +flat=이 파일에만 적용 +#custom +recursive=하위 폴더에도 적용 rdpAllowListBlocked=선택한 RemoteApp이 서버의 RDP 허용 목록에 포함되어 있지 않은 것 같습니다. psonoServerUrl=서버 URL psonoServerUrlDescription=Psono 백엔드 서버의 URL @@ -1418,8 +1466,10 @@ updateFail=업데이트 설치에 성공하지 못했습니다 updateFailAction=수동으로 업데이트 설치 updateFailActionDescription=GitHub에서 최신 릴리스를 확인하세요 onePasswordPlaceholder=항목 이름 -computeDirectorySizes=디렉토리 크기 계산 -computeSize=계산 크기 +#custom +computeDirectorySizes=폴더 용량 계산 +#custom +computeSize=용량 계산 vncClient=VNC 클라이언트 vncClientDescription=XPipe에서 VNC 연결을 열 때 실행할 VNC 클라이언트입니다.\n\nXPipe 내에서 통합된 VNC 클라이언트를 사용하거나 더 많은 사용자 지정을 원하는 경우 로컬에 설치된 외부 VNC 클라이언트를 실행하는 옵션이 있습니다. integratedXPipeVncClient=통합 XPipe VNC 클라이언트 @@ -1500,7 +1550,8 @@ gitRepoTryAgain=다시 시도 gitRepoTryAgainDescription=동일한 작업을 다시 시도합니다 gitRepoDisable=지금은 깃 볼트 비활성화 gitRepoDisableDescription=이 세션 중에는 변경 내용을 커밋하지 마세요 -gitRepoPullRefresh=변경 사항 가져오기 및 새로 고침 +#custom +gitRepoPullRefresh=변경 사항 가져오기 및 새로고침 gitRepoPullRefreshDescription=원격 변경 사항 병합 및 데이터 다시 로드 breakOutCategory=브레이크아웃 카테고리 mergeCategory=카테고리 병합 @@ -1539,7 +1590,7 @@ enableMcpMutationTools=MCP 변이 도구 사용 enableMcpMutationToolsDescription=기본적으로 MCP 서버에서는 읽기 전용 도구만 사용하도록 설정되어 있습니다. 이는 시스템을 수정할 수 있는 우발적인 조작이 발생하지 않도록 하기 위한 것입니다.\n\nMCP 클라이언트를 통해 시스템을 변경하려는 경우, 이 옵션을 활성화하기 전에 잠재적으로 시스템을 파괴할 수 있는 작업을 확인하도록 MCP 클라이언트가 구성되어 있는지 확인하세요. 적용하려면 MCP 클라이언트를 다시 연결해야 합니다. mcpClientConfigurationDetails=MCP 클라이언트 구성 mcpClientConfigurationDetailsDescription=이 구성 데이터를 사용하여 선택한 MCP 클라이언트에서 XPipe MCP 서버에 연결합니다. -switchHostAddress=스위치 호스트 주소 +switchHostAddress=호스트 주소 변경 addAnotherHostName=다른 호스트 이름 추가 addNetwork=네트워크 스캔 ... networkScan=네트워크 스캔 @@ -1580,7 +1631,8 @@ parentHostDoesNotSupportTunneling=상위 호스트 $NAME$ 는 터널링을 지 connectionNotesTemplate=메모 템플릿 connectionNotesTemplateDescription=연결에 새 노트 항목을 추가할 때 사용해야 하는 마크다운 템플릿입니다. connectionNotesButton=노트 편집 -rdpSmartSizing=스마트 크기 조정 사용 +#custom +rdpSmartSizing=자동 크기 조정 사용 rdpSmartSizingDescription=활성화하면 창이 너무 작아 전체 해상도로 표시할 수 없는 경우 mstsc가 바탕 화면 크기를 축소합니다. 축소 시 바탕 화면의 종횡비는 그대로 유지됩니다. disableStartOnInit=자동 시작 사용 안 함 enableStartOnInit=자동 시작 사용 @@ -1590,7 +1642,8 @@ netbirdInstall.displayName=Netbird 설치 netbirdInstall.displayDescription=Netbird 네트워크의 피어에 연결합니다 netbirdProfile.displayName=Netbird 프로필 netbirdProfile.displayDescription=특정 프로필에 있는 동료 목록 -netbirdPeer.displayName=넷버드 피어 +#custom +netbirdPeer.displayName=Netbird 피어 netbirdPeer.displayDescription=SSH를 통해 피어에 연결 netbirdPublicKey=공개 키 netbirdPublicKeyDescription=피어의 내부 공개 키 @@ -1606,10 +1659,13 @@ abstractHostGateway=게이트웨이 abstractHostGatewayDescription=이 호스트에 연결하기 위한 게이트웨이 시스템(선택 사항) abstractHostConvert=추상 호스트 항목으로 변환 hostNoConnections=사용 가능한 연결이 없습니다 -hostHasConnections=$COUNT$ 사용 가능한 연결 -hostHasConnection=$COUNT$ 사용 가능한 연결 +#custom +hostHasConnections=$COUNT$개의 사용 가능한 연결 +#custom +hostHasConnection=$COUNT$개의 사용 가능한 연결 largeFileWarningTitle=대용량 파일 편집 -largeFileWarningContent=편집하려는 파일이 $SIZE$ 로 상당히 큽니다. 이 파일을 텍스트 편집기에서 정말 열어야 하나요? +#custom +largeFileWarningContent=편집하려는 파일이 $SIZE$ 로 상당히 큽니다. 이 파일을 텍스트 편집기에서 열까요? rdpAskpassUser=호스트의 RDP 사용자 이름 $HOST$ rdpAskpassPassword=사용자의 비밀번호 $USER$ inPlaceKey=제자리 키 @@ -1627,3 +1683,5 @@ netbirdProfileNameAsktext=새 넷버드 프로필의 이름 openSftp=SFTP 세션에서 열기 capslockWarning=캡록이 활성화되어 있습니다 inherit=Inherit +sshConfigStringSelected=대상 호스트 +sshConfigStringSelectedDescription=호스트가 여러 개인 경우 첫 번째 호스트가 대상으로 사용됩니다. 호스트를 재정렬하여 대상을 변경하세요 diff --git a/lang/strings/translations_nl.properties b/lang/strings/translations_nl.properties index 35e132120..9e3472868 100644 --- a/lang/strings/translations_nl.properties +++ b/lang/strings/translations_nl.properties @@ -410,7 +410,7 @@ retry=Opnieuw proberen retryAll=Alles opnieuw proberen replace=Vervangen replaceAll=Alles vervangen -copyPassword=kopieerwachtwoord +copyPassword=Wachtwoord kopiëren hibernateBehaviour=Slaapstand gedrag hibernateBehaviourDescription=Regelt hoe de toepassing zich gedraagt wanneer je systeem in slaapstand wordt gezet. overview=Overzicht @@ -568,13 +568,13 @@ browseVaultButton=Bladeren door kluis vaultUsers=Gebruikers van kluizen createHeapDump=Een heap dump maken createHeapDumpDescription=Dump de geheugeninhoud naar een bestand om het geheugengebruik te controleren -initializingApp=Verbindingen laden ... -checkingLicense=Licentie controleren ... -loadingGit=Synchroniseren met git repo ... -loadingGpg=GnuPG daemon voor git starten ... -loadingSettings=Instellingen laden ... -loadingConnections=Verbindingen laden ... -loadingUserInterface=Gebruikersinterface laden ... +initializingApp=Verbindingen laden +checkingLicense=Licentie controleren +loadingGit=Synchroniseren met git repo +loadingGpg=GnuPG daemon voor git starten +loadingSettings=Instellingen laden +loadingConnections=Verbindingen laden +loadingUserInterface=Gebruikersinterface laden ptbNotice=Aankondiging voor de openbare test build userDeletionTitle=Verwijdering van gebruikers userDeletionContent=Wil je deze kluisgebruiker verwijderen? Dit zal al je persoonlijke identiteiten en verbindingsgeheimen opnieuw versleutelen met behulp van de kluissleutel die beschikbaar is voor alle gebruikers. XPipe zal opnieuw opstarten om de gebruikerswijzigingen toe te passen. @@ -1375,6 +1375,7 @@ categoryColor=Categorie kleur categoryColorDescription=De standaard te gebruiken kleur voor verbindingen binnen deze categorie categorySync=Synchroniseren met git repository categorySyncDescription=Synchroniseer alle verbindingen automatisch met een git repository. Alle lokale wijzigingen aan verbindingen worden naar de remote gepushed. +categorySyncSpecial=Synchroniseren met git repository\n(Niet configureerbaar voor speciale categorie "$NAME$") categoryDontAllowScripts=Scripts uitschakelen categoryDontAllowScriptsDescription=Schakel het maken van scripts uit op systemen binnen deze categorie om wijzigingen aan het bestandssysteem te voorkomen. Dit schakelt alle scriptfunctionaliteit, shell-omgevingsopdrachten, prompts en meer uit. categoryConfirmAllModifications=Bevestig alle wijzigingen @@ -1539,7 +1540,7 @@ enableMcpMutationTools=MCP mutatiegereedschappen inschakelen enableMcpMutationToolsDescription=Standaard zijn alleen alleen-lezen tools ingeschakeld in de MCP-server. Dit is om ervoor te zorgen dat er niet per ongeluk bewerkingen kunnen worden uitgevoerd die een systeem mogelijk kunnen wijzigen.\n\nAls je van plan bent om wijzigingen in systemen aan te brengen via MCP-clients, controleer dan of je MCP-client geconfigureerd is om mogelijk destructieve acties te bevestigen voordat je deze optie inschakelt. Vereist een herstart van MCP-clients om toe te passen. mcpClientConfigurationDetails=MCP-client configuratie mcpClientConfigurationDetailsDescription=Gebruik deze configuratiegegevens om verbinding te maken met de XPipe MCP-server vanaf een MCP-client naar keuze. -switchHostAddress=Hostadres van een switch +switchHostAddress=Hostadres wijzigen addAnotherHostName=Een andere hostnaam toevoegen addNetwork=Netwerkscan ... networkScan=Netwerk scan @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Naam van nieuw netbird profiel openSftp=Openen in SFTP-sessie capslockWarning=Je hebt capslock ingeschakeld inherit=Erven +sshConfigStringSelected=Doelhost +sshConfigStringSelectedDescription=Bij meerdere hosts wordt de eerste host als doel gebruikt. Wijzig de volgorde van je hosts om het doel te veranderen diff --git a/lang/strings/translations_pl.properties b/lang/strings/translations_pl.properties index b03902209..d12689118 100644 --- a/lang/strings/translations_pl.properties +++ b/lang/strings/translations_pl.properties @@ -410,7 +410,7 @@ retry=Retry retryAll=Ponów wszystkie replace=Wymień replaceAll=Zastąp wszystko -copyPassword=copyPassword +copyPassword=Kopiuj hasło hibernateBehaviour=Zachowanie w stanie hibernacji hibernateBehaviourDescription=Kontroluje zachowanie aplikacji, gdy system jest w stanie hibernacji/uśpienia. overview=Przegląd @@ -568,13 +568,13 @@ browseVaultButton=Przeglądaj skarbiec vaultUsers=Użytkownicy sejfu createHeapDump=Utwórz zrzut sterty createHeapDumpDescription=Zrzuć zawartość pamięci do pliku, aby rozwiązać problem z wykorzystaniem pamięci -initializingApp=Ładowanie połączeń ... -checkingLicense=Sprawdzanie licencji ... -loadingGit=Synchronizacja z git repo ... -loadingGpg=Uruchamianie demona GnuPG dla git ... -loadingSettings=Ładowanie ustawień ... -loadingConnections=Ładowanie połączeń ... -loadingUserInterface=Ładowanie interfejsu użytkownika ... +initializingApp=Ładowanie połączeń +checkingLicense=Sprawdzanie licencji +loadingGit=Synchronizacja z repozytorium git +loadingGpg=Uruchamianie demona GnuPG dla git +loadingSettings=Ustawienia ładowania +loadingConnections=Ładowanie połączeń +loadingUserInterface=Ładowanie interfejsu użytkownika ptbNotice=Powiadomienie o publicznej wersji testowej userDeletionTitle=Usuwanie użytkownika userDeletionContent=Czy chcesz usunąć tego użytkownika skarbca? Spowoduje to ponowne zaszyfrowanie wszystkich twoich osobistych tożsamości i sekretów połączeń przy użyciu klucza skarbca, który jest dostępny dla wszystkich użytkowników. XPipe uruchomi się ponownie, aby zastosować zmiany użytkownika. @@ -1376,6 +1376,7 @@ categoryColor=Kolor kategorii categoryColorDescription=Domyślny kolor używany dla połączeń w tej kategorii categorySync=Zsynchronizuj z repozytorium git categorySyncDescription=Synchronizuj wszystkie połączenia automatycznie z repozytorium git. Wszystkie lokalne zmiany w połączeniach zostaną przesłane do repozytorium zdalnego. +categorySyncSpecial=Synchronizuj z repozytorium git\n(Nie konfigurowalne dla kategorii specjalnej "$NAME$") categoryDontAllowScripts=Wyłącz skrypty categoryDontAllowScriptsDescription=Wyłącz tworzenie skryptów w systemach należących do tej kategorii, aby zapobiec modyfikacjom systemu plików. Spowoduje to wyłączenie wszystkich funkcji skryptów, poleceń środowiska powłoki, monitów i innych. categoryConfirmAllModifications=Potwierdź wszystkie modyfikacje @@ -1540,7 +1541,7 @@ enableMcpMutationTools=Włącz narzędzia mutacji MCP enableMcpMutationToolsDescription=Domyślnie na serwerze MCP włączone są tylko narzędzia tylko do odczytu. Ma to na celu zapewnienie, że nie zostaną wykonane żadne przypadkowe operacje, które mogą potencjalnie zmodyfikować system.\n\nJeśli planujesz wprowadzać zmiany w systemach za pośrednictwem klientów MCP, upewnij się, że klient MCP jest skonfigurowany do potwierdzania wszelkich potencjalnie destrukcyjnych działań przed włączeniem tej opcji. Wymaga ponownego połączenia wszystkich klientów MCP w celu zastosowania. mcpClientConfigurationDetails=Konfiguracja klienta MCP mcpClientConfigurationDetailsDescription=Użyj tych danych konfiguracyjnych, aby połączyć się z serwerem XPipe MCP z wybranego klienta MCP. -switchHostAddress=Adres hosta przełącznika +switchHostAddress=Zmień adres hosta addAnotherHostName=Dodaj kolejną nazwę hosta addNetwork=Skanowanie sieci ... networkScan=Skanowanie sieci @@ -1628,3 +1629,5 @@ netbirdProfileNameAsktext=Nazwa nowego profilu netbird openSftp=Otwórz w sesji SFTP capslockWarning=Masz włączony capslock inherit=Dziedzicz +sshConfigStringSelected=Host docelowy +sshConfigStringSelectedDescription=W przypadku wielu hostów, pierwszy z nich jest używany jako cel. Zmień kolejność hostów, aby zmienić cel diff --git a/lang/strings/translations_pt.properties b/lang/strings/translations_pt.properties index ddbd8ba55..bb098c76d 100644 --- a/lang/strings/translations_pt.properties +++ b/lang/strings/translations_pt.properties @@ -410,7 +410,7 @@ retry=Repetir retryAll=Repetir tudo replace=Substitui replaceAll=Substitui tudo -copyPassword=copyPassword +copyPassword=Copia a palavra-passe hibernateBehaviour=Comportamento de hibernação hibernateBehaviourDescription=Controla a forma como a aplicação se comporta quando o sistema é colocado em hibernação/sono. overview=Resumo @@ -568,13 +568,13 @@ browseVaultButton=Navega no cofre vaultUsers=Utilizadores de cofres createHeapDump=Cria um despejo de heap createHeapDumpDescription=Despeja o conteúdo da memória num ficheiro para resolver problemas de utilização da memória -initializingApp=Carregamento de ligações ... -checkingLicense=Verificação da licença ... -loadingGit=Sincroniza com o repositório git ... -loadingGpg=Iniciando o daemon GnuPG para o git ... -loadingSettings=Carregamento de definições ... -loadingConnections=Carregamento de ligações ... -loadingUserInterface=Carregamento da interface do utilizador ... +initializingApp=Carregamento de ligações +checkingLicense=Verificação da licença +loadingGit=Sincronização com o repositório git +loadingGpg=Iniciando o daemon GnuPG para o git +loadingSettings=Carregamento de definições +loadingConnections=Carregamento de ligações +loadingUserInterface=Carregamento da interface do utilizador ptbNotice=Aviso para a compilação de teste pública userDeletionTitle=Eliminação do utilizador userDeletionContent=Pretendes eliminar este utilizador da abóbada? Isto irá reencriptar todas as tuas identidades pessoais e segredos de ligação utilizando a chave da abóbada que está disponível para todos os utilizadores. O XPipe será reiniciado para aplicar as alterações ao utilizador. @@ -1375,6 +1375,7 @@ categoryColor=Categoria cor categoryColorDescription=A cor predefinida a utilizar para ligações dentro desta categoria categorySync=Sincroniza com o repositório git categorySyncDescription=Sincroniza todas as ligações automaticamente com o repositório git. Todas as alterações locais às ligações serão enviadas para o repositório remoto. +categorySyncSpecial=Sincroniza com o repositório git\n(Não configurável para a categoria especial "$NAME$") categoryDontAllowScripts=Desativar scripts categoryDontAllowScriptsDescription=Desabilita a criação de scripts em sistemas dentro desta categoria para evitar qualquer modificação no sistema de arquivos. Isto irá desativar todas as funcionalidades de scripting, comandos de ambiente shell, prompts e muito mais. categoryConfirmAllModifications=Confirma todas as modificações @@ -1539,7 +1540,7 @@ enableMcpMutationTools=Habilita as ferramentas de mutação da CIM enableMcpMutationToolsDescription=Por defeito, apenas as ferramentas só de leitura estão activadas no servidor MCP. Isso é para garantir que nenhuma operação acidental possa ser feita e potencialmente modificar um sistema.\n\nSe planeja fazer alterações nos sistemas por meio de clientes MCP, certifica-se de verificar se o cliente MCP está configurado para confirmar quaisquer ações potencialmente destrutivas antes de ativar esta opção. Requer uma reconexão de quaisquer clientes MCP para aplicar. mcpClientConfigurationDetails=Configuração do cliente MCP mcpClientConfigurationDetailsDescription=Utiliza estes dados de configuração para estabelecer ligação ao servidor XPipe MCP a partir do cliente MCP da tua escolha. -switchHostAddress=Troca o endereço do anfitrião +switchHostAddress=Altera o endereço do anfitrião addAnotherHostName=Adiciona outro nome de anfitrião addNetwork=Verificação de rede ... networkScan=Pesquisa de rede @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Nome do novo perfil Netbird openSftp=Abre uma sessão SFTP capslockWarning=Tens o capslock ativado inherit=Herdar +sshConfigStringSelected=Anfitrião de destino +sshConfigStringSelectedDescription=Para vários hosts, o primeiro é usado como alvo. Reordena os anfitriões para alterar o destino diff --git a/lang/strings/translations_ru.properties b/lang/strings/translations_ru.properties index 172ab09bb..137d4e9b1 100644 --- a/lang/strings/translations_ru.properties +++ b/lang/strings/translations_ru.properties @@ -622,14 +622,14 @@ browseVaultButton=Просматривай хранилище vaultUsers=Пользователи хранилища createHeapDump=Создайте дамп кучи createHeapDumpDescription=Сбрасывать содержимое памяти в файл, чтобы устранить неполадки с использованием памяти -initializingApp=Загрузка соединений ... -checkingLicense=Проверка лицензии ... +initializingApp=Загрузочные соединения +checkingLicense=Проверка лицензии #custom loadingGit=Синхронизация с git ... -loadingGpg=Запуск демона GnuPG для git ... -loadingSettings=Загрузка настроек ... -loadingConnections=Загрузка соединений ... -loadingUserInterface=Загрузка пользовательского интерфейса ... +loadingGpg=Запуск демона GnuPG для git +loadingSettings=Настройки загрузки +loadingConnections=Загрузочные соединения +loadingUserInterface=Загружаемый пользовательский интерфейс ptbNotice=Уведомление для публичной тестовой сборки userDeletionTitle=Удаление пользователя userDeletionContent=Хочешь удалить этого пользователя хранилища? Это позволит заново зашифровать все твои личные данные и секреты соединения с помощью ключа хранилища, который доступен всем пользователям. XPipe перезапустится, чтобы применить изменения пользователя. @@ -1479,6 +1479,7 @@ categoryColor=Цвет категории categoryColorDescription=Цвет по умолчанию, который будет использоваться для соединений в этой категории categorySync=Синхронизация с git-репозиторием categorySyncDescription=Автоматически синхронизируй все соединения с git-репозиторием. Все локальные изменения в соединениях будут выгружаться в удаленный. +categorySyncSpecial=Синхронизация с git-репозиторием\n(Не настраивается для специальной категории "$NAME$") categoryDontAllowScripts=Отключить скрипты categoryDontAllowScriptsDescription=Отключи создание скриптов в системах этой категории, чтобы предотвратить любые модификации файловой системы. Это отключит все функции скриптов, команды среды оболочки, подсказки и прочее. categoryConfirmAllModifications=Подтверди все модификации @@ -1652,7 +1653,7 @@ enableMcpMutationTools=Включите инструменты для мутац enableMcpMutationToolsDescription=По умолчанию на MCP-сервере включены только инструменты, предназначенные только для чтения. Это сделано для того, чтобы исключить возможность случайных операций, потенциально способных модифицировать систему.\n\nЕсли ты планируешь вносить изменения в системы через MCP-клиенты, то перед включением этой опции обязательно проверь, настроен ли твой MCP-клиент на подтверждение любых потенциально разрушительных действий. Требуется переподключение всех MCP-клиентов для применения. mcpClientConfigurationDetails=Настройка клиента MCP mcpClientConfigurationDetailsDescription=Используй эти конфигурационные данные для подключения к MCP-серверу XPipe с выбранного тобой MCP-клиента. -switchHostAddress=Адрес хоста коммутатора +switchHostAddress=Изменить адрес хоста addAnotherHostName=Добавьте еще одно имя хоста addNetwork=Сетевое сканирование ... networkScan=Сканирование сети @@ -1740,3 +1741,5 @@ netbirdProfileNameAsktext=Имя нового профиля netbird openSftp=Открыть в SFTP-сессии capslockWarning=У тебя включен capslock inherit=Наследуй +sshConfigStringSelected=Целевой хост +sshConfigStringSelectedDescription=Для нескольких хостов в качестве цели используется первый. Переставить хосты, чтобы изменить цель diff --git a/lang/strings/translations_sv.properties b/lang/strings/translations_sv.properties index 1ff02e4e8..60a43a763 100644 --- a/lang/strings/translations_sv.properties +++ b/lang/strings/translations_sv.properties @@ -410,7 +410,7 @@ retry=Försök igen retryAll=Försök igen alla replace=Byt ut replaceAll=Ersätt alla -copyPassword=kopieraLösenord +copyPassword=Kopiera lösenord hibernateBehaviour=Beteende vid viloläge hibernateBehaviourDescription=Styr hur programmet ska bete sig när systemet försätts i viloläge/viloläge. overview=Översikt över @@ -568,13 +568,13 @@ browseVaultButton=Bläddra bland valv vaultUsers=Vault-användare createHeapDump=Skapa heap dump createHeapDumpDescription=Dumpa minnesinnehåll till fil för att felsöka minnesanvändning -initializingApp=Laddar anslutningar ... -checkingLicense=Kontroll av licens ... -loadingGit=Synkronisering med git repo ... -loadingGpg=Startar GnuPG-daemon för git ... -loadingSettings=Laddar inställningar ... -loadingConnections=Laddar anslutningar ... -loadingUserInterface=Laddar användargränssnitt ... +initializingApp=Laddar anslutningar +checkingLicense=Kontroll av licens +loadingGit=Synkronisering med git repo +loadingGpg=Startar GnuPG-daemon för git +loadingSettings=Inställningar för laddning +loadingConnections=Laddar anslutningar +loadingUserInterface=Laddar användargränssnitt ptbNotice=Meddelande för den offentliga testversionen userDeletionTitle=Radering av användare userDeletionContent=Vill du ta bort den här valvanvändaren? Detta kommer att kryptera om alla dina personliga identiteter och anslutningshemligheter med hjälp av valvnyckeln som är tillgänglig för alla användare. XPipe kommer att starta om för att tillämpa användarändringarna. @@ -1375,6 +1375,7 @@ categoryColor=Kategori färg categoryColorDescription=Standardfärgen som ska användas för anslutningar inom denna kategori categorySync=Synkronisera med git-förvaret categorySyncDescription=Synkronisera alla anslutningar automatiskt med git-förvaret. Alla lokala ändringar av anslutningar kommer att skjutas till fjärrkontrollen. +categorySyncSpecial=Synkronisera med git-förvaret\n(Ej konfigurerbar för specialkategori "$NAME$") categoryDontAllowScripts=Inaktivera skript categoryDontAllowScriptsDescription=Inaktivera skapandet av skript på system inom denna kategori för att förhindra ändringar i filsystemet. Detta inaktiverar all skriptfunktionalitet, kommandon i skalmiljön, uppmaningar med mera. categoryConfirmAllModifications=Bekräfta alla ändringar @@ -1539,7 +1540,7 @@ enableMcpMutationTools=Aktivera MCP-mutationsverktyg enableMcpMutationToolsDescription=Som standard är endast skrivskyddade verktyg aktiverade i MCP-servern. Detta för att säkerställa att inga oavsiktliga åtgärder kan vidtas som potentiellt kan modifiera ett system.\n\nOm du planerar att göra ändringar i system via MCP-klienter bör du kontrollera att MCP-klienten är konfigurerad för att bekräfta potentiellt destruktiva åtgärder innan du aktiverar det här alternativet. Kräver en återanslutning av alla MCP-klienter för att gälla. mcpClientConfigurationDetails=Konfiguration av MCP-klient mcpClientConfigurationDetailsDescription=Använd dessa konfigurationsdata för att ansluta till XPipe MCP-servern från den MCP-klient du väljer. -switchHostAddress=Växelns värdadress +switchHostAddress=Ändra värdadress addAnotherHostName=Lägga till ett annat värdnamn addNetwork=Nätverksskanning ... networkScan=Nätverksskanning @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Namn på ny netbird-profil openSftp=Öppna i en SFTP-session capslockWarning=Du har aktiverat capslock inherit=Ärva +sshConfigStringSelected=Målvärd +sshConfigStringSelectedDescription=För flera värdar används den första som mål. Ordna om dina värdar för att ändra målet diff --git a/lang/strings/translations_tr.properties b/lang/strings/translations_tr.properties index 994f377bd..26bf18a58 100644 --- a/lang/strings/translations_tr.properties +++ b/lang/strings/translations_tr.properties @@ -410,7 +410,7 @@ retry=Yeniden Dene retryAll=Tümünü yeniden dene replace=Değiştirin replaceAll=Tümünü değiştirin -copyPassword=copyPassword +copyPassword=Şifreyi kopyala hibernateBehaviour=Kış uykusu davranışı hibernateBehaviourDescription=Sisteminiz hazırda bekletme/uyku moduna geçirildiğinde uygulamanın nasıl davranacağını kontrol eder. overview=Genel Bakış @@ -568,13 +568,13 @@ browseVaultButton=Kasaya göz atın vaultUsers=Kasa kullanıcıları createHeapDump=Yığın dökümü oluştur createHeapDumpDescription=Bellek kullanımında sorun gidermek için bellek içeriğini dosyaya dökme -initializingApp=Bağlantılar yükleniyor ... -checkingLicense=Lisans kontrolü ... -loadingGit=Git repo ile senkronize ediliyor ... -loadingGpg=Git için GnuPG daemon'u başlatılıyor ... -loadingSettings=Ayarlar yükleniyor ... -loadingConnections=Bağlantılar yükleniyor ... -loadingUserInterface=Kullanıcı arayüzü yükleniyor ... +initializingApp=Yükleme bağlantıları +checkingLicense=Lisans kontrolü +loadingGit=Git repo ile senkronize etme +loadingGpg=Git için GnuPG arka plan programını başlatma +loadingSettings=Yükleme ayarları +loadingConnections=Yükleme bağlantıları +loadingUserInterface=Kullanıcı arayüzü yükleniyor ptbNotice=Genel test derlemesi için bildirim userDeletionTitle=Kullanıcı silme userDeletionContent=Bu kasa kullanıcısını silmek istiyor musunuz? Bu, tüm kullanıcılar için mevcut olan kasa anahtarını kullanarak tüm kişisel kimliklerinizi ve bağlantı sırlarınızı yeniden şifreleyecektir. XPipe kullanıcı değişikliklerini uygulamak için yeniden başlayacaktır. @@ -1375,6 +1375,7 @@ categoryColor=Kategori rengi categoryColorDescription=Bu kategorideki bağlantılar için kullanılacak varsayılan renk categorySync=Git deposu ile senkronize et categorySyncDescription=Tüm bağlantıları git deposu ile otomatik olarak senkronize edin. Bağlantılardaki tüm yerel değişiklikler uzağa itilecektir. +categorySyncSpecial=Git deposu ile senkronize et\n(Özel kategori "$NAME$" için yapılandırılamaz) categoryDontAllowScripts=Komut dosyalarını devre dışı bırak categoryDontAllowScriptsDescription=Herhangi bir dosya sistemi değişikliğini önlemek için bu kategorideki sistemlerde komut dosyası oluşturmayı devre dışı bırakın. Bu, tüm komut dosyası işlevlerini, kabuk ortamı komutlarını, istemleri ve daha fazlasını devre dışı bırakacaktır. categoryConfirmAllModifications=Tüm değişiklikleri onaylayın @@ -1539,7 +1540,7 @@ enableMcpMutationTools=MCP mutasyon araçlarını etkinleştirin enableMcpMutationToolsDescription=Varsayılan olarak, MCP sunucusunda yalnızca salt okunur araçlar etkinleştirilir. Bu, bir sistemi potansiyel olarak değiştirecek kazara işlemlerin yapılmamasını sağlamak içindir.\n\nMCP istemcileri aracılığıyla sistemlerde değişiklik yapmayı planlıyorsanız, bu seçeneği etkinleştirmeden önce MCP istemcinizin potansiyel olarak yıkıcı eylemleri onaylamak üzere yapılandırıldığından emin olun. Uygulanması için tüm MCP istemcilerinin yeniden bağlanmasını gerektirir. mcpClientConfigurationDetails=MCP istemci yapılandırması mcpClientConfigurationDetailsDescription=Seçtiğiniz MCP istemcisinden XPipe MCP sunucusuna bağlanmak için bu yapılandırma verilerini kullanın. -switchHostAddress=Anahtar ana bilgisayar adresi +switchHostAddress=Ana bilgisayar adresini değiştirme addAnotherHostName=Başka bir ana bilgisayar adı ekleyin addNetwork=Ağ taraması ... networkScan=Ağ taraması @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Yeni netbird profilinin adı openSftp=SFTP oturumunda açın capslockWarning=Capslock'u etkinleştirdiniz inherit=Miras +sshConfigStringSelected=Hedef ev sahibi +sshConfigStringSelectedDescription=Birden fazla ana bilgisayar için ilk ana bilgisayar hedef olarak kullanılır. Hedefi değiştirmek için ana bilgisayarlarınızı yeniden sıralayın diff --git a/lang/strings/translations_vi.properties b/lang/strings/translations_vi.properties index cadcf67ae..7bae73836 100644 --- a/lang/strings/translations_vi.properties +++ b/lang/strings/translations_vi.properties @@ -410,7 +410,7 @@ retry=Thử lại retryAll=Thử lại tất cả replace=Thay thế replaceAll=Thay thế tất cả -copyPassword=copyPassword +copyPassword=Sao chép mật khẩu hibernateBehaviour=Hành vi ngủ đông hibernateBehaviourDescription=Quy định cách ứng dụng hoạt động khi hệ thống của cậu được đưa vào chế độ ngủ đông/ngủ. overview=Tổng quan @@ -568,13 +568,13 @@ browseVaultButton=Duyệt kho lưu trữ vaultUsers=Người dùng kho lưu trữ createHeapDump=Tạo bản sao lưu bộ nhớ đống createHeapDumpDescription=Sao chép nội dung bộ nhớ vào tệp để khắc phục sự cố sử dụng bộ nhớ -initializingApp=Đang tải kết nối ... -checkingLicense=Kiểm tra giấy phép ... -loadingGit=Đồng bộ hóa với kho lưu trữ Git ... -loadingGpg=Khởi động dịch vụ GnuPG cho git ... -loadingSettings=Đang tải cài đặt ... -loadingConnections=Đang tải kết nối ... -loadingUserInterface=Đang tải giao diện người dùng ... +initializingApp=Đang tải kết nối +checkingLicense=Kiểm tra giấy phép +loadingGit=Đồng bộ hóa với kho lưu trữ Git +loadingGpg=Khởi động dịch vụ GnuPG cho Git +loadingSettings=Đang tải cài đặt +loadingConnections=Đang tải kết nối +loadingUserInterface=Giao diện người dùng đang tải ptbNotice=Thông báo về phiên bản thử nghiệm công khai userDeletionTitle=Xóa người dùng userDeletionContent=Bạn có muốn xóa người dùng kho này không? Điều này sẽ mã hóa lại tất cả thông tin cá nhân và thông tin kết nối của bạn bằng khóa kho có sẵn cho tất cả người dùng. XPipe sẽ khởi động lại để áp dụng các thay đổi của người dùng. @@ -1375,6 +1375,7 @@ categoryColor=Màu sắc danh mục categoryColorDescription=Màu mặc định được sử dụng cho các kết nối trong danh mục này categorySync=Đồng bộ hóa với kho lưu trữ Git categorySyncDescription=Tự động đồng bộ hóa tất cả kết nối với kho lưu trữ Git. Tất cả thay đổi cục bộ đối với kết nối sẽ được đẩy lên kho lưu trữ từ xa. +categorySyncSpecial=Đồng bộ hóa với kho lưu trữ Git\n(Không thể cấu hình cho danh mục đặc biệt "$NAME$") categoryDontAllowScripts=Tắt các tập lệnh categoryDontAllowScriptsDescription=Vô hiệu hóa việc tạo kịch bản trên các hệ thống trong danh mục này để ngăn chặn bất kỳ thay đổi nào đối với hệ thống tệp. Điều này sẽ vô hiệu hóa tất cả các chức năng kịch bản, lệnh môi trường shell, lời nhắc và nhiều tính năng khác. categoryConfirmAllModifications=Xác nhận tất cả các thay đổi @@ -1429,7 +1430,7 @@ vncConnections=Kết nối VNC passwordManagerIdentity=Quản lý mật khẩu passwordManagerIdentity.displayName=Quản lý mật khẩu passwordManagerIdentity.displayDescription=Lấy tên người dùng và mật khẩu của một tài khoản từ trình quản lý mật khẩu của cậu -useAsJumpServer=Máy chủ chuyển tiếp +useAsJumpServer=Máy chủ trung gian useAsJumpServerDescription=Hệ thống này là một máy chủ chuyển tiếp được sử dụng với ProxyJump passwordCopied=Mật khẩu kết nối đã được sao chép vào khay nhớ tạm errorOccurred=Xảy ra lỗi @@ -1539,7 +1540,7 @@ enableMcpMutationTools=Bật công cụ biến đổi MCP enableMcpMutationToolsDescription=Theo mặc định, chỉ các công cụ chỉ đọc được kích hoạt trên máy chủ MCP. Điều này nhằm đảm bảo rằng không có thao tác vô tình nào có thể thực hiện và tiềm ẩn nguy cơ thay đổi hệ thống.\n\nNếu cậu có kế hoạch thực hiện thay đổi trên hệ thống thông qua các client MCP, hãy đảm bảo rằng client MCP của cậu đã được cấu hình để xác nhận bất kỳ hành động tiềm ẩn nguy hiểm nào trước khi kích hoạt tùy chọn này. Yêu cầu kết nối lại tất cả các client MCP để áp dụng thay đổi. mcpClientConfigurationDetails=Cấu hình client MCP mcpClientConfigurationDetailsDescription=Sử dụng dữ liệu cấu hình này để kết nối với máy chủ XPipe MCP từ ứng dụng khách MCP mà cậu chọn. -switchHostAddress=Địa chỉ máy chủ chuyển mạch +switchHostAddress=Thay đổi địa chỉ máy chủ addAnotherHostName=Thêm tên máy chủ khác addNetwork=Quét mạng ... networkScan=Quét mạng @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=Tên của hồ sơ Netbird mới openSftp=Mở trong phiên SFTP capslockWarning=Cậu đã bật chế độ Caps Lock inherit=Kế thừa +sshConfigStringSelected=Máy chủ đích +sshConfigStringSelectedDescription=Đối với nhiều máy chủ, máy chủ đầu tiên được sử dụng làm mục tiêu. Sắp xếp lại các máy chủ của cậu để thay đổi mục tiêu diff --git a/lang/strings/translations_zh-Hans.properties b/lang/strings/translations_zh-Hans.properties index 96ce2b3e4..29c28c6fb 100644 --- a/lang/strings/translations_zh-Hans.properties +++ b/lang/strings/translations_zh-Hans.properties @@ -823,10 +823,10 @@ createHeapDump=创建堆转储 createHeapDumpDescription=将内存内容转存为文件,以分析内存使用问题。 #custom initializingApp=正在加载连接... -checkingLicense=检查许可证 ... +checkingLicense=检查许可证 #custom loadingGit=正在同步 Git 仓库... -loadingGpg=为 git 启动 GnuPG 守护进程 ... +loadingGpg=为 git 启动 GnuPG 守护进程 #custom loadingSettings=正在加载设置... #custom @@ -1921,6 +1921,7 @@ categoryColorDescription=该类别中的连接使用的默认颜色 categorySync=与 Git 仓库同步 #custom categorySyncDescription=自动将该类别下的所有连接与 Git 仓库同步。本地更改会在保存时推送到远程。 +categorySyncSpecial=与 git 仓库同步\n(特殊类别 "$NAME$" 无法配置) categoryDontAllowScripts=禁用脚本 #custom categoryDontAllowScriptsDescription=禁止在此类别内的系统上创建脚本,以避免任何文件系统修改。此操作将禁用全部脚本功能、Shell 环境命令、提示符等。 @@ -2162,7 +2163,7 @@ enableMcpMutationToolsDescription=默认仅启用只读工具以避免意外更 mcpClientConfigurationDetails=MCP 客户端配置 #custom mcpClientConfigurationDetailsDescription=使用以下配置数据从选定 MCP 客户端连接到 XPipe MCP 服务端。 -switchHostAddress=交换机主机地址 +switchHostAddress=更改主机地址 addAnotherHostName=添加另一个主机名 addNetwork=网络扫描 ... networkScan=网络扫描 @@ -2262,3 +2263,5 @@ netbirdProfileNameAsktext=新网鸟配置文件的名称 openSftp=在 SFTP 会话中打开 capslockWarning=您已启用盖帽锁 inherit=继承 +sshConfigStringSelected=目标主机 +sshConfigStringSelectedDescription=对于多个主机,第一个会被用作目标。重新排列主机顺序以更改目标 diff --git a/lang/strings/translations_zh-Hant.properties b/lang/strings/translations_zh-Hant.properties index 64a778844..a9bca9290 100644 --- a/lang/strings/translations_zh-Hant.properties +++ b/lang/strings/translations_zh-Hant.properties @@ -568,13 +568,13 @@ browseVaultButton=瀏覽保險庫 vaultUsers=保險庫使用者 createHeapDump=建立堆轉儲 createHeapDumpDescription=將記憶體內容轉存至檔案,以排除記憶體使用的問題 -initializingApp=載入連接 ... -checkingLicense=檢查許可證 ... -loadingGit=與 git repo 同步 ... -loadingGpg=啟動 GnuPG daemon for git ... -loadingSettings=載入設定 ... -loadingConnections=載入連接 ... -loadingUserInterface=載入使用者介面... +initializingApp=載入連線 +checkingLicense=檢查許可證 +loadingGit=與 git repo 同步 +loadingGpg=啟動 git 的 GnuPG 守护进程 +loadingSettings=載入設定 +loadingConnections=載入連線 +loadingUserInterface=載入使用者介面 ptbNotice=公開測試建置的通知 userDeletionTitle=使用者刪除 userDeletionContent=您要刪除這個儲存庫使用者嗎?這將使用所有使用者都可使用的保險庫金鑰,重新加密您所有的個人身分和連線秘密。XPipe 會重新啟動以套用使用者變更。 @@ -1375,6 +1375,7 @@ categoryColor=分類顏色 categoryColorDescription=此類別內連線使用的預設顏色 categorySync=與 git 倉庫同步 categorySyncDescription=自動將所有連線與 git 套件庫同步。所有本地連線的變更都會推送到遠端。 +categorySyncSpecial=與 git 儲存庫同步\n(特殊類別 "$NAME$" 不可設定) categoryDontAllowScripts=停用腳本 categoryDontAllowScriptsDescription=在此類別的系統上停用指令碼建立功能,以防止任何檔案系統修改。這將停用所有指令碼功能、shell 環境指令、提示等。 categoryConfirmAllModifications=確認所有修改 @@ -1539,7 +1540,7 @@ enableMcpMutationTools=啟用 MCP 變異工具 enableMcpMutationToolsDescription=預設情況下,MCP 伺服器只啟用唯讀工具。這是為了確保不會發生可能修改系統的意外操作。\n\n如果您計劃透過 MCP 用戶端對系統進行變更,請務必檢查您的 MCP 用戶端是否已設定,以便在啟用此選項之前確認任何可能的破壞性操作。需要重新連接任何 MCP 用戶端才能套用。 mcpClientConfigurationDetails=MCP 用戶端配置 mcpClientConfigurationDetailsDescription=使用此設定資料,從您所選擇的 MCP 用戶端連線至 XPipe MCP 伺服器。 -switchHostAddress=交換器主機位址 +switchHostAddress=變更主機位址 addAnotherHostName=新增另一個主機名稱 addNetwork=網路掃描 ... networkScan=網路掃描 @@ -1627,3 +1628,5 @@ netbirdProfileNameAsktext=新 netbird 配置文件的名稱 openSftp=在 SFTP 會話中開啟 capslockWarning=您已啟用上限鎖定功能 inherit=繼承 +sshConfigStringSelected=目標主機 +sshConfigStringSelectedDescription=對於多台主機,第一台會作為目標。重新排列主機以變更目標 diff --git a/version b/version index a824897d2..218e04a89 100644 --- a/version +++ b/version @@ -1 +1 @@ -19.2 +19.6-2