mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-05-03 19:30:31 +00:00
Merge 13.4-release into master [release]
This commit is contained in:
@@ -20,6 +20,7 @@ It currently supports:
|
||||
- [Kubernetes](https://kubernetes.io/) clusters, pods, and containers
|
||||
- [Windows Subsystem for Linux](https://ubuntu.com/wsl), [Cygwin](https://www.cygwin.com/), and [MSYS2](https://www.msys2.org/) instances
|
||||
- [Powershell Remote Sessions](https://learn.microsoft.com/en-us/powershell/scripting/learn/remoting/running-remote-commands?view=powershell-7.3)
|
||||
- [Teleport tsh connections](https://goteleport.com/)
|
||||
- VNC connections
|
||||
- Any other custom remote connection methods that work through the command-line
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
@@ -108,7 +109,7 @@ public class BrowserFileListCompEntry {
|
||||
|
||||
if (item.getRawFileEntry().resolved().getKind() != FileKind.DIRECTORY) {
|
||||
return event.getButton() == MouseButton.SECONDARY
|
||||
|| event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2;
|
||||
|| !AppPrefs.get().editFilesWithDoubleClick().get() && event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
@@ -14,10 +15,7 @@ import javafx.collections.ObservableList;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
@@ -144,8 +142,17 @@ public final class BrowserFileListModel {
|
||||
}
|
||||
|
||||
public void onDoubleClick(BrowserEntry entry) {
|
||||
if (entry.getRawFileEntry().resolved().getKind() == FileKind.DIRECTORY) {
|
||||
fileSystemModel.cdAsync(entry.getRawFileEntry().resolved().getPath());
|
||||
var r = entry.getRawFileEntry().resolved();
|
||||
if (r.getKind() == FileKind.DIRECTORY) {
|
||||
fileSystemModel.cdAsync(r.getPath());
|
||||
}
|
||||
|
||||
if (AppPrefs.get().editFilesWithDoubleClick().get() && r.getKind() == FileKind.FILE) {
|
||||
var selection = new LinkedHashSet<>(getSelection());
|
||||
selection.add(entry);
|
||||
for (BrowserEntry e : selection) {
|
||||
BrowserFileOpener.openInTextEditor(getFileSystemModel(), e.getRawFileEntry());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,9 +147,16 @@ public class AppPrefs {
|
||||
final BooleanProperty requireDoubleClickForConnections =
|
||||
mapLocal(new SimpleBooleanProperty(false), "requireDoubleClickForConnections", Boolean.class, false);
|
||||
|
||||
final BooleanProperty editFilesWithDoubleClick =
|
||||
mapLocal(new SimpleBooleanProperty(false), "editFilesWithDoubleClick", Boolean.class, false);
|
||||
|
||||
final BooleanProperty enableTerminalDocking =
|
||||
mapLocal(new SimpleBooleanProperty(true), "enableTerminalDocking", Boolean.class, false);
|
||||
|
||||
public ObservableBooleanValue editFilesWithDoubleClick() {
|
||||
return editFilesWithDoubleClick;
|
||||
}
|
||||
|
||||
public ObservableBooleanValue requireDoubleClickForConnections() {
|
||||
return requireDoubleClickForConnections;
|
||||
}
|
||||
@@ -509,11 +516,9 @@ public class AppPrefs {
|
||||
}
|
||||
|
||||
public void initDefaultValues() {
|
||||
externalEditor.setValue(ExternalEditorType.detectDefault(externalEditor.get()));
|
||||
externalEditor.setValue(ExternalEditorType.determineDefault(externalEditor.get()));
|
||||
terminalType.set(ExternalTerminalType.determineDefault(terminalType.get()));
|
||||
if (rdpClientType.get() == null) {
|
||||
rdpClientType.setValue(ExternalRdpClientType.determineDefault());
|
||||
}
|
||||
rdpClientType.setValue(ExternalRdpClientType.determineDefault(rdpClientType.get()));
|
||||
if (AppProperties.get().isInitialLaunch()) {
|
||||
performanceMode.setValue(XPipeDistributionType.get() == XPipeDistributionType.WEBTOP);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue {
|
||||
public boolean isAvailable() {
|
||||
try (ShellControl pc = LocalShell.getShell().start()) {
|
||||
var out = pc.command(String.format(
|
||||
"mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications",
|
||||
"mdfind -name '%s.app' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications",
|
||||
applicationName))
|
||||
.readStdoutIfPossible();
|
||||
return out.isPresent() && !out.get().isBlank();
|
||||
|
||||
@@ -160,7 +160,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||
})
|
||||
.get();
|
||||
|
||||
static ExternalEditorType detectDefault(ExternalEditorType existing) {
|
||||
static ExternalEditorType determineDefault(ExternalEditorType existing) {
|
||||
// Verify that our selection is still valid
|
||||
if (existing != null && existing.isAvailable()) {
|
||||
return existing;
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package io.xpipe.app.prefs;
|
||||
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
|
||||
import lombok.Value;
|
||||
@@ -145,10 +148,30 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
ExternalRdpClientType WINDOWS_APP_MACOS =
|
||||
new MacOsType("app.windowsApp", "Windows App.app") {
|
||||
|
||||
@Override
|
||||
public void launch(LaunchConfiguration configuration) throws Exception {
|
||||
var file = writeConfig(configuration.getConfig());
|
||||
LocalShell.getShell()
|
||||
.executeSimpleCommand(CommandBuilder.of()
|
||||
.add("open", "-a")
|
||||
.addQuoted("Windows App.app")
|
||||
.addFile(file.toString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
ExternalRdpClientType CUSTOM = new CustomType();
|
||||
List<ExternalRdpClientType> WINDOWS_CLIENTS = List.of(MSTSC, DEVOLUTIONS);
|
||||
List<ExternalRdpClientType> LINUX_CLIENTS = List.of(REMMINA);
|
||||
List<ExternalRdpClientType> MACOS_CLIENTS = List.of(MICROSOFT_REMOTE_DESKTOP_MACOS_APP);
|
||||
List<ExternalRdpClientType> MACOS_CLIENTS = List.of(MICROSOFT_REMOTE_DESKTOP_MACOS_APP, WINDOWS_APP_MACOS);
|
||||
|
||||
@SuppressWarnings("TrivialFunctionalExpressionUsage")
|
||||
List<ExternalRdpClientType> ALL = ((Supplier<List<ExternalRdpClientType>>) () -> {
|
||||
@@ -167,12 +190,25 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
|
||||
})
|
||||
.get();
|
||||
|
||||
static ExternalRdpClientType determineDefault() {
|
||||
return ALL.stream()
|
||||
static ExternalRdpClientType determineDefault(ExternalRdpClientType existing) {
|
||||
// Verify that our selection is still valid
|
||||
if (existing != null && existing.isAvailable()) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
var r = ALL.stream()
|
||||
.filter(t -> !t.equals(CUSTOM))
|
||||
.filter(t -> t.isAvailable())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
// Check if detection failed for some reason
|
||||
if (r == null) {
|
||||
var def = OsType.getLocal() == OsType.WINDOWS ? MSTSC : OsType.getLocal() == OsType.MACOS ? WINDOWS_APP_MACOS : REMMINA;
|
||||
r = def;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void launch(LaunchConfiguration configuration) throws Exception;
|
||||
|
||||
@@ -18,12 +18,15 @@ public class FileBrowserCategory extends AppPrefsCategory {
|
||||
.sub(new OptionsBuilder()
|
||||
.pref(prefs.enableTerminalDocking)
|
||||
.addToggle(prefs.enableTerminalDocking)
|
||||
.pref(prefs.editFilesWithDoubleClick)
|
||||
.addToggle(prefs.editFilesWithDoubleClick)
|
||||
.pref(prefs.confirmAllDeletions)
|
||||
.addToggle(prefs.confirmAllDeletions)
|
||||
.pref(prefs.downloadsDirectory)
|
||||
.addString(prefs.downloadsDirectory)
|
||||
.pref(prefs.pinLocalMachineOnStartup)
|
||||
.addToggle(prefs.pinLocalMachineOnStartup))
|
||||
.addToggle(prefs.pinLocalMachineOnStartup)
|
||||
)
|
||||
.buildComp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||
|
||||
@Override
|
||||
public boolean isRecommended() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -34,7 +34,8 @@ public class DataStoreCategoryChoiceComp extends SimpleComp {
|
||||
} else if (root == null) {
|
||||
value.setValue(newValue);
|
||||
} else if (!newValue.getRoot().equals(root)) {
|
||||
value.setValue(root);
|
||||
// Ignore change, that is more user-friendly
|
||||
// value.setValue(root);
|
||||
} else {
|
||||
value.setValue(newValue);
|
||||
}
|
||||
|
||||
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
## VMs
|
||||
|
||||
- There is now support for KVM/QEMU virtual machines that can be accessed via the libvirt CLI tools `virsh`. This includes support for other driver URLs as well aside from KVM and QEMU. This integration is available starting from the homelab plan and can be used for free for two weeks after this release using the new release preview
|
||||
- You can now override a VM IP if you're using an advanced networking setup where the default IP detection is not suitable
|
||||
- Fix remote VM SSH connections not being able to use the keys and identities from the local system
|
||||
- There is now a new restart button for containers and VMs
|
||||
|
||||
## File browser
|
||||
|
||||
- There is now a new option in the context menu of a tab to pin it, allowing for having a split view with two different file systems
|
||||
- There is now the option to dock terminals in the file browser (this is only available on Windows for now). You can disable this in Settings -> File browser -> Terminal docking if you don't like it
|
||||
- The previous system history tab is now always shown
|
||||
- You can now change the default download location for the move to downloads button
|
||||
|
||||
## Shell sessions
|
||||
|
||||
Many improvements have been implemented for reusability of shell sessions running in the background. Whenever you access a system or a parent system, XPipe will connect to it just as before but keep this session open in the background for some time, under the assumption that you will typically perform multiple actions shortly afterward. This will improve the speed of many actions and also results in less authentication prompts when you are using something like 2FA.
|
||||
|
||||
## Terminals
|
||||
|
||||
- Closing a terminal tab/window while the session is loading will now cancel the loading process in XPipe as well
|
||||
- A newly opened terminal will now regain focus after any password prompt was entered in xpipe
|
||||
|
||||
## Security updates
|
||||
|
||||
There's now a new mechanism in place for checking for security updates separately from the normal update check. This is important going forward, to be able to act quickly when any security patch is published, so that all users have the possibility to get notified even if they don't follow announcements on the GitHub repo or on Discord. You can also disable this functionality in the settings if you want.
|
||||
|
||||
## Other
|
||||
|
||||
- The application style has been reworked
|
||||
- The settings menu now shows a restart button when a setting has been changed that requires a restart to apply
|
||||
- There is now an intro to scripts to provide some more information before using scripts
|
||||
- Add ability to enable agent forwarding when using the SSH-Agent for identities
|
||||
- The .rpm releases are now signed
|
||||
|
||||
## Fixes
|
||||
|
||||
- Fix Proxmox detection not working when not logging in as root
|
||||
- Fix tunnels not closing properly when having to be closed forcefully
|
||||
- Fix vmware integration failing when files other than .vmx were in the VM directories
|
||||
- Fix Tabby not launching properly on Windows
|
||||
- Fix SSH and docker issues with home assistant systems
|
||||
- Fix git readme not showing connections in nested children categories
|
||||
- Fix Windows Terminal Preview and Canary not being recognized
|
||||
- Fix style issues with the mocha theme
|
||||
- Fix color contrast for some themes
|
||||
- Fix system dark mode changes not being applied if they were changed while XPipe was not running
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
- There's now a new setting that you can enable to open files with your text editor when double-clicking them
|
||||
- You can now input custom values for the chmod, chown, and chgrp actions in the context menu when clicking on `...`
|
||||
- Fix RDP launcher on macOS getting confused by the rename from Microsoft Remote Desktop to Windows App
|
||||
- Fix terminal autodetection mistakenly choosing Warp on macOS if another app that contained the word warp was installed
|
||||
|
||||
@@ -4,6 +4,8 @@ import io.xpipe.app.browser.action.BrowserBranchAction;
|
||||
import io.xpipe.app.browser.action.BrowserLeafAction;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
@@ -12,9 +14,11 @@ import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
import javafx.scene.control.TextField;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ChgrpAction implements BrowserBranchAction {
|
||||
|
||||
@@ -41,13 +45,13 @@ public class ChgrpAction implements BrowserBranchAction {
|
||||
|
||||
@Override
|
||||
public List<BrowserLeafAction> getBranchingActions(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getCache().getGroups().entrySet().stream()
|
||||
return Stream.concat(model.getCache().getGroups().entrySet().stream()
|
||||
.filter(e -> !e.getValue().equals("nohome")
|
||||
&& !e.getValue().equals("nogroup")
|
||||
&& !e.getValue().equals("nobody")
|
||||
&& (e.getKey().equals(0) || e.getKey() >= 900))
|
||||
.map(e -> e.getValue())
|
||||
.map(s -> (BrowserLeafAction) new Chgrp(s))
|
||||
.map(s -> (BrowserLeafAction) new Chgrp(s)), Stream.of(new Custom()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -77,4 +81,38 @@ public class ChgrpAction implements BrowserBranchAction {
|
||||
.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class Custom implements BrowserLeafAction {
|
||||
@Override
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var group = new SimpleStringProperty();
|
||||
model.getOverlay()
|
||||
.setValue(new ModalOverlayComp.OverlayContent(
|
||||
"groupName",
|
||||
Comp.of(() -> {
|
||||
var creationName = new TextField();
|
||||
creationName.textProperty().bindBidirectional(group);
|
||||
return creationName;
|
||||
})
|
||||
.prefWidth(350),
|
||||
null,
|
||||
"finish",
|
||||
() -> {
|
||||
model.runCommandAsync(CommandBuilder.of()
|
||||
.add("chgrp", group.getValue())
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath())
|
||||
.toList()), false);
|
||||
},
|
||||
true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(
|
||||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return new SimpleStringProperty("...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import io.xpipe.app.browser.action.BrowserBranchAction;
|
||||
import io.xpipe.app.browser.action.BrowserLeafAction;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.browser.icon.BrowserIcons;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
@@ -12,6 +15,7 @@ import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
import javafx.scene.control.TextField;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
@@ -40,6 +44,7 @@ public class ChmodAction implements BrowserBranchAction {
|
||||
|
||||
@Override
|
||||
public List<BrowserLeafAction> getBranchingActions(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var custom = new Custom();
|
||||
return List.of(
|
||||
new Chmod("400"),
|
||||
new Chmod("600"),
|
||||
@@ -48,7 +53,8 @@ public class ChmodAction implements BrowserBranchAction {
|
||||
new Chmod("755"),
|
||||
new Chmod("777"),
|
||||
new Chmod("u+x"),
|
||||
new Chmod("a+x"));
|
||||
new Chmod("a+x"),
|
||||
custom);
|
||||
}
|
||||
|
||||
private static class Chmod implements BrowserLeafAction {
|
||||
@@ -77,4 +83,37 @@ public class ChmodAction implements BrowserBranchAction {
|
||||
.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
private static class Custom implements BrowserLeafAction {
|
||||
@Override
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var permissions = new SimpleStringProperty();
|
||||
model.getOverlay()
|
||||
.setValue(new ModalOverlayComp.OverlayContent(
|
||||
"chmodPermissions",
|
||||
Comp.of(() -> {
|
||||
var creationName = new TextField();
|
||||
creationName.textProperty().bindBidirectional(permissions);
|
||||
return creationName;
|
||||
})
|
||||
.prefWidth(350),
|
||||
null,
|
||||
"finish",
|
||||
() -> {
|
||||
model.runCommandAsync(CommandBuilder.of()
|
||||
.add("chmod", permissions.getValue())
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath())
|
||||
.toList()), false);
|
||||
},
|
||||
true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(
|
||||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return new SimpleStringProperty("...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import io.xpipe.app.browser.action.BrowserBranchAction;
|
||||
import io.xpipe.app.browser.action.BrowserLeafAction;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
@@ -12,9 +14,11 @@ import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
import javafx.scene.control.TextField;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ChownAction implements BrowserBranchAction {
|
||||
|
||||
@@ -41,12 +45,12 @@ public class ChownAction implements BrowserBranchAction {
|
||||
|
||||
@Override
|
||||
public List<BrowserLeafAction> getBranchingActions(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getCache().getUsers().entrySet().stream()
|
||||
return Stream.concat(model.getCache().getUsers().entrySet().stream()
|
||||
.filter(e -> !e.getValue().equals("nohome")
|
||||
&& !e.getValue().equals("nobody")
|
||||
&& (e.getKey().equals(0) || e.getKey() >= 900))
|
||||
.map(e -> e.getValue())
|
||||
.map(s -> (BrowserLeafAction) new Chown(s))
|
||||
.map(s -> (BrowserLeafAction) new Chown(s)), Stream.of(new Custom()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -76,4 +80,38 @@ public class ChownAction implements BrowserBranchAction {
|
||||
.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class Custom implements BrowserLeafAction {
|
||||
@Override
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var user = new SimpleStringProperty();
|
||||
model.getOverlay()
|
||||
.setValue(new ModalOverlayComp.OverlayContent(
|
||||
"userName",
|
||||
Comp.of(() -> {
|
||||
var creationName = new TextField();
|
||||
creationName.textProperty().bindBidirectional(user);
|
||||
return creationName;
|
||||
})
|
||||
.prefWidth(350),
|
||||
null,
|
||||
"finish",
|
||||
() -> {
|
||||
model.runCommandAsync(CommandBuilder.of()
|
||||
.add("chown", user.getValue())
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath())
|
||||
.toList()), false);
|
||||
},
|
||||
true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(
|
||||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return new SimpleStringProperty("...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,3 +71,4 @@ zed=Zed
|
||||
windowsCredentialManager=Windows credential manager
|
||||
webtop=Webtop
|
||||
keeper=Keeper
|
||||
windowsApp=Windows App.app
|
||||
|
||||
@@ -557,3 +557,7 @@ downloadsDirectoryDescription=Den brugerdefinerede mappe, som downloadede filer
|
||||
pinLocalMachineOnStartup=Fastgør fane for lokal maskine ved opstart
|
||||
pinLocalMachineOnStartupDescription=Åbn automatisk en fane på den lokale maskine og fastgør den. Det er nyttigt, hvis du ofte bruger en delt filbrowser med den lokale maskine og fjernfilsystemet åbent.
|
||||
terminalErrorDescription=Denne fejl er terminal, og XPipe kan ikke fortsætte uden at løse den.
|
||||
groupName=Gruppens navn
|
||||
chmodPermissions=Nye tilladelser
|
||||
editFilesWithDoubleClick=Rediger filer med dobbeltklik
|
||||
editFilesWithDoubleClickDescription=Når det er aktiveret, vil dobbeltklik på filer åbne dem direkte i din teksteditor i stedet for at vise kontekstmenuen.
|
||||
|
||||
@@ -559,3 +559,7 @@ downloadsDirectoryDescription=Das benutzerdefinierte Verzeichnis, in das herunte
|
||||
pinLocalMachineOnStartup=Tab "Lokaler Rechner" beim Starten anheften
|
||||
pinLocalMachineOnStartupDescription=Öffne automatisch eine Tab für den lokalen Rechner und pinne sie an. Dies ist nützlich, wenn du häufig einen geteilten Dateibrowser verwendest, bei dem der lokale Rechner und das entfernte Dateisystem geöffnet sind.
|
||||
terminalErrorDescription=Dieser Fehler ist terminal und XPipe kann nicht weiterarbeiten, ohne ihn zu beheben.
|
||||
groupName=Gruppenname
|
||||
chmodPermissions=Neue Berechtigungen
|
||||
editFilesWithDoubleClick=Dateien mit Doppelklick bearbeiten
|
||||
editFilesWithDoubleClickDescription=Wenn diese Funktion aktiviert ist, werden Dateien durch einen Doppelklick direkt in deinem Texteditor geöffnet, anstatt das Kontextmenü anzuzeigen.
|
||||
|
||||
@@ -557,3 +557,8 @@ downloadsDirectoryDescription=The custom directory to put downloaded files into
|
||||
pinLocalMachineOnStartup=Pin local machine tab on startup
|
||||
pinLocalMachineOnStartupDescription=Automatically open a local machine tab and pin it. This is useful if you are frequently using a split file browser with the local machine and remote file system open.
|
||||
terminalErrorDescription=This error is terminal and XPipe can't continue without fixing it.
|
||||
groupName=Group name
|
||||
chmodPermissions=New permissions
|
||||
editFilesWithDoubleClick=Edit files with double click
|
||||
editFilesWithDoubleClickDescription=When enabled, double-clicking files will straight up open them in your text editor instead of showing the context menu.
|
||||
userName=Username
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=El directorio personalizado en el que colocar los
|
||||
pinLocalMachineOnStartup=Fijar la pestaña de máquina local al iniciar
|
||||
pinLocalMachineOnStartupDescription=Abre automáticamente una pestaña de la máquina local y fíjala. Esto es útil si utilizas con frecuencia un explorador de archivos dividido con la máquina local y el sistema de archivos remoto abiertos.
|
||||
terminalErrorDescription=Este error es terminal y XPipe no puede continuar sin solucionarlo.
|
||||
groupName=Nombre del grupo
|
||||
chmodPermissions=Nuevos permisos
|
||||
editFilesWithDoubleClick=Editar archivos con doble clic
|
||||
editFilesWithDoubleClickDescription=Cuando está activado, al hacer doble clic en los archivos se abrirán directamente en tu editor de texto en lugar de mostrar el menú contextual.
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=Le répertoire personnalisé dans lequel placer le
|
||||
pinLocalMachineOnStartup=Onglet de la machine locale au démarrage
|
||||
pinLocalMachineOnStartupDescription=Ouvrir automatiquement un onglet de machine locale et l'épingler. C'est utile si tu utilises fréquemment un navigateur de fichiers fractionné avec la machine locale et le système de fichiers distant ouverts.
|
||||
terminalErrorDescription=Cette erreur est terminale et XPipe ne peut pas continuer sans la réparer.
|
||||
groupName=Nom du groupe
|
||||
chmodPermissions=Nouvelles autorisations
|
||||
editFilesWithDoubleClick=Éditer des fichiers avec un double clic
|
||||
editFilesWithDoubleClickDescription=Lorsque cette option est activée, un double-clic sur les fichiers les ouvrira directement dans ton éditeur de texte au lieu d'afficher le menu contextuel.
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=La directory personalizzata in cui inserire i file
|
||||
pinLocalMachineOnStartup=Blocca la scheda della macchina locale all'avvio
|
||||
pinLocalMachineOnStartupDescription=Apre automaticamente una scheda del computer locale e la blocca. Questa funzione è utile se utilizzi spesso un browser di file suddiviso con il computer locale e il file system remoto aperti.
|
||||
terminalErrorDescription=Questo errore è un terminale e XPipe non può continuare senza risolvere il problema.
|
||||
groupName=Nome del gruppo
|
||||
chmodPermissions=Nuovi permessi
|
||||
editFilesWithDoubleClick=Modifica i file con un doppio clic
|
||||
editFilesWithDoubleClickDescription=Se abilitato, facendo doppio clic sui file, questi verranno aperti direttamente nell'editor di testo invece di mostrare il menu contestuale.
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=ダウンロードに移動ボタンをクリッ
|
||||
pinLocalMachineOnStartup=起動時にローカルマシンのタブをピン留めする
|
||||
pinLocalMachineOnStartupDescription=ローカルマシンのタブを自動的に開き、ピン留めする。これは、ローカルマシンとリモートファイルシステムを開いた状態で、分割ファイルブラウザを頻繁に使用する場合に便利である。
|
||||
terminalErrorDescription=このエラーは末期的なもので、XPipeはこのエラーを修正しなければ続行できない。
|
||||
groupName=グループ名
|
||||
chmodPermissions=新しいパーミッション
|
||||
editFilesWithDoubleClick=ダブルクリックでファイルを編集する
|
||||
editFilesWithDoubleClickDescription=有効にすると、ファイルをダブルクリックしてもコンテキストメニューが表示されず、そのままテキストエディタで開くことができる。
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=De aangepaste map om gedownloade bestanden in te p
|
||||
pinLocalMachineOnStartup=Tabblad lokale machine vastpinnen bij het opstarten
|
||||
pinLocalMachineOnStartupDescription=Automatisch een lokale machine tab openen en vastpinnen. Dit is handig als je vaak een gesplitste bestandsbrowser gebruikt met de lokale machine en het externe bestandssysteem open.
|
||||
terminalErrorDescription=Deze fout is terminaal en XPipe kan niet verder zonder deze fout op te lossen.
|
||||
groupName=Groepsnaam
|
||||
chmodPermissions=Nieuwe machtigingen
|
||||
editFilesWithDoubleClick=Bestanden bewerken met dubbelklikken
|
||||
editFilesWithDoubleClickDescription=Als deze optie is ingeschakeld, zal dubbelklikken op bestanden deze direct openen in je tekstverwerker in plaats van het contextmenu te tonen.
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=O diretório personalizado para colocar os arquivo
|
||||
pinLocalMachineOnStartup=Fixa o separador da máquina local no arranque
|
||||
pinLocalMachineOnStartupDescription=Abre automaticamente um separador da máquina local e fixa-o. Isto é útil se estiveres a utilizar frequentemente um navegador de ficheiros dividido com a máquina local e o sistema de ficheiros remoto abertos.
|
||||
terminalErrorDescription=Este erro é terminal e o XPipe não pode continuar sem o corrigir.
|
||||
groupName=Nome do grupo
|
||||
chmodPermissions=Novas permissões
|
||||
editFilesWithDoubleClick=Edita ficheiros com um duplo clique
|
||||
editFilesWithDoubleClickDescription=Quando ativado, fazer duplo clique em ficheiros abre-os diretamente no teu editor de texto em vez de mostrar o menu de contexto.
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=Пользовательская директор
|
||||
pinLocalMachineOnStartup=Закрепить вкладку локальной машины при запуске
|
||||
pinLocalMachineOnStartupDescription=Автоматически открывай вкладку локальной машины и закрепляй ее. Это полезно, если ты часто используешь разделенный файловый браузер с открытыми локальной машиной и удаленной файловой системой.
|
||||
terminalErrorDescription=Эта ошибка является терминальной, и XPipe не сможет продолжить работу без ее устранения.
|
||||
groupName=Название группы
|
||||
chmodPermissions=Новые разрешения
|
||||
editFilesWithDoubleClick=Редактирование файлов с помощью двойного клика
|
||||
editFilesWithDoubleClickDescription=Когда эта функция включена, двойной щелчок по файлам будет сразу открывать их в твоем текстовом редакторе, а не показывать контекстное меню.
|
||||
|
||||
@@ -539,3 +539,7 @@ downloadsDirectoryDescription=İndirilen dosyaları indirilenlere taşı düğme
|
||||
pinLocalMachineOnStartup=Başlangıçta yerel makine sekmesini sabitleme
|
||||
pinLocalMachineOnStartupDescription=Otomatik olarak bir yerel makine sekmesi açın ve sabitleyin. Bu, yerel makine ve uzak dosya sistemi açıkken sık sık bölünmüş bir dosya tarayıcısı kullanıyorsanız kullanışlıdır.
|
||||
terminalErrorDescription=Bu hata ölümcüldür ve XPipe bunu düzeltmeden devam edemez.
|
||||
groupName=Grup adı
|
||||
chmodPermissions=Yeni izinler
|
||||
editFilesWithDoubleClick=Dosyaları çift tıklama ile düzenleme
|
||||
editFilesWithDoubleClickDescription=Etkinleştirildiğinde, dosyalara çift tıklamak içerik menüsünü göstermek yerine onları doğrudan metin düzenleyicinizde açacaktır.
|
||||
|
||||
@@ -538,3 +538,7 @@ downloadsDirectoryDescription=单击 "移动到下载 "按钮时将下载文件
|
||||
pinLocalMachineOnStartup=启动时 Pin 本地计算机选项卡
|
||||
pinLocalMachineOnStartupDescription=自动打开本地计算机标签并将其固定。如果你经常在打开本地机器和远程文件系统的情况下使用分割文件浏览器,这将非常有用。
|
||||
terminalErrorDescription=此错误为终端错误,如果不修复,XPipe 将无法继续运行。
|
||||
groupName=组名
|
||||
chmodPermissions=新权限
|
||||
editFilesWithDoubleClick=双击编辑文件
|
||||
editFilesWithDoubleClickDescription=启用后,双击文件将直接在文本编辑器中打开,而不是显示上下文菜单。
|
||||
|
||||
@@ -232,7 +232,7 @@ dockerContainerDescription=Navnet på docker-containeren
|
||||
lxdHostDescription=Den vært, som LXD-containeren er placeret på. Skal have lxc installeret.
|
||||
lxdContainerDescription=Navnet på LXD-containeren
|
||||
localMachine=Lokal maskine
|
||||
rootScan=Root shell-miljø
|
||||
rootScan=Sudo shell-miljø
|
||||
loginEnvironmentScan=Brugerdefineret login-miljø
|
||||
k8sScan=Kubernetes-klynge
|
||||
options=Muligheder
|
||||
|
||||
@@ -215,7 +215,7 @@ dockerContainerDescription=Der Name des Docker-Containers
|
||||
lxdHostDescription=Der Host, auf dem sich der LXD-Container befindet. Muss lxc installiert haben.
|
||||
lxdContainerDescription=Der Name des LXD-Containers
|
||||
localMachine=Lokale Maschine
|
||||
rootScan=Root-Shell-Umgebung
|
||||
rootScan=Sudo-Shell-Umgebung
|
||||
loginEnvironmentScan=Benutzerdefinierte Anmeldeumgebung
|
||||
k8sScan=Kubernetes-Cluster
|
||||
options=Optionen
|
||||
|
||||
@@ -213,7 +213,7 @@ dockerContainerDescription=The name of the docker container
|
||||
lxdHostDescription=The host on which the LXD container is located on. Must have lxc installed.
|
||||
lxdContainerDescription=The name of the LXD container
|
||||
localMachine=Local Machine
|
||||
rootScan=Root shell environment
|
||||
rootScan=Sudo shell environment
|
||||
loginEnvironmentScan=Custom login environment
|
||||
k8sScan=Kubernetes cluster
|
||||
options=Options
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=El nombre del contenedor docker
|
||||
lxdHostDescription=El host en el que se encuentra el contenedor LXD. Debe tener lxc instalado.
|
||||
lxdContainerDescription=El nombre del contenedor LXD
|
||||
localMachine=Máquina local
|
||||
rootScan=Entorno shell raíz
|
||||
rootScan=Entorno shell Sudo
|
||||
loginEnvironmentScan=Entorno de inicio de sesión personalizado
|
||||
k8sScan=Clúster Kubernetes
|
||||
options=Opciones
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=Le nom du conteneur docker
|
||||
lxdHostDescription=L'hôte sur lequel se trouve le conteneur LXD. Lxc doit être installé.
|
||||
lxdContainerDescription=Le nom du conteneur LXD
|
||||
localMachine=Machine locale
|
||||
rootScan=Environnement de l'interpréteur de commandes racine
|
||||
rootScan=Environnement shell Sudo
|
||||
loginEnvironmentScan=Environnement de connexion personnalisé
|
||||
k8sScan=Cluster Kubernetes
|
||||
options=Options
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=Il nome del contenitore docker
|
||||
lxdHostDescription=L'host su cui si trova il contenitore LXD. Deve essere installato lxc.
|
||||
lxdContainerDescription=Il nome del contenitore LXD
|
||||
localMachine=Macchina locale
|
||||
rootScan=Ambiente shell root
|
||||
rootScan=Ambiente di shell Sudo
|
||||
loginEnvironmentScan=Ambiente di login personalizzato
|
||||
k8sScan=Cluster Kubernetes
|
||||
options=Opzioni
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=ドッカーコンテナの名前
|
||||
lxdHostDescription=LXD コンテナが置かれているホスト。lxc がインストールされている必要がある。
|
||||
lxdContainerDescription=LXDコンテナの名前
|
||||
localMachine=ローカルマシン
|
||||
rootScan=ルートシェル環境
|
||||
rootScan=須藤シェル環境
|
||||
loginEnvironmentScan=カスタムログイン環境
|
||||
k8sScan=Kubernetesクラスタ
|
||||
options=オプション
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=De naam van de docker container
|
||||
lxdHostDescription=De host waarop de LXD container staat. Moet lxc geïnstalleerd hebben.
|
||||
lxdContainerDescription=De naam van de LXD-container
|
||||
localMachine=Lokale machine
|
||||
rootScan=Root shell-omgeving
|
||||
rootScan=Sudo shell-omgeving
|
||||
loginEnvironmentScan=Aangepaste inlogomgeving
|
||||
k8sScan=Kubernetes cluster
|
||||
options=Opties
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=O nome do contentor docker
|
||||
lxdHostDescription=O host no qual o contêiner LXD está localizado. Deve ter o lxc instalado.
|
||||
lxdContainerDescription=O nome do contentor LXD
|
||||
localMachine=Máquina local
|
||||
rootScan=Ambiente da shell de raiz
|
||||
rootScan=Ambiente de shell Sudo
|
||||
loginEnvironmentScan=Ambiente de início de sessão personalizado
|
||||
k8sScan=Cluster Kubernetes
|
||||
options=Opções
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=Имя докер-контейнера
|
||||
lxdHostDescription=Хост, на котором находится контейнер LXD. Должен быть установлен lxc.
|
||||
lxdContainerDescription=Имя контейнера LXD
|
||||
localMachine=Локальная машина
|
||||
rootScan=Корневая среда оболочки
|
||||
rootScan=Среда оболочки Sudo
|
||||
loginEnvironmentScan=Пользовательская среда входа в систему
|
||||
k8sScan=Кластер Kubernetes
|
||||
options=Опции
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=Docker konteynerinin adı
|
||||
lxdHostDescription=LXD konteynerinin üzerinde bulunduğu ana bilgisayar. Lxc yüklü olmalıdır.
|
||||
lxdContainerDescription=LXD konteynerinin adı
|
||||
localMachine=Yerel Makine
|
||||
rootScan=Kök kabuk ortamı
|
||||
rootScan=Sudo kabuk ortamı
|
||||
loginEnvironmentScan=Özel oturum açma ortamı
|
||||
k8sScan=Kubernetes kümesi
|
||||
options=Seçenekler
|
||||
|
||||
@@ -212,7 +212,7 @@ dockerContainerDescription=docker 容器的名称
|
||||
lxdHostDescription=LXD 容器所在的主机。必须已安装 lxc。
|
||||
lxdContainerDescription=LXD 容器的名称
|
||||
localMachine=本地机器
|
||||
rootScan=根 shell 环境
|
||||
rootScan=Sudo shell 环境
|
||||
loginEnvironmentScan=自定义登录环境
|
||||
k8sScan=Kubernetes 集群
|
||||
options=选项
|
||||
|
||||
Reference in New Issue
Block a user