mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
More browser fixes
This commit is contained in:
parent
7ca4d64e2d
commit
305f8d69e8
14 changed files with 150 additions and 100 deletions
|
@ -1,8 +1,6 @@
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import io.xpipe.core.store.DataStore;
|
|
||||||
import io.xpipe.core.store.FileSystem;
|
|
||||||
import io.xpipe.core.store.ShellStore;
|
import io.xpipe.core.store.ShellStore;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
|
@ -18,20 +16,6 @@ public class BrowserModel {
|
||||||
private final ObservableList<OpenFileSystemModel> openFileSystems = FXCollections.observableArrayList();
|
private final ObservableList<OpenFileSystemModel> openFileSystems = FXCollections.observableArrayList();
|
||||||
private final Property<OpenFileSystemModel> selected = new SimpleObjectProperty<>();
|
private final Property<OpenFileSystemModel> selected = new SimpleObjectProperty<>();
|
||||||
|
|
||||||
public OpenFileSystemModel getOpenModelFor(DataStore store) {
|
|
||||||
return openFileSystems.stream()
|
|
||||||
.filter(model -> model.getStore().equals(store))
|
|
||||||
.findFirst()
|
|
||||||
.orElseThrow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenFileSystemModel getOpenModelFor(FileSystem fileSystem) {
|
|
||||||
return openFileSystems.stream()
|
|
||||||
.filter(model -> model.getFileSystem().equals(fileSystem))
|
|
||||||
.findFirst()
|
|
||||||
.orElseThrow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeFileSystem(OpenFileSystemModel open) {
|
public void closeFileSystem(OpenFileSystemModel open) {
|
||||||
ThreadHelper.runAsync(() -> {
|
ThreadHelper.runAsync(() -> {
|
||||||
open.closeSync();
|
open.closeSync();
|
||||||
|
@ -41,7 +25,7 @@ public class BrowserModel {
|
||||||
|
|
||||||
public void openFileSystem(ShellStore store) {
|
public void openFileSystem(ShellStore store) {
|
||||||
var found = openFileSystems.stream()
|
var found = openFileSystems.stream()
|
||||||
.filter(fileSystemModel -> fileSystemModel.getStore().equals(store))
|
.filter(fileSystemModel -> fileSystemModel.getStore().getValue().equals(store))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
if (found.isPresent()) {
|
if (found.isPresent()) {
|
||||||
selected.setValue(found.get());
|
selected.setValue(found.get());
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
import io.xpipe.app.util.ExternalEditor;
|
import io.xpipe.app.util.*;
|
||||||
import io.xpipe.app.util.ScriptHelper;
|
|
||||||
import io.xpipe.app.util.TerminalHelper;
|
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellProcessControl;
|
import io.xpipe.core.process.ShellProcessControl;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
|
@ -21,11 +18,15 @@ import java.util.List;
|
||||||
|
|
||||||
final class FileContextMenu extends ContextMenu {
|
final class FileContextMenu extends ContextMenu {
|
||||||
|
|
||||||
public boolean isScript(FileSystem.FileEntry e) {
|
public boolean isExecutable(FileSystem.FileEntry e) {
|
||||||
if (e.isDirectory()) {
|
if (e.isDirectory()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.getExecutable() != null && e.getExecutable()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var shell = e.getFileSystem().getShell();
|
var shell = e.getFileSystem().getShell();
|
||||||
if (shell.isEmpty()) {
|
if (shell.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,7 +34,7 @@ final class FileContextMenu extends ContextMenu {
|
||||||
|
|
||||||
var os = shell.get().getOsType();
|
var os = shell.get().getOsType();
|
||||||
var ending = FilenameUtils.getExtension(e.getPath()).toLowerCase();
|
var ending = FilenameUtils.getExtension(e.getPath()).toLowerCase();
|
||||||
if (os.equals(OsType.WINDOWS) && List.of("bat", "ps1", "cmd").contains(ending)) {
|
if (os.equals(OsType.WINDOWS) && List.of("exe", "bat", "ps1", "cmd").contains(ending)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ final class FileContextMenu extends ContextMenu {
|
||||||
});
|
});
|
||||||
getItems().add(terminal);
|
getItems().add(terminal);
|
||||||
} else {
|
} else {
|
||||||
if (isScript(entry)) {
|
if (isExecutable(entry)) {
|
||||||
var execute = new MenuItem("Run in terminal");
|
var execute = new MenuItem("Run in terminal");
|
||||||
execute.setOnAction(event -> {
|
execute.setOnAction(event -> {
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
|
@ -91,23 +92,21 @@ final class FileContextMenu extends ContextMenu {
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
getItems().add(executeInBackground);
|
getItems().add(executeInBackground);
|
||||||
}
|
} else {
|
||||||
|
var open = new MenuItem("Open default");
|
||||||
var open = new MenuItem("Open default");
|
open.setOnAction(event -> {
|
||||||
open.setOnAction(event -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
FileOpener.openInDefaultApplication(entry);
|
||||||
ShellProcessControl pc = model.getFileSystem().getShell().orElseThrow();
|
});
|
||||||
var cmd = "\"" + entry.getPath() + "\"";
|
event.consume();
|
||||||
pc.executeBooleanSimpleCommand(cmd);
|
|
||||||
});
|
});
|
||||||
event.consume();
|
getItems().add(open);
|
||||||
});
|
}
|
||||||
getItems().add(open);
|
|
||||||
|
|
||||||
var edit = new MenuItem("Edit");
|
var edit = new MenuItem("Edit");
|
||||||
edit.setOnAction(event -> {
|
edit.setOnAction(event -> {
|
||||||
|
FileOpener.openInTextEditor(entry);
|
||||||
event.consume();
|
event.consume();
|
||||||
ExternalEditor.get().openInEditor(model.getFileSystem(), entry.getPath());
|
|
||||||
});
|
});
|
||||||
getItems().add(edit);
|
getItems().add(edit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import atlantafx.base.theme.Tweaks;
|
||||||
import io.xpipe.app.comp.base.LazyTextFieldComp;
|
import io.xpipe.app.comp.base.LazyTextFieldComp;
|
||||||
import io.xpipe.app.core.AppResources;
|
import io.xpipe.app.core.AppResources;
|
||||||
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
|
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
|
||||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
|
||||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
import io.xpipe.app.util.Containers;
|
import io.xpipe.app.util.Containers;
|
||||||
import io.xpipe.app.util.HumanReadableFormat;
|
import io.xpipe.app.util.HumanReadableFormat;
|
||||||
|
@ -235,7 +234,11 @@ final class FileListComp extends AnchorPane {
|
||||||
});
|
});
|
||||||
|
|
||||||
fileList.getShown().addListener((observable, oldValue, newValue) -> {
|
fileList.getShown().addListener((observable, oldValue, newValue) -> {
|
||||||
BindingsHelper.setContent(table.getItems(), newValue);
|
table.getItems().setAll(newValue);
|
||||||
|
|
||||||
|
if (newValue.size() > 0) {
|
||||||
|
table.scrollTo(0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return table;
|
return table;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.util.ExternalEditor;
|
import io.xpipe.app.util.FileOpener;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import javafx.beans.property.ObjectProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
@ -73,7 +73,7 @@ final class FileListModel {
|
||||||
if (entry.isDirectory()) {
|
if (entry.isDirectory()) {
|
||||||
model.navigate(entry.getPath(), true);
|
model.navigate(entry.getPath(), true);
|
||||||
} else {
|
} else {
|
||||||
ExternalEditor.get().openInEditor(entry.getFileSystem(), entry.getPath());
|
FileOpener.openInTextEditor(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ public class FileSystemHelper {
|
||||||
Files.getLastModifiedTime(file).toInstant(),
|
Files.getLastModifiedTime(file).toInstant(),
|
||||||
Files.isDirectory(file),
|
Files.isDirectory(file),
|
||||||
Files.isHidden(file),
|
Files.isHidden(file),
|
||||||
|
Files.isExecutable(file),
|
||||||
Files.size(file));
|
Files.size(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ final class OpenFileSystemModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileSystem.FileEntry getCurrentDirectory() {
|
public FileSystem.FileEntry getCurrentDirectory() {
|
||||||
return new FileSystem.FileEntry(fileSystem, currentPath.get(), Instant.now(), true, false, 0);
|
return new FileSystem.FileEntry(fileSystem, currentPath.get(), Instant.now(), true, false, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cd(String path) {
|
public void cd(String path) {
|
||||||
|
@ -75,7 +75,7 @@ final class OpenFileSystemModel {
|
||||||
newList = getFileSystem().listFiles(dir).collect(Collectors.toCollection(ArrayList::new));
|
newList = getFileSystem().listFiles(dir).collect(Collectors.toCollection(ArrayList::new));
|
||||||
} else {
|
} else {
|
||||||
newList = getFileSystem().listRoots().stream()
|
newList = getFileSystem().listRoots().stream()
|
||||||
.map(s -> new FileSystem.FileEntry(getFileSystem(), s, Instant.now(), true, false, 0))
|
.map(s -> new FileSystem.FileEntry(getFileSystem(), s, Instant.now(), true, false, false, 0))
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
}
|
}
|
||||||
fileList.setAll(newList);
|
fileList.setAll(newList);
|
||||||
|
@ -180,7 +180,9 @@ final class OpenFileSystemModel {
|
||||||
|
|
||||||
public void switchAsync(FileSystemStore fileSystem) {
|
public void switchAsync(FileSystemStore fileSystem) {
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
switchSync(fileSystem);
|
BusyProperty.execute(busy, () -> {
|
||||||
|
switchSync(fileSystem);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.issue.UserReportComp;
|
import io.xpipe.app.issue.UserReportComp;
|
||||||
import io.xpipe.app.util.DesktopHelper;
|
import io.xpipe.app.util.DesktopHelper;
|
||||||
import io.xpipe.app.util.DynamicOptionsBuilder;
|
import io.xpipe.app.util.DynamicOptionsBuilder;
|
||||||
import io.xpipe.app.util.ExternalEditor;
|
import io.xpipe.app.util.FileOpener;
|
||||||
import io.xpipe.core.util.XPipeInstallation;
|
import io.xpipe.core.util.XPipeInstallation;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@ public class BrowseDirectoryComp extends SimpleComp {
|
||||||
.addComp(
|
.addComp(
|
||||||
"logFile",
|
"logFile",
|
||||||
new ButtonComp(AppI18n.observable("openCurrentLogFile"), () -> {
|
new ButtonComp(AppI18n.observable("openCurrentLogFile"), () -> {
|
||||||
ExternalEditor.get()
|
FileOpener.openInTextEditor(AppLogs.get()
|
||||||
.openInEditor(AppLogs.get()
|
|
||||||
.getSessionLogsDirectory()
|
.getSessionLogsDirectory()
|
||||||
.resolve("xpipe.log")
|
.resolve("xpipe.log")
|
||||||
.toString());
|
.toString());
|
||||||
|
|
|
@ -4,7 +4,7 @@ import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.impl.IconButtonComp;
|
import io.xpipe.app.fxcomps.impl.IconButtonComp;
|
||||||
import io.xpipe.app.fxcomps.impl.TextAreaComp;
|
import io.xpipe.app.fxcomps.impl.TextAreaComp;
|
||||||
import io.xpipe.app.util.ExternalEditor;
|
import io.xpipe.app.util.FileOpener;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
@ -47,8 +47,8 @@ public class IntegratedTextAreaComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Region createOpenButton(Region container) {
|
private Region createOpenButton(Region container) {
|
||||||
var button = new IconButtonComp("mdal-edit", () -> ExternalEditor.get()
|
var button = new IconButtonComp("mdal-edit", () -> FileOpener
|
||||||
.startEditing(identifier, fileType, this, value.getValue(), (s) -> {
|
.openString(identifier, fileType, this, value.getValue(), (s) -> {
|
||||||
Platform.runLater(() -> value.setValue(s));
|
Platform.runLater(() -> value.setValue(s));
|
||||||
}))
|
}))
|
||||||
.createRegion();
|
.createRegion();
|
||||||
|
|
|
@ -9,7 +9,7 @@ import io.xpipe.app.issue.TrackEvent;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.update.AppUpdater;
|
import io.xpipe.app.update.AppUpdater;
|
||||||
import io.xpipe.app.util.ExternalEditor;
|
import io.xpipe.app.util.FileBridge;
|
||||||
import io.xpipe.core.util.JacksonMapper;
|
import io.xpipe.core.util.JacksonMapper;
|
||||||
|
|
||||||
public class BaseMode extends OperationMode {
|
public class BaseMode extends OperationMode {
|
||||||
|
@ -40,7 +40,7 @@ public class BaseMode extends OperationMode {
|
||||||
AppCharsetter.init();
|
AppCharsetter.init();
|
||||||
DataStorage.init();
|
DataStorage.init();
|
||||||
FileWatchManager.init();
|
FileWatchManager.init();
|
||||||
ExternalEditor.init();
|
FileBridge.init();
|
||||||
AppSocketServer.init();
|
AppSocketServer.init();
|
||||||
AppUpdater.init();
|
AppUpdater.init();
|
||||||
TrackEvent.info("mode", "Finished base components initialization");
|
TrackEvent.info("mode", "Finished base components initialization");
|
||||||
|
|
|
@ -4,11 +4,8 @@ import io.xpipe.app.core.FileWatchManager;
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.issue.TrackEvent;
|
import io.xpipe.app.issue.TrackEvent;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.core.impl.FileNames;
|
|
||||||
import io.xpipe.core.store.FileSystem;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
|
||||||
import org.apache.commons.lang3.function.FailableSupplier;
|
import org.apache.commons.lang3.function.FailableSupplier;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -24,14 +21,14 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class ExternalEditor {
|
public class FileBridge {
|
||||||
|
|
||||||
private static final Path TEMP =
|
private static final Path TEMP =
|
||||||
FileUtils.getTempDirectory().toPath().resolve("xpipe").resolve("editor");
|
FileUtils.getTempDirectory().toPath().resolve("xpipe").resolve("bridge");
|
||||||
private static ExternalEditor INSTANCE;
|
private static FileBridge INSTANCE;
|
||||||
private final Set<Entry> openEntries = new CopyOnWriteArraySet<>();
|
private final Set<Entry> openEntries = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
public static ExternalEditor get() {
|
public static FileBridge get() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +41,7 @@ public class ExternalEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
INSTANCE = new ExternalEditor();
|
INSTANCE = new FileBridge();
|
||||||
try {
|
try {
|
||||||
FileUtils.forceMkdir(TEMP.toFile());
|
FileUtils.forceMkdir(TEMP.toFile());
|
||||||
|
|
||||||
|
@ -124,13 +121,13 @@ public class ExternalEditor {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startEditing(String keyName, String fileType, Object key, String input, Consumer<String> output) {
|
public void openString(String keyName, String fileType, Object key, String input, Consumer<String> output, Consumer<String> consumer) {
|
||||||
if (input == null) {
|
if (input == null) {
|
||||||
input = "";
|
input = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String s = input;
|
String s = input;
|
||||||
startEditing(
|
openIO(
|
||||||
keyName,
|
keyName,
|
||||||
fileType,
|
fileType,
|
||||||
key,
|
key,
|
||||||
|
@ -141,18 +138,20 @@ public class ExternalEditor {
|
||||||
super.close();
|
super.close();
|
||||||
output.accept(new String(toByteArray(), StandardCharsets.UTF_8));
|
output.accept(new String(toByteArray(), StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startEditing(
|
public void openIO(
|
||||||
String keyName,
|
String keyName,
|
||||||
String fileType,
|
String fileType,
|
||||||
Object key,
|
Object key,
|
||||||
FailableSupplier<InputStream, Exception> input,
|
FailableSupplier<InputStream, Exception> input,
|
||||||
FailableSupplier<OutputStream, Exception> output) {
|
FailableSupplier<OutputStream, Exception> output,
|
||||||
|
Consumer<String> consumer) {
|
||||||
var ext = getForKey(key);
|
var ext = getForKey(key);
|
||||||
if (ext.isPresent()) {
|
if (ext.isPresent()) {
|
||||||
openInEditor(ext.get().file.toString());
|
consumer.accept(ext.get().file.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,31 +180,7 @@ public class ExternalEditor {
|
||||||
openEntries.add(entry);
|
openEntries.add(entry);
|
||||||
|
|
||||||
ext = getForKey(key);
|
ext = getForKey(key);
|
||||||
openInEditor(ext.orElseThrow().file.toString());
|
consumer.accept(ext.orElseThrow().file.toString());
|
||||||
}
|
|
||||||
|
|
||||||
public void openInEditor(FileSystem fileSystem, String file) {
|
|
||||||
var editor = AppPrefs.get().externalEditor().getValue();
|
|
||||||
if (editor == null || !editor.isSelectable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
startEditing(FileNames.getFileName(file), FilenameUtils.getExtension(file), file, () -> {
|
|
||||||
return fileSystem.openInput(file);
|
|
||||||
}, () -> fileSystem.openOutput(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openInEditor(String file) {
|
|
||||||
var editor = AppPrefs.get().externalEditor().getValue();
|
|
||||||
if (editor == null || !editor.isSelectable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
editor.launch(Path.of(file).toRealPath());
|
|
||||||
} catch (Exception e) {
|
|
||||||
ErrorEvent.fromThrowable(e).handle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
84
app/src/main/java/io/xpipe/app/util/FileOpener.java
Normal file
84
app/src/main/java/io/xpipe/app/util/FileOpener.java
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package io.xpipe.app.util;
|
||||||
|
|
||||||
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
|
import io.xpipe.core.impl.FileNames;
|
||||||
|
import io.xpipe.core.process.OsType;
|
||||||
|
import io.xpipe.core.store.FileSystem;
|
||||||
|
import io.xpipe.core.store.ShellStore;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class FileOpener {
|
||||||
|
|
||||||
|
public static void openInDefaultApplication(FileSystem.FileEntry entry) {
|
||||||
|
var editor = AppPrefs.get().externalEditor().getValue();
|
||||||
|
if (editor == null || !editor.isSelectable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = entry.getPath();
|
||||||
|
FileBridge.get()
|
||||||
|
.openIO(
|
||||||
|
FileNames.getFileName(file),
|
||||||
|
FilenameUtils.getExtension(file),
|
||||||
|
file,
|
||||||
|
() -> {
|
||||||
|
return entry.getFileSystem().openInput(file);
|
||||||
|
},
|
||||||
|
() -> entry.getFileSystem().openOutput(file),
|
||||||
|
s -> openInDefaultApplication(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openInTextEditor(FileSystem.FileEntry entry) {
|
||||||
|
var editor = AppPrefs.get().externalEditor().getValue();
|
||||||
|
if (editor == null || !editor.isSelectable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = entry.getPath();
|
||||||
|
FileBridge.get()
|
||||||
|
.openIO(
|
||||||
|
FileNames.getFileName(file),
|
||||||
|
FilenameUtils.getExtension(file),
|
||||||
|
file,
|
||||||
|
() -> {
|
||||||
|
return entry.getFileSystem().openInput(file);
|
||||||
|
},
|
||||||
|
() -> entry.getFileSystem().openOutput(file),
|
||||||
|
FileOpener::openInTextEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openInTextEditor(String file) {
|
||||||
|
var editor = AppPrefs.get().externalEditor().getValue();
|
||||||
|
if (editor == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
editor.launch(Path.of(file).toRealPath());
|
||||||
|
} catch (Exception e) {
|
||||||
|
ErrorEvent.fromThrowable(e).handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openInDefaultApplication(String file) {
|
||||||
|
try (var pc = ShellStore.local().create().start()) {
|
||||||
|
if (pc.getOsType().equals(OsType.WINDOWS)) {
|
||||||
|
pc.executeSimpleCommand("\"" + file + "\"");
|
||||||
|
} else if (pc.getOsType().equals(OsType.LINUX)) {
|
||||||
|
pc.executeSimpleCommand("xdg-open \"" + file + "\"");
|
||||||
|
} else {
|
||||||
|
pc.executeSimpleCommand("open \"" + file + "\"");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
ErrorEvent.fromThrowable(e).handle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void openString(String keyName, String fileType, Object key, String input, Consumer<String> output) {
|
||||||
|
FileBridge.get().openString(keyName, fileType, key, input, output, file -> openInTextEditor(file));
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,6 +15,16 @@ import java.util.Random;
|
||||||
|
|
||||||
public class ScriptHelper {
|
public class ScriptHelper {
|
||||||
|
|
||||||
|
public static String createDefaultOpenCommand(ShellProcessControl pc, String file) {
|
||||||
|
if (pc.getOsType().equals(OsType.WINDOWS)) {
|
||||||
|
return "\"" + file + "\"";
|
||||||
|
} else if (pc.getOsType().equals(OsType.LINUX)){
|
||||||
|
return "xdg-open \"" + file + "\"";
|
||||||
|
} else {
|
||||||
|
return "open \"" + file + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String createDetachCommand(ShellProcessControl pc, String command) {
|
public static String createDetachCommand(ShellProcessControl pc, String command) {
|
||||||
if (pc.getOsType().equals(OsType.WINDOWS)) {
|
if (pc.getOsType().equals(OsType.WINDOWS)) {
|
||||||
return "start \"\" " + command;
|
return "start \"\" " + command;
|
||||||
|
|
|
@ -24,6 +24,7 @@ public interface FileSystem extends Closeable, AutoCloseable {
|
||||||
Instant date;
|
Instant date;
|
||||||
boolean directory;
|
boolean directory;
|
||||||
boolean hidden;
|
boolean hidden;
|
||||||
|
Boolean executable;
|
||||||
long size;
|
long size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package io.xpipe.ext.base.actions;
|
||||||
|
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.ext.ActionProvider;
|
import io.xpipe.app.ext.ActionProvider;
|
||||||
import io.xpipe.app.util.ExternalEditor;
|
import io.xpipe.app.util.FileOpener;
|
||||||
import io.xpipe.core.impl.FileStore;
|
import io.xpipe.core.impl.FileStore;
|
||||||
import io.xpipe.core.impl.LocalStore;
|
import io.xpipe.core.impl.LocalStore;
|
||||||
import io.xpipe.core.store.DataFlow;
|
import io.xpipe.core.store.DataFlow;
|
||||||
|
@ -24,15 +24,7 @@ public class FileEditAction implements ActionProvider {
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
if (store.getFileSystem().equals(new LocalStore())) {
|
if (store.getFileSystem().equals(new LocalStore())) {
|
||||||
ExternalEditor.get().openInEditor(store.getFile());
|
FileOpener.openInTextEditor(store.getFile());
|
||||||
} else {
|
|
||||||
ExternalEditor.get()
|
|
||||||
.startEditing(
|
|
||||||
store.getFileName(),
|
|
||||||
store.getFileExtension(),
|
|
||||||
store,
|
|
||||||
() -> store.openInput(),
|
|
||||||
() -> store.openOutput());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue