mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-07-08 15:56:09 +12:00
Polish various features
This commit is contained in:
parent
c0abdf968a
commit
6263b791cf
|
@ -25,19 +25,15 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
|||
}
|
||||
|
||||
public static ObservableList<StoreEntrySection> createTopLevels() {
|
||||
var topLevel = BindingsHelper.mappedContentBinding(
|
||||
StoreViewState.get()
|
||||
.getAllEntries()
|
||||
.filtered(storeEntryWrapper ->
|
||||
!storeEntryWrapper.getEntry().getState().isUsable()
|
||||
|| storeEntryWrapper
|
||||
.getEntry()
|
||||
.getProvider()
|
||||
.getParent(storeEntryWrapper
|
||||
.getEntry()
|
||||
.getStore())
|
||||
== null),
|
||||
storeEntryWrapper -> create(storeEntryWrapper));
|
||||
var filtered = BindingsHelper.filteredContentBinding(
|
||||
StoreViewState.get().getAllEntries(),
|
||||
storeEntryWrapper -> !storeEntryWrapper.getEntry().getState().isUsable()
|
||||
|| storeEntryWrapper
|
||||
.getEntry()
|
||||
.getProvider()
|
||||
.getParent(storeEntryWrapper.getEntry().getStore())
|
||||
== null);
|
||||
var topLevel = BindingsHelper.mappedContentBinding(filtered, storeEntryWrapper -> create(storeEntryWrapper));
|
||||
var ordered = BindingsHelper.orderedContentBinding(
|
||||
topLevel,
|
||||
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
||||
|
@ -51,16 +47,15 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
|||
return new StoreEntrySection(e, FXCollections.observableArrayList());
|
||||
}
|
||||
|
||||
var children = BindingsHelper.mappedContentBinding(
|
||||
StoreViewState.get()
|
||||
.getAllEntries()
|
||||
.filtered(other -> other.getEntry().getState().isUsable()
|
||||
&& e.getEntry()
|
||||
.getStore()
|
||||
.equals(other.getEntry()
|
||||
.getProvider()
|
||||
.getParent(other.getEntry().getStore()))),
|
||||
entry1 -> create(entry1));
|
||||
var filtered = BindingsHelper.filteredContentBinding(
|
||||
StoreViewState.get().getAllEntries(),
|
||||
other -> other.getEntry().getState().isUsable()
|
||||
&& e.getEntry()
|
||||
.getStore()
|
||||
.equals(other.getEntry()
|
||||
.getProvider()
|
||||
.getParent(other.getEntry().getStore())));
|
||||
var children = BindingsHelper.mappedContentBinding(filtered, entry1 -> create(entry1));
|
||||
var ordered = BindingsHelper.orderedContentBinding(
|
||||
children,
|
||||
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
||||
|
@ -94,7 +89,9 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
|||
storeEntrySection.entry.lastAccessProperty().getValue()));
|
||||
var shown = BindingsHelper.filteredContentBinding(
|
||||
all,
|
||||
StoreViewState.get().getFilterString().map(s -> (storeEntrySection -> storeEntrySection.shouldShow(s))));
|
||||
StoreViewState.get()
|
||||
.getFilterString()
|
||||
.map(s -> (storeEntrySection -> storeEntrySection.shouldShow(s))));
|
||||
var content = new ListBoxViewComp<>(shown, all, (StoreEntrySection e) -> {
|
||||
return e.comp(false).apply(GrowAugment.create(true, false));
|
||||
})
|
||||
|
|
|
@ -80,12 +80,12 @@ public class App extends Application {
|
|||
appWindow.show();
|
||||
|
||||
// For demo purposes
|
||||
if (true) {
|
||||
stage.setX(310);
|
||||
stage.setY(178);
|
||||
stage.setWidth(1300);
|
||||
stage.setHeight(730);
|
||||
}
|
||||
// if (true) {
|
||||
// stage.setX(310);
|
||||
// stage.setY(178);
|
||||
// stage.setWidth(1300);
|
||||
// stage.setHeight(730);
|
||||
// }
|
||||
}
|
||||
|
||||
public void focus() {
|
||||
|
|
|
@ -90,6 +90,7 @@ public class AppGreetings {
|
|||
label.setGraphic(cb);
|
||||
AppFont.medium(label);
|
||||
label.setPadding(new Insets(40, 0, 10, 0));
|
||||
label.setOnMouseClicked(event -> accepted.set(!accepted.get()));
|
||||
return label;
|
||||
})
|
||||
.createRegion();
|
||||
|
|
|
@ -54,28 +54,23 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue {
|
|||
}
|
||||
}
|
||||
|
||||
public static class LinuxPathApplication extends ExternalApplicationType {
|
||||
public static abstract class PathApplication extends ExternalApplicationType {
|
||||
|
||||
protected final String command;
|
||||
protected final String executable;
|
||||
|
||||
public LinuxPathApplication(String id, String command) {
|
||||
public PathApplication(String id, String executable) {
|
||||
super(id);
|
||||
this.command = command;
|
||||
this.executable = executable;
|
||||
}
|
||||
|
||||
public boolean isAvailable() {
|
||||
try (ShellProcessControl pc = ShellStore.local().create().start()) {
|
||||
return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(command));
|
||||
return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(executable));
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).omit().handle();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return OsType.getLocal().equals(OsType.LINUX);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class WindowsFullPathType extends ExternalApplicationType {
|
||||
|
|
|
@ -109,7 +109,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
public void launch(Path file) throws Exception;
|
||||
|
||||
|
||||
public static class LinuxPathType extends ExternalApplicationType.LinuxPathApplication implements ExternalEditorType {
|
||||
public static class LinuxPathType extends ExternalApplicationType.PathApplication implements ExternalEditorType {
|
||||
|
||||
public LinuxPathType(String id, String command) {
|
||||
super(id, command);
|
||||
|
@ -117,9 +117,14 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
|
||||
@Override
|
||||
public void launch(Path file) throws IOException {
|
||||
var list = ShellTypes.getPlatformDefault().executeCommandListWithShell(command + " \"" + file + "\"");
|
||||
var list = ShellTypes.getPlatformDefault().executeCommandListWithShell(executable + " \"" + file + "\"");
|
||||
new ProcessBuilder(list).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return OsType.getLocal().equals(OsType.LINUX);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType implements ExternalEditorType {
|
||||
|
@ -174,7 +179,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
var env = System.getenv("VISUAL");
|
||||
if (env != null) {
|
||||
var found = LINUX_EDITORS.stream()
|
||||
.filter(externalEditorType -> externalEditorType.command.equalsIgnoreCase(env))
|
||||
.filter(externalEditorType -> externalEditorType.executable.equalsIgnoreCase(env))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (found == null) {
|
||||
|
|
|
@ -69,6 +69,14 @@ recentlyUsed=Recently used
|
|||
programmingLanguages=Programming languages
|
||||
applications=Applications
|
||||
addMore=Add more
|
||||
vscode=Visual Studio Code
|
||||
kate=Kate
|
||||
gedit=GEdit
|
||||
leafpad=Leafpad
|
||||
mousepad=Mousepad
|
||||
pluma=Pluma
|
||||
textEdit=Text Edit
|
||||
sublime=Sublime Text
|
||||
newTable=new_table
|
||||
unknown=Unknown
|
||||
editRaw=Edit Raw
|
||||
|
|
|
@ -46,15 +46,10 @@ specific information we send, please visit https://xpipe.io/privacy_policy. You
|
|||
1. **Automatic Software Updates.** The Software communicates with its server (and sends information described at the URL
|
||||
above) to determine whether there are any patches, bug fixes, updates, upgrades or other modifications to improve the
|
||||
Software. You agree that the Software may automatically install any such improvements to the Software on your
|
||||
computer without providing any further notice or receiving any additional consent. This feature may not be disabled.
|
||||
If you do not want to receive automatic updates, you must uninstall the Software.
|
||||
computer without providing any further notice or receiving any additional consent. This feature may be disabled.
|
||||
2. **Error Reports.** In order to help us improve the Software, when the Software encounters certain errors, it will
|
||||
automatically send some information to its server about the error (as described at the URL above). This feature may
|
||||
not be disabled. If you do not want to send error reports to its server, you must uninstall the Software.
|
||||
3. **Anonymized Usage Data.** X-Pipe collects anonymized data about your usage of the Software to help us make it more
|
||||
awesome. Approximately once a day the Software sends such data (as described in more detail at the URL above) to its
|
||||
server. If you do not want to send anonymized usage data to the server, you may opt out by changing your settings in
|
||||
the Preferences view.
|
||||
be disabled.
|
||||
|
||||
### Open-Source Notices
|
||||
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
## Welcome to X-Pipe!
|
||||
|
||||
X-Pipe (short for eXtended Pipe) is a tool that enables a fast and an efficient data transfer/exchange between
|
||||
all types of producers and consumers of data, e.g. different file types,
|
||||
applications, programming languages, databases, technologies, and more.
|
||||
Thank you for trying out the X-Pipe Alpha.
|
||||
You can overview the development status, report issues, and more at the following places:
|
||||
|
||||
It is currently in early development and this build is an alpha version.
|
||||
A lot of features are incomplete or bugged.
|
||||
You can overview and contribute to the development here:
|
||||
|
||||
#### [Issue Tracker](https://github.com/xpipe-io/xpipe/issues)
|
||||
#### [GitHub Repository](https://github.com/xpipe-io/xpipe/)
|
||||
|
||||
#### [Discord Server](https://discord.gg/8y89vS8cRb)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.xpipe.ext.proc;
|
||||
|
||||
import io.xpipe.app.prefs.ExternalApplicationType;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
|
@ -7,18 +8,12 @@ import io.xpipe.extension.event.ErrorEvent;
|
|||
import io.xpipe.extension.prefs.PrefsChoiceValue;
|
||||
import io.xpipe.extension.prefs.PrefsProvider;
|
||||
import io.xpipe.extension.util.ApplicationHelper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public abstract class TerminalType implements PrefsChoiceValue {
|
||||
public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||
|
||||
public static final TerminalType CMD = new SimpleType("proc.cmd", "cmd", "cmd.exe") {
|
||||
public static final ExternalTerminalType CMD = new SimpleType("proc.cmd", "cmd", "cmd.exe") {
|
||||
|
||||
@Override
|
||||
protected String toCommand(String name, String command) {
|
||||
|
@ -31,7 +26,7 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
public static final TerminalType POWERSHELL = new SimpleType("proc.powershell", "powershell", "PowerShell") {
|
||||
public static final ExternalTerminalType POWERSHELL = new SimpleType("proc.powershell", "powershell", "PowerShell") {
|
||||
|
||||
@Override
|
||||
protected String toCommand(String name, String command) {
|
||||
|
@ -44,7 +39,7 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
public static final TerminalType WINDOWS_TERMINAL =
|
||||
public static final ExternalTerminalType WINDOWS_TERMINAL =
|
||||
new SimpleType("proc.windowsTerminal", "wt.exe", "Windows Terminal") {
|
||||
|
||||
@Override
|
||||
|
@ -58,7 +53,7 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
public static final TerminalType GNOME_TERMINAL =
|
||||
public static final ExternalTerminalType GNOME_TERMINAL =
|
||||
new SimpleType("proc.gnomeTerminal", "gnome-terminal", "Gnome Terminal") {
|
||||
|
||||
@Override
|
||||
|
@ -72,7 +67,7 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
public static final TerminalType KONSOLE = new SimpleType("proc.konsole", "konsole", "Konsole") {
|
||||
public static final ExternalTerminalType KONSOLE = new SimpleType("proc.konsole", "konsole", "Konsole") {
|
||||
|
||||
@Override
|
||||
protected String toCommand(String name, String command) {
|
||||
|
@ -85,7 +80,7 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
public static final TerminalType XFCE = new SimpleType("proc.xfce", "xfce4-terminal", "Xfce") {
|
||||
public static final ExternalTerminalType XFCE = new SimpleType("proc.xfce", "xfce4-terminal", "Xfce") {
|
||||
|
||||
@Override
|
||||
protected String toCommand(String name, String command) {
|
||||
|
@ -98,38 +93,15 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
public static final TerminalType MACOS_TERMINAL = new MacType("proc.macosTerminal", "Terminal");
|
||||
public static final ExternalTerminalType MACOS_TERMINAL = new MacOsType();
|
||||
|
||||
public static final TerminalType ITERM2 = new ITerm2Type();
|
||||
public static final ExternalTerminalType ITERM2 = new ITerm2Type();
|
||||
|
||||
public static final TerminalType WARP = new WarpType();
|
||||
public static final ExternalTerminalType WARP = new WarpType();
|
||||
|
||||
public static final TerminalType CUSTOM = new TerminalType("app.custom") {
|
||||
public static final ExternalTerminalType CUSTOM = new CustomType();
|
||||
|
||||
@Override
|
||||
public void launch(String name, String command) throws Exception {
|
||||
var custom =
|
||||
PrefsProvider.get(ProcPrefs.class).customTerminalCommand().getValue();
|
||||
if (custom == null || custom.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var format = custom.contains("$cmd") ? custom : custom + " $cmd";
|
||||
ShellStore.local().create().executeSimpleCommand(format.replace("$cmd", command));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public static final List<TerminalType> ALL = List.of(
|
||||
public static final List<ExternalTerminalType> ALL = List.of(
|
||||
WINDOWS_TERMINAL,
|
||||
POWERSHELL,
|
||||
CMD,
|
||||
|
@ -144,42 +116,60 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
.filter(terminalType -> terminalType.isSelectable())
|
||||
.toList();
|
||||
|
||||
public static TerminalType getDefault() {
|
||||
public static ExternalTerminalType getDefault() {
|
||||
return ALL.stream()
|
||||
.filter(terminalType -> terminalType.isAvailable())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private String id;
|
||||
|
||||
public abstract void launch(String name, String command) throws Exception;
|
||||
|
||||
public abstract boolean isSelectable();
|
||||
static class MacOsType extends ExternalApplicationType.MacApplication implements ExternalTerminalType {
|
||||
|
||||
public abstract boolean isAvailable();
|
||||
public MacOsType() {
|
||||
super("proc.macosTerminal", "Terminal");
|
||||
}
|
||||
|
||||
static class MacType extends TerminalType {
|
||||
@Override
|
||||
public void launch(String name, String command) throws Exception {
|
||||
var custom =
|
||||
PrefsProvider.get(ProcPrefs.class).customTerminalCommand().getValue();
|
||||
if (custom == null || custom.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
private final String terminalName;
|
||||
var format = custom.contains("$cmd") ? custom : custom + " $cmd";
|
||||
try (var pc = ShellStore.local().create().start()) {
|
||||
var toExecute = format.replace("$cmd", command);
|
||||
if (pc.getOsType().equals(OsType.WINDOWS)) {
|
||||
toExecute = "start \"" + name + "\" " + toExecute;
|
||||
} else {
|
||||
toExecute = "nohup " + toExecute + " </dev/null &>/dev/null & disown";
|
||||
}
|
||||
pc.executeSimpleCommand(toExecute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MacType(String id, String terminalName) {
|
||||
super(id);
|
||||
this.terminalName = terminalName;
|
||||
static class CustomType extends ExternalApplicationType implements ExternalTerminalType {
|
||||
|
||||
public CustomType() {
|
||||
super("proc.custom");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launch(String name, String command) throws Exception {
|
||||
try (ShellProcessControl pc = ShellStore.local().create().start()) {
|
||||
var suffix = command.equals(pc.getShellType().getNormalOpenCommand()) ? "\"\"" : "\"" + command + "\"";
|
||||
var cmd = "osascript -e 'tell app \"" + terminalName + "\" to do script " + suffix + "'";
|
||||
var cmd = "osascript -e 'tell app \"" + "Terminal" + "\" to do script " + suffix + "'";
|
||||
pc.executeSimpleCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return OsType.getLocal().equals(OsType.MAC);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -188,10 +178,10 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
}
|
||||
}
|
||||
|
||||
static class ITerm2Type extends TerminalType {
|
||||
static class ITerm2Type extends ExternalApplicationType.MacApplication implements ExternalTerminalType {
|
||||
|
||||
public ITerm2Type() {
|
||||
super("proc.iterm2");
|
||||
super("proc.iterm2", "iTerm2");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -200,7 +190,6 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
var cmd = String.format(
|
||||
"""
|
||||
osascript - "$@" <<EOF
|
||||
on run argv
|
||||
tell application "iTerm"
|
||||
activate
|
||||
set new_term to (create window with profile "Default" command "%s")
|
||||
|
@ -211,22 +200,12 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
pc.executeSimpleCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return OsType.getLocal().equals(OsType.MAC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return Files.exists(Path.of("/Applications/iTerm2.app"));
|
||||
}
|
||||
}
|
||||
|
||||
static class WarpType extends TerminalType {
|
||||
static class WarpType extends ExternalApplicationType.MacApplication implements ExternalTerminalType {
|
||||
|
||||
public WarpType() {
|
||||
super("proc.warp");
|
||||
super("proc.warp", "Warp");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -234,41 +213,30 @@ public abstract class TerminalType implements PrefsChoiceValue {
|
|||
try (ShellProcessControl pc = ShellStore.local().create().start()) {
|
||||
var cmd = String.format(
|
||||
"""
|
||||
osascript - "$@" <<EOF
|
||||
tell application "Warp" to activate'
|
||||
sudo osascript -e 'tell application "System Events" to tell process "Warp" to keystroke "t" using command down'
|
||||
sleep 1
|
||||
sudo osascript -e 'tell application "System Events"
|
||||
tell process "Warp"
|
||||
keystroke "%s"
|
||||
key code 36
|
||||
end tell
|
||||
end tell
|
||||
EOF""",
|
||||
osascript - "$@" <<EOF
|
||||
tell application "Warp" to activate
|
||||
tell application "System Events" to tell process "Warp" to keystroke "t" using command down
|
||||
delay 1
|
||||
tell application "System Events"
|
||||
tell process "Warp"
|
||||
keystroke "%s"
|
||||
key code 36
|
||||
end tell
|
||||
end tell
|
||||
EOF
|
||||
""",
|
||||
command);
|
||||
pc.executeSimpleCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return OsType.getLocal().equals(OsType.MAC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return Files.exists(Path.of("/Applications/iTerm2.app"));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class SimpleType extends TerminalType {
|
||||
public abstract static class SimpleType extends ExternalApplicationType.PathApplication implements ExternalTerminalType {
|
||||
|
||||
private final String executable;
|
||||
private final String displayName;
|
||||
|
||||
public SimpleType(String id, String executable, String displayName) {
|
||||
super(id);
|
||||
this.executable = executable;
|
||||
super(id, executable);
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
|
@ -25,10 +25,10 @@ public class ProcPrefs extends PrefsProvider {
|
|||
return enableCaching;
|
||||
}
|
||||
|
||||
private final ObjectProperty<TerminalType> terminalType = new SimpleObjectProperty<>();
|
||||
private final SimpleListProperty<TerminalType> terminalTypeList = new SimpleListProperty<>(
|
||||
FXCollections.observableArrayList(PrefsChoiceValue.getSupported(TerminalType.class)));
|
||||
private final SingleSelectionField<TerminalType> terminalTypeControl = Field.ofSingleSelectionType(
|
||||
private final ObjectProperty<ExternalTerminalType> terminalType = new SimpleObjectProperty<>();
|
||||
private final SimpleListProperty<ExternalTerminalType> terminalTypeList = new SimpleListProperty<>(
|
||||
FXCollections.observableArrayList(PrefsChoiceValue.getSupported(ExternalTerminalType.class)));
|
||||
private final SingleSelectionField<ExternalTerminalType> terminalTypeControl = Field.ofSingleSelectionType(
|
||||
terminalTypeList, terminalType)
|
||||
.render(() -> new TranslatableComboBoxControl<>());
|
||||
|
||||
|
@ -37,9 +37,9 @@ public class ProcPrefs extends PrefsProvider {
|
|||
private final StringProperty customTerminalCommand = new SimpleStringProperty("");
|
||||
private final StringField customTerminalCommandControl = editable(
|
||||
StringField.ofStringType(customTerminalCommand).render(() -> new SimpleTextControl()),
|
||||
terminalType.isEqualTo(TerminalType.CUSTOM));
|
||||
terminalType.isEqualTo(ExternalTerminalType.CUSTOM));
|
||||
|
||||
public ObservableValue<TerminalType> terminalType() {
|
||||
public ObservableValue<ExternalTerminalType> terminalType() {
|
||||
return terminalType;
|
||||
}
|
||||
|
||||
|
@ -53,19 +53,19 @@ public class ProcPrefs extends PrefsProvider {
|
|||
List.of("integrations"),
|
||||
"proc.terminal",
|
||||
Setting.of("app.defaultProgram", terminalTypeControl, terminalType),
|
||||
TerminalType.class);
|
||||
ExternalTerminalType.class);
|
||||
handler.addSetting(
|
||||
List.of("integrations"),
|
||||
"proc.terminal",
|
||||
Setting.of("proc.customTerminalCommand", customTerminalCommandControl, customTerminalCommand)
|
||||
.applyVisibility(VisibilityProperty.of(terminalType.isEqualTo(TerminalType.CUSTOM))),
|
||||
.applyVisibility(VisibilityProperty.of(terminalType.isEqualTo(ExternalTerminalType.CUSTOM))),
|
||||
String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (terminalType.get() == null) {
|
||||
terminalType.set(TerminalType.getDefault());
|
||||
terminalType.set(ExternalTerminalType.getDefault());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,4 +88,7 @@ keyPassword=Key Password
|
|||
key=Key
|
||||
installConnector=Install Connector
|
||||
konsole=Konsole
|
||||
xfce=Xfce
|
||||
xfce=Xfce
|
||||
macosTerminal=Terminal
|
||||
iterm2=iTerm2
|
||||
warp=Warp
|
|
@ -1,10 +1,14 @@
|
|||
package io.xpipe.extension.fxcomps.util;
|
||||
|
||||
import io.xpipe.extension.util.ThreadHelper;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.binding.ListBinding;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import lombok.Value;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
|
@ -14,6 +18,37 @@ import java.util.function.Predicate;
|
|||
|
||||
public class BindingsHelper {
|
||||
|
||||
private static final Set<ReferenceEntry> REFERENCES = Collections.newSetFromMap(new ConcurrentHashMap<ReferenceEntry, Boolean>());
|
||||
|
||||
@Value
|
||||
private static class ReferenceEntry {
|
||||
|
||||
WeakReference<?> source;
|
||||
Object target;
|
||||
|
||||
public boolean canGc() {
|
||||
return source.get() == null;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
ThreadHelper.create("referenceGC", true, () -> {
|
||||
while (true) {
|
||||
for (ReferenceEntry reference : REFERENCES) {
|
||||
if (reference.canGc()) {
|
||||
REFERENCES.remove(reference);
|
||||
}
|
||||
}
|
||||
ThreadHelper.sleep(1000);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
}
|
||||
|
||||
public static void linkPersistently(Object source, Object target) {
|
||||
REFERENCES.add(new ReferenceEntry(new WeakReference<>(source), target));
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Proper cleanup. Maybe with a separate thread?
|
||||
*/
|
||||
|
@ -30,6 +65,17 @@ public class BindingsHelper {
|
|||
return binding;
|
||||
}
|
||||
|
||||
public static <T extends ListBinding<?>> T persist(T binding) {
|
||||
var dependencies = new HashSet<javafx.beans.Observable>();
|
||||
while (dependencies.addAll(binding.getDependencies().stream()
|
||||
.map(o -> (javafx.beans.Observable) o)
|
||||
.toList())) {
|
||||
}
|
||||
dependencies.add(binding);
|
||||
BINDINGS.put(new WeakReference<>(binding), dependencies);
|
||||
return binding;
|
||||
}
|
||||
|
||||
public static <T> void bindContent(ObservableList<T> l1, ObservableList<? extends T> l2) {
|
||||
setContent(l1, l2);
|
||||
l2.addListener((ListChangeListener<? super T>) c -> {
|
||||
|
@ -56,6 +102,7 @@ public class BindingsHelper {
|
|||
l2.addListener((ListChangeListener<? super V>) c -> {
|
||||
runnable.run();
|
||||
});
|
||||
linkPersistently(l2, l1);
|
||||
return l1;
|
||||
}
|
||||
|
||||
|
@ -68,9 +115,14 @@ public class BindingsHelper {
|
|||
l2.addListener((ListChangeListener<? super V>) c -> {
|
||||
runnable.run();
|
||||
});
|
||||
linkPersistently(l2, l1);
|
||||
return l1;
|
||||
}
|
||||
|
||||
public static <V> ObservableList<V> filteredContentBinding(ObservableList<V> l2,Predicate<V> predicate) {
|
||||
return filteredContentBinding(l2, new SimpleObjectProperty<>(predicate));
|
||||
}
|
||||
|
||||
public static <V> ObservableList<V> filteredContentBinding(ObservableList<V> l2, ObservableValue<Predicate<V>> predicate) {
|
||||
ObservableList<V> l1 = FXCollections.observableList(new ArrayList<>());
|
||||
Runnable runnable = () -> {
|
||||
|
@ -83,6 +135,7 @@ public class BindingsHelper {
|
|||
predicate.addListener((c,o,n) -> {
|
||||
runnable.run();
|
||||
});
|
||||
linkPersistently(l2, l1);
|
||||
return l1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue