mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
More file browser improvements
This commit is contained in:
parent
0eea4f3e3f
commit
a199b114c7
14 changed files with 126 additions and 26 deletions
|
@ -42,6 +42,7 @@ public class BrowserNavBar extends SimpleComp {
|
||||||
.createRegion();
|
.createRegion();
|
||||||
|
|
||||||
var stack = new StackPane(pathBar, breadcrumbs);
|
var stack = new StackPane(pathBar, breadcrumbs);
|
||||||
|
breadcrumbs.prefHeightProperty().bind(pathBar.heightProperty());
|
||||||
HBox.setHgrow(stack, Priority.ALWAYS);
|
HBox.setHgrow(stack, Priority.ALWAYS);
|
||||||
stack.setAlignment(Pos.CENTER_LEFT);
|
stack.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class FileBrowserBreadcrumbBar extends SimpleComp {
|
public class FileBrowserBreadcrumbBar extends SimpleComp {
|
||||||
|
|
||||||
private final OpenFileSystemModel model;
|
private final OpenFileSystemModel model;
|
||||||
|
@ -23,7 +25,8 @@ public class FileBrowserBreadcrumbBar extends SimpleComp {
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
Callback<Breadcrumbs.BreadCrumbItem<String>, ButtonBase> crumbFactory = crumb -> {
|
Callback<Breadcrumbs.BreadCrumbItem<String>, ButtonBase> crumbFactory = crumb -> {
|
||||||
var btn = new Button(FileNames.getFileName(crumb.getValue()), null);
|
var btn = new Button(crumb.getValue().equals("/") ? "/" : FileNames.getFileName(crumb.getValue()), null);
|
||||||
|
btn.setMnemonicParsing(false);
|
||||||
btn.setFocusTraversable(false);
|
btn.setFocusTraversable(false);
|
||||||
return btn;
|
return btn;
|
||||||
};
|
};
|
||||||
|
@ -45,11 +48,25 @@ public class FileBrowserBreadcrumbBar extends SimpleComp {
|
||||||
if (sc.isEmpty()) {
|
if (sc.isEmpty()) {
|
||||||
breadcrumbs.setDividerFactory(item -> item != null && !item.isLast() ? new Label("/") : null);
|
breadcrumbs.setDividerFactory(item -> item != null && !item.isLast() ? new Label("/") : null);
|
||||||
} else {
|
} else {
|
||||||
breadcrumbs.setDividerFactory(item -> item != null && !item.isLast() ? new Label(sc.get().getOsType().getFileSystemSeparator()) : null);
|
breadcrumbs.setDividerFactory(item -> {
|
||||||
|
if (item == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.isFirst() && item.getValue().equals("/")) {
|
||||||
|
return new Label("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return !item.isLast() ? new Label(sc.get().getOsType().getFileSystemSeparator()) : null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var elements = FileNames.splitHierarchy(val);
|
var elements = FileNames.splitHierarchy(val);
|
||||||
Breadcrumbs.BreadCrumbItem<String> items = Breadcrumbs.buildTreeModel(elements.toArray(String[]::new));
|
var modifiedElements = new ArrayList<>(elements);
|
||||||
|
if (val.startsWith("/")) {
|
||||||
|
modifiedElements.add(0, "/");
|
||||||
|
}
|
||||||
|
Breadcrumbs.BreadCrumbItem<String> items = Breadcrumbs.buildTreeModel(modifiedElements.toArray(String[]::new));
|
||||||
breadcrumbs.setSelectedCrumb(items);
|
breadcrumbs.setSelectedCrumb(items);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||||
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
||||||
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
|
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
|
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.util.BusyProperty;
|
import io.xpipe.app.util.BusyProperty;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
|
@ -58,6 +59,14 @@ public class FileBrowserComp extends SimpleComp {
|
||||||
|
|
||||||
return !model.getMode().equals(FileBrowserModel.Mode.BROWSER);
|
return !model.getMode().equals(FileBrowserModel.Mode.BROWSER);
|
||||||
}, PlatformThread.sync(model.getOpenFileSystems()))).createRegion();
|
}, PlatformThread.sync(model.getOpenFileSystems()))).createRegion();
|
||||||
|
SimpleChangeListener.apply(model.getSelected(), val -> {
|
||||||
|
localDownloadStage.visibleProperty().unbind();
|
||||||
|
if (val == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
localDownloadStage.visibleProperty().bind(PlatformThread.sync(val.getLocal().not()));
|
||||||
|
});
|
||||||
var vertical = new VBox(bookmarksList, localDownloadStage);
|
var vertical = new VBox(bookmarksList, localDownloadStage);
|
||||||
vertical.setFillWidth(true);
|
vertical.setFillWidth(true);
|
||||||
|
|
||||||
|
@ -68,7 +77,9 @@ public class FileBrowserComp extends SimpleComp {
|
||||||
// set sidebar width in pixels depending on split pane width
|
// set sidebar width in pixels depending on split pane width
|
||||||
(obs, old, val) -> splitPane.setDividerPosition(0, 230 / splitPane.getWidth()));
|
(obs, old, val) -> splitPane.setDividerPosition(0, 230 / splitPane.getWidth()));
|
||||||
|
|
||||||
return addBottomBar(splitPane);
|
var r = addBottomBar(splitPane);
|
||||||
|
// AppFont.small(r);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Region addBottomBar(Region r) {
|
private Region addBottomBar(Region r) {
|
||||||
|
|
|
@ -3,12 +3,11 @@ package io.xpipe.app.browser;
|
||||||
import atlantafx.base.theme.Styles;
|
import atlantafx.base.theme.Styles;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.CompStructure;
|
import io.xpipe.app.fxcomps.CompStructure;
|
||||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
|
||||||
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
|
||||||
import io.xpipe.app.fxcomps.impl.TextFieldComp;
|
import io.xpipe.app.fxcomps.impl.TextFieldComp;
|
||||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
@ -47,7 +46,6 @@ public class FileFilterComp extends Comp<FileFilterComp.Structure> {
|
||||||
});
|
});
|
||||||
|
|
||||||
var fi = new FontIcon("mdi2m-magnify");
|
var fi = new FontIcon("mdi2m-magnify");
|
||||||
GrowAugment.create(false, true).augment(new SimpleCompStructure<>(button));
|
|
||||||
button.setGraphic(fi);
|
button.setGraphic(fi);
|
||||||
button.setOnAction(event -> {
|
button.setOnAction(event -> {
|
||||||
if (expanded.get()) {
|
if (expanded.get()) {
|
||||||
|
@ -75,9 +73,10 @@ public class FileFilterComp extends Comp<FileFilterComp.Structure> {
|
||||||
button.getStyleClass().add(Styles.FLAT);
|
button.getStyleClass().add(Styles.FLAT);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
button.prefHeightProperty().bind(text.heightProperty());
|
||||||
|
|
||||||
var box = new HBox(text, button);
|
var box = new HBox(text, button);
|
||||||
box.setFillHeight(true);
|
box.setAlignment(Pos.CENTER);
|
||||||
return new Structure(box, (TextField) text, button);
|
return new Structure(box, (TextField) text, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,11 @@ package io.xpipe.app.browser;
|
||||||
import atlantafx.base.controls.Spacer;
|
import atlantafx.base.controls.Spacer;
|
||||||
import io.xpipe.app.browser.action.BranchAction;
|
import io.xpipe.app.browser.action.BranchAction;
|
||||||
import io.xpipe.app.browser.action.BrowserAction;
|
import io.xpipe.app.browser.action.BrowserAction;
|
||||||
import io.xpipe.app.comp.base.AlertOverlayComp;
|
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.impl.TextFieldComp;
|
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.fxcomps.util.Shortcuts;
|
import io.xpipe.app.fxcomps.util.Shortcuts;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.MenuButton;
|
import javafx.scene.control.MenuButton;
|
||||||
|
@ -17,7 +15,6 @@ import javafx.scene.control.ToolBar;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
import javafx.scene.input.KeyCombination;
|
import javafx.scene.input.KeyCombination;
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
@ -39,7 +36,7 @@ public class OpenFileSystemComp extends SimpleComp {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var alertOverlay = new AlertOverlayComp(
|
var alertOverlay = new ModalOverlayComp(
|
||||||
Comp.of(() -> createContent()),
|
Comp.of(() -> createContent()),
|
||||||
model.getOverlay());
|
model.getOverlay());
|
||||||
return alertOverlay.createRegion();
|
return alertOverlay.createRegion();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
import io.xpipe.app.comp.base.AlertOverlayComp;
|
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||||
import io.xpipe.app.core.AppCache;
|
import io.xpipe.app.core.AppCache;
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
|
@ -44,7 +44,8 @@ public final class OpenFileSystemModel {
|
||||||
private final BooleanProperty noDirectory = new SimpleBooleanProperty();
|
private final BooleanProperty noDirectory = new SimpleBooleanProperty();
|
||||||
private final Property<OpenFileSystemSavedState> savedState = new SimpleObjectProperty<>();
|
private final Property<OpenFileSystemSavedState> savedState = new SimpleObjectProperty<>();
|
||||||
private final OpenFileSystemCache cache = new OpenFileSystemCache(this);
|
private final OpenFileSystemCache cache = new OpenFileSystemCache(this);
|
||||||
private final Property<AlertOverlayComp.OverlayContent> overlay = new SimpleObjectProperty<>();
|
private final Property<ModalOverlayComp.OverlayContent> overlay = new SimpleObjectProperty<>();
|
||||||
|
private final BooleanProperty local = new SimpleBooleanProperty();
|
||||||
|
|
||||||
public OpenFileSystemModel(FileBrowserModel browserModel) {
|
public OpenFileSystemModel(FileBrowserModel browserModel) {
|
||||||
this.browserModel = browserModel;
|
this.browserModel = browserModel;
|
||||||
|
@ -122,6 +123,11 @@ public final class OpenFileSystemModel {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle commands typed into navigation bar
|
||||||
|
if (!FileNames.isAbsolute(path)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
String newPath = null;
|
String newPath = null;
|
||||||
try {
|
try {
|
||||||
newPath = FileSystemHelper.resolveDirectoryPath(this, path);
|
newPath = FileSystemHelper.resolveDirectoryPath(this, path);
|
||||||
|
@ -300,6 +306,7 @@ public final class OpenFileSystemModel {
|
||||||
var fs = fileSystem.createFileSystem();
|
var fs = fileSystem.createFileSystem();
|
||||||
fs.open();
|
fs.open();
|
||||||
this.fileSystem = fs;
|
this.fileSystem = fs;
|
||||||
|
this.local.set(fs.getShell().map(shellControl -> shellControl.isLocal()).orElse(false));
|
||||||
|
|
||||||
var storageEntry = DataStorage.get()
|
var storageEntry = DataStorage.get()
|
||||||
.getStoreEntryIfPresent(fileSystem)
|
.getStoreEntryIfPresent(fileSystem)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.xpipe.app.comp.base;
|
package io.xpipe.app.comp.base;
|
||||||
|
|
||||||
|
import atlantafx.base.controls.ModalPane;
|
||||||
import atlantafx.base.theme.Styles;
|
import atlantafx.base.theme.Styles;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
|
@ -21,10 +22,10 @@ import javafx.scene.layout.VBox;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
public class AlertOverlayComp extends SimpleComp {
|
public class ModalOverlayComp extends SimpleComp {
|
||||||
|
|
||||||
|
|
||||||
public AlertOverlayComp(Comp<?> background, Property<OverlayContent> overlayContent) {
|
public ModalOverlayComp(Comp<?> background, Property<OverlayContent> overlayContent) {
|
||||||
this.background = background;
|
this.background = background;
|
||||||
this.overlayContent = overlayContent;
|
this.overlayContent = overlayContent;
|
||||||
}
|
}
|
||||||
|
@ -43,11 +44,12 @@ public class AlertOverlayComp extends SimpleComp {
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var bgRegion = background.createRegion();
|
var bgRegion = background.createRegion();
|
||||||
var pane = new StackPane(bgRegion);
|
var modal = new ModalPane();
|
||||||
|
var pane = new StackPane(bgRegion, modal);
|
||||||
pane.setPickOnBounds(false);
|
pane.setPickOnBounds(false);
|
||||||
PlatformThread.sync(overlayContent).addListener((observable, oldValue, newValue) -> {
|
PlatformThread.sync(overlayContent).addListener((observable, oldValue, newValue) -> {
|
||||||
if (oldValue != null) {
|
if (oldValue != null) {
|
||||||
pane.getChildren().remove(1);
|
modal.hide(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newValue != null) {
|
if (newValue != null) {
|
||||||
|
@ -91,7 +93,7 @@ public class AlertOverlayComp extends SimpleComp {
|
||||||
close.maxWidthProperty().bind(tp.widthProperty());
|
close.maxWidthProperty().bind(tp.widthProperty());
|
||||||
close.maxHeightProperty().bind(tp.heightProperty());
|
close.maxHeightProperty().bind(tp.heightProperty());
|
||||||
|
|
||||||
pane.getChildren().add(stack);
|
modal.show(stack);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return pane;
|
return pane;
|
|
@ -8,6 +8,7 @@ import io.xpipe.app.launcher.LauncherCommand;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import io.xpipe.app.util.XPipeSession;
|
import io.xpipe.app.util.XPipeSession;
|
||||||
import io.xpipe.core.util.XPipeDaemonMode;
|
import io.xpipe.core.util.XPipeDaemonMode;
|
||||||
|
import io.xpipe.core.util.XPipeSystemId;
|
||||||
import org.apache.commons.lang3.function.FailableRunnable;
|
import org.apache.commons.lang3.function.FailableRunnable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -91,6 +92,7 @@ public abstract class OperationMode {
|
||||||
AppProperties.logArguments(args);
|
AppProperties.logArguments(args);
|
||||||
AppProperties.logSystemProperties();
|
AppProperties.logSystemProperties();
|
||||||
AppProperties.logPassedProperties();
|
AppProperties.logPassedProperties();
|
||||||
|
XPipeSystemId.init();
|
||||||
TrackEvent.info("mode", "Finished initial setup");
|
TrackEvent.info("mode", "Finished initial setup");
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
ErrorEvent.fromThrowable(ex).term().handle();
|
ErrorEvent.fromThrowable(ex).term().handle();
|
||||||
|
|
|
@ -76,6 +76,10 @@
|
||||||
-fx-padding: 0;
|
-fx-padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.browser .breadcrumbs {
|
||||||
|
-fx-padding: 2px 10px 2px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.browser .context-menu .separator .line {
|
.browser .context-menu .separator .line {
|
||||||
-fx-padding: 0;
|
-fx-padding: 0;
|
||||||
-fx-border-insets: 0px;
|
-fx-border-insets: 0px;
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class FileNames {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file.startsWith("/") && !file.startsWith("~") && !file.matches("^\\w:.*")) {
|
if (!file.startsWith("\\") && !file.startsWith("/") && !file.startsWith("~") && !file.matches("^\\w:.*")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package io.xpipe.core.process;
|
package io.xpipe.core.process;
|
||||||
|
|
||||||
|
import io.xpipe.core.impl.FileNames;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -23,6 +25,14 @@ public sealed interface OsType permits OsType.Windows, OsType.Linux, OsType.MacO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default String getXPipeHomeDirectory(ShellControl pc) throws Exception {
|
||||||
|
return FileNames.join(getHomeDirectory(pc), ".xpipe");
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getSystemIdFile(ShellControl pc) throws Exception {
|
||||||
|
return FileNames.join(getXPipeHomeDirectory(pc), "system_id");
|
||||||
|
}
|
||||||
|
|
||||||
String getHomeDirectory(ShellControl pc) throws Exception;
|
String getHomeDirectory(ShellControl pc) throws Exception;
|
||||||
|
|
||||||
String getFileSystemSeparator();
|
String getFileSystemSeparator();
|
||||||
|
|
|
@ -2,17 +2,25 @@ package io.xpipe.core.process;
|
||||||
|
|
||||||
import io.xpipe.core.util.FailableFunction;
|
import io.xpipe.core.util.FailableFunction;
|
||||||
import io.xpipe.core.util.SecretValue;
|
import io.xpipe.core.util.SecretValue;
|
||||||
|
import io.xpipe.core.util.XPipeSystemId;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public interface ShellControl extends ProcessControl {
|
public interface ShellControl extends ProcessControl {
|
||||||
|
|
||||||
|
default boolean isLocal() {
|
||||||
|
return getSystemId().equals(XPipeSystemId.getLocal());
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID getSystemId();
|
||||||
|
|
||||||
Semaphore getCommandLock();
|
Semaphore getCommandLock();
|
||||||
|
|
||||||
ShellControl onInit(Consumer<ShellControl> pc);
|
ShellControl onInit(Consumer<ShellControl> pc);
|
||||||
|
@ -63,8 +71,6 @@ public interface ShellControl extends ProcessControl {
|
||||||
|
|
||||||
void restart() throws Exception;
|
void restart() throws Exception;
|
||||||
|
|
||||||
boolean isLocal();
|
|
||||||
|
|
||||||
OsType getOsType();
|
OsType getOsType();
|
||||||
|
|
||||||
ShellControl elevated(FailableFunction<ShellControl, Boolean, Exception> elevationFunction);
|
ShellControl elevated(FailableFunction<ShellControl, Boolean, Exception> elevationFunction);
|
||||||
|
|
44
core/src/main/java/io/xpipe/core/util/XPipeSystemId.java
Normal file
44
core/src/main/java/io/xpipe/core/util/XPipeSystemId.java
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package io.xpipe.core.util;
|
||||||
|
|
||||||
|
import io.xpipe.core.impl.FileNames;
|
||||||
|
import io.xpipe.core.process.ShellControl;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class XPipeSystemId {
|
||||||
|
|
||||||
|
private static UUID localId;
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
try {
|
||||||
|
var file = Path.of(System.getProperty("user.home")).resolve(".xpipe").resolve("system_id");
|
||||||
|
if (!Files.exists(file)) {
|
||||||
|
Files.writeString(file, UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
localId = UUID.fromString(Files.readString(file).trim());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
localId = UUID.randomUUID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID getLocal() {
|
||||||
|
return localId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID getSystemId(ShellControl proc) throws Exception {
|
||||||
|
var file = proc.getOsType().getSystemIdFile(proc);
|
||||||
|
|
||||||
|
if (!proc.getShellDialect().createFileExistsCommand(proc, file).executeAndCheck()) {
|
||||||
|
proc.executeSimpleCommand(
|
||||||
|
proc.getShellDialect().getMkdirsCommand(FileNames.getParent(file)),
|
||||||
|
"Unable to access or create directory " + file);
|
||||||
|
var id = UUID.randomUUID();
|
||||||
|
proc.getShellDialect().createTextFileWriteCommand(proc, id.toString(), file).execute();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UUID.fromString(proc.executeSimpleStringCommand(proc.getShellDialect().getFileReadCommand(file)).trim());
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import io.xpipe.app.browser.action.BranchAction;
|
||||||
import io.xpipe.app.browser.action.BrowserAction;
|
import io.xpipe.app.browser.action.BrowserAction;
|
||||||
import io.xpipe.app.browser.action.LeafAction;
|
import io.xpipe.app.browser.action.LeafAction;
|
||||||
import io.xpipe.app.browser.icon.FileBrowserIcons;
|
import io.xpipe.app.browser.icon.FileBrowserIcons;
|
||||||
import io.xpipe.app.comp.base.AlertOverlayComp;
|
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
@ -55,7 +55,7 @@ public class NewItemAction implements BrowserAction, BranchAction {
|
||||||
@Override
|
@Override
|
||||||
public void execute(OpenFileSystemModel model, List<FileBrowserEntry> entries) throws Exception {
|
public void execute(OpenFileSystemModel model, List<FileBrowserEntry> entries) throws Exception {
|
||||||
var name = new SimpleStringProperty();
|
var name = new SimpleStringProperty();
|
||||||
model.getOverlay().setValue(new AlertOverlayComp.OverlayContent(AppI18n.observable("newFile"), Comp.of(() -> {
|
model.getOverlay().setValue(new ModalOverlayComp.OverlayContent(AppI18n.observable("newFile"), Comp.of(() -> {
|
||||||
var creationName = new TextField();
|
var creationName = new TextField();
|
||||||
creationName.textProperty().bindBidirectional(name);
|
creationName.textProperty().bindBidirectional(name);
|
||||||
return creationName;
|
return creationName;
|
||||||
|
@ -78,7 +78,7 @@ public class NewItemAction implements BrowserAction, BranchAction {
|
||||||
@Override
|
@Override
|
||||||
public void execute(OpenFileSystemModel model, List<FileBrowserEntry> entries) throws Exception {
|
public void execute(OpenFileSystemModel model, List<FileBrowserEntry> entries) throws Exception {
|
||||||
var name = new SimpleStringProperty();
|
var name = new SimpleStringProperty();
|
||||||
model.getOverlay().setValue(new AlertOverlayComp.OverlayContent(AppI18n.observable("newDirectory"), Comp.of(() -> {
|
model.getOverlay().setValue(new ModalOverlayComp.OverlayContent(AppI18n.observable("newDirectory"), Comp.of(() -> {
|
||||||
var creationName = new TextField();
|
var creationName = new TextField();
|
||||||
creationName.textProperty().bindBidirectional(name);
|
creationName.textProperty().bindBidirectional(name);
|
||||||
return creationName;
|
return creationName;
|
||||||
|
|
Loading…
Reference in a new issue