This commit is contained in:
crschnick 2024-05-01 17:16:19 +00:00
parent c7f6bcf7d7
commit 6408390535
41 changed files with 248 additions and 163 deletions

View file

@ -86,8 +86,7 @@ public final class BrowserBookmarkComp extends SimpleComp {
selectedCategory) selectedCategory)
.styleClass(Styles.LEFT_PILL) .styleClass(Styles.LEFT_PILL)
.minWidth(Region.USE_PREF_SIZE); .minWidth(Region.USE_PREF_SIZE);
var filter = var filter = new FilterComp(filterText).hgrow();
new FilterComp(filterText).hgrow();
var top = new HorizontalComp(List.of(category, filter)) var top = new HorizontalComp(List.of(category, filter))
.styleClass("categories") .styleClass("categories")

View file

@ -1,6 +1,5 @@
package io.xpipe.app.browser; package io.xpipe.app.browser;
import atlantafx.base.theme.Styles;
import io.xpipe.app.browser.session.BrowserSessionModel; import io.xpipe.app.browser.session.BrowserSessionModel;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.comp.base.ListBoxViewComp;
@ -32,6 +31,7 @@ import javafx.scene.layout.Region;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import atlantafx.base.controls.Spacer; import atlantafx.base.controls.Spacer;
import atlantafx.base.theme.Styles;
import java.util.List; import java.util.List;
@ -139,7 +139,8 @@ public class BrowserWelcomeComp extends SimpleComp {
private Comp<?> entryButton(BrowserSavedState.Entry e, BooleanProperty disable) { private Comp<?> entryButton(BrowserSavedState.Entry e, BooleanProperty disable) {
var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid()); var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid());
var graphic = entry.get().getProvider().getDisplayIconFileName(entry.get().getStore()); var graphic =
entry.get().getProvider().getDisplayIconFileName(entry.get().getStore());
var view = PrettyImageHelper.ofFixedSize(graphic, 30, 24); var view = PrettyImageHelper.ofFixedSize(graphic, 30, 24);
return new ButtonComp( return new ButtonComp(
new SimpleStringProperty(DataStorage.get().getStoreDisplayName(entry.get())), new SimpleStringProperty(DataStorage.get().getStoreDisplayName(entry.get())),

View file

@ -8,8 +8,10 @@ import io.xpipe.app.fxcomps.util.Shortcuts;
import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.LicenseProvider; import io.xpipe.app.util.LicenseProvider;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
import java.util.List; import java.util.List;
@ -91,7 +93,8 @@ public interface LeafAction extends BrowserAction {
mi.setMnemonicParsing(false); mi.setMnemonicParsing(false);
mi.setDisable(!isActive(model, selected)); mi.setDisable(!isActive(model, selected));
if (getProFeatureId() != null && !LicenseProvider.get().getFeature(getProFeatureId()).isSupported()) { if (getProFeatureId() != null
&& !LicenseProvider.get().getFeature(getProFeatureId()).isSupported()) {
mi.setDisable(true); mi.setDisable(true);
} }

View file

@ -8,6 +8,7 @@ import io.xpipe.app.util.InputHelper;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.FileKind; import io.xpipe.core.store.FileKind;
import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.FileSystem;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Side; import javafx.geometry.Side;
@ -19,6 +20,7 @@ import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import lombok.Getter; import lombok.Getter;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -22,8 +22,10 @@ import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.process.ShellOpenFunction; import io.xpipe.core.process.ShellOpenFunction;
import io.xpipe.core.store.*; import io.xpipe.core.store.*;
import io.xpipe.core.util.FailableConsumer; import io.xpipe.core.util.FailableConsumer;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.*; import javafx.beans.property.*;
import lombok.Getter; import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
@ -297,7 +299,8 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
loadFilesSync(path); loadFilesSync(path);
} }
public void withFiles(String dir, FailableConsumer<Stream<FileSystem.FileEntry>, Exception> consumer) throws Exception { public void withFiles(String dir, FailableConsumer<Stream<FileSystem.FileEntry>, Exception> consumer)
throws Exception {
BooleanScope.executeExclusive(busy, () -> { BooleanScope.executeExclusive(busy, () -> {
if (dir != null) { if (dir != null) {
startIfNeeded(); startIfNeeded();

View file

@ -6,11 +6,13 @@ import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableBooleanValue;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -29,17 +31,29 @@ public class StoreToggleComp extends SimpleComp {
@Setter @Setter
private ObservableBooleanValue customVisibility = new SimpleBooleanProperty(true); private ObservableBooleanValue customVisibility = new SimpleBooleanProperty(true);
public static <T extends DataStore> StoreToggleComp simpleToggle(String nameKey, StoreSection section, Function<T, Boolean> initial, BiConsumer<T, Boolean> setter) { public static <T extends DataStore> StoreToggleComp simpleToggle(
return new StoreToggleComp(nameKey, section,new SimpleBooleanProperty(initial.apply(section.getWrapper().getEntry().getStore().asNeeded())),v -> { String nameKey, StoreSection section, Function<T, Boolean> initial, BiConsumer<T, Boolean> setter) {
setter.accept(section.getWrapper().getEntry().getStore().asNeeded(),v); return new StoreToggleComp(
}); nameKey,
section,
new SimpleBooleanProperty(
initial.apply(section.getWrapper().getEntry().getStore().asNeeded())),
v -> {
setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v);
});
} }
public static <T extends DataStore> StoreToggleComp childrenToggle(String nameKey, StoreSection section, Function<T, Boolean> initial, BiConsumer<T, Boolean> setter) { public static <T extends DataStore> StoreToggleComp childrenToggle(
return new StoreToggleComp(nameKey, section,new SimpleBooleanProperty(initial.apply(section.getWrapper().getEntry().getStore().asNeeded())),v -> { String nameKey, StoreSection section, Function<T, Boolean> initial, BiConsumer<T, Boolean> setter) {
setter.accept(section.getWrapper().getEntry().getStore().asNeeded(),v); return new StoreToggleComp(
section.getWrapper().refreshChildren(); nameKey,
}); section,
new SimpleBooleanProperty(
initial.apply(section.getWrapper().getEntry().getStore().asNeeded())),
v -> {
setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v);
section.getWrapper().refreshChildren();
});
} }
public StoreToggleComp(String nameKey, StoreSection section, boolean initial, Consumer<Boolean> onChange) { public StoreToggleComp(String nameKey, StoreSection section, boolean initial, Consumer<Boolean> onChange) {

View file

@ -5,10 +5,12 @@ import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders; import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
import io.xpipe.app.util.ScanAlert; import io.xpipe.app.util.ScanAlert;
import javafx.scene.control.Menu; import javafx.scene.control.Menu;
import javafx.scene.control.MenuButton; import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.SeparatorMenuItem;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
public class StoreCreationMenu { public class StoreCreationMenu {
@ -83,7 +85,9 @@ public class StoreCreationMenu {
category); category);
event.consume(); event.consume();
}); });
var providers = sub.stream().sorted((o1, o2) -> -o1.getModuleName().compareTo(o2.getModuleName())).toList(); var providers = sub.stream()
.sorted((o1, o2) -> -o1.getModuleName().compareTo(o2.getModuleName()))
.toList();
for (int i = 0; i < providers.size(); i++) { for (int i = 0; i < providers.size(); i++) {
var dataStoreProvider = providers.get(i); var dataStoreProvider = providers.get(i);
if (i > 0 && !providers.get(i - 1).getModuleName().equals(dataStoreProvider.getModuleName())) { if (i > 0 && !providers.get(i - 1).getModuleName().equals(dataStoreProvider.getModuleName())) {

View file

@ -116,9 +116,9 @@ public abstract class StoreEntryComp extends SimpleComp {
var loading = LoadingOverlayComp.noProgress( var loading = LoadingOverlayComp.noProgress(
Comp.of(() -> button), Comp.of(() -> button),
wrapper.getEntry().getValidity().isUsable() ? wrapper.getEntry().getValidity().isUsable()
wrapper.getBusy().or(wrapper.getEntry().getProvider().busy(wrapper)): ? wrapper.getBusy().or(wrapper.getEntry().getProvider().busy(wrapper))
wrapper.getBusy()); : wrapper.getBusy());
return loading.createRegion(); return loading.createRegion();
} }

View file

@ -8,6 +8,7 @@ import io.xpipe.core.process.ProcessControlProvider;
import io.xpipe.core.util.ModuleHelper; import io.xpipe.core.util.ModuleHelper;
import io.xpipe.core.util.ModuleLayerLoader; import io.xpipe.core.util.ModuleLayerLoader;
import io.xpipe.core.util.XPipeInstallation; import io.xpipe.core.util.XPipeInstallation;
import lombok.Getter; import lombok.Getter;
import lombok.Value; import lombok.Value;
@ -95,12 +96,16 @@ public class AppExtensionManager {
} }
var iv = getLocalInstallVersion(); var iv = getLocalInstallVersion();
var installVersion = AppVersion.parse(iv).orElseThrow(() -> new IllegalArgumentException("Invalid installation version: " + iv)); var installVersion = AppVersion.parse(iv)
var sv = !AppProperties.get().isImage() ? Files.readString(Path.of("version")).trim() : AppProperties.get().getVersion(); .orElseThrow(() -> new IllegalArgumentException("Invalid installation version: " + iv));
var sourceVersion = AppVersion.parse(sv).orElseThrow(() -> new IllegalArgumentException("Invalid source version: " + sv)); var sv = !AppProperties.get().isImage()
? Files.readString(Path.of("version")).trim()
: AppProperties.get().getVersion();
var sourceVersion = AppVersion.parse(sv)
.orElseThrow(() -> new IllegalArgumentException("Invalid source version: " + sv));
if (!installVersion.equals(sourceVersion)) { if (!installVersion.equals(sourceVersion)) {
throw new IllegalStateException( throw new IllegalStateException("Incompatible development version. Source: " + iv + ", Installation: "
"Incompatible development version. Source: " + iv + ", Installation: " + sv + "\n\nPlease try to check out the matching release version in the repository."); + sv + "\n\nPlease try to check out the matching release version in the repository.");
} }
var extensions = XPipeInstallation.getLocalExtensionsDirectory(p); var extensions = XPipeInstallation.getLocalExtensionsDirectory(p);
@ -171,8 +176,8 @@ public class AppExtensionManager {
if (loadedExtensions.stream().anyMatch(extension -> dir.equals(extension.dir)) if (loadedExtensions.stream().anyMatch(extension -> dir.equals(extension.dir))
|| loadedExtensions.stream() || loadedExtensions.stream()
.anyMatch(extension -> .anyMatch(extension ->
extension.id.equals(dir.getFileName().toString()))) { extension.id.equals(dir.getFileName().toString()))) {
return Optional.empty(); return Optional.empty();
} }

View file

@ -55,7 +55,9 @@ public class AppProperties {
.orElse(UUID.randomUUID()); .orElse(UUID.randomUUID());
sentryUrl = System.getProperty("io.xpipe.app.sentryUrl"); sentryUrl = System.getProperty("io.xpipe.app.sentryUrl");
arch = System.getProperty("io.xpipe.app.arch"); arch = System.getProperty("io.xpipe.app.arch");
languages = Arrays.stream(System.getProperty("io.xpipe.app.languages").split(";")).sorted().toList(); languages = Arrays.stream(System.getProperty("io.xpipe.app.languages").split(";"))
.sorted()
.toList();
staging = XPipeInstallation.isStaging(); staging = XPipeInstallation.isStaging();
useVirtualThreads = Optional.ofNullable(System.getProperty("io.xpipe.app.useVirtualThreads")) useVirtualThreads = Optional.ofNullable(System.getProperty("io.xpipe.app.useVirtualThreads"))
.map(Boolean::parseBoolean) .map(Boolean::parseBoolean)

View file

@ -19,10 +19,11 @@ import io.xpipe.core.process.OsType;
import io.xpipe.core.util.FailableRunnable; import io.xpipe.core.util.FailableRunnable;
import io.xpipe.core.util.XPipeDaemonMode; import io.xpipe.core.util.XPipeDaemonMode;
import io.xpipe.core.util.XPipeInstallation; import io.xpipe.core.util.XPipeInstallation;
import javafx.application.Platform; import javafx.application.Platform;
import lombok.Getter; import lombok.Getter;
import javax.imageio.ImageIO;
import java.awt.*; import java.awt.*;
import java.awt.desktop.AppReopenedEvent; import java.awt.desktop.AppReopenedEvent;
import java.awt.desktop.AppReopenedListener; import java.awt.desktop.AppReopenedListener;
@ -30,6 +31,7 @@ import java.awt.desktop.SystemEventListener;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.imageio.ImageIO;
public abstract class OperationMode { public abstract class OperationMode {

View file

@ -1,18 +1,20 @@
package io.xpipe.app.fxcomps.impl; package io.xpipe.app.fxcomps.impl;
import atlantafx.base.layout.InputGroup;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.util.ClipboardHelper; import io.xpipe.app.util.ClipboardHelper;
import io.xpipe.core.util.InPlaceSecretValue; import io.xpipe.core.util.InPlaceSecretValue;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.PasswordField; import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority; import javafx.scene.layout.Priority;
import atlantafx.base.layout.InputGroup;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.kordamp.ikonli.javafx.FontIcon; import org.kordamp.ikonli.javafx.FontIcon;
@ -27,6 +29,7 @@ public class SecretFieldComp extends Comp<SecretFieldComp.Structure> {
public static class Structure implements CompStructure<InputGroup> { public static class Structure implements CompStructure<InputGroup> {
private final InputGroup inputGroup; private final InputGroup inputGroup;
@Getter @Getter
private final TextField field; private final TextField field;
@ -85,8 +88,11 @@ public class SecretFieldComp extends Comp<SecretFieldComp.Structure> {
HBox.setHgrow(text, Priority.ALWAYS); HBox.setHgrow(text, Priority.ALWAYS);
var copyButton = new ButtonComp(null, new FontIcon("mdi2c-clipboard-multiple-outline"), () -> { var copyButton = new ButtonComp(null, new FontIcon("mdi2c-clipboard-multiple-outline"), () -> {
ClipboardHelper.copyPassword(value.getValue()); ClipboardHelper.copyPassword(value.getValue());
}).grow(false, true).tooltipKey("copyPassword").createRegion(); })
.grow(false, true)
.tooltipKey("copyPassword")
.createRegion();
var ig = new InputGroup(text); var ig = new InputGroup(text);
ig.getStyleClass().add("secret-field-comp"); ig.getStyleClass().add("secret-field-comp");

View file

@ -4,8 +4,8 @@ import io.xpipe.app.core.*;
import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.update.XPipeDistributionType; import io.xpipe.app.update.XPipeDistributionType;
import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar; import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;

View file

@ -1,7 +1,5 @@
package io.xpipe.app.issue; package io.xpipe.app.issue;
import atlantafx.base.controls.Popover;
import atlantafx.base.controls.Spacer;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.ListSelectorComp; import io.xpipe.app.comp.base.ListSelectorComp;
import io.xpipe.app.comp.base.MarkdownComp; import io.xpipe.app.comp.base.MarkdownComp;
@ -9,6 +7,7 @@ import io.xpipe.app.comp.base.TitledPaneComp;
import io.xpipe.app.core.*; import io.xpipe.app.core.*;
import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import javafx.beans.property.ListProperty; import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty; import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@ -23,6 +22,9 @@ import javafx.scene.control.TextField;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.stage.Stage; import javafx.stage.Stage;
import atlantafx.base.controls.Popover;
import atlantafx.base.controls.Spacer;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;

View file

@ -139,21 +139,22 @@ public class AppPrefs {
private AppPrefs() { private AppPrefs() {
this.categories = Stream.of( this.categories = Stream.of(
new AboutCategory(), new AboutCategory(),
new SystemCategory(), new SystemCategory(),
new AppearanceCategory(), new AppearanceCategory(),
new SyncCategory(), new SyncCategory(),
new VaultCategory(), new VaultCategory(),
new PasswordManagerCategory(), new PasswordManagerCategory(),
new TerminalCategory(), new TerminalCategory(),
new EditorCategory(), new EditorCategory(),
new RdpCategory(), new RdpCategory(),
new SshCategory(), new SshCategory(),
new LocalShellCategory(), new LocalShellCategory(),
new SecurityCategory(), new SecurityCategory(),
new TroubleshootCategory(), new TroubleshootCategory(),
new DeveloperCategory()) new DeveloperCategory())
.filter(appPrefsCategory -> appPrefsCategory.show()).toList(); .filter(appPrefsCategory -> appPrefsCategory.show())
.toList();
var selected = AppCache.get("selectedPrefsCategory", Integer.class, () -> 0); var selected = AppCache.get("selectedPrefsCategory", Integer.class, () -> 0);
if (selected == null) { if (selected == null) {
selected = 0; selected = 0;

View file

@ -46,7 +46,9 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue {
public boolean isAvailable() { public boolean isAvailable() {
try (ShellControl pc = LocalShell.getShell().start()) { try (ShellControl pc = LocalShell.getShell().start()) {
return pc.command(String.format( return pc.command(String.format(
"mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications", applicationName)).executeAndCheck(); "mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications",
applicationName))
.executeAndCheck();
} catch (Exception e) { } catch (Exception e) {
ErrorEvent.fromThrowable(e).handle(); ErrorEvent.fromThrowable(e).handle();
return false; return false;

View file

@ -5,8 +5,8 @@ import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.*; import io.xpipe.app.util.*;
import io.xpipe.core.process.CommandBuilder; import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType; import io.xpipe.core.process.OsType;
import io.xpipe.core.util.SecretValue; import io.xpipe.core.util.SecretValue;
import lombok.Value; import lombok.Value;
import java.nio.file.Files; import java.nio.file.Files;
@ -59,8 +59,8 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
private String encrypt(SecretValue password) throws Exception { private String encrypt(SecretValue password) throws Exception {
var ps = LocalShell.getLocalPowershell(); var ps = LocalShell.getLocalPowershell();
var cmd = ps.command( var cmd = ps.command("(\"" + password.getSecretValue()
"(\"" + password.getSecretValue() + "\" | ConvertTo-SecureString -AsPlainText -Force) | ConvertFrom-SecureString;"); + "\" | ConvertTo-SecureString -AsPlainText -Force) | ConvertFrom-SecureString;");
cmd.setSensitive(); cmd.setSensitive();
return cmd.readStdoutOrThrow(); return cmd.readStdoutOrThrow();
} }

View file

@ -7,7 +7,9 @@ import io.xpipe.app.util.FixedHierarchyStore;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.*; import io.xpipe.core.store.*;
import io.xpipe.core.util.UuidHelper; import io.xpipe.core.util.UuidHelper;
import javafx.util.Pair; import javafx.util.Pair;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
@ -311,8 +313,8 @@ public abstract class DataStorage {
DataStoreCategory p = category; DataStoreCategory p = category;
if (share) { if (share) {
while ((p = DataStorage.get() while ((p = DataStorage.get()
.getStoreCategoryIfPresent(p.getParentCategory()) .getStoreCategoryIfPresent(p.getParentCategory())
.orElse(null)) .orElse(null))
!= null) { != null) {
p.setShare(true); p.setShare(true);
} }
@ -428,7 +430,8 @@ public abstract class DataStorage {
// Children classes might not be the same, the same goes for state classes // Children classes might not be the same, the same goes for state classes
// This can happen when there are multiple child classes and the ids got switched around // This can happen when there are multiple child classes and the ids got switched around
if (classMatch) { if (classMatch) {
DataStore merged = ((FixedChildStore) pair.getKey().getStore()).merge(pair.getValue().getStore().asNeeded()); DataStore merged = ((FixedChildStore) pair.getKey().getStore())
.merge(pair.getValue().getStore().asNeeded());
if (merged != pair.getKey().getStore()) { if (merged != pair.getKey().getStore()) {
pair.getKey().setStoreInternal(merged, false); pair.getKey().setStoreInternal(merged, false);
} }
@ -781,9 +784,11 @@ public abstract class DataStorage {
public Optional<DataStoreEntry> getStoreEntryIfPresent(@NonNull DataStore store, boolean identityOnly) { public Optional<DataStoreEntry> getStoreEntryIfPresent(@NonNull DataStore store, boolean identityOnly) {
return storeEntriesSet.stream() return storeEntriesSet.stream()
.filter(n -> n.getStore() == store .filter(n -> n.getStore() == store
|| (!identityOnly && (n.getStore() != null || (!identityOnly
&& Objects.equals(store.getClass(), n.getStore().getClass()) && (n.getStore() != null
&& store.equals(n.getStore())))) && Objects.equals(
store.getClass(), n.getStore().getClass())
&& store.equals(n.getStore()))))
.findFirst(); .findFirst();
} }

View file

@ -1,17 +1,18 @@
package io.xpipe.app.storage; package io.xpipe.app.storage;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.FixedHierarchyStore;
import io.xpipe.core.store.*;
import io.xpipe.core.util.JacksonMapper;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.FixedHierarchyStore;
import io.xpipe.core.store.*;
import io.xpipe.core.util.JacksonMapper;
import lombok.*; import lombok.*;
import lombok.experimental.NonFinal; import lombok.experimental.NonFinal;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;

View file

@ -166,7 +166,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
} }
@Override @Override
public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand(ShellDialect systemDialect) { public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand(
ShellDialect systemDialect) {
return launchConfiguration -> { return launchConfiguration -> {
var toExecute = CommandBuilder.of() var toExecute = CommandBuilder.of()
.add(executable, "-v", "--title") .add(executable, "-v", "--title")
@ -608,7 +609,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
} }
@Override @Override
public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand(ShellDialect systemDialect) { public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand(
ShellDialect systemDialect) {
return launchConfiguration -> { return launchConfiguration -> {
var toExecute = CommandBuilder.of() var toExecute = CommandBuilder.of()
.add("open", "-a") .add("open", "-a")
@ -806,7 +808,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
} }
@Override @Override
public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand(ShellDialect systemDialect) { public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand(
ShellDialect systemDialect) {
return launchConfiguration -> { return launchConfiguration -> {
var args = toCommand(launchConfiguration); var args = toCommand(launchConfiguration);
args.add(0, executable); args.add(0, executable);

View file

@ -1,6 +1,5 @@
package io.xpipe.app.terminal; package io.xpipe.app.terminal;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.CommandSupport; import io.xpipe.app.util.CommandSupport;
import io.xpipe.app.util.LocalShell; import io.xpipe.app.util.LocalShell;
@ -11,6 +10,8 @@ import io.xpipe.core.process.ShellControl;
import io.xpipe.core.store.FilePath; import io.xpipe.core.store.FilePath;
import io.xpipe.core.util.XPipeInstallation; import io.xpipe.core.util.XPipeInstallation;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
public interface KittyTerminalType extends ExternalTerminalType { public interface KittyTerminalType extends ExternalTerminalType {
ExternalTerminalType KITTY_LINUX = new Linux(); ExternalTerminalType KITTY_LINUX = new Linux();

View file

@ -36,22 +36,22 @@ public interface TabbyTerminalType extends ExternalTerminalType {
@Override @Override
default TerminalInitFunction additionalInitCommands() { default TerminalInitFunction additionalInitCommands() {
// return TerminalInitFunction.of(sc -> { // return TerminalInitFunction.of(sc -> {
// if (sc.getShellDialect() == ShellDialects.ZSH) { // if (sc.getShellDialect() == ShellDialects.ZSH) {
// return "export PS1=\"$PS1\\[\\e]1337;CurrentDir=\"'$(pwd)\\a\\]'"; // return "export PS1=\"$PS1\\[\\e]1337;CurrentDir=\"'$(pwd)\\a\\]'";
// } // }
// if (sc.getShellDialect() == ShellDialects.BASH) { // if (sc.getShellDialect() == ShellDialects.BASH) {
// return "precmd () { echo -n \"\\x1b]1337;CurrentDir=$(pwd)\\x07\" }"; // return "precmd () { echo -n \"\\x1b]1337;CurrentDir=$(pwd)\\x07\" }";
// } // }
// if (sc.getShellDialect() == ShellDialects.FISH) { // if (sc.getShellDialect() == ShellDialects.FISH) {
// return """ // return """
// function __tabby_working_directory_reporting --on-event fish_prompt // function __tabby_working_directory_reporting --on-event fish_prompt
// echo -en "\\e]1337;CurrentDir=$PWD\\x7" // echo -en "\\e]1337;CurrentDir=$PWD\\x7"
// end // end
// """; // """;
// } // }
// return null; // return null;
// }); // });
return TerminalInitFunction.none(); return TerminalInitFunction.none();
} }

View file

@ -81,8 +81,11 @@ public interface WezTerminalType extends ExternalTerminalType {
@Override @Override
public void launch(LaunchConfiguration configuration) throws Exception { public void launch(LaunchConfiguration configuration) throws Exception {
var path = LocalShell.getShell().command(String.format( var path = LocalShell.getShell()
"mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null", applicationName)).readStdoutOrThrow(); .command(String.format(
"mdfind -name '%s' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications 2>/dev/null",
applicationName))
.readStdoutOrThrow();
var c = CommandBuilder.of() var c = CommandBuilder.of()
.addFile(Path.of(path) .addFile(Path.of(path)
.resolve("Contents") .resolve("Contents")

View file

@ -2,6 +2,7 @@ package io.xpipe.app.util;
import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.core.util.SecretValue; import io.xpipe.core.util.SecretValue;
import javafx.animation.PauseTransition; import javafx.animation.PauseTransition;
import javafx.scene.input.Clipboard; import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat; import javafx.scene.input.DataFormat;
@ -21,9 +22,16 @@ public class ClipboardHelper {
PlatformThread.runLaterIfNeeded(() -> { PlatformThread.runLaterIfNeeded(() -> {
Clipboard clipboard = Clipboard.getSystemClipboard(); Clipboard clipboard = Clipboard.getSystemClipboard();
Map<DataFormat, Object> previous = Stream.of(DataFormat.PLAIN_TEXT, DataFormat.URL, DataFormat.RTF, DataFormat.HTML, DataFormat.IMAGE, DataFormat.FILES) Map<DataFormat, Object> previous = Stream.of(
.map(dataFormat -> new AbstractMap.SimpleEntry<>(dataFormat, clipboard.getContent(dataFormat))).filter(o -> o.getValue() != null) DataFormat.PLAIN_TEXT,
.collect(HashMap::new, (m,v)->m.put(v.getKey(), v.getValue()), HashMap::putAll); DataFormat.URL,
DataFormat.RTF,
DataFormat.HTML,
DataFormat.IMAGE,
DataFormat.FILES)
.map(dataFormat -> new AbstractMap.SimpleEntry<>(dataFormat, clipboard.getContent(dataFormat)))
.filter(o -> o.getValue() != null)
.collect(HashMap::new, (m, v) -> m.put(v.getKey(), v.getValue()), HashMap::putAll);
var withPassword = new HashMap<>(previous); var withPassword = new HashMap<>(previous);
withPassword.put(DataFormat.PLAIN_TEXT, pass.getSecretValue()); withPassword.put(DataFormat.PLAIN_TEXT, pass.getSecretValue());

View file

@ -8,6 +8,7 @@ import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.process.ShellStoreState; import io.xpipe.core.process.ShellStoreState;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.ShellStore; import io.xpipe.core.store.ShellStore;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import java.util.function.IntFunction; import java.util.function.IntFunction;
@ -32,7 +33,8 @@ public class DataStoreFormatter {
return null; return null;
} }
if (s.getShellDialect() != null && !s.getShellDialect().getDumbMode().supportsAnyPossibleInteraction()) { if (s.getShellDialect() != null
&& !s.getShellDialect().getDumbMode().supportsAnyPossibleInteraction()) {
if (s.getOsName() != null) { if (s.getOsName() != null) {
return formattedOsName(s.getOsName()); return formattedOsName(s.getOsName());
} }

View file

@ -29,34 +29,33 @@ public class DesktopHelper {
} }
public static void browsePathRemote(ShellControl sc, String path, FileKind kind) throws Exception { public static void browsePathRemote(ShellControl sc, String path, FileKind kind) throws Exception {
var d = sc.getShellDialect(); var d = sc.getShellDialect();
switch (sc.getOsType()) { switch (sc.getOsType()) {
case OsType.Windows windows -> { case OsType.Windows windows -> {
// Explorer does not support single quotes, so use normal quotes // Explorer does not support single quotes, so use normal quotes
if (kind == FileKind.DIRECTORY) { if (kind == FileKind.DIRECTORY) {
sc.executeSimpleCommand("explorer " + d.quoteArgument(path)); sc.executeSimpleCommand("explorer " + d.quoteArgument(path));
} else { } else {
sc.executeSimpleCommand("explorer /select," + d.quoteArgument(path)); sc.executeSimpleCommand("explorer /select," + d.quoteArgument(path));
}
}
case OsType.Linux linux -> {
var action = kind == FileKind.DIRECTORY ?
"org.freedesktop.FileManager1.ShowFolders" :
"org.freedesktop.FileManager1.ShowItems";
var dbus = String.format("""
dbus-send --session --print-reply --dest=org.freedesktop.FileManager1 --type=method_call /org/freedesktop/FileManager1 %s array:string:"file://%s" string:""
""", action, path);
sc.executeSimpleCommand(dbus);
}
case OsType.MacOs macOs -> {
sc.executeSimpleCommand(
"open " + (kind == FileKind.DIRECTORY ? "" : "-R ") + d.fileArgument(path));
}
case OsType.Bsd bsd -> {
}
case OsType.Solaris solaris -> {
} }
} }
case OsType.Linux linux -> {
var action = kind == FileKind.DIRECTORY
? "org.freedesktop.FileManager1.ShowFolders"
: "org.freedesktop.FileManager1.ShowItems";
var dbus = String.format(
"""
dbus-send --session --print-reply --dest=org.freedesktop.FileManager1 --type=method_call /org/freedesktop/FileManager1 %s array:string:"file://%s" string:""
""",
action, path);
sc.executeSimpleCommand(dbus);
}
case OsType.MacOs macOs -> {
sc.executeSimpleCommand("open " + (kind == FileKind.DIRECTORY ? "" : "-R ") + d.fileArgument(path));
}
case OsType.Bsd bsd -> {}
case OsType.Solaris solaris -> {}
}
} }
public static void browsePathLocal(Path file) { public static void browsePathLocal(Path file) {

View file

@ -32,7 +32,7 @@ public class TerminalLauncher {
title, title,
type.shouldClear() type.shouldClear()
&& AppPrefs.get().clearTerminalOnInit().get(), && AppPrefs.get().clearTerminalOnInit().get(),
TerminalInitFunction.none()), TerminalInitFunction.none()),
true); true);
var config = new ExternalTerminalType.LaunchConfiguration(null, title, title, script, sc.getShellDialect()); var config = new ExternalTerminalType.LaunchConfiguration(null, title, title, script, sc.getShellDialect());
type.launch(config); type.launch(config);

View file

@ -1,11 +1,12 @@
package io.xpipe.app.util; package io.xpipe.app.util;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;
import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.process.CommandBuilder; import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.ShellControl;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.WinReg;
import java.util.Optional; import java.util.Optional;
public class WindowsRegistry { public class WindowsRegistry {
@ -56,7 +57,8 @@ public class WindowsRegistry {
} }
} }
public static Optional<String> findRemoteValuesRecursive(ShellControl shellControl, int hkey, String key, String valueName) throws Exception { public static Optional<String> findRemoteValuesRecursive(
ShellControl shellControl, int hkey, String key, String valueName) throws Exception {
var command = CommandBuilder.of() var command = CommandBuilder.of()
.add("reg", "query") .add("reg", "query")
.addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key) .addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key)

View file

@ -1,7 +1,6 @@
package io.xpipe.core.store; package io.xpipe.core.store;
public interface SingletonSessionStore<T extends Session> public interface SingletonSessionStore<T extends Session> extends ExpandedLifecycleStore, InternalCacheDataStore {
extends ExpandedLifecycleStore, InternalCacheDataStore {
@Override @Override
default void finalizeValidate() throws Exception { default void finalizeValidate() throws Exception {

View file

@ -21,7 +21,8 @@ public interface StatefulDataStore<T extends DataStoreState> extends DataStore {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
default T getState() { default T getState() {
return (T) DataStateProvider.get().getState(this, this::createDefaultState).deepCopy(); return (T)
DataStateProvider.get().getState(this, this::createDefaultState).deepCopy();
} }
default void setState(T val) { default void setState(T val) {

View file

@ -1,6 +1,5 @@
package io.xpipe.core.util; package io.xpipe.core.util;
import com.fasterxml.jackson.databind.*;
import io.xpipe.core.dialog.BaseQueryElement; import io.xpipe.core.dialog.BaseQueryElement;
import io.xpipe.core.dialog.BusyElement; import io.xpipe.core.dialog.BusyElement;
import io.xpipe.core.dialog.ChoiceElement; import io.xpipe.core.dialog.ChoiceElement;
@ -14,6 +13,7 @@ import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.jsontype.NamedType; import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.module.SimpleModule;

View file

@ -8,8 +8,10 @@ import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.core.process.ShellStoreState; import io.xpipe.core.process.ShellStoreState;
import io.xpipe.core.store.ShellStore; import io.xpipe.core.store.ShellStore;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import lombok.Value; import lombok.Value;
public class BrowseStoreAction implements ActionProvider { public class BrowseStoreAction implements ActionProvider {
@ -22,8 +24,8 @@ public class BrowseStoreAction implements ActionProvider {
public boolean isApplicable(DataStoreEntryRef<ShellStore> o) { public boolean isApplicable(DataStoreEntryRef<ShellStore> o) {
var state = o.get().getStorePersistentState(); var state = o.get().getStorePersistentState();
if (state instanceof ShellStoreState shellStoreState) { if (state instanceof ShellStoreState shellStoreState) {
return shellStoreState.getShellDialect() == null || return shellStoreState.getShellDialect() == null
shellStoreState.getShellDialect().getDumbMode().supportsAnyPossibleInteraction(); || shellStoreState.getShellDialect().getDumbMode().supportsAnyPossibleInteraction();
} else { } else {
return true; return true;
} }

View file

@ -43,8 +43,9 @@ public class LaunchAction implements ActionProvider {
@Override @Override
public boolean isApplicable(DataStoreEntryRef<DataStore> o) { public boolean isApplicable(DataStoreEntryRef<DataStore> o) {
return o.get().getValidity().isUsable() && (o.getStore() instanceof LaunchableStore || o.get().getProvider().launchAction(o.get()) != return o.get().getValidity().isUsable()
null); && (o.getStore() instanceof LaunchableStore
|| o.get().getProvider().launchAction(o.get()) != null);
} }
@Override @Override
@ -75,8 +76,9 @@ public class LaunchAction implements ActionProvider {
@Override @Override
public boolean isApplicable(DataStoreEntryRef<DataStore> o) { public boolean isApplicable(DataStoreEntryRef<DataStore> o) {
return o.get().getValidity().isUsable() && (o.getStore() instanceof LaunchableStore || o.get().getProvider().launchAction(o.get()) != return o.get().getValidity().isUsable()
null); && (o.getStore() instanceof LaunchableStore
|| o.get().getProvider().launchAction(o.get()) != null);
} }
}; };
} }

View file

@ -7,7 +7,9 @@ import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.ScanAlert; import io.xpipe.app.util.ScanAlert;
import io.xpipe.core.process.ShellStoreState; import io.xpipe.core.process.ShellStoreState;
import io.xpipe.core.store.ShellStore; import io.xpipe.core.store.ShellStore;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import lombok.Value; import lombok.Value;
public class ScanAction implements ActionProvider { public class ScanAction implements ActionProvider {
@ -39,8 +41,8 @@ public class ScanAction implements ActionProvider {
var state = o.get().getStorePersistentState(); var state = o.get().getStorePersistentState();
if (state instanceof ShellStoreState shellStoreState) { if (state instanceof ShellStoreState shellStoreState) {
return shellStoreState.getShellDialect() == null || return shellStoreState.getShellDialect() == null
shellStoreState.getShellDialect().getDumbMode().supportsAnyPossibleInteraction(); || shellStoreState.getShellDialect().getDumbMode().supportsAnyPossibleInteraction();
} else { } else {
return true; return true;
} }

View file

@ -8,6 +8,7 @@ import io.xpipe.app.util.DesktopHelper;
import io.xpipe.app.util.LocalShell; import io.xpipe.app.util.LocalShell;
import io.xpipe.core.process.OsType; import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.ShellControl;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import java.util.List; import java.util.List;
@ -21,7 +22,8 @@ public class BrowseInNativeManagerAction implements LeafAction {
var e = entry.getRawFileEntry().getPath(); var e = entry.getRawFileEntry().getPath();
var localFile = sc.getLocalSystemAccess().translateToLocalSystemPath(e); var localFile = sc.getLocalSystemAccess().translateToLocalSystemPath(e);
try (var local = LocalShell.getShell().start()) { try (var local = LocalShell.getShell().start()) {
DesktopHelper.browsePathRemote(local,localFile, entry.getRawFileEntry().getKind()); DesktopHelper.browsePathRemote(
local, localFile, entry.getRawFileEntry().getKind());
} }
} }
} }

View file

@ -9,6 +9,7 @@ import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.TerminalLauncher; import io.xpipe.app.util.TerminalLauncher;
import io.xpipe.core.process.CommandBuilder; import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.ShellControl; import io.xpipe.core.process.ShellControl;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import java.util.List; import java.util.List;

View file

@ -74,7 +74,8 @@ public class DesktopCommandStoreProvider implements DataStoreProvider {
entry, entry,
env, env,
DesktopEnvironmentStore.class, DesktopEnvironmentStore.class,
desktopStoreDataStoreEntryRef -> desktopStoreDataStoreEntryRef.getStore().supportsDesktopAccess(), desktopStoreDataStoreEntryRef ->
desktopStoreDataStoreEntryRef.getStore().supportsDesktopAccess(),
StoreViewState.get().getAllConnectionsCategory()), StoreViewState.get().getAllConnectionsCategory()),
env) env)
.nonNull() .nonNull()

View file

@ -95,9 +95,9 @@ public class DesktopEnvironmentStore extends JacksonizedValue
: getMergedInitCommands(null)); : getMergedInitCommands(null));
var scriptFile = base.getStore().createScript(dialect, toExecute); var scriptFile = base.getStore().createScript(dialect, toExecute);
var launchScriptFile = base.getStore() var launchScriptFile = base.getStore()
.createScript(dialect, dialect.prepareTerminalInitFileOpenCommand(dialect, null, scriptFile.toString())); .createScript(
var launchConfig = dialect, dialect.prepareTerminalInitFileOpenCommand(dialect, null, scriptFile.toString()));
new ExternalTerminalType.LaunchConfiguration(null, name, name, launchScriptFile, dialect); var launchConfig = new ExternalTerminalType.LaunchConfiguration(null, name, name, launchScriptFile, dialect);
base.getStore().runDesktopScript(name, launchCommand.apply(launchConfig)); base.getStore().runDesktopScript(name, launchCommand.apply(launchConfig));
} }

View file

@ -127,7 +127,9 @@ public class DesktopEnvironmentStoreProvider implements DataStoreProvider {
.nonNull() .nonNull()
.nameAndDescription("desktopTerminal") .nameAndDescription("desktopTerminal")
.addComp( .addComp(
ChoiceComp.ofTranslatable(terminal, ExternalTerminalType.getTypes(st.getUsedOsType(), true, false), true).maxWidth(2000), ChoiceComp.ofTranslatable(
terminal, ExternalTerminalType.getTypes(st.getUsedOsType(), true, false), true)
.maxWidth(2000),
terminal) terminal)
.nonNull() .nonNull()
.nameAndDescription("desktopShellDialect") .nameAndDescription("desktopShellDialect")

View file

@ -29,17 +29,19 @@ public class ScriptGroupStoreProvider implements DataStoreProvider {
return new DenseStoreEntryComp(sec.getWrapper(), true, null); return new DenseStoreEntryComp(sec.getWrapper(), true, null);
} }
var def = StoreToggleComp.<ScriptGroupStore>simpleToggle("base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> { var def = StoreToggleComp.<ScriptGroupStore>simpleToggle(
var state = s.getState(); "base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> {
state.setDefault(aBoolean); var state = s.getState();
s.setState(state); state.setDefault(aBoolean);
}); s.setState(state);
});
var bring = StoreToggleComp.<ScriptGroupStore>simpleToggle("base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> { var bring = StoreToggleComp.<ScriptGroupStore>simpleToggle(
var state = s.getState(); "base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> {
state.setBringToShell(aBoolean); var state = s.getState();
s.setState(state); state.setBringToShell(aBoolean);
}); s.setState(state);
});
var dropdown = new DropdownComp(List.of(def, bring)); var dropdown = new DropdownComp(List.of(def, bring));
return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown); return new DenseStoreEntryComp(sec.getWrapper(), true, dropdown);

View file

@ -54,17 +54,19 @@ public class SimpleScriptStoreProvider implements DataStoreProvider {
return new DenseStoreEntryComp(sec.getWrapper(), true, null); return new DenseStoreEntryComp(sec.getWrapper(), true, null);
} }
var def = StoreToggleComp.<SimpleScriptStore>simpleToggle("base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> { var def = StoreToggleComp.<SimpleScriptStore>simpleToggle(
var state = s.getState(); "base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> {
state.setDefault(aBoolean); var state = s.getState();
s.setState(state); state.setDefault(aBoolean);
}); s.setState(state);
});
var bring = StoreToggleComp.<SimpleScriptStore>simpleToggle("base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> { var bring = StoreToggleComp.<SimpleScriptStore>simpleToggle(
var state = s.getState(); "base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> {
state.setBringToShell(aBoolean); var state = s.getState();
s.setState(state); state.setBringToShell(aBoolean);
}); s.setState(state);
});
SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded(); SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded();
var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry()); var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry());
@ -136,7 +138,8 @@ public class SimpleScriptStoreProvider implements DataStoreProvider {
var group = new SimpleObjectProperty<>(st.getGroup()); var group = new SimpleObjectProperty<>(st.getGroup());
Property<ShellDialect> dialect = new SimpleObjectProperty<>(st.getMinimumDialect()); Property<ShellDialect> dialect = new SimpleObjectProperty<>(st.getMinimumDialect());
var others = new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>(st.getEffectiveScripts()))); var others =
new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>(st.getEffectiveScripts())));
Property<String> commandProp = new SimpleObjectProperty<>(st.getCommands()); Property<String> commandProp = new SimpleObjectProperty<>(st.getCommands());
Comp<?> choice = (Comp<?>) Class.forName( Comp<?> choice = (Comp<?>) Class.forName(
@ -268,9 +271,7 @@ public class SimpleScriptStoreProvider implements DataStoreProvider {
@Override @Override
public DataStore defaultStore() { public DataStore defaultStore() {
return SimpleScriptStore.builder() return SimpleScriptStore.builder().scripts(List.of()).build();
.scripts(List.of())
.build();
} }
@Override @Override