mirror of
https://github.com/xpipe-io/xpipe.git
synced 2025-04-18 10:13:38 +00:00
Format
This commit is contained in:
parent
fec34c2f70
commit
7337eaf8c3
122 changed files with 624 additions and 486 deletions
|
@ -15,9 +15,10 @@ public class CategoryAddExchangeImpl extends CategoryAddExchange {
|
|||
throw new BeaconClientException("Parent category with id " + msg.getParent() + " does not exist");
|
||||
}
|
||||
|
||||
var found = DataStorage.get().getStoreCategories().stream().filter(
|
||||
dataStoreCategory -> msg.getParent().equals(dataStoreCategory.getParentCategory()) &&
|
||||
msg.getName().equals(dataStoreCategory.getName())).findAny();
|
||||
var found = DataStorage.get().getStoreCategories().stream()
|
||||
.filter(dataStoreCategory -> msg.getParent().equals(dataStoreCategory.getParentCategory())
|
||||
&& msg.getName().equals(dataStoreCategory.getName()))
|
||||
.findAny();
|
||||
if (found.isPresent()) {
|
||||
return Response.builder().category(found.get().getUuid()).build();
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@ package io.xpipe.app.beacon.impl;
|
|||
|
||||
import io.xpipe.app.beacon.AppBeaconServer;
|
||||
import io.xpipe.app.beacon.BlobManager;
|
||||
import io.xpipe.app.ext.ConnectionFileSystem;
|
||||
import io.xpipe.app.util.FixedSizeInputStream;
|
||||
import io.xpipe.beacon.BeaconClientException;
|
||||
import io.xpipe.beacon.api.FsReadExchange;
|
||||
import io.xpipe.app.ext.ConnectionFileSystem;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import lombok.SneakyThrows;
|
||||
|
|
|
@ -2,8 +2,8 @@ package io.xpipe.app.beacon.impl;
|
|||
|
||||
import io.xpipe.app.beacon.AppBeaconServer;
|
||||
import io.xpipe.app.beacon.BlobManager;
|
||||
import io.xpipe.beacon.api.FsWriteExchange;
|
||||
import io.xpipe.app.ext.ConnectionFileSystem;
|
||||
import io.xpipe.beacon.api.FsWriteExchange;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import lombok.SneakyThrows;
|
||||
|
|
|
@ -7,7 +7,6 @@ import io.xpipe.app.util.BooleanScope;
|
|||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.util.FileReference;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
import io.xpipe.core.util.FailableFunction;
|
||||
|
|
|
@ -10,7 +10,6 @@ import io.xpipe.app.storage.DataStorage;
|
|||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
import io.xpipe.core.util.FailableFunction;
|
||||
|
|
|
@ -4,7 +4,6 @@ import io.xpipe.app.browser.icon.BrowserIconDirectoryType;
|
|||
import io.xpipe.app.browser.icon.BrowserIconFileType;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import io.xpipe.core.process.OsType;
|
|||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileInfo;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
|
|
@ -294,7 +294,8 @@ public class BrowserFileListCompEntry {
|
|||
return;
|
||||
}
|
||||
|
||||
model.getFileSystemModel().cdAsync(item.getRawFileEntry().getPath().toString());
|
||||
model.getFileSystemModel()
|
||||
.cdAsync(item.getRawFileEntry().getPath().toString());
|
||||
}
|
||||
};
|
||||
DROP_TIMER.schedule(activeTask, 1200);
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.app.prefs.AppPrefs;
|
|||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
@ -66,7 +65,10 @@ public final class BrowserFileListModel {
|
|||
List<BrowserEntry> filtered = fileSystemModel.getFilter().getValue() != null
|
||||
? all.getValue().stream()
|
||||
.filter(entry -> {
|
||||
var name = entry.getRawFileEntry().getPath().getFileName().toLowerCase(Locale.ROOT);
|
||||
var name = entry.getRawFileEntry()
|
||||
.getPath()
|
||||
.getFileName()
|
||||
.toLowerCase(Locale.ROOT);
|
||||
var filterString =
|
||||
fileSystemModel.getFilter().getValue().toLowerCase(Locale.ROOT);
|
||||
return name.contains(filterString);
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.ext.ConnectionFileSystem;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.FileBridge;
|
||||
import io.xpipe.app.util.FileOpener;
|
||||
import io.xpipe.core.process.ElevationFunction;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.app.ext.ConnectionFileSystem;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileInfo;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ import io.xpipe.app.comp.base.*;
|
|||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.util.InputHelper;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
|
|
|
@ -299,7 +299,10 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
|
|||
}
|
||||
|
||||
// Handle commands typed into navigation bar
|
||||
if (customInput && !evaluatedPath.isBlank() && !FileNames.isAbsolute(evaluatedPath) && fileSystem.getShell().isPresent()) {
|
||||
if (customInput
|
||||
&& !evaluatedPath.isBlank()
|
||||
&& !FileNames.isAbsolute(evaluatedPath)
|
||||
&& fileSystem.getShell().isPresent()) {
|
||||
var directory = currentPath.get();
|
||||
var name = adjustedPath + " - " + entry.get().getName();
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
|
|
|
@ -223,8 +223,7 @@ public class BrowserFileTransferOperation {
|
|||
if (matcher.matches()) {
|
||||
try {
|
||||
var number = Integer.parseInt(matcher.group(2));
|
||||
var newFile =
|
||||
target.getParent().join(matcher.group(1) + " (" + (number + 1) + ")." + matcher.group(3));
|
||||
var newFile = target.getParent().join(matcher.group(1) + " (" + (number + 1) + ")." + matcher.group(3));
|
||||
return newFile;
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
|
|
@ -169,7 +169,9 @@ public class BrowserHistoryTabComp extends SimpleComp {
|
|||
var name = Bindings.createStringBinding(
|
||||
() -> {
|
||||
var n = e.getPath();
|
||||
return AppPrefs.get().censorMode().get() ? "*".repeat(n.toString().length()) : n.toString();
|
||||
return AppPrefs.get().censorMode().get()
|
||||
? "*".repeat(n.toString().length())
|
||||
: n.toString();
|
||||
},
|
||||
AppPrefs.get().censorMode());
|
||||
return new ButtonComp(name, () -> {
|
||||
|
|
|
@ -11,7 +11,6 @@ import io.xpipe.app.comp.base.TooltipAugment;
|
|||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.app.browser.icon;
|
|||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
|
@ -38,7 +37,8 @@ public abstract class BrowserIconDirectoryType {
|
|||
|
||||
@Override
|
||||
public boolean matches(FileEntry entry) {
|
||||
return entry.getPath().toString().equals("/") || entry.getPath().toString().matches("\\w:\\\\");
|
||||
return entry.getPath().toString().equals("/")
|
||||
|| entry.getPath().toString().matches("\\w:\\\\");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.app.browser.icon;
|
|||
import io.xpipe.app.resources.AppResources;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
|
|
|
@ -6,12 +6,11 @@ import io.xpipe.app.comp.SimpleCompStructure;
|
|||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.value.ObservableIntegerValue;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.OverrunStyle;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
@ -28,15 +27,17 @@ public class CountComp extends Comp<CompStructure<Label>> {
|
|||
var label = new Label();
|
||||
label.setTextOverrun(OverrunStyle.CLIP);
|
||||
label.setAlignment(Pos.CENTER);
|
||||
var binding = Bindings.createStringBinding(() -> {
|
||||
if (sub.get() == all.get()) {
|
||||
return transformation.apply(all.get() + "");
|
||||
} else {
|
||||
return transformation.apply(sub.get() + "/" + all.get());
|
||||
}
|
||||
}, sub, all);
|
||||
label.textProperty()
|
||||
.bind(PlatformThread.sync(binding));
|
||||
var binding = Bindings.createStringBinding(
|
||||
() -> {
|
||||
if (sub.get() == all.get()) {
|
||||
return transformation.apply(all.get() + "");
|
||||
} else {
|
||||
return transformation.apply(sub.get() + "/" + all.get());
|
||||
}
|
||||
},
|
||||
sub,
|
||||
all);
|
||||
label.textProperty().bind(PlatformThread.sync(binding));
|
||||
label.getStyleClass().add("count-comp");
|
||||
return new SimpleCompStructure<>(label);
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ import io.xpipe.app.comp.CompStructure;
|
|||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.FileOpener;
|
||||
|
||||
import io.xpipe.core.process.ShellScript;
|
||||
import io.xpipe.core.process.ShellStoreState;
|
||||
import io.xpipe.core.store.StatefulDataStore;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
|
@ -27,24 +27,27 @@ import java.nio.file.Files;
|
|||
|
||||
public class IntegratedTextAreaComp extends Comp<IntegratedTextAreaComp.Structure> {
|
||||
|
||||
public static IntegratedTextAreaComp script(ObservableValue<DataStoreEntryRef<ShellStore>> host, Property<ShellScript> value) {
|
||||
var string = new SimpleStringProperty(value.getValue() != null ? value.getValue().getValue() : null);
|
||||
public static IntegratedTextAreaComp script(
|
||||
ObservableValue<DataStoreEntryRef<ShellStore>> host, Property<ShellScript> value) {
|
||||
var string = new SimpleStringProperty(
|
||||
value.getValue() != null ? value.getValue().getValue() : null);
|
||||
string.addListener((observable, oldValue, newValue) -> {
|
||||
value.setValue(newValue != null ? new ShellScript(newValue) : null);
|
||||
});
|
||||
var i = new IntegratedTextAreaComp(
|
||||
string,
|
||||
false,
|
||||
"script",
|
||||
Bindings.createStringBinding(
|
||||
() -> {
|
||||
return host.getValue() != null && host.getValue().getStore() instanceof StatefulDataStore<?> sd &&
|
||||
sd.getState() instanceof ShellStoreState sss && sss.getShellDialect() != null
|
||||
? sss.getShellDialect()
|
||||
.getScriptFileEnding()
|
||||
: "sh";
|
||||
},
|
||||
host));
|
||||
string,
|
||||
false,
|
||||
"script",
|
||||
Bindings.createStringBinding(
|
||||
() -> {
|
||||
return host.getValue() != null
|
||||
&& host.getValue().getStore() instanceof StatefulDataStore<?> sd
|
||||
&& sd.getState() instanceof ShellStoreState sss
|
||||
&& sss.getShellDialect() != null
|
||||
? sss.getShellDialect().getScriptFileEnding()
|
||||
: "sh";
|
||||
},
|
||||
host));
|
||||
i.minHeight(60);
|
||||
i.prefHeight(60);
|
||||
i.maxHeight(60);
|
||||
|
|
|
@ -91,7 +91,8 @@ public class ListSelectorComp<T> extends SimpleComp {
|
|||
|
||||
if (showAllSelector.get()) {
|
||||
var allSelector = new CheckBox(null);
|
||||
allSelector.setSelected(currentVals.stream().filter(t -> !disable.test(t)).count() == selected.size());
|
||||
allSelector.setSelected(
|
||||
currentVals.stream().filter(t -> !disable.test(t)).count() == selected.size());
|
||||
allSelector.selectedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
cbs.forEach(checkBox -> {
|
||||
if (checkBox.isDisabled()) {
|
||||
|
|
|
@ -5,16 +5,17 @@ import io.xpipe.app.comp.CompStructure;
|
|||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ScrollBar;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.skin.VirtualFlow;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -55,7 +56,6 @@ public class ListVirtualViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
|||
vbox.getStyleClass().add("list-box-content");
|
||||
vbox.setFocusTraversable(false);
|
||||
|
||||
|
||||
var scroll = new ScrollPane(vbox);
|
||||
if (scrollBar) {
|
||||
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
|
||||
|
|
|
@ -21,7 +21,6 @@ import javafx.scene.control.ButtonBar;
|
|||
import javafx.scene.control.Label;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
@ -47,7 +46,8 @@ public class ModalOverlayComp extends SimpleComp {
|
|||
var bgRegion = background.createRegion();
|
||||
var modal = new ModalPane();
|
||||
modal.setInTransitionFactory(null);
|
||||
modal.setOutTransitionFactory(OsType.getLocal() == OsType.LINUX ? null : node -> Animations.fadeOut(node, Duration.millis(50)));
|
||||
modal.setOutTransitionFactory(
|
||||
OsType.getLocal() == OsType.LINUX ? null : node -> Animations.fadeOut(node, Duration.millis(50)));
|
||||
modal.focusedProperty().addListener((observable, oldValue, newValue) -> {
|
||||
var c = modal.getContent();
|
||||
if (newValue && c != null) {
|
||||
|
@ -228,13 +228,14 @@ public class ModalOverlayComp extends SimpleComp {
|
|||
var busy = mocc.busy();
|
||||
if (busy != null) {
|
||||
var loading = LoadingOverlayComp.noProgress(Comp.of(() -> modalBox), busy);
|
||||
// loading.apply(struc -> {
|
||||
// var bg = struc.get().getChildren().getFirst();
|
||||
// struc.get().getChildren().get(1).addEventFilter(MouseEvent.MOUSE_PRESSED, event -> {
|
||||
// bg.fireEvent(event);
|
||||
// event.consume();
|
||||
// });
|
||||
// });
|
||||
// loading.apply(struc -> {
|
||||
// var bg = struc.get().getChildren().getFirst();
|
||||
// struc.get().getChildren().get(1).addEventFilter(MouseEvent.MOUSE_PRESSED, event ->
|
||||
// {
|
||||
// bg.fireEvent(event);
|
||||
// event.consume();
|
||||
// });
|
||||
// });
|
||||
return loading.createRegion();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import io.xpipe.app.storage.DataStorage;
|
|||
import io.xpipe.app.storage.DataStoreCategory;
|
||||
import io.xpipe.app.util.ClipboardHelper;
|
||||
import io.xpipe.app.util.ContextMenuHelper;
|
||||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
@ -118,7 +117,10 @@ public class StoreCategoryComp extends SimpleComp {
|
|||
}))
|
||||
.styleClass("status-button");
|
||||
|
||||
var count = new CountComp(category.getShownContainedEntriesCount(), category.getAllContainedEntriesCount(), string -> "(" + string + ")");
|
||||
var count = new CountComp(
|
||||
category.getShownContainedEntriesCount(),
|
||||
category.getAllContainedEntriesCount(),
|
||||
string -> "(" + string + ")");
|
||||
count.visible(Bindings.notEqual(0, category.getShownContainedEntriesCount()));
|
||||
|
||||
var showStatus = hover.or(new SimpleBooleanProperty(DataStorage.get().supportsSharing()))
|
||||
|
@ -134,7 +136,8 @@ public class StoreCategoryComp extends SimpleComp {
|
|||
statusButton.hide(showStatus.not())));
|
||||
h.padding(new Insets(0, 10, 0, (category.getDepth() * 10)));
|
||||
|
||||
var categoryButton = new ButtonComp(null, new SimpleObjectProperty<>(new LabelGraphic.CompGraphic(h)), category::select)
|
||||
var categoryButton = new ButtonComp(
|
||||
null, new SimpleObjectProperty<>(new LabelGraphic.CompGraphic(h)), category::select)
|
||||
.focusTraversable()
|
||||
.styleClass("category-button")
|
||||
.apply(struc -> hover.bind(struc.get().hoverProperty()))
|
||||
|
|
|
@ -10,7 +10,6 @@ import io.xpipe.app.util.PlatformThread;
|
|||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ObservableNumberValue;
|
||||
import javafx.beans.value.ObservableStringValue;
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
|
@ -185,17 +184,22 @@ public class StoreCategoryWrapper {
|
|||
.equals(storeCategoryWrapper.getCategory().getParentCategory()))
|
||||
.toList());
|
||||
var direct = directContainedEntries.getList().size();
|
||||
var sub = children.getList().stream().mapToInt(value -> value.allContainedEntriesCount.get()).sum();
|
||||
var sub = children.getList().stream()
|
||||
.mapToInt(value -> value.allContainedEntriesCount.get())
|
||||
.sum();
|
||||
allContainedEntriesCount.setValue(direct + sub);
|
||||
|
||||
var directFiltered = directContainedEntries.getList().stream().filter(storeEntryWrapper ->
|
||||
storeEntryWrapper.matchesFilter(StoreViewState.get().getFilterString().getValue())).count();
|
||||
var subFiltered = children.getList().stream().mapToInt(value -> value.shownContainedEntriesCount.get()).sum();
|
||||
var directFiltered = directContainedEntries.getList().stream()
|
||||
.filter(storeEntryWrapper -> storeEntryWrapper.matchesFilter(
|
||||
StoreViewState.get().getFilterString().getValue()))
|
||||
.count();
|
||||
var subFiltered = children.getList().stream()
|
||||
.mapToInt(value -> value.shownContainedEntriesCount.get())
|
||||
.sum();
|
||||
shownContainedEntriesCount.setValue(directFiltered + subFiltered);
|
||||
Optional.ofNullable(getParent()).ifPresent(storeCategoryWrapper -> {
|
||||
storeCategoryWrapper.update();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private String translatedName(String original) {
|
||||
|
|
|
@ -449,8 +449,13 @@ public class StoreCreationComp extends DialogComp {
|
|||
|
||||
private Region createStoreProperties(Comp<?> comp, Validator propVal) {
|
||||
var p = provider.getValue();
|
||||
var nameKey = p == null || p.getCreationCategory() == null || p.getCreationCategory().getCategory().equals(DataStorage.ALL_CONNECTIONS_CATEGORY_UUID) ?
|
||||
"connection" : p.getCreationCategory().getCategory().equals(DataStorage.ALL_SCRIPTS_CATEGORY_UUID) ? "script" : "identity";
|
||||
var nameKey = p == null
|
||||
|| p.getCreationCategory() == null
|
||||
|| p.getCreationCategory().getCategory().equals(DataStorage.ALL_CONNECTIONS_CATEGORY_UUID)
|
||||
? "connection"
|
||||
: p.getCreationCategory().getCategory().equals(DataStorage.ALL_SCRIPTS_CATEGORY_UUID)
|
||||
? "script"
|
||||
: "identity";
|
||||
return new OptionsBuilder()
|
||||
.addComp(comp, store)
|
||||
.name(nameKey + "Name")
|
||||
|
|
|
@ -8,7 +8,6 @@ import io.xpipe.app.storage.DataColor;
|
|||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreCategory;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
@ -16,7 +15,6 @@ import io.xpipe.core.store.SingletonSessionStore;
|
|||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ObservableStringValue;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
|
@ -186,7 +184,7 @@ public class StoreEntryWrapper {
|
|||
validity.setValue(entry.getValidity());
|
||||
expanded.setValue(entry.isExpanded());
|
||||
persistentState.setValue(entry.getStorePersistentState());
|
||||
|
||||
|
||||
// The property values are only registered as changed once they are queried
|
||||
// If we use information bindings that depend on some of these properties
|
||||
// but use the store methods to retrieve data instead of the wrapper properties,
|
||||
|
|
|
@ -1,31 +1,26 @@
|
|||
package io.xpipe.app.comp.store;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.*;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.icon.SystemIcon;
|
||||
|
||||
import io.xpipe.app.icon.SystemIconCache;
|
||||
import io.xpipe.app.icon.SystemIconManager;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import javafx.application.Platform;
|
||||
|
||||
import javafx.beans.property.*;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import atlantafx.base.theme.Tweaks;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import atlantafx.base.theme.Tweaks;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static atlantafx.base.theme.Styles.TEXT_SMALL;
|
||||
|
@ -40,7 +35,8 @@ public class StoreIconChoiceComp extends SimpleComp {
|
|||
private final Runnable doubleClick;
|
||||
|
||||
public StoreIconChoiceComp(
|
||||
Runnable reshow, Property<SystemIcon> selected,
|
||||
Runnable reshow,
|
||||
Property<SystemIcon> selected,
|
||||
Set<SystemIcon> icons,
|
||||
int columns,
|
||||
SimpleStringProperty filter,
|
||||
|
@ -83,17 +79,23 @@ public class StoreIconChoiceComp extends SimpleComp {
|
|||
table.getStyleClass().add("icon-browser");
|
||||
|
||||
var busy = new SimpleBooleanProperty(false);
|
||||
var refreshButton = new ButtonComp(AppI18n.observable("refreshIcons"), new SimpleObjectProperty<>(new LabelGraphic.IconGraphic("mdi2r-refresh")), () -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
try (var ignored = new BooleanScope(busy).start()) {
|
||||
SystemIconManager.reload();
|
||||
}
|
||||
reshow.run();
|
||||
});
|
||||
});
|
||||
var refreshButton = new ButtonComp(
|
||||
AppI18n.observable("refreshIcons"),
|
||||
new SimpleObjectProperty<>(new LabelGraphic.IconGraphic("mdi2r-refresh")),
|
||||
() -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
try (var ignored = new BooleanScope(busy).start()) {
|
||||
SystemIconManager.reload();
|
||||
}
|
||||
reshow.run();
|
||||
});
|
||||
});
|
||||
refreshButton.disable(busy);
|
||||
var text = new LabelComp(AppI18n.observable("refreshIconsDescription", SystemIconManager.getSources().values().stream()
|
||||
.mapToInt(value -> value.getIcons().size()).sum()));
|
||||
var text = new LabelComp(AppI18n.observable(
|
||||
"refreshIconsDescription",
|
||||
SystemIconManager.getSources().values().stream()
|
||||
.mapToInt(value -> value.getIcons().size())
|
||||
.sum()));
|
||||
text.apply(struc -> {
|
||||
struc.get().setWrapText(true);
|
||||
struc.get().setTextAlignment(TextAlignment.CENTER);
|
||||
|
@ -109,7 +111,9 @@ public class StoreIconChoiceComp extends SimpleComp {
|
|||
|
||||
private void updateData(TableView<List<SystemIcon>> table, String filterString) {
|
||||
var displayedIcons = filterString == null || filterString.isBlank() || filterString.length() < 2
|
||||
? icons.stream().sorted(Comparator.<SystemIcon, String>comparing(systemIcon -> systemIcon.getId())).toList()
|
||||
? icons.stream()
|
||||
.sorted(Comparator.<SystemIcon, String>comparing(systemIcon -> systemIcon.getId()))
|
||||
.toList()
|
||||
: icons.stream()
|
||||
.filter(icon -> containsString(icon.getId(), filterString))
|
||||
.toList();
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.app.icon.SystemIcon;
|
|||
import io.xpipe.app.icon.SystemIconManager;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
|
@ -38,21 +37,27 @@ public class StoreIconChoiceDialog {
|
|||
var filter = new FilterComp(filterText).grow(true, false);
|
||||
filter.focusOnShow();
|
||||
var github = new ButtonComp(null, new FontIcon("mdomz-settings"), () -> {
|
||||
overlay.close();
|
||||
AppPrefs.get().selectCategory("icons");
|
||||
overlay.close();
|
||||
AppPrefs.get().selectCategory("icons");
|
||||
})
|
||||
.grow(false, true);
|
||||
var modal = ModalOverlay.of(
|
||||
"chooseCustomIcon",
|
||||
new StoreIconChoiceComp(() -> {
|
||||
var showing = overlay.isShowing();
|
||||
overlay.close();
|
||||
if (showing) {
|
||||
Platform.runLater(() -> overlay.show());
|
||||
}
|
||||
}, selected, SystemIconManager.getIcons(), 5, filterText, () -> {
|
||||
finish();
|
||||
})
|
||||
new StoreIconChoiceComp(
|
||||
() -> {
|
||||
var showing = overlay.isShowing();
|
||||
overlay.close();
|
||||
if (showing) {
|
||||
Platform.runLater(() -> overlay.show());
|
||||
}
|
||||
},
|
||||
selected,
|
||||
SystemIconManager.getIcons(),
|
||||
5,
|
||||
filterText,
|
||||
() -> {
|
||||
finish();
|
||||
})
|
||||
.prefWidth(600));
|
||||
modal.addButtonBarComp(github);
|
||||
modal.addButtonBarComp(filter);
|
||||
|
@ -72,7 +77,12 @@ public class StoreIconChoiceDialog {
|
|||
}
|
||||
|
||||
private void finish() {
|
||||
entry.setIcon(selected.get() != null ? selected.getValue().getSource().getId() + "/" + selected.getValue().getId() : null, true);
|
||||
entry.setIcon(
|
||||
selected.get() != null
|
||||
? selected.getValue().getSource().getId() + "/"
|
||||
+ selected.getValue().getId()
|
||||
: null,
|
||||
true);
|
||||
overlay.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,9 +85,8 @@ public class StoreSection {
|
|||
}
|
||||
});
|
||||
var comp = explicitOrderComp;
|
||||
var mappedSortMode = BindingsHelper.flatMap(
|
||||
category,
|
||||
storeCategoryWrapper -> storeCategoryWrapper.getSortMode());
|
||||
var mappedSortMode =
|
||||
BindingsHelper.flatMap(category, storeCategoryWrapper -> storeCategoryWrapper.getSortMode());
|
||||
return list.sorted(
|
||||
(o1, o2) -> {
|
||||
var r = comp.compare(o1, o2);
|
||||
|
@ -114,7 +113,8 @@ public class StoreSection {
|
|||
ObservableIntegerValue updateObservable) {
|
||||
var topLevel = all.filtered(
|
||||
section -> {
|
||||
return DataStorage.get().isRootEntry(section.getEntry(), category.getValue().getCategory());
|
||||
return DataStorage.get()
|
||||
.isRootEntry(section.getEntry(), category.getValue().getCategory());
|
||||
},
|
||||
category,
|
||||
updateObservable);
|
||||
|
@ -200,7 +200,10 @@ public class StoreSection {
|
|||
// If this entry is already shown as root due to a different category than parent, don't
|
||||
// show it
|
||||
// again here
|
||||
!DataStorage.get().isRootEntry(section.getWrapper().getEntry(), category.getValue().getCategory());
|
||||
!DataStorage.get()
|
||||
.isRootEntry(
|
||||
section.getWrapper().getEntry(),
|
||||
category.getValue().getCategory());
|
||||
},
|
||||
category,
|
||||
filterString,
|
||||
|
|
|
@ -7,34 +7,20 @@ import io.xpipe.app.prefs.SupportedLocale;
|
|||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.PlatformState;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import lombok.Value;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AppI18n {
|
||||
|
||||
private static AppI18n INSTANCE;
|
||||
private final Property<AppI18nData> currentLanguage = new SimpleObjectProperty<>();
|
||||
private final ObservableValue<SupportedLocale> currentLocale = BindingsHelper.map(currentLanguage,appI18nData -> appI18nData.getLocale());
|
||||
private final ObservableValue<SupportedLocale> currentLocale =
|
||||
BindingsHelper.map(currentLanguage, appI18nData -> appI18nData.getLocale());
|
||||
private final Map<String, ObservableValue<String>> observableCache = new HashMap<>();
|
||||
private AppI18nData english;
|
||||
|
||||
|
@ -71,9 +57,11 @@ public class AppI18n {
|
|||
|
||||
// Don't cache vars
|
||||
if (vars.length > 0) {
|
||||
var binding = Bindings.createStringBinding(() -> {
|
||||
return getLocalised(key, vars);
|
||||
}, currentLanguage);
|
||||
var binding = Bindings.createStringBinding(
|
||||
() -> {
|
||||
return getLocalised(key, vars);
|
||||
},
|
||||
currentLanguage);
|
||||
return binding;
|
||||
}
|
||||
|
||||
|
@ -82,9 +70,11 @@ public class AppI18n {
|
|||
return found;
|
||||
}
|
||||
|
||||
var binding = Bindings.createStringBinding(() -> {
|
||||
return getLocalised(key, vars);
|
||||
}, currentLanguage);
|
||||
var binding = Bindings.createStringBinding(
|
||||
() -> {
|
||||
return getLocalised(key, vars);
|
||||
},
|
||||
currentLanguage);
|
||||
observableCache.put(key, binding);
|
||||
return binding;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.issue.ErrorEvent;
|
|||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.SupportedLocale;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
||||
import lombok.Value;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
|
@ -123,5 +124,4 @@ public class AppI18nData {
|
|||
var ending = "_" + l.toLanguageTag();
|
||||
return name.endsWith(ending);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import io.xpipe.app.browser.BrowserFullSessionComp;
|
|||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.store.StoreLayoutComp;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.prefs.AppPrefsComp;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
|
|
|
@ -6,8 +6,8 @@ import io.xpipe.app.ext.ActionProvider;
|
|||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.net.URI;
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.xpipe.app.core.window;
|
|||
|
||||
import io.xpipe.app.comp.base.AppLayoutComp;
|
||||
import io.xpipe.app.comp.base.AppMainWindowContentComp;
|
||||
import io.xpipe.app.comp.base.ModalOverlay;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
|
|
|
@ -141,7 +141,12 @@ public interface ActionProvider {
|
|||
};
|
||||
}
|
||||
|
||||
static <T extends DataStore> LeafDataStoreCallSite<T> simple(boolean major, String nameKey, String icon, Class<T> applicableClass, FailableConsumer<DataStoreEntryRef<T>, Exception> action) {
|
||||
static <T extends DataStore> LeafDataStoreCallSite<T> simple(
|
||||
boolean major,
|
||||
String nameKey,
|
||||
String icon,
|
||||
Class<T> applicableClass,
|
||||
FailableConsumer<DataStoreEntryRef<T>, Exception> action) {
|
||||
return new LeafDataStoreCallSite<T>() {
|
||||
@Override
|
||||
public boolean isMajor(DataStoreEntryRef<T> o) {
|
||||
|
|
|
@ -3,11 +3,11 @@ package io.xpipe.app.ext;
|
|||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.store.FileSystem;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
@ -29,8 +29,10 @@ public class ConnectionFileSystem implements FileSystem {
|
|||
|
||||
@Override
|
||||
public long getFileSize(FilePath file) throws Exception {
|
||||
return Long.parseLong(
|
||||
shellControl.getShellDialect().queryFileSize(shellControl, file.toString()).readStdoutOrThrow());
|
||||
return Long.parseLong(shellControl
|
||||
.getShellDialect()
|
||||
.queryFileSize(shellControl, file.toString())
|
||||
.readStdoutOrThrow());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,7 +71,8 @@ public class ConnectionFileSystem implements FileSystem {
|
|||
|
||||
@Override
|
||||
public OutputStream openOutput(FilePath file, long totalBytes) throws Exception {
|
||||
var cmd = shellControl.getShellDialect().createStreamFileWriteCommand(shellControl, file.toString(), totalBytes);
|
||||
var cmd =
|
||||
shellControl.getShellDialect().createStreamFileWriteCommand(shellControl, file.toString(), totalBytes);
|
||||
cmd.setExitTimeout(Duration.ofMillis(Long.MAX_VALUE));
|
||||
return cmd.startExternalStdin();
|
||||
}
|
||||
|
@ -167,7 +170,11 @@ public class ConnectionFileSystem implements FileSystem {
|
|||
|
||||
@Override
|
||||
public List<FilePath> listRoots() throws Exception {
|
||||
return shellControl.getShellDialect().listRoots(shellControl).map(s -> FilePath.of(s)).toList();
|
||||
return shellControl
|
||||
.getShellDialect()
|
||||
.listRoots(shellControl)
|
||||
.map(s -> FilePath.of(s))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,9 +42,7 @@ public class DataStoreProviders {
|
|||
throw new IllegalStateException("Not initialized");
|
||||
}
|
||||
|
||||
return ALL.stream()
|
||||
.filter(d -> d.getId().equalsIgnoreCase(id))
|
||||
.findAny();
|
||||
return ALL.stream().filter(d -> d.getId().equalsIgnoreCase(id)).findAny();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
package io.xpipe.app.icon;
|
||||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
|
||||
import com.github.weisj.jsvg.SVGDocument;
|
||||
import com.github.weisj.jsvg.SVGRenderingHints;
|
||||
import com.github.weisj.jsvg.attributes.ViewBox;
|
||||
import com.github.weisj.jsvg.parser.SVGLoader;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
|
@ -18,11 +17,13 @@ import java.nio.file.*;
|
|||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
public class SystemIconCache {
|
||||
|
||||
private static final Path DIRECTORY = AppProperties.get().getDataDir().resolve("cache").resolve("icons").resolve("raster");
|
||||
private static final int[] sizes = new int[]{16, 24, 40, 80};
|
||||
private static final Path DIRECTORY =
|
||||
AppProperties.get().getDataDir().resolve("cache").resolve("icons").resolve("raster");
|
||||
private static final int[] sizes = new int[] {16, 24, 40, 80};
|
||||
|
||||
@Getter
|
||||
private static boolean built = false;
|
||||
|
@ -49,11 +50,11 @@ public class SystemIconCache {
|
|||
Files.createDirectories(target);
|
||||
|
||||
for (var icon : e.getValue().getIcons()) {
|
||||
if (refreshChecksum(icon.getFile(),target,icon.getName(), icon.isDark())) {
|
||||
if (refreshChecksum(icon.getFile(), target, icon.getName(), icon.isDark())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rasterizeSizes(icon.getFile(),target,icon.getName(), icon.isDark());
|
||||
rasterizeSizes(icon.getFile(), target, icon.getName(), icon.isDark());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -110,6 +111,6 @@ public class SystemIconCache {
|
|||
g.dispose();
|
||||
|
||||
var out = dir.resolve(name + "-" + px + (dark ? "-dark" : "") + ".png");
|
||||
ImageIO.write(image,"png", out.toFile());
|
||||
ImageIO.write(image, "png", out.toFile());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ import java.util.*;
|
|||
|
||||
public class SystemIconManager {
|
||||
|
||||
private static final Path DIRECTORY = AppProperties.get().getDataDir().resolve("cache").resolve("icons").resolve("pool");
|
||||
private static final Path DIRECTORY =
|
||||
AppProperties.get().getDataDir().resolve("cache").resolve("icons").resolve("pool");
|
||||
|
||||
private static final Map<SystemIconSource, SystemIconSourceData> LOADED = new HashMap<>();
|
||||
private static final Set<SystemIcon> ICONS = new HashSet<>();
|
||||
|
@ -20,8 +21,14 @@ public class SystemIconManager {
|
|||
public static List<SystemIconSource> getEffectiveSources() {
|
||||
var prefs = AppPrefs.get().getIconSources().getValue();
|
||||
var all = new ArrayList<SystemIconSource>();
|
||||
all.add(SystemIconSource.Directory.builder().path(DataStorage.get().getIconsDir()).id("custom").build());
|
||||
all.add(SystemIconSource.GitRepository.builder().remote("https://github.com/selfhst/icons").id("selfhst").build());
|
||||
all.add(SystemIconSource.Directory.builder()
|
||||
.path(DataStorage.get().getIconsDir())
|
||||
.id("custom")
|
||||
.build());
|
||||
all.add(SystemIconSource.GitRepository.builder()
|
||||
.remote("https://github.com/selfhst/icons")
|
||||
.id("selfhst")
|
||||
.build());
|
||||
for (var pref : prefs) {
|
||||
if (!all.contains(pref)) {
|
||||
all.add(pref);
|
||||
|
@ -53,7 +60,7 @@ public class SystemIconManager {
|
|||
|
||||
LOADED.clear();
|
||||
for (var source : getEffectiveSources()) {
|
||||
LOADED.put(source,SystemIconSourceData.of(source));
|
||||
LOADED.put(source, SystemIconSourceData.of(source));
|
||||
}
|
||||
|
||||
ICONS.clear();
|
||||
|
@ -88,6 +95,10 @@ public class SystemIconManager {
|
|||
}
|
||||
|
||||
public static Path getPoolPath() {
|
||||
return AppProperties.get().getDataDir().resolve("cache").resolve("icons").resolve("pool");
|
||||
return AppProperties.get()
|
||||
.getDataDir()
|
||||
.resolve("cache")
|
||||
.resolve("icons")
|
||||
.resolve("pool");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package io.xpipe.app.icon;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.util.DesktopHelper;
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
@ -16,11 +17,10 @@ import lombok.extern.jackson.Jacksonized;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = SystemIconSource.Directory.class),
|
||||
@JsonSubTypes.Type(value = SystemIconSource.GitRepository.class)
|
||||
@JsonSubTypes.Type(value = SystemIconSource.Directory.class),
|
||||
@JsonSubTypes.Type(value = SystemIconSource.GitRepository.class)
|
||||
})
|
||||
public interface SystemIconSource {
|
||||
|
||||
|
@ -28,7 +28,7 @@ public interface SystemIconSource {
|
|||
@Builder
|
||||
@Jacksonized
|
||||
@JsonTypeName("directory")
|
||||
static class Directory implements SystemIconSource{
|
||||
static class Directory implements SystemIconSource {
|
||||
|
||||
Path path;
|
||||
String id;
|
||||
|
@ -69,19 +69,26 @@ public interface SystemIconSource {
|
|||
@Builder
|
||||
@Jacksonized
|
||||
@JsonTypeName("git")
|
||||
static class GitRepository implements SystemIconSource{
|
||||
static class GitRepository implements SystemIconSource {
|
||||
|
||||
String remote;
|
||||
String id;
|
||||
|
||||
@Override
|
||||
public void refresh() throws Exception {
|
||||
try (var sc = ProcessControlProvider.get().createLocalProcessControl(true).start()) {
|
||||
try (var sc =
|
||||
ProcessControlProvider.get().createLocalProcessControl(true).start()) {
|
||||
var dir = SystemIconManager.getPoolPath().resolve(id);
|
||||
if (!Files.exists(dir)) {
|
||||
sc.command(CommandBuilder.of().add("git", "clone").addQuoted(remote).addFile(dir.toString())).execute();
|
||||
sc.command(CommandBuilder.of()
|
||||
.add("git", "clone")
|
||||
.addQuoted(remote)
|
||||
.addFile(dir.toString()))
|
||||
.execute();
|
||||
} else {
|
||||
sc.command(CommandBuilder.of().add("git", "pull")).withWorkingDirectory(FilePath.of(dir)).execute();
|
||||
sc.command(CommandBuilder.of().add("git", "pull"))
|
||||
.withWorkingDirectory(FilePath.of(dir))
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
package io.xpipe.app.icon;
|
||||
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
|
||||
import lombok.Value;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitOption;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.app.issue;
|
|||
import io.xpipe.app.core.AppLogs;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.util.Deobfuscator;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
|
|
@ -78,8 +78,9 @@ public class TerminalErrorHandler extends GuiErrorHandlerBase implements ErrorHa
|
|||
try {
|
||||
var rel = XPipeDistributionType.get().getUpdateHandler().refreshUpdateCheck(false, false);
|
||||
if (rel != null && rel.isUpdate()) {
|
||||
var updateModal =
|
||||
ModalOverlay.of("updateAvailableTitle", AppDialog.dialogText(AppI18n.get("updateAvailableContent", rel.getVersion())));
|
||||
var updateModal = ModalOverlay.of(
|
||||
"updateAvailableTitle",
|
||||
AppDialog.dialogText(AppI18n.get("updateAvailableContent", rel.getVersion())));
|
||||
updateModal.addButton(
|
||||
new ModalButton("checkOutUpdate", () -> Hyperlinks.open(rel.getReleaseUrl()), false, true));
|
||||
updateModal.addButton(new ModalButton("ignore", null, true, false));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
|
@ -21,6 +20,7 @@ import javafx.beans.value.ObservableDoubleValue;
|
|||
import javafx.beans.value.ObservableStringValue;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.type.SimpleType;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
|
@ -84,9 +84,11 @@ public class AppPrefs {
|
|||
.key("iconSources")
|
||||
.valueType(TypeFactory.defaultInstance().constructType(new TypeReference<List<SystemIconSource>>() {}))
|
||||
.build());
|
||||
|
||||
public final ObservableValue<List<SystemIconSource>> getIconSources() {
|
||||
return iconSources;
|
||||
}
|
||||
|
||||
public final BooleanProperty disableCertutilUse =
|
||||
mapLocal(new SimpleBooleanProperty(false), "disableCertutilUse", Boolean.class, false);
|
||||
public final BooleanProperty useLocalFallbackShell =
|
||||
|
@ -99,8 +101,11 @@ public class AppPrefs {
|
|||
mapVaultShared(new SimpleBooleanProperty(false), "dontCachePasswords", Boolean.class, false);
|
||||
public final BooleanProperty denyTempScriptCreation =
|
||||
mapVaultShared(new SimpleBooleanProperty(false), "denyTempScriptCreation", Boolean.class, false);
|
||||
final Property<ExternalPasswordManager> passwordManager =
|
||||
mapVaultShared(new SimpleObjectProperty<>(ExternalPasswordManager.NONE), "passwordManager", ExternalPasswordManager.class, false);
|
||||
final Property<ExternalPasswordManager> passwordManager = mapVaultShared(
|
||||
new SimpleObjectProperty<>(ExternalPasswordManager.NONE),
|
||||
"passwordManager",
|
||||
ExternalPasswordManager.class,
|
||||
false);
|
||||
final StringProperty passwordManagerCommand =
|
||||
mapLocal(new SimpleStringProperty(""), "passwordManagerCommand", String.class, false);
|
||||
final ObjectProperty<StartupBehaviour> startupBehaviour = mapLocal(
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
import com.fasterxml.jackson.databind.util.TokenBuffer;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
|
@ -13,9 +9,9 @@ import com.fasterxml.jackson.databind.JavaType;
|
|||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.NullNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.databind.node.TextNode;
|
||||
import com.fasterxml.jackson.databind.util.TokenBuffer;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
|
|
|
@ -64,13 +64,14 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
|
||||
@Override
|
||||
protected Optional<Path> determineInstallation() {
|
||||
var found =
|
||||
WindowsRegistry.local().readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null);
|
||||
var found = WindowsRegistry.local()
|
||||
.readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Notepad++", null);
|
||||
|
||||
// Check 32 bit install
|
||||
if (found.isEmpty()) {
|
||||
found = WindowsRegistry.local()
|
||||
.readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "WOW6432Node\\SOFTWARE\\Notepad++", null);
|
||||
.readStringValueIfPresent(
|
||||
WindowsRegistry.HKEY_LOCAL_MACHINE, "WOW6432Node\\SOFTWARE\\Notepad++", null);
|
||||
}
|
||||
return found.map(p -> p + "\\notepad++.exe").map(Path::of);
|
||||
}
|
||||
|
|
|
@ -83,7 +83,8 @@ public interface ExternalRdpClientType extends PrefsChoiceValue {
|
|||
protected Optional<Path> determineInstallation() {
|
||||
try {
|
||||
var r = WindowsRegistry.local()
|
||||
.readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\rdm\\DefaultIcon");
|
||||
.readStringValueIfPresent(
|
||||
WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\rdm\\DefaultIcon");
|
||||
return r.map(Path::of);
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).omit().handle();
|
||||
|
|
|
@ -3,26 +3,19 @@ package io.xpipe.app.prefs;
|
|||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.*;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.window.AppDialog;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.icon.SystemIcon;
|
||||
import io.xpipe.app.icon.SystemIconCache;
|
||||
import io.xpipe.app.icon.SystemIconManager;
|
||||
import io.xpipe.app.icon.SystemIconSource;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStorageUserHandler;
|
||||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.TextField;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
|
@ -41,10 +34,7 @@ public class IconsCategory extends AppPrefsCategory {
|
|||
var prefs = AppPrefs.get();
|
||||
return new OptionsBuilder()
|
||||
.addTitle("customIcons")
|
||||
.sub(new OptionsBuilder()
|
||||
.nameAndDescription("iconSources")
|
||||
.addComp(createOverview())
|
||||
)
|
||||
.sub(new OptionsBuilder().nameAndDescription("iconSources").addComp(createOverview()))
|
||||
.buildComp();
|
||||
}
|
||||
|
||||
|
@ -67,58 +57,81 @@ public class IconsCategory extends AppPrefsCategory {
|
|||
refreshButton.disable(PlatformThread.sync(busy.or(Bindings.isEmpty(sources))));
|
||||
refreshButton.grow(true, false);
|
||||
|
||||
var addGitButton = new TileButtonComp("addGitIconSource", "addGitIconSourceDescription", "mdi2a-access-point-plus", e -> {
|
||||
var remote = new SimpleStringProperty();
|
||||
var modal = ModalOverlay.of(
|
||||
"repositoryUrl",
|
||||
Comp.of(() -> {
|
||||
var creationName = new TextField();
|
||||
creationName.textProperty().bindBidirectional(remote);
|
||||
return creationName;
|
||||
})
|
||||
.prefWidth(350));
|
||||
modal.withDefaultButtons(() -> {
|
||||
if (remote.get() == null || remote.get().isBlank()) {
|
||||
return;
|
||||
}
|
||||
var addGitButton =
|
||||
new TileButtonComp("addGitIconSource", "addGitIconSourceDescription", "mdi2a-access-point-plus", e -> {
|
||||
var remote = new SimpleStringProperty();
|
||||
var modal = ModalOverlay.of(
|
||||
"repositoryUrl",
|
||||
Comp.of(() -> {
|
||||
var creationName = new TextField();
|
||||
creationName.textProperty().bindBidirectional(remote);
|
||||
return creationName;
|
||||
})
|
||||
.prefWidth(350));
|
||||
modal.withDefaultButtons(() -> {
|
||||
if (remote.get() == null || remote.get().isBlank()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var source = SystemIconSource.GitRepository.builder().remote(remote.get()).id(UUID.randomUUID().toString()).build();
|
||||
if (!sources.contains(source)) {
|
||||
sources.add(source);
|
||||
var nl = new ArrayList<>(AppPrefs.get().getIconSources().getValue());
|
||||
nl.add(source);
|
||||
AppPrefs.get().iconSources.setValue(nl);
|
||||
}
|
||||
});
|
||||
modal.show();
|
||||
e.consume();
|
||||
});
|
||||
var source = SystemIconSource.GitRepository.builder()
|
||||
.remote(remote.get())
|
||||
.id(UUID.randomUUID().toString())
|
||||
.build();
|
||||
if (!sources.contains(source)) {
|
||||
sources.add(source);
|
||||
var nl = new ArrayList<>(
|
||||
AppPrefs.get().getIconSources().getValue());
|
||||
nl.add(source);
|
||||
AppPrefs.get().iconSources.setValue(nl);
|
||||
}
|
||||
});
|
||||
modal.show();
|
||||
e.consume();
|
||||
});
|
||||
addGitButton.grow(true, false);
|
||||
|
||||
var addDirectoryButton = new TileButtonComp("addDirectoryIconSource", "addDirectoryIconSourceDescription", "mdi2f-folder-plus", e -> {
|
||||
var dir = new SimpleObjectProperty<FilePath>();
|
||||
var modal = ModalOverlay.of(
|
||||
"iconDirectory",
|
||||
new ContextualFileReferenceChoiceComp(new SimpleObjectProperty<>(DataStorage.get().local().ref()),dir,null,List.of()).prefWidth(350));
|
||||
modal.withDefaultButtons(() -> {
|
||||
if (dir.get() == null) {
|
||||
return;
|
||||
}
|
||||
var addDirectoryButton = new TileButtonComp(
|
||||
"addDirectoryIconSource", "addDirectoryIconSourceDescription", "mdi2f-folder-plus", e -> {
|
||||
var dir = new SimpleObjectProperty<FilePath>();
|
||||
var modal = ModalOverlay.of(
|
||||
"iconDirectory",
|
||||
new ContextualFileReferenceChoiceComp(
|
||||
new SimpleObjectProperty<>(
|
||||
DataStorage.get().local().ref()),
|
||||
dir,
|
||||
null,
|
||||
List.of())
|
||||
.prefWidth(350));
|
||||
modal.withDefaultButtons(() -> {
|
||||
if (dir.get() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var source = SystemIconSource.Directory.builder().path(Path.of(dir.get().toString())).id(UUID.randomUUID().toString()).build();
|
||||
if (!sources.contains(source)) {
|
||||
sources.add(source);
|
||||
var nl = new ArrayList<>(AppPrefs.get().getIconSources().getValue());
|
||||
nl.add(source);
|
||||
AppPrefs.get().iconSources.setValue(nl);
|
||||
}
|
||||
});
|
||||
modal.show();
|
||||
e.consume();
|
||||
});
|
||||
var source = SystemIconSource.Directory.builder()
|
||||
.path(Path.of(dir.get().toString()))
|
||||
.id(UUID.randomUUID().toString())
|
||||
.build();
|
||||
if (!sources.contains(source)) {
|
||||
sources.add(source);
|
||||
var nl = new ArrayList<>(
|
||||
AppPrefs.get().getIconSources().getValue());
|
||||
nl.add(source);
|
||||
AppPrefs.get().iconSources.setValue(nl);
|
||||
}
|
||||
});
|
||||
modal.show();
|
||||
e.consume();
|
||||
});
|
||||
addDirectoryButton.grow(true, false);
|
||||
|
||||
var vbox = new VerticalComp(List.of(Comp.vspacer(10), box, Comp.separator(), refreshButton, Comp.separator(), addDirectoryButton, addGitButton));
|
||||
var vbox = new VerticalComp(List.of(
|
||||
Comp.vspacer(10),
|
||||
box,
|
||||
Comp.separator(),
|
||||
refreshButton,
|
||||
Comp.separator(),
|
||||
addDirectoryButton,
|
||||
addGitButton));
|
||||
vbox.spacing(10);
|
||||
return vbox;
|
||||
}
|
||||
|
@ -141,7 +154,10 @@ public class IconsCategory extends AppPrefsCategory {
|
|||
}
|
||||
|
||||
var tile = new TileButtonComp(
|
||||
new SimpleStringProperty(AppPrefs.get().getIconSources().getValue().contains(source) ? source.getDisplayName() : source.getId()),
|
||||
new SimpleStringProperty(
|
||||
AppPrefs.get().getIconSources().getValue().contains(source)
|
||||
? source.getDisplayName()
|
||||
: source.getId()),
|
||||
new SimpleStringProperty(source.getDescription()),
|
||||
new SimpleObjectProperty<>(source.getIcon()),
|
||||
actionEvent -> {
|
||||
|
|
|
@ -36,7 +36,11 @@ public class PasswordManagerCategory extends AppPrefsCategory {
|
|||
private static class Choice {
|
||||
|
||||
public static Choice ofOther(ExternalPasswordManager externalPasswordManager) {
|
||||
return new Choice(externalPasswordManager.getId(), null, externalPasswordManager.getDocsLink(),externalPasswordManager);
|
||||
return new Choice(
|
||||
externalPasswordManager.getId(),
|
||||
null,
|
||||
externalPasswordManager.getDocsLink(),
|
||||
externalPasswordManager);
|
||||
}
|
||||
|
||||
String id;
|
||||
|
|
|
@ -14,7 +14,6 @@ import java.util.Locale;
|
|||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum SupportedLocale implements PrefsChoiceValue {
|
||||
|
||||
ENGLISH(Locale.ENGLISH, "en", false),
|
||||
GERMAN(Locale.GERMAN, "de", false),
|
||||
DUTCH(Locale.of("nl"), "nl", false),
|
||||
|
@ -38,7 +37,8 @@ public enum SupportedLocale implements PrefsChoiceValue {
|
|||
public static SupportedLocale getInitial() {
|
||||
var s = Locale.getDefault();
|
||||
return Arrays.stream(values())
|
||||
.filter(supportedLocale -> supportedLocale.isSetDefault() && supportedLocale.getLocale().getLanguage().equals(s.getLanguage()))
|
||||
.filter(supportedLocale -> supportedLocale.isSetDefault()
|
||||
&& supportedLocale.getLocale().getLanguage().equals(s.getLanguage()))
|
||||
.findFirst()
|
||||
.orElse(getEnglish());
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ public class AppImages {
|
|||
TrackEvent.trace("Loaded images in " + module + ":" + dir + " in " + elapsed.toMillis() + " ms");
|
||||
}
|
||||
|
||||
|
||||
public static void loadRasterImages(Path directory, String prefix) throws IOException {
|
||||
if (!Files.isDirectory(directory)) {
|
||||
return;
|
||||
|
|
|
@ -2,16 +2,13 @@ package io.xpipe.app.storage;
|
|||
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
|
@ -26,7 +23,9 @@ public class ContextualFileReference {
|
|||
|
||||
private static FilePath getDataDir() {
|
||||
if (DataStorage.get() == null) {
|
||||
return lastDataDir != null ? lastDataDir : FilePath.of(AppPrefs.DEFAULT_STORAGE_DIR.resolve("data")).toUnix();
|
||||
return lastDataDir != null
|
||||
? lastDataDir
|
||||
: FilePath.of(AppPrefs.DEFAULT_STORAGE_DIR.resolve("data")).toUnix();
|
||||
}
|
||||
|
||||
return lastDataDir = FilePath.of(DataStorage.get().getDataDir()).toUnix();
|
||||
|
@ -65,7 +64,8 @@ public class ContextualFileReference {
|
|||
}
|
||||
|
||||
public FilePath toAbsoluteFilePath(ShellControl sc) {
|
||||
return FilePath.of(path.replaceAll("/", Matcher.quoteReplacement(sc != null ? sc.getOsType().getFileSystemSeparator() : "/")));
|
||||
return FilePath.of(path.replaceAll(
|
||||
"/", Matcher.quoteReplacement(sc != null ? sc.getOsType().getFileSystemSeparator() : "/")));
|
||||
}
|
||||
|
||||
public boolean isInDataDirectory() {
|
||||
|
|
|
@ -444,7 +444,9 @@ public abstract class DataStorage {
|
|||
try {
|
||||
List<? extends DataStoreEntryRef<? extends FixedChildStore>> l = h.listChildren();
|
||||
if (l != null) {
|
||||
newChildren = l.stream().filter(dataStoreEntryRef -> dataStoreEntryRef != null && dataStoreEntryRef.get() != null).toList();
|
||||
newChildren = l.stream()
|
||||
.filter(dataStoreEntryRef -> dataStoreEntryRef != null && dataStoreEntryRef.get() != null)
|
||||
.toList();
|
||||
} else {
|
||||
newChildren = null;
|
||||
}
|
||||
|
@ -490,24 +492,31 @@ public abstract class DataStorage {
|
|||
.filter(oc -> oc.getStore() instanceof FixedChildStore)
|
||||
.filter(oc -> getFixedChildId(oc).isPresent())
|
||||
.noneMatch(oc -> {
|
||||
return getFixedChildId(oc).getAsInt()
|
||||
== nid.getAsInt();
|
||||
return getFixedChildId(oc).getAsInt() == nid.getAsInt();
|
||||
});
|
||||
})
|
||||
.toList();
|
||||
var toUpdate = new ArrayList<>(oldChildren.stream().map(oc -> {
|
||||
var oid = getFixedChildId(oc);
|
||||
if (oid.isEmpty()) {
|
||||
return new Pair<DataStoreEntry, DataStoreEntryRef<? extends FixedChildStore>>(oc, null);
|
||||
}
|
||||
var toUpdate = new ArrayList<>(oldChildren.stream()
|
||||
.map(oc -> {
|
||||
var oid = getFixedChildId(oc);
|
||||
if (oid.isEmpty()) {
|
||||
return new Pair<DataStoreEntry, DataStoreEntryRef<? extends FixedChildStore>>(oc, null);
|
||||
}
|
||||
|
||||
var found = newChildren.stream().filter(nc -> getFixedChildId(nc.get()).isPresent()).filter(nc -> getFixedChildId(nc.get()).getAsInt() ==
|
||||
oid.getAsInt()).findFirst().orElse(null);
|
||||
return new Pair<DataStoreEntry, DataStoreEntryRef<? extends FixedChildStore>>(oc, found);
|
||||
}).filter(en -> en.getValue() != null).toList());
|
||||
var found = newChildren.stream()
|
||||
.filter(nc -> getFixedChildId(nc.get()).isPresent())
|
||||
.filter(nc -> getFixedChildId(nc.get()).getAsInt() == oid.getAsInt())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
return new Pair<DataStoreEntry, DataStoreEntryRef<? extends FixedChildStore>>(oc, found);
|
||||
})
|
||||
.filter(en -> en.getValue() != null)
|
||||
.toList());
|
||||
|
||||
toUpdate.removeIf(pair -> {
|
||||
return pair.getKey().getStorePersistentState().equals(pair.getValue().get().getStorePersistentState());
|
||||
return pair.getKey()
|
||||
.getStorePersistentState()
|
||||
.equals(pair.getValue().get().getStorePersistentState());
|
||||
});
|
||||
|
||||
if (toRemove.isEmpty() && toAdd.isEmpty() && toUpdate.isEmpty()) {
|
||||
|
@ -794,7 +803,8 @@ public abstract class DataStorage {
|
|||
return true;
|
||||
}
|
||||
|
||||
var parentCat = getStoreCategoryIfPresent(parent.get().getCategoryUuid()).orElseThrow();
|
||||
var parentCat =
|
||||
getStoreCategoryIfPresent(parent.get().getCategoryUuid()).orElseThrow();
|
||||
var parentCatHierarchy = getCategoryParentHierarchy(parentCat);
|
||||
var cat = getStoreCategoryIfPresent(entry.getCategoryUuid()).orElseThrow();
|
||||
var catHierarchy = getCategoryParentHierarchy(cat);
|
||||
|
|
|
@ -41,10 +41,10 @@ public class StandardStorage extends DataStorage {
|
|||
|
||||
@Getter
|
||||
private boolean disposed;
|
||||
|
||||
private boolean saveQueued;
|
||||
private final ReentrantLock busyIo = new ReentrantLock();
|
||||
|
||||
|
||||
StandardStorage() {
|
||||
this.dataStorageSyncHandler = DataStorageSyncHandler.getInstance();
|
||||
this.dataStorageUserHandler = DataStorageUserHandler.getInstance();
|
||||
|
|
|
@ -26,7 +26,8 @@ public class MobaXTermTerminalType extends ExternalTerminalType.WindowsType {
|
|||
protected Optional<Path> determineInstallation() {
|
||||
try {
|
||||
var r = WindowsRegistry.local()
|
||||
.readStringValueIfPresent(WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\mobaxterm\\DefaultIcon");
|
||||
.readStringValueIfPresent(
|
||||
WindowsRegistry.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\mobaxterm\\DefaultIcon");
|
||||
return r.map(Path::of);
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).omit().handle();
|
||||
|
|
|
@ -47,7 +47,8 @@ public class TerminalLauncher {
|
|||
open(null, title, null, cc, request, true);
|
||||
}
|
||||
|
||||
public static void open(DataStoreEntry entry, String title, FilePath directory, ProcessControl cc) throws Exception {
|
||||
public static void open(DataStoreEntry entry, String title, FilePath directory, ProcessControl cc)
|
||||
throws Exception {
|
||||
open(entry, title, directory, cc, UUID.randomUUID(), true);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,14 +41,20 @@ public interface WaveTerminalType extends ExternalTerminalType, TrackableTermina
|
|||
default void launch(TerminalLaunchConfiguration configuration) throws Exception {
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
var wsh = CommandSupport.findProgram(sc, "wsh");
|
||||
var env = sc.command(sc.getShellDialect().getPrintEnvironmentVariableCommand("WAVETERM_JWT")).readStdoutOrThrow();
|
||||
var env = sc.command(sc.getShellDialect().getPrintEnvironmentVariableCommand("WAVETERM_JWT"))
|
||||
.readStdoutOrThrow();
|
||||
if (wsh.isEmpty() || env.isEmpty()) {
|
||||
var inPath = CommandSupport.findProgram(sc, "xpipe").isPresent();
|
||||
var msg = """
|
||||
var msg =
|
||||
"""
|
||||
The Wave integration requires XPipe to be launched from Wave itself to have access to its environment variables. Otherwise, XPipe does not have access to the token to control Wave.
|
||||
|
||||
|
||||
You can do this by running the command "%s" in a local terminal block inside Wave.
|
||||
""".formatted(inPath ? "xpipe open" : XPipeInstallation.getLocalDefaultCliExecutable() + " open");
|
||||
"""
|
||||
.formatted(
|
||||
inPath
|
||||
? "xpipe open"
|
||||
: XPipeInstallation.getLocalDefaultCliExecutable() + " open");
|
||||
throw ErrorEvent.expected(new IllegalStateException(msg));
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,8 @@ public interface WezTerminalType extends ExternalTerminalType, TrackableTerminal
|
|||
"http://wezfurlong.org/wezterm");
|
||||
if (foundKey.isPresent()) {
|
||||
var installKey = WindowsRegistry.local()
|
||||
.readStringValueIfPresent(foundKey.get().getHkey(), foundKey.get().getKey(), "InstallLocation");
|
||||
.readStringValueIfPresent(
|
||||
foundKey.get().getHkey(), foundKey.get().getKey(), "InstallLocation");
|
||||
if (installKey.isPresent()) {
|
||||
return installKey.map(p -> p + "\\wezterm-gui.exe").map(Path::of);
|
||||
}
|
||||
|
|
|
@ -147,7 +147,9 @@ public enum XPipeDistributionType {
|
|||
}
|
||||
}
|
||||
|
||||
var yumRepo = sc.command(CommandBuilder.of().add("test", "-f").addFile("/etc/yum.repos.d/rpm.xpipe.io.repo")).executeAndCheck();
|
||||
var yumRepo = sc.command(
|
||||
CommandBuilder.of().add("test", "-f").addFile("/etc/yum.repos.d/rpm.xpipe.io.repo"))
|
||||
.executeAndCheck();
|
||||
if (yumRepo) {
|
||||
return RPM_REPO;
|
||||
}
|
||||
|
|
|
@ -52,9 +52,11 @@ public class DesktopHelper {
|
|||
case OsType.Windows windows -> {
|
||||
// Explorer does not support single quotes, so use normal quotes
|
||||
if (kind == FileKind.DIRECTORY) {
|
||||
sc.command(CommandBuilder.of().add("explorer").addQuoted(path.toString())).execute();
|
||||
sc.command(CommandBuilder.of().add("explorer").addQuoted(path.toString()))
|
||||
.execute();
|
||||
} else {
|
||||
sc.command(CommandBuilder.of().add("explorer", "/select,\"" + path.toString() + "\"")).execute();
|
||||
sc.command(CommandBuilder.of().add("explorer", "/select,\"" + path.toString() + "\""))
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
case OsType.Linux linux -> {
|
||||
|
@ -77,7 +79,11 @@ public class DesktopHelper {
|
|||
.execute();
|
||||
}
|
||||
case OsType.MacOs macOs -> {
|
||||
sc.command(CommandBuilder.of().add("open").addIf(kind == FileKind.DIRECTORY, "-R").addFile(path)).execute();
|
||||
sc.command(CommandBuilder.of()
|
||||
.add("open")
|
||||
.addIf(kind == FileKind.DIRECTORY, "-R")
|
||||
.addFile(path))
|
||||
.execute();
|
||||
}
|
||||
case OsType.Bsd bsd -> {}
|
||||
case OsType.Solaris solaris -> {}
|
||||
|
|
|
@ -70,7 +70,9 @@ public final class HumanReadableFormat {
|
|||
|
||||
// not this week
|
||||
if (getWeekNumber(x) != getWeekNumber(now)) {
|
||||
return DAY_MONTH.withLocale(AppI18n.activeLanguage().getValue().getLocale()).format(x);
|
||||
return DAY_MONTH
|
||||
.withLocale(AppI18n.activeLanguage().getValue().getLocale())
|
||||
.format(x);
|
||||
}
|
||||
|
||||
// not today
|
||||
|
@ -80,14 +82,19 @@ public final class HumanReadableFormat {
|
|||
return AppI18n.get("yesterday");
|
||||
}
|
||||
if (xDay != nowDay) {
|
||||
return DAY_OF_WEEK.withLocale(AppI18n.activeLanguage().getValue().getLocale()).format(x);
|
||||
return DAY_OF_WEEK
|
||||
.withLocale(AppI18n.activeLanguage().getValue().getLocale())
|
||||
.format(x);
|
||||
}
|
||||
|
||||
return HOUR_MINUTE.withLocale(AppI18n.activeLanguage().getValue().getLocale()).format(x);
|
||||
return HOUR_MINUTE
|
||||
.withLocale(AppI18n.activeLanguage().getValue().getLocale())
|
||||
.format(x);
|
||||
}
|
||||
|
||||
private static int getWeekNumber(LocalDateTime date) {
|
||||
return date.get(WeekFields.of(AppI18n.activeLanguage().getValue().getLocale()).weekOfYear());
|
||||
return date.get(
|
||||
WeekFields.of(AppI18n.activeLanguage().getValue().getLocale()).weekOfYear());
|
||||
}
|
||||
|
||||
public static String duration(Duration duration) {
|
||||
|
|
|
@ -22,8 +22,8 @@ public class RdpConfig {
|
|||
Map<String, TypedValue> content;
|
||||
|
||||
public static RdpConfig parseFile(FilePath file) throws Exception {
|
||||
try (var in = new BufferedReader(
|
||||
StreamCharset.detectedReader(new BufferedInputStream(Files.newInputStream(Path.of(file.toString())))))) {
|
||||
try (var in = new BufferedReader(StreamCharset.detectedReader(
|
||||
new BufferedInputStream(Files.newInputStream(Path.of(file.toString())))))) {
|
||||
var content = in.lines().collect(Collectors.joining("\n"));
|
||||
return parseContent(content);
|
||||
} catch (NoSuchFileException e) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.app.comp.base.LoadingOverlayComp;
|
||||
import io.xpipe.app.comp.base.ModalButton;
|
||||
import io.xpipe.app.comp.base.ModalOverlay;
|
||||
import io.xpipe.app.ext.ScanProvider;
|
||||
|
|
|
@ -15,7 +15,6 @@ import io.xpipe.app.storage.DataStoreEntryRef;
|
|||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.layout.Region;
|
||||
|
@ -23,7 +22,6 @@ import javafx.scene.layout.StackPane;
|
|||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static javafx.scene.layout.Priority.ALWAYS;
|
||||
|
@ -33,7 +31,8 @@ class ScanDialogComp extends ModalOverlayContentComp {
|
|||
private final DataStoreEntryRef<ShellStore> initialStore;
|
||||
private final ScanDialogAction action;
|
||||
private final ObjectProperty<DataStoreEntryRef<ShellStore>> entry;
|
||||
private final ObservableList<ScanProvider.ScanOpportunity> available = FXCollections.synchronizedObservableList(FXCollections.observableArrayList());
|
||||
private final ObservableList<ScanProvider.ScanOpportunity> available =
|
||||
FXCollections.synchronizedObservableList(FXCollections.observableArrayList());
|
||||
private final ListProperty<ScanProvider.ScanOpportunity> selected =
|
||||
new SimpleListProperty<>(FXCollections.synchronizedObservableList(FXCollections.observableArrayList()));
|
||||
private final BooleanProperty busy = new SimpleBooleanProperty();
|
||||
|
@ -131,7 +130,8 @@ class ScanDialogComp extends ModalOverlayContentComp {
|
|||
.disable(busy.or(new SimpleBooleanProperty(initialStore != null))))
|
||||
.name("scanAlertHeader")
|
||||
.description("scanAlertHeaderDescription")
|
||||
.addComp(LoadingOverlayComp.noProgress(Comp.of(() -> stackPane), busy).vgrow())
|
||||
.addComp(LoadingOverlayComp.noProgress(Comp.of(() -> stackPane), busy)
|
||||
.vgrow())
|
||||
.buildComp()
|
||||
.prefWidth(500)
|
||||
.prefHeight(680)
|
||||
|
|
|
@ -36,7 +36,8 @@ public class SecretManager {
|
|||
List<SecretQueryFormatter> formatters,
|
||||
CountDown countDown,
|
||||
boolean interactive) {
|
||||
var p = new SecretQueryProgress(request, storeId, suppliers, fallback, filters, formatters, countDown, interactive);
|
||||
var p = new SecretQueryProgress(
|
||||
request, storeId, suppliers, fallback, filters, formatters, countDown, interactive);
|
||||
progress.add(p);
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface SecretQueryFormatter {
|
||||
|
|
|
@ -31,7 +31,8 @@ public class SecretQueryProgress {
|
|||
@NonNull UUID storeId,
|
||||
@NonNull List<SecretQuery> suppliers,
|
||||
@NonNull SecretQuery fallback,
|
||||
@NonNull List<SecretQueryFilter> filters, List<SecretQueryFormatter> formatters,
|
||||
@NonNull List<SecretQueryFilter> filters,
|
||||
List<SecretQueryFormatter> formatters,
|
||||
@NonNull CountDown countDown,
|
||||
boolean interactive) {
|
||||
this.requestId = requestId;
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.xpipe.app.util;
|
|||
|
||||
import io.xpipe.app.comp.store.StoreSection;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.process.ShellEnvironmentStoreState;
|
||||
import io.xpipe.core.process.ShellStoreState;
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.app.core.AppProperties;
|
|||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
|
|
|
@ -9,7 +9,8 @@ import java.util.List;
|
|||
|
||||
public class Validators {
|
||||
|
||||
public static <T extends DataStore> void isType(DataStoreEntryRef<? extends T> ref, Class<T> c) throws ValidationException {
|
||||
public static <T extends DataStore> void isType(DataStoreEntryRef<? extends T> ref, Class<T> c)
|
||||
throws ValidationException {
|
||||
if (ref != null && !c.isAssignableFrom(ref.getStore().getClass())) {
|
||||
throw new ValidationException("Value must be an instance of " + c.getSimpleName());
|
||||
}
|
||||
|
|
|
@ -180,13 +180,14 @@ public abstract class WindowsRegistry {
|
|||
@Override
|
||||
public List<String> listSubKeys(int hkey, String key) throws Exception {
|
||||
var prefix = hkey(hkey) + "\\" + key;
|
||||
var command = CommandBuilder.of()
|
||||
.add("reg", "query")
|
||||
.addQuoted(prefix);
|
||||
var command = CommandBuilder.of().add("reg", "query").addQuoted(prefix);
|
||||
var out = shellControl.command(command).readStdoutOrThrow();
|
||||
return out.lines().filter(s -> {
|
||||
return s.contains(prefix + "\\");
|
||||
}).map(s -> s.replace(prefix + "\\", "")).toList();
|
||||
return out.lines()
|
||||
.filter(s -> {
|
||||
return s.contains(prefix + "\\");
|
||||
})
|
||||
.map(s -> s.replace(prefix + "\\", ""))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package io.xpipe.beacon.api;
|
||||
|
||||
import io.xpipe.beacon.BeaconInterface;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package io.xpipe.beacon.api;
|
||||
|
||||
import io.xpipe.beacon.BeaconInterface;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.core.process;
|
||||
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -58,11 +57,7 @@ public interface OsType {
|
|||
@Override
|
||||
public List<FilePath> determineInterestingPaths(ShellControl pc) throws Exception {
|
||||
var home = pc.view().userHome();
|
||||
return List.of(
|
||||
home,
|
||||
home.join("Documents"),
|
||||
home.join("Downloads"),
|
||||
home.join("Desktop"));
|
||||
return List.of(home, home.join("Documents"), home.join("Downloads"), home.join("Desktop"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -180,8 +175,7 @@ public interface OsType {
|
|||
FilePath.of("/Library"),
|
||||
FilePath.of("/System"),
|
||||
FilePath.of("/etc"),
|
||||
FilePath.of("/tmp")
|
||||
);
|
||||
FilePath.of("/tmp"));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,9 +46,7 @@ public class ShellView {
|
|||
}
|
||||
|
||||
public boolean directoryExists(FilePath path) throws Exception {
|
||||
return getDialect()
|
||||
.directoryExists(shellControl, path.toString())
|
||||
.executeAndCheck();
|
||||
return getDialect().directoryExists(shellControl, path.toString()).executeAndCheck();
|
||||
}
|
||||
|
||||
public String user() throws Exception {
|
||||
|
@ -91,6 +89,8 @@ public class ShellView {
|
|||
}
|
||||
|
||||
public String environmentVariable(String name) throws Exception {
|
||||
return shellControl.command(shellControl.getShellDialect().getPrintEnvironmentVariableCommand(name)).readStdoutOrThrow();
|
||||
return shellControl
|
||||
.command(shellControl.getShellDialect().getPrintEnvironmentVariableCommand(name))
|
||||
.readStdoutOrThrow();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@ public final class FilePath {
|
|||
public static FilePath of(String path) {
|
||||
return path != null ? new FilePath(path) : null;
|
||||
}
|
||||
|
||||
|
||||
public static FilePath of(Path path) {
|
||||
return path != null ? new FilePath(path.toString()) : null;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
private final String value;
|
||||
|
||||
|
|
|
@ -78,8 +78,7 @@ public class CoreJacksonModule extends SimpleModule {
|
|||
public static class ShellScriptSerializer extends JsonSerializer<ShellScript> {
|
||||
|
||||
@Override
|
||||
public void serialize(ShellScript value, JsonGenerator jgen, SerializerProvider provider)
|
||||
throws IOException {
|
||||
public void serialize(ShellScript value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
|
||||
jgen.writeString(value.getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import io.xpipe.core.process.CommandControl;
|
|||
import io.xpipe.core.process.ElevationFunction;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
import lombok.Value;
|
||||
|
|
|
@ -78,8 +78,10 @@ public class ChgrpAction implements BrowserBranchAction {
|
|||
.executeSimpleCommand(CommandBuilder.of()
|
||||
.add("chgrp", option)
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath().toString())
|
||||
.map(browserEntry -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString())
|
||||
.toList()));
|
||||
}
|
||||
}
|
||||
|
@ -106,8 +108,10 @@ public class ChgrpAction implements BrowserBranchAction {
|
|||
CommandBuilder.of()
|
||||
.add("chgrp", group.getValue())
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath().toString())
|
||||
.map(browserEntry -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString())
|
||||
.toList()),
|
||||
false);
|
||||
});
|
||||
|
|
|
@ -77,8 +77,10 @@ public class ChmodAction implements BrowserBranchAction {
|
|||
.executeSimpleCommand(CommandBuilder.of()
|
||||
.add("chmod", option)
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath().toString())
|
||||
.map(browserEntry -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString())
|
||||
.toList()));
|
||||
}
|
||||
}
|
||||
|
@ -104,8 +106,10 @@ public class ChmodAction implements BrowserBranchAction {
|
|||
CommandBuilder.of()
|
||||
.add("chmod", permissions.getValue())
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath().toString())
|
||||
.map(browserEntry -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString())
|
||||
.toList()),
|
||||
false);
|
||||
});
|
||||
|
|
|
@ -77,8 +77,10 @@ public class ChownAction implements BrowserBranchAction {
|
|||
.executeSimpleCommand(CommandBuilder.of()
|
||||
.add("chown", option)
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath().toString())
|
||||
.map(browserEntry -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString())
|
||||
.toList()));
|
||||
}
|
||||
}
|
||||
|
@ -104,8 +106,10 @@ public class ChownAction implements BrowserBranchAction {
|
|||
CommandBuilder.of()
|
||||
.add("chown", user.getValue())
|
||||
.addFiles(entries.stream()
|
||||
.map(browserEntry ->
|
||||
browserEntry.getRawFileEntry().getPath().toString())
|
||||
.map(browserEntry -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString())
|
||||
.toList()),
|
||||
false);
|
||||
});
|
||||
|
|
|
@ -9,7 +9,6 @@ import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
|||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.util.ClipboardHelper;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -51,7 +50,11 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
if (entries.size() == 1) {
|
||||
return new SimpleObjectProperty<>(BrowserActionFormatter.centerEllipsis(
|
||||
entries.getFirst().getRawFileEntry().getPath().toString(), 50));
|
||||
entries.getFirst()
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString(),
|
||||
50));
|
||||
}
|
||||
|
||||
return AppI18n.observable("absolutePaths");
|
||||
|
@ -71,7 +74,11 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
if (entries.size() == 1) {
|
||||
return new SimpleObjectProperty<>(BrowserActionFormatter.centerEllipsis(
|
||||
entries.getFirst().getRawFileEntry().getPath().toString(), 50));
|
||||
entries.getFirst()
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString(),
|
||||
50));
|
||||
}
|
||||
|
||||
return AppI18n.observable("absoluteLinkPaths");
|
||||
|
@ -104,7 +111,11 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
if (entries.size() == 1) {
|
||||
return new SimpleObjectProperty<>("\""
|
||||
+ BrowserActionFormatter.centerEllipsis(
|
||||
entries.getFirst().getRawFileEntry().getPath().toString(), 50)
|
||||
entries.getFirst()
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString(),
|
||||
50)
|
||||
+ "\"");
|
||||
}
|
||||
|
||||
|
@ -113,9 +124,10 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return entries.stream()
|
||||
.anyMatch(entry ->
|
||||
entry.getRawFileEntry().getPath().toString().contains(" "));
|
||||
return entries.stream().anyMatch(entry -> entry.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString()
|
||||
.contains(" "));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -138,7 +150,10 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
if (entries.size() == 1) {
|
||||
return new SimpleObjectProperty<>(BrowserActionFormatter.centerEllipsis(
|
||||
entries.getFirst().getRawFileEntry().getPath().getFileName(),
|
||||
entries.getFirst()
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.getFileName(),
|
||||
50));
|
||||
}
|
||||
|
||||
|
@ -159,7 +174,10 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
if (entries.size() == 1) {
|
||||
return new SimpleObjectProperty<>(BrowserActionFormatter.centerEllipsis(
|
||||
entries.getFirst().getRawFileEntry().getPath().getFileName(),
|
||||
entries.getFirst()
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.getFileName(),
|
||||
50));
|
||||
}
|
||||
|
||||
|
@ -176,7 +194,8 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
.equals(browserEntry
|
||||
.getRawFileEntry()
|
||||
.resolved()
|
||||
.getPath().getFileName()));
|
||||
.getPath()
|
||||
.getFileName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -198,9 +217,11 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
if (entries.size() == 1) {
|
||||
return new SimpleObjectProperty<>("\""
|
||||
+ BrowserActionFormatter.centerEllipsis(entries.getFirst()
|
||||
+ BrowserActionFormatter.centerEllipsis(
|
||||
entries.getFirst()
|
||||
.getRawFileEntry()
|
||||
.getPath().getFileName(),
|
||||
.getPath()
|
||||
.getFileName(),
|
||||
50)
|
||||
+ "\"");
|
||||
}
|
||||
|
@ -210,15 +231,17 @@ public class CopyPathAction implements BrowserAction, BrowserBranchAction {
|
|||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return entries.stream().anyMatch(entry -> entry.getRawFileEntry().getPath().getFileName()
|
||||
return entries.stream().anyMatch(entry -> entry.getRawFileEntry()
|
||||
.getPath()
|
||||
.getFileName()
|
||||
.contains(" "));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var s = entries.stream()
|
||||
.map(entry -> "\""
|
||||
+ entry.getRawFileEntry().getPath().getFileName() + "\"")
|
||||
.map(entry ->
|
||||
"\"" + entry.getRawFileEntry().getPath().getFileName() + "\"")
|
||||
.collect(Collectors.joining("\n"));
|
||||
ClipboardHelper.copyText(s);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.app.browser.file.BrowserEntry;
|
|||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.app.browser.file.BrowserEntry;
|
|||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.browser.icon.BrowserIconFileType;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
@ -36,6 +35,8 @@ public class JavapAction extends ToFileCommandAction implements FileTypeAction,
|
|||
|
||||
@Override
|
||||
protected CommandBuilder createCommand(BrowserFileSystemTabModel model, BrowserEntry entry) {
|
||||
return CommandBuilder.of().add("javap", "-c", "-p").addFile(entry.getRawFileEntry().getPath());
|
||||
return CommandBuilder.of()
|
||||
.add("javap", "-c", "-p")
|
||||
.addFile(entry.getRawFileEntry().getPath());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.ext.base.browser;
|
||||
|
||||
import atlantafx.base.layout.ModalBox;
|
||||
import io.xpipe.app.browser.action.BrowserBranchAction;
|
||||
import io.xpipe.app.browser.action.BrowserLeafAction;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
|
@ -9,7 +8,6 @@ import io.xpipe.app.comp.Comp;
|
|||
import io.xpipe.app.comp.base.ModalOverlay;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.window.AppDialog;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
|
@ -19,7 +17,6 @@ import io.xpipe.core.process.ShellControl;
|
|||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -95,9 +92,10 @@ public abstract class MultiExecuteSelectionAction implements BrowserBranchAction
|
|||
|
||||
if (out.length() > 10000) {
|
||||
var counter = new AtomicInteger();
|
||||
var start = out.lines().filter(s -> {
|
||||
counter.incrementAndGet();
|
||||
return true;
|
||||
var start = out.lines()
|
||||
.filter(s -> {
|
||||
counter.incrementAndGet();
|
||||
return true;
|
||||
})
|
||||
.limit(100)
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
@ -114,16 +112,19 @@ public abstract class MultiExecuteSelectionAction implements BrowserBranchAction
|
|||
}
|
||||
|
||||
String finalOut = out;
|
||||
var modal = ModalOverlay.of("commandOutput", Comp.of(() -> {
|
||||
var text = new TextArea(finalOut);
|
||||
text.setWrapText(true);
|
||||
text.setEditable(false);
|
||||
text.setPrefRowCount(Math.max(8,( int) finalOut.lines().count()));
|
||||
AppFont.medium(text);
|
||||
var sp = new StackPane(text);
|
||||
return sp;
|
||||
})
|
||||
.prefWidth(650));
|
||||
var modal = ModalOverlay.of(
|
||||
"commandOutput",
|
||||
Comp.of(() -> {
|
||||
var text = new TextArea(finalOut);
|
||||
text.setWrapText(true);
|
||||
text.setEditable(false);
|
||||
text.setPrefRowCount(Math.max(8, (int)
|
||||
finalOut.lines().count()));
|
||||
AppFont.medium(text);
|
||||
var sp = new StackPane(text);
|
||||
return sp;
|
||||
})
|
||||
.prefWidth(650));
|
||||
modal.show();
|
||||
},
|
||||
true);
|
||||
|
|
|
@ -11,8 +11,8 @@ import io.xpipe.app.comp.base.ModalOverlay;
|
|||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
|
|
@ -9,8 +9,6 @@ import io.xpipe.core.process.CommandBuilder;
|
|||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.input.KeyCode;
|
||||
|
|
|
@ -6,8 +6,8 @@ import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
|||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.input.KeyCode;
|
||||
|
|
|
@ -76,9 +76,12 @@ public abstract class BaseCompressAction implements BrowserAction, BrowserBranch
|
|||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var ext = List.of("zip", "tar", "tar.gz", "tgz", "7z", "rar", "xar");
|
||||
if (entries.stream().anyMatch(browserEntry -> ext.stream()
|
||||
.anyMatch(s ->
|
||||
browserEntry.getRawFileEntry().getPath().toString().toLowerCase().endsWith("." + s)))) {
|
||||
if (entries.stream().anyMatch(browserEntry -> ext.stream().anyMatch(s -> browserEntry
|
||||
.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.endsWith("." + s)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -172,14 +175,10 @@ public abstract class BaseCompressAction implements BrowserAction, BrowserBranch
|
|||
() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(base)
|
||||
.execute();
|
||||
sc.command(command).withWorkingDirectory(base).execute();
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
sub.command(command)
|
||||
.withWorkingDirectory(base)
|
||||
.execute();
|
||||
sub.command(command).withWorkingDirectory(base).execute();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -205,9 +204,7 @@ public abstract class BaseCompressAction implements BrowserAction, BrowserBranch
|
|||
var target = base.join(fileName);
|
||||
var command = CommandBuilder.of().add("zip", "-r", "-");
|
||||
for (BrowserEntry entry : entries) {
|
||||
var rel = entry.getRawFileEntry().getPath()
|
||||
.relativize(base)
|
||||
.toUnix();
|
||||
var rel = entry.getRawFileEntry().getPath().relativize(base).toUnix();
|
||||
if (directory) {
|
||||
command.add(".");
|
||||
} else {
|
||||
|
|
|
@ -9,8 +9,8 @@ import io.xpipe.app.browser.icon.BrowserIcons;
|
|||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
|
@ -69,19 +69,27 @@ public class BaseUntarAction implements BrowserApplicationPathAction, BrowserLea
|
|||
@Override
|
||||
public ObservableValue<String> getName(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var sep = model.getFileSystem().getShell().orElseThrow().getOsType().getFileSystemSeparator();
|
||||
var dir = entries.size() > 1 ? "[...]" : getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
var dir = entries.size() > 1
|
||||
? "[...]"
|
||||
: getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
return toDirectory ? AppI18n.observable("untarDirectory", dir) : AppI18n.observable("untarHere");
|
||||
}
|
||||
|
||||
private FilePath getTarget(FilePath name) {
|
||||
return FilePath.of(name.toString().replaceAll("\\.tar$", "").replaceAll("\\.tar.gz$", "").replaceAll("\\.tgz$", ""));
|
||||
return FilePath.of(name.toString()
|
||||
.replaceAll("\\.tar$", "")
|
||||
.replaceAll("\\.tar.gz$", "")
|
||||
.replaceAll("\\.tgz$", ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
if (gz) {
|
||||
return entries.stream()
|
||||
.allMatch(entry -> entry.getRawFileEntry().getPath().toString().endsWith(".tar.gz")
|
||||
.allMatch(entry -> entry.getRawFileEntry()
|
||||
.getPath()
|
||||
.toString()
|
||||
.endsWith(".tar.gz")
|
||||
|| entry.getRawFileEntry().getPath().toString().endsWith(".tgz"));
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,9 @@ public abstract class BaseUnzipUnixAction extends ExecuteApplicationAction {
|
|||
@Override
|
||||
public ObservableValue<String> getName(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var sep = model.getFileSystem().getShell().orElseThrow().getOsType().getFileSystemSeparator();
|
||||
var dir = entries.size() > 1 ? "[...]" : getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
var dir = entries.size() > 1
|
||||
? "[...]"
|
||||
: getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
return toDirectory ? AppI18n.observable("unzipDirectory", dir) : AppI18n.observable("unzipHere");
|
||||
}
|
||||
|
||||
|
@ -68,7 +70,8 @@ public abstract class BaseUnzipUnixAction extends ExecuteApplicationAction {
|
|||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return entries.stream()
|
||||
.allMatch(entry -> entry.getRawFileEntry().getPath().toString().endsWith(".zip"))
|
||||
.allMatch(entry ->
|
||||
entry.getRawFileEntry().getPath().toString().endsWith(".zip"))
|
||||
&& !model.getFileSystem().getShell().orElseThrow().getOsType().equals(OsType.WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import io.xpipe.core.process.CommandBuilder;
|
|||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
|
@ -70,7 +70,9 @@ public abstract class BaseUnzipWindowsAction implements BrowserLeafAction {
|
|||
@Override
|
||||
public ObservableValue<String> getName(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
var sep = model.getFileSystem().getShell().orElseThrow().getOsType().getFileSystemSeparator();
|
||||
var dir = entries.size() > 1 ? "[...]" : getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
var dir = entries.size() > 1
|
||||
? "[...]"
|
||||
: getTarget(entries.getFirst().getRawFileEntry().getPath()).getFileName() + sep;
|
||||
return toDirectory ? AppI18n.observable("unzipDirectory", dir) : AppI18n.observable("unzipHere");
|
||||
}
|
||||
|
||||
|
@ -81,7 +83,8 @@ public abstract class BaseUnzipWindowsAction implements BrowserLeafAction {
|
|||
@Override
|
||||
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return entries.stream()
|
||||
.allMatch(entry -> entry.getRawFileEntry().getPath().toString().endsWith(".zip"))
|
||||
.allMatch(entry ->
|
||||
entry.getRawFileEntry().getPath().toString().endsWith(".zip"))
|
||||
&& model.getFileSystem().getShell().orElseThrow().getOsType().equals(OsType.WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,8 +109,8 @@ public class DesktopApplicationStoreProvider implements DataStoreProvider {
|
|||
return DesktopApplicationStore.builder().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
@Override
|
||||
public String getId() {
|
||||
return "desktopApplication";
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import io.xpipe.app.comp.store.StoreEntryWrapper;
|
|||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.ext.DataStoreCreationCategory;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
|
|
|
@ -71,14 +71,17 @@ public class LocalIdentityStoreProvider extends IdentityStoreProvider {
|
|||
return AppI18n.get("localIdentity");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
@Override
|
||||
public String getId() {
|
||||
return "localIdentity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore() {
|
||||
return LocalIdentityStore.builder().password(EncryptedValue.of(new SecretRetrievalStrategy.None())).sshIdentity(EncryptedValue.of(new SshIdentityStrategy.None())).build();
|
||||
return LocalIdentityStore.builder()
|
||||
.password(EncryptedValue.of(new SecretRetrievalStrategy.None()))
|
||||
.sshIdentity(EncryptedValue.of(new SshIdentityStrategy.None()))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -173,8 +173,9 @@ public interface SshIdentityStrategy {
|
|||
if (s.startsWith("~")) {
|
||||
s = s.resolveTildeHome(parent.getOsType().getUserHomeDirectory(parent));
|
||||
}
|
||||
var resolved =
|
||||
parent.getShellDialect().evaluateExpression(parent, s.toString()).readStdoutOrThrow();
|
||||
var resolved = parent.getShellDialect()
|
||||
.evaluateExpression(parent, s.toString())
|
||||
.readStdoutOrThrow();
|
||||
if (!parent.getShellDialect()
|
||||
.createFileExistsCommand(parent, resolved)
|
||||
.executeAndCheck()) {
|
||||
|
@ -216,8 +217,9 @@ public interface SshIdentityStrategy {
|
|||
if (s.startsWith("~")) {
|
||||
s = s.resolveTildeHome(sc.getOsType().getUserHomeDirectory(sc));
|
||||
}
|
||||
var resolved =
|
||||
sc.getShellDialect().evaluateExpression(sc, s.toString()).readStdoutOrThrow();
|
||||
var resolved = sc.getShellDialect()
|
||||
.evaluateExpression(sc, s.toString())
|
||||
.readStdoutOrThrow();
|
||||
return sc.getShellDialect().fileArgument(resolved);
|
||||
})
|
||||
.add("-oIdentitiesOnly=yes");
|
||||
|
|
|
@ -7,8 +7,8 @@ import io.xpipe.app.ext.ShellStore;
|
|||
import io.xpipe.app.storage.ContextualFileReference;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.*;
|
||||
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue