mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-09-30 00:56:56 +13:00
Introduce file kinds
This commit is contained in:
parent
daa011ffe6
commit
4a21dffdab
25 changed files with 94 additions and 164 deletions
|
@ -2,6 +2,7 @@ package io.xpipe.app.browser;
|
||||||
|
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.core.AppWindowHelper;
|
import io.xpipe.app.core.AppWindowHelper;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ import java.util.stream.Collectors;
|
||||||
public class BrowserAlerts {
|
public class BrowserAlerts {
|
||||||
|
|
||||||
public static boolean showMoveAlert(List<FileSystem.FileEntry> source, FileSystem.FileEntry target) {
|
public static boolean showMoveAlert(List<FileSystem.FileEntry> source, FileSystem.FileEntry target) {
|
||||||
if (source.stream().noneMatch(entry -> entry.isDirectory())) {
|
if (source.stream().noneMatch(entry -> entry.getKind() == FileKind.DIRECTORY)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ public class BrowserAlerts {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean showDeleteAlert(List<FileSystem.FileEntry> source) {
|
public static boolean showDeleteAlert(List<FileSystem.FileEntry> source) {
|
||||||
if (source.stream().noneMatch(entry -> entry.isDirectory())) {
|
if (source.stream().noneMatch(entry -> entry.getKind() == FileKind.DIRECTORY)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.app.browser;
|
||||||
import io.xpipe.app.browser.icon.DirectoryType;
|
import io.xpipe.app.browser.icon.DirectoryType;
|
||||||
import io.xpipe.app.browser.icon.FileType;
|
import io.xpipe.app.browser.icon.FileType;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ public class BrowserEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FileType fileType(FileSystem.FileEntry rawFileEntry) {
|
private static FileType fileType(FileSystem.FileEntry rawFileEntry) {
|
||||||
if (rawFileEntry.isDirectory()) {
|
if (rawFileEntry.getKind() == FileKind.DIRECTORY) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ public class BrowserEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DirectoryType directoryType(FileSystem.FileEntry rawFileEntry) {
|
private static DirectoryType directoryType(FileSystem.FileEntry rawFileEntry) {
|
||||||
if (!rawFileEntry.isDirectory()) {
|
if (rawFileEntry.getKind() != FileKind.DIRECTORY) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import io.xpipe.app.util.HumanReadableFormat;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
|
@ -111,7 +112,7 @@ final class BrowserFileListComp extends SimpleComp {
|
||||||
|
|
||||||
var syntheticFirst = Comparator.<BrowserEntry, Boolean>comparing(path -> !path.isSynthetic());
|
var syntheticFirst = Comparator.<BrowserEntry, Boolean>comparing(path -> !path.isSynthetic());
|
||||||
var dirsFirst = Comparator.<BrowserEntry, Boolean>comparing(
|
var dirsFirst = Comparator.<BrowserEntry, Boolean>comparing(
|
||||||
path -> !path.getRawFileEntry().isDirectory());
|
path -> path.getRawFileEntry().getKind() != FileKind.DIRECTORY);
|
||||||
|
|
||||||
Comparator<? super BrowserEntry> us =
|
Comparator<? super BrowserEntry> us =
|
||||||
syntheticFirst.thenComparing(dirsFirst).thenComparing(comp);
|
syntheticFirst.thenComparing(dirsFirst).thenComparing(comp);
|
||||||
|
@ -149,9 +150,9 @@ final class BrowserFileListComp extends SimpleComp {
|
||||||
.getCurrentParentDirectory()
|
.getCurrentParentDirectory()
|
||||||
.getPath()));
|
.getPath()));
|
||||||
// Remove unsuitable selection
|
// Remove unsuitable selection
|
||||||
toSelect.removeIf(browserEntry -> (browserEntry.getRawFileEntry().isDirectory()
|
toSelect.removeIf(browserEntry -> (browserEntry.getRawFileEntry().getKind() == FileKind.DIRECTORY
|
||||||
&& !fileList.getMode().isAcceptsDirectories())
|
&& !fileList.getMode().isAcceptsDirectories())
|
||||||
|| (!browserEntry.getRawFileEntry().isDirectory()
|
|| (browserEntry.getRawFileEntry().getKind() != FileKind.DIRECTORY
|
||||||
&& !fileList.getMode().isAcceptsFiles()));
|
&& !fileList.getMode().isAcceptsFiles()));
|
||||||
fileList.getSelection().setAll(toSelect);
|
fileList.getSelection().setAll(toSelect);
|
||||||
|
|
||||||
|
@ -233,11 +234,11 @@ final class BrowserFileListComp extends SimpleComp {
|
||||||
return event.getButton() == MouseButton.SECONDARY;
|
return event.getButton() == MouseButton.SECONDARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row.getItem() != null && row.getItem().getRawFileEntry().isDirectory()) {
|
if (row.getItem() != null && row.getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY) {
|
||||||
return event.getButton() == MouseButton.SECONDARY;
|
return event.getButton() == MouseButton.SECONDARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row.getItem() != null && !row.getItem().getRawFileEntry().isDirectory()) {
|
if (row.getItem() != null && row.getItem().getRawFileEntry().getKind() != FileKind.DIRECTORY) {
|
||||||
return event.getButton() == MouseButton.SECONDARY || event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2;
|
return event.getButton() == MouseButton.SECONDARY || event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,9 +262,9 @@ final class BrowserFileListComp extends SimpleComp {
|
||||||
row.itemProperty().addListener((observable, oldValue, newValue) -> {
|
row.itemProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
row.pseudoClassStateChanged(EMPTY, newValue == null);
|
row.pseudoClassStateChanged(EMPTY, newValue == null);
|
||||||
row.pseudoClassStateChanged(
|
row.pseudoClassStateChanged(
|
||||||
FILE, newValue != null && !newValue.getRawFileEntry().isDirectory());
|
FILE, newValue != null && newValue.getRawFileEntry().getKind() != FileKind.DIRECTORY);
|
||||||
row.pseudoClassStateChanged(
|
row.pseudoClassStateChanged(
|
||||||
FOLDER, newValue != null && newValue.getRawFileEntry().isDirectory());
|
FOLDER, newValue != null && newValue.getRawFileEntry().getKind() == FileKind.DIRECTORY);
|
||||||
});
|
});
|
||||||
|
|
||||||
fileList.getDraggedOverDirectory().addListener((observable, oldValue, newValue) -> {
|
fileList.getDraggedOverDirectory().addListener((observable, oldValue, newValue) -> {
|
||||||
|
@ -455,7 +456,7 @@ final class BrowserFileListComp extends SimpleComp {
|
||||||
: getTableRow().getItem().getRawFileEntry(),
|
: getTableRow().getItem().getRawFileEntry(),
|
||||||
isParentLink));
|
isParentLink));
|
||||||
|
|
||||||
var isDirectory = getTableRow().getItem().getRawFileEntry().isDirectory();
|
var isDirectory = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY;
|
||||||
pseudoClassStateChanged(FOLDER, isDirectory);
|
pseudoClassStateChanged(FOLDER, isDirectory);
|
||||||
|
|
||||||
var fileName = isParentLink ? ".." : FileNames.getFileName(fullPath);
|
var fileName = isParentLink ? ".." : FileNames.getFileName(fullPath);
|
||||||
|
@ -477,7 +478,7 @@ final class BrowserFileListComp extends SimpleComp {
|
||||||
setText(null);
|
setText(null);
|
||||||
} else {
|
} else {
|
||||||
var path = getTableRow().getItem();
|
var path = getTableRow().getItem();
|
||||||
if (path.getRawFileEntry().isDirectory()) {
|
if (path.getRawFileEntry().getKind() == FileKind.DIRECTORY) {
|
||||||
setText("");
|
setText("");
|
||||||
} else {
|
} else {
|
||||||
setText(byteCount(fileSize.longValue()));
|
setText(byteCount(fileSize.longValue()));
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.TableView;
|
import javafx.scene.control.TableView;
|
||||||
|
@ -80,7 +81,7 @@ public class BrowserFileListCompEntry {
|
||||||
// Prevent drag and drops of files into the current directory
|
// Prevent drag and drops of files into the current directory
|
||||||
if (BrowserClipboard.currentDragClipboard
|
if (BrowserClipboard.currentDragClipboard
|
||||||
.getBaseDirectory().getPath()
|
.getBaseDirectory().getPath()
|
||||||
.equals(model.getFileSystemModel().getCurrentDirectory().getPath()) && (item == null || !item.getRawFileEntry().isDirectory())) {
|
.equals(model.getFileSystemModel().getCurrentDirectory().getPath()) && (item == null || item.getRawFileEntry().getKind() != FileKind.DIRECTORY)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +101,7 @@ public class BrowserFileListCompEntry {
|
||||||
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
||||||
Dragboard db = event.getDragboard();
|
Dragboard db = event.getDragboard();
|
||||||
var list = db.getFiles().stream().map(File::toPath).toList();
|
var list = db.getFiles().stream().map(File::toPath).toList();
|
||||||
var target = item != null && item.getRawFileEntry().isDirectory()
|
var target = item != null && item.getRawFileEntry().getKind() == FileKind.DIRECTORY
|
||||||
? item.getRawFileEntry()
|
? item.getRawFileEntry()
|
||||||
: model.getFileSystemModel().getCurrentDirectory();
|
: model.getFileSystemModel().getCurrentDirectory();
|
||||||
model.getFileSystemModel().dropLocalFilesIntoAsync(target, list);
|
model.getFileSystemModel().dropLocalFilesIntoAsync(target, list);
|
||||||
|
@ -111,7 +112,7 @@ public class BrowserFileListCompEntry {
|
||||||
// Accept drops from inside the app window
|
// Accept drops from inside the app window
|
||||||
if (event.getGestureSource() != null) {
|
if (event.getGestureSource() != null) {
|
||||||
var files = BrowserClipboard.retrieveDrag(event.getDragboard()).getEntries();
|
var files = BrowserClipboard.retrieveDrag(event.getDragboard()).getEntries();
|
||||||
var target = item != null && item.getRawFileEntry().isDirectory()
|
var target = item != null && item.getRawFileEntry().getKind() == FileKind.DIRECTORY
|
||||||
? item.getRawFileEntry()
|
? item.getRawFileEntry()
|
||||||
: model.getFileSystemModel().getCurrentDirectory();
|
: model.getFileSystemModel().getCurrentDirectory();
|
||||||
model.getFileSystemModel().dropFilesIntoAsync(target, files, false);
|
model.getFileSystemModel().dropFilesIntoAsync(target, files, false);
|
||||||
|
@ -121,7 +122,7 @@ public class BrowserFileListCompEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDragExited(DragEvent event) {
|
public void onDragExited(DragEvent event) {
|
||||||
if (item != null && item.getRawFileEntry().isDirectory()) {
|
if (item != null && item.getRawFileEntry().getKind() == FileKind.DIRECTORY) {
|
||||||
model.getDraggedOverDirectory().setValue(null);
|
model.getDraggedOverDirectory().setValue(null);
|
||||||
} else {
|
} else {
|
||||||
model.getDraggedOverEmpty().setValue(false);
|
model.getDraggedOverEmpty().setValue(false);
|
||||||
|
@ -151,13 +152,13 @@ public class BrowserFileListCompEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void acceptDrag(DragEvent event) {
|
private void acceptDrag(DragEvent event) {
|
||||||
model.getDraggedOverEmpty().setValue(item == null || !item.getRawFileEntry().isDirectory());
|
model.getDraggedOverEmpty().setValue(item == null || item.getRawFileEntry().getKind() != FileKind.DIRECTORY);
|
||||||
model.getDraggedOverDirectory().setValue(item);
|
model.getDraggedOverDirectory().setValue(item);
|
||||||
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleHoverTimer(DragEvent event) {
|
private void handleHoverTimer(DragEvent event) {
|
||||||
if (item == null || !item.getRawFileEntry().isDirectory()) {
|
if (item == null || item.getRawFileEntry().getKind() != FileKind.DIRECTORY) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.app.browser;
|
||||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
@ -23,7 +24,7 @@ import java.util.stream.Stream;
|
||||||
public final class BrowserFileListModel {
|
public final class BrowserFileListModel {
|
||||||
|
|
||||||
static final Comparator<BrowserEntry> FILE_TYPE_COMPARATOR =
|
static final Comparator<BrowserEntry> FILE_TYPE_COMPARATOR =
|
||||||
Comparator.comparing(path -> !path.getRawFileEntry().isDirectory());
|
Comparator.comparing(path -> path.getRawFileEntry().getKind() != FileKind.DIRECTORY);
|
||||||
static final Predicate<BrowserEntry> PREDICATE_ANY = path -> true;
|
static final Predicate<BrowserEntry> PREDICATE_ANY = path -> true;
|
||||||
static final Predicate<BrowserEntry> PREDICATE_NOT_HIDDEN = path -> true;
|
static final Predicate<BrowserEntry> PREDICATE_NOT_HIDDEN = path -> true;
|
||||||
|
|
||||||
|
@ -112,12 +113,12 @@ public final class BrowserFileListModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDoubleClick(BrowserEntry entry) {
|
public void onDoubleClick(BrowserEntry entry) {
|
||||||
if (!entry.getRawFileEntry().isDirectory() && getMode().equals(BrowserModel.Mode.SINGLE_FILE_CHOOSER)) {
|
if (entry.getRawFileEntry().getKind() != FileKind.DIRECTORY && getMode().equals(BrowserModel.Mode.SINGLE_FILE_CHOOSER)) {
|
||||||
getFileSystemModel().getBrowserModel().finishChooser();
|
getFileSystemModel().getBrowserModel().finishChooser();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.getRawFileEntry().isDirectory()) {
|
if (entry.getRawFileEntry().getKind() == FileKind.DIRECTORY) {
|
||||||
var dir = fileSystemModel.cd(entry.getRawFileEntry().getPath());
|
var dir = fileSystemModel.cd(entry.getRawFileEntry().getPath());
|
||||||
if (dir.isPresent()) {
|
if (dir.isPresent()) {
|
||||||
fileSystemModel.cd(dir.get());
|
fileSystemModel.cd(dir.get());
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.core.impl.FileNames;
|
||||||
import io.xpipe.core.impl.LocalStore;
|
import io.xpipe.core.impl.LocalStore;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.store.ConnectionFileSystem;
|
import io.xpipe.core.store.ConnectionFileSystem;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -96,11 +97,11 @@ public class FileSystemHelper {
|
||||||
localFileSystem,
|
localFileSystem,
|
||||||
file.toString(),
|
file.toString(),
|
||||||
Files.getLastModifiedTime(file).toInstant(),
|
Files.getLastModifiedTime(file).toInstant(),
|
||||||
Files.isDirectory(file),
|
|
||||||
Files.isHidden(file),
|
Files.isHidden(file),
|
||||||
Files.isExecutable(file),
|
Files.isExecutable(file),
|
||||||
Files.size(file),
|
Files.size(file),
|
||||||
null
|
null,
|
||||||
|
Files.isDirectory(file) ? FileKind.DIRECTORY : FileKind.FILE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +177,7 @@ public class FileSystemHelper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source.isDirectory()) {
|
if (source.getKind() == FileKind.DIRECTORY) {
|
||||||
var directoryName = FileNames.getFileName(source.getPath());
|
var directoryName = FileNames.getFileName(source.getPath());
|
||||||
flatFiles.put(source, directoryName);
|
flatFiles.put(source, directoryName);
|
||||||
|
|
||||||
|
@ -197,7 +198,7 @@ public class FileSystemHelper {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceFile.isDirectory()) {
|
if (sourceFile.getKind() == FileKind.DIRECTORY) {
|
||||||
target.getFileSystem().mkdirs(targetFile);
|
target.getFileSystem().mkdirs(targetFile);
|
||||||
} else {
|
} else {
|
||||||
try (var in = sourceFile.getFileSystem().openInput(sourceFile.getPath());
|
try (var in = sourceFile.getFileSystem().openInput(sourceFile.getPath());
|
||||||
|
|
|
@ -10,10 +10,7 @@ import io.xpipe.app.util.XPipeDaemon;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
import io.xpipe.core.process.ShellControl;
|
import io.xpipe.core.process.ShellControl;
|
||||||
import io.xpipe.core.process.ShellDialects;
|
import io.xpipe.core.process.ShellDialects;
|
||||||
import io.xpipe.core.store.ConnectionFileSystem;
|
import io.xpipe.core.store.*;
|
||||||
import io.xpipe.core.store.FileSystem;
|
|
||||||
import io.xpipe.core.store.FileSystemStore;
|
|
||||||
import io.xpipe.core.store.ShellStore;
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -94,7 +91,7 @@ public final class OpenFileSystemModel {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FileSystem.FileEntry(fileSystem, parent, null, true, false, false, 0, null);
|
return new FileSystem.FileEntry(fileSystem, parent, null, false, false, 0, null, FileKind.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileSystem.FileEntry getCurrentDirectory() {
|
public FileSystem.FileEntry getCurrentDirectory() {
|
||||||
|
@ -102,7 +99,7 @@ public final class OpenFileSystemModel {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FileSystem.FileEntry(fileSystem, currentPath.get(), null, true, false, false, 0, null);
|
return new FileSystem.FileEntry(fileSystem, currentPath.get(), null, false, false, 0, null, FileKind.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<String> cd(String path) {
|
public Optional<String> cd(String path) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.browser.icon;
|
||||||
|
|
||||||
import io.xpipe.app.core.AppResources;
|
import io.xpipe.app.core.AppResources;
|
||||||
import io.xpipe.core.impl.FileNames;
|
import io.xpipe.core.impl.FileNames;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ public interface DirectoryType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(FileSystem.FileEntry entry) {
|
public boolean matches(FileSystem.FileEntry entry) {
|
||||||
if (!entry.isDirectory()) {
|
if (entry.getKind() != FileKind.DIRECTORY) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.app.browser.icon;
|
||||||
import io.xpipe.app.core.AppImages;
|
import io.xpipe.app.core.AppImages;
|
||||||
import io.xpipe.app.core.AppResources;
|
import io.xpipe.app.core.AppResources;
|
||||||
import io.xpipe.app.fxcomps.impl.SvgCache;
|
import io.xpipe.app.fxcomps.impl.SvgCache;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -46,7 +47,7 @@ public class FileIconManager {
|
||||||
|
|
||||||
loadIfNecessary();
|
loadIfNecessary();
|
||||||
|
|
||||||
if (!entry.isDirectory()) {
|
if (entry.getKind() != FileKind.DIRECTORY) {
|
||||||
for (var f : FileType.ALL) {
|
for (var f : FileType.ALL) {
|
||||||
if (f.matches(entry)) {
|
if (f.matches(entry)) {
|
||||||
return getIconPath(f.getIcon());
|
return getIconPath(f.getIcon());
|
||||||
|
@ -60,7 +61,7 @@ public class FileIconManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry.isDirectory() ? (open ? "default_folder_opened.svg" : "default_folder.svg") : "default_file.svg";
|
return entry.getKind() == FileKind.DIRECTORY ? (open ? "default_folder_opened.svg" : "default_folder.svg") : "default_file.svg";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getIconPath(String name) {
|
private static String getIconPath(String name) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.xpipe.app.browser.icon;
|
package io.xpipe.app.browser.icon;
|
||||||
|
|
||||||
import io.xpipe.app.core.AppResources;
|
import io.xpipe.app.core.AppResources;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@ -65,7 +66,7 @@ public interface FileType {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(FileSystem.FileEntry entry) {
|
public boolean matches(FileSystem.FileEntry entry) {
|
||||||
if (entry.isDirectory()) {
|
if (entry.getKind() == FileKind.DIRECTORY) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ import javafx.application.Application;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.input.MouseEvent;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
@ -64,12 +63,6 @@ public class App extends Application {
|
||||||
|
|
||||||
public void setupWindow() {
|
public void setupWindow() {
|
||||||
var content = new AppLayoutComp();
|
var content = new AppLayoutComp();
|
||||||
content.apply(struc -> {
|
|
||||||
struc.get().addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
|
|
||||||
// AppActionLinkDetector.detectOnFocus();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var titleBinding = Bindings.createStringBinding(
|
var titleBinding = Bindings.createStringBinding(
|
||||||
() -> {
|
() -> {
|
||||||
var base = String.format(
|
var base = String.format(
|
||||||
|
|
|
@ -9,6 +9,7 @@ import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.util.DefaultSecretValue;
|
import io.xpipe.app.util.DefaultSecretValue;
|
||||||
import io.xpipe.app.util.FileBridge;
|
import io.xpipe.app.util.FileBridge;
|
||||||
import io.xpipe.app.util.LockedSecretValue;
|
import io.xpipe.app.util.LockedSecretValue;
|
||||||
|
import io.xpipe.core.impl.LocalStore;
|
||||||
import io.xpipe.core.util.JacksonMapper;
|
import io.xpipe.core.util.JacksonMapper;
|
||||||
|
|
||||||
public class BaseMode extends OperationMode {
|
public class BaseMode extends OperationMode {
|
||||||
|
@ -37,6 +38,7 @@ public class BaseMode extends OperationMode {
|
||||||
JacksonMapper.configure(objectMapper -> {
|
JacksonMapper.configure(objectMapper -> {
|
||||||
objectMapper.registerSubtypes(LockedSecretValue.class, DefaultSecretValue.class);
|
objectMapper.registerSubtypes(LockedSecretValue.class, DefaultSecretValue.class);
|
||||||
});
|
});
|
||||||
|
LocalStore.init();
|
||||||
AppPrefs.init();
|
AppPrefs.init();
|
||||||
AppCharsets.init();
|
AppCharsets.init();
|
||||||
AppCharsetter.init();
|
AppCharsetter.init();
|
||||||
|
|
|
@ -47,6 +47,8 @@ public class TerminalErrorHandler implements ErrorHandler {
|
||||||
event.clearAttachments();
|
event.clearAttachments();
|
||||||
handleSecondaryException(event, r);
|
handleSecondaryException(event, r);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
PlatformState.setCurrent(PlatformState.RUNNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,131 +2,38 @@ package io.xpipe.core.impl;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
import io.xpipe.core.process.ProcessControlProvider;
|
import io.xpipe.core.process.ProcessControlProvider;
|
||||||
import io.xpipe.core.process.ShellDialects;
|
|
||||||
import io.xpipe.core.process.ShellControl;
|
import io.xpipe.core.process.ShellControl;
|
||||||
import io.xpipe.core.store.ConnectionFileSystem;
|
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import io.xpipe.core.store.FileSystemStore;
|
|
||||||
import io.xpipe.core.store.ShellStore;
|
import io.xpipe.core.store.ShellStore;
|
||||||
import io.xpipe.core.util.JacksonizedValue;
|
import io.xpipe.core.util.JacksonizedValue;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
@JsonTypeName("local")
|
@JsonTypeName("local")
|
||||||
public class LocalStore extends JacksonizedValue implements ShellStore {
|
public class LocalStore extends JacksonizedValue implements ShellStore {
|
||||||
|
|
||||||
private static ShellControl local;
|
private static ShellControl local;
|
||||||
private static FileSystem localFileSystem;
|
private static FileSystem localFileSystem;
|
||||||
|
|
||||||
public static ShellControl getShell() throws Exception {
|
public static void init() throws Exception {
|
||||||
|
local = ProcessControlProvider.createLocal(false).start();
|
||||||
|
localFileSystem = new LocalStore().createFileSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShellControl getShell() {
|
||||||
if (local == null) {
|
if (local == null) {
|
||||||
local = ProcessControlProvider.createLocal(false).start();
|
throw new IllegalStateException("Local shell not initialized yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileSystem getFileSystem() throws Exception {
|
public static FileSystem getFileSystem() {
|
||||||
if (localFileSystem == null) {
|
if (localFileSystem == null) {
|
||||||
localFileSystem = new LocalStore().createFileSystem();
|
throw new IllegalStateException("Local file system not initialized yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
return localFileSystem;
|
return localFileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileSystem createFileSystem() {
|
|
||||||
return new ConnectionFileSystem(ShellStore.createLocal().control(), LocalStore.this) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileSystemStore getStore() {
|
|
||||||
return LocalStore.this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Path wrap(String file) {
|
|
||||||
for (var e : System.getenv().entrySet()) {
|
|
||||||
file = file.replace(
|
|
||||||
ShellDialects.getPlatformDefault().environmentVariable(e.getKey()),
|
|
||||||
e.getValue());
|
|
||||||
}
|
|
||||||
return Path.of(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public boolean exists(String file) {
|
|
||||||
// return Files.exists(wrap(file));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void delete(String file) throws Exception {
|
|
||||||
// Files.delete(wrap(file));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void copy(String file, String newFile) throws Exception {
|
|
||||||
// Files.copy(wrap(file), wrap(newFile), StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void move(String file, String newFile) throws Exception {
|
|
||||||
// Files.move(wrap(file), wrap(newFile), StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean mkdirs(String file) throws Exception {
|
|
||||||
// try {
|
|
||||||
// Files.createDirectories(wrap(file));
|
|
||||||
// return true;
|
|
||||||
// } catch (Exception ex) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void touch(String file) throws Exception {
|
|
||||||
// if (exists(file)) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Files.createFile(wrap(file));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public boolean isDirectory(String file) throws Exception {
|
|
||||||
// return Files.isDirectory(wrap(file));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Stream<FileEntry> listFiles(String file) throws Exception {
|
|
||||||
// return Files.list(wrap(file)).map(path -> {
|
|
||||||
// try {
|
|
||||||
// var date = Files.getLastModifiedTime(path);
|
|
||||||
// var size = Files.isDirectory(path) ? 0 : Files.size(path);
|
|
||||||
// return new FileEntry(
|
|
||||||
// this,
|
|
||||||
// path.toString(),
|
|
||||||
// date.toInstant(),
|
|
||||||
// Files.isDirectory(path),
|
|
||||||
// Files.isHidden(path),
|
|
||||||
// Files.isExecutable(path),
|
|
||||||
// size);
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// throw new UncheckedIOException(e);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public List<String> listRoots() throws Exception {
|
|
||||||
// return StreamSupport.stream(
|
|
||||||
// FileSystems.getDefault().getRootDirectories().spliterator(), false)
|
|
||||||
// .map(path -> path.toString())
|
|
||||||
// .toList();
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShellControl createBasicControl() {
|
public ShellControl createBasicControl() {
|
||||||
return ProcessControlProvider.createLocal(true);
|
return ProcessControlProvider.createLocal(true);
|
||||||
|
|
9
core/src/main/java/io/xpipe/core/store/FileKind.java
Normal file
9
core/src/main/java/io/xpipe/core/store/FileKind.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package io.xpipe.core.store;
|
||||||
|
|
||||||
|
public enum FileKind {
|
||||||
|
|
||||||
|
FILE,
|
||||||
|
DIRECTORY,
|
||||||
|
LINK,
|
||||||
|
OTHER;
|
||||||
|
}
|
|
@ -22,29 +22,31 @@ public interface FileSystem extends Closeable, AutoCloseable {
|
||||||
@NonNull
|
@NonNull
|
||||||
String path;
|
String path;
|
||||||
Instant date;
|
Instant date;
|
||||||
boolean directory;
|
|
||||||
boolean hidden;
|
boolean hidden;
|
||||||
Boolean executable;
|
Boolean executable;
|
||||||
long size;
|
long size;
|
||||||
String mode;
|
String mode;
|
||||||
|
@NonNull
|
||||||
|
FileKind kind;
|
||||||
|
|
||||||
public FileEntry(
|
public FileEntry(
|
||||||
@NonNull FileSystem fileSystem, @NonNull String path, Instant date, boolean directory, boolean hidden, Boolean executable,
|
@NonNull FileSystem fileSystem, @NonNull String path, Instant date, boolean hidden, Boolean executable,
|
||||||
long size,
|
long size,
|
||||||
String mode
|
String mode,
|
||||||
|
@NonNull FileKind kind
|
||||||
) {
|
) {
|
||||||
this.fileSystem = fileSystem;
|
this.fileSystem = fileSystem;
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
this.path = directory ? FileNames.toDirectory(path) : path;
|
this.kind = kind;
|
||||||
|
this.path = kind == FileKind.DIRECTORY ? FileNames.toDirectory(path) : path;
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.directory = directory;
|
|
||||||
this.hidden = hidden;
|
this.hidden = hidden;
|
||||||
this.executable = executable;
|
this.executable = executable;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileEntry ofDirectory(FileSystem fileSystem, String path) {
|
public static FileEntry ofDirectory(FileSystem fileSystem, String path) {
|
||||||
return new FileEntry(fileSystem, path, Instant.now(), true, false, false, 0, null);
|
return new FileEntry(fileSystem, path, Instant.now(), true, false, 0, null, FileKind.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,7 +81,7 @@ public interface FileSystem extends Closeable, AutoCloseable {
|
||||||
|
|
||||||
default Stream<FileEntry> listFilesRecursively(String file) throws Exception {
|
default Stream<FileEntry> listFilesRecursively(String file) throws Exception {
|
||||||
return listFiles(file).flatMap(fileEntry -> {
|
return listFiles(file).flatMap(fileEntry -> {
|
||||||
if (!fileEntry.isDirectory()) {
|
if (fileEntry.getKind() != FileKind.DIRECTORY) {
|
||||||
return Stream.of(fileEntry);
|
return Stream.of(fileEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import io.xpipe.app.browser.action.LeafAction;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellControl;
|
import io.xpipe.core.process.ShellControl;
|
||||||
import io.xpipe.core.process.ShellDialect;
|
import io.xpipe.core.process.ShellDialect;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -19,21 +20,21 @@ public class BrowseInNativeManagerAction implements LeafAction {
|
||||||
var e = entry.getRawFileEntry().getPath();
|
var e = entry.getRawFileEntry().getPath();
|
||||||
switch (OsType.getLocal()) {
|
switch (OsType.getLocal()) {
|
||||||
case OsType.Windows windows -> {
|
case OsType.Windows windows -> {
|
||||||
if (entry.getRawFileEntry().isDirectory()) {
|
if (entry.getRawFileEntry().getKind() == FileKind.DIRECTORY) {
|
||||||
sc.executeSimpleCommand("explorer " + d.fileArgument(e));
|
sc.executeSimpleCommand("explorer " + d.fileArgument(e));
|
||||||
} else {
|
} else {
|
||||||
sc.executeSimpleCommand("explorer /select," + d.fileArgument(e));
|
sc.executeSimpleCommand("explorer /select," + d.fileArgument(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case OsType.Linux linux -> {
|
case OsType.Linux linux -> {
|
||||||
var action = entry.getRawFileEntry().isDirectory() ? "org.freedesktop.FileManager1.ShowFolders" : "org.freedesktop.FileManager1.ShowItems";
|
var action = entry.getRawFileEntry().getKind() == FileKind.DIRECTORY ? "org.freedesktop.FileManager1.ShowFolders" : "org.freedesktop.FileManager1.ShowItems";
|
||||||
var dbus = String.format("""
|
var dbus = String.format("""
|
||||||
dbus-send --session --print-reply --dest=org.freedesktop.FileManager1 --type=method_call /org/freedesktop/FileManager1 %s array:string:"file://%s" string:""
|
dbus-send --session --print-reply --dest=org.freedesktop.FileManager1 --type=method_call /org/freedesktop/FileManager1 %s array:string:"file://%s" string:""
|
||||||
""", action, entry.getRawFileEntry().getPath());
|
""", action, entry.getRawFileEntry().getPath());
|
||||||
sc.executeSimpleCommand(dbus);
|
sc.executeSimpleCommand(dbus);
|
||||||
}
|
}
|
||||||
case OsType.MacOs macOs -> {
|
case OsType.MacOs macOs -> {
|
||||||
sc.executeSimpleCommand("open " + (entry.getRawFileEntry().isDirectory() ? "" : "-R ")
|
sc.executeSimpleCommand("open " + (entry.getRawFileEntry().getKind() == FileKind.DIRECTORY ? "" : "-R ")
|
||||||
+ d.fileArgument(entry.getRawFileEntry().getPath()));
|
+ d.fileArgument(entry.getRawFileEntry().getPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.app.browser.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.action.LeafAction;
|
import io.xpipe.app.browser.action.LeafAction;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.util.FileOpener;
|
import io.xpipe.app.util.FileOpener;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ public class EditFileAction implements LeafAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return entries.stream().noneMatch(entry -> entry.getRawFileEntry().isDirectory());
|
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.ext.base.browser;
|
||||||
import io.xpipe.app.browser.BrowserEntry;
|
import io.xpipe.app.browser.BrowserEntry;
|
||||||
import io.xpipe.app.browser.OpenFileSystemModel;
|
import io.xpipe.app.browser.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.action.LeafAction;
|
import io.xpipe.app.browser.action.LeafAction;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
|
@ -30,7 +31,7 @@ public class OpenDirectoryAction implements LeafAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return entries.size() == 1 && entries.stream().allMatch(entry -> entry.getRawFileEntry().isDirectory());
|
return entries.size() == 1 && entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.ext.base.browser;
|
||||||
import io.xpipe.app.browser.BrowserEntry;
|
import io.xpipe.app.browser.BrowserEntry;
|
||||||
import io.xpipe.app.browser.OpenFileSystemModel;
|
import io.xpipe.app.browser.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.action.LeafAction;
|
import io.xpipe.app.browser.action.LeafAction;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
|
@ -30,7 +31,7 @@ public class OpenDirectoryInNewTabAction implements LeafAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return entries.size() == 1 && entries.stream().allMatch(entry -> entry.getRawFileEntry().isDirectory());
|
return entries.size() == 1 && entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.browser.BrowserEntry;
|
||||||
import io.xpipe.app.browser.OpenFileSystemModel;
|
import io.xpipe.app.browser.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.action.LeafAction;
|
import io.xpipe.app.browser.action.LeafAction;
|
||||||
import io.xpipe.app.util.FileOpener;
|
import io.xpipe.app.util.FileOpener;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
|
@ -33,7 +34,7 @@ public class OpenFileDefaultAction implements LeafAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return entries.stream().noneMatch(entry -> entry.getRawFileEntry().isDirectory());
|
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.xpipe.app.browser.action.LeafAction;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellControl;
|
import io.xpipe.core.process.ShellControl;
|
||||||
import io.xpipe.core.process.ShellDialect;
|
import io.xpipe.core.process.ShellDialect;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
|
@ -58,7 +59,7 @@ public class OpenFileWithAction implements LeafAction {
|
||||||
return os.isPresent()
|
return os.isPresent()
|
||||||
&& os.get().getOsType().equals(OsType.WINDOWS)
|
&& os.get().getOsType().equals(OsType.WINDOWS)
|
||||||
&& entries.size() == 1
|
&& entries.size() == 1
|
||||||
&& entries.stream().noneMatch(entry -> entry.getRawFileEntry().isDirectory());
|
&& entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.ext.base.browser;
|
||||||
import io.xpipe.app.browser.BrowserEntry;
|
import io.xpipe.app.browser.BrowserEntry;
|
||||||
import io.xpipe.app.browser.OpenFileSystemModel;
|
import io.xpipe.app.browser.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.action.LeafAction;
|
import io.xpipe.app.browser.action.LeafAction;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
|
@ -46,7 +47,7 @@ public class OpenTerminalAction implements LeafAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return entries.stream().allMatch(entry -> entry.getRawFileEntry().isDirectory());
|
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.browser.BrowserClipboard;
|
||||||
import io.xpipe.app.browser.BrowserEntry;
|
import io.xpipe.app.browser.BrowserEntry;
|
||||||
import io.xpipe.app.browser.OpenFileSystemModel;
|
import io.xpipe.app.browser.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.action.LeafAction;
|
import io.xpipe.app.browser.action.LeafAction;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyCodeCombination;
|
import javafx.scene.input.KeyCodeCombination;
|
||||||
|
@ -21,7 +22,7 @@ public class PasteAction implements LeafAction {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = entries.size() == 1 && entries.get(0).getRawFileEntry().isDirectory() ? entries.get(0).getRawFileEntry() : model.getCurrentDirectory();
|
var target = entries.size() == 1 && entries.get(0).getRawFileEntry().getKind() == FileKind.DIRECTORY ? entries.get(0).getRawFileEntry() : model.getCurrentDirectory();
|
||||||
var files = clipboard.getEntries();
|
var files = clipboard.getEntries();
|
||||||
model.dropFilesIntoAsync(target, files, true);
|
model.dropFilesIntoAsync(target, files, true);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +39,7 @@ public class PasteAction implements LeafAction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return entries.size() < 2 && entries.stream().allMatch(entry -> entry.getRawFileEntry().isDirectory());
|
return entries.size() < 2 && entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.app.browser.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.action.MultiExecuteAction;
|
import io.xpipe.app.browser.action.MultiExecuteAction;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellControl;
|
import io.xpipe.core.process.ShellControl;
|
||||||
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileSystem;
|
import io.xpipe.core.store.FileSystem;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
@ -14,7 +15,7 @@ import java.util.List;
|
||||||
public class RunAction extends MultiExecuteAction {
|
public class RunAction extends MultiExecuteAction {
|
||||||
|
|
||||||
private boolean isExecutable(FileSystem.FileEntry e) {
|
private boolean isExecutable(FileSystem.FileEntry e) {
|
||||||
if (e.isDirectory()) {
|
if (e.getKind() != FileKind.FILE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue