mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
File browser improvements
This commit is contained in:
parent
9e505c68ed
commit
355de8e2fc
9 changed files with 256 additions and 136 deletions
|
@ -136,7 +136,7 @@ run {
|
|||
systemProperty 'io.xpipe.app.writeLogs', "true"
|
||||
systemProperty 'io.xpipe.app.writeSysOut', "true"
|
||||
systemProperty 'io.xpipe.app.developerMode', "true"
|
||||
systemProperty 'io.xpipe.app.logLevel', "trace"
|
||||
systemProperty 'io.xpipe.app.logLevel', "debug"
|
||||
systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion
|
||||
// systemProperty "io.xpipe.beacon.port", "21724"
|
||||
// systemProperty "io.xpipe.beacon.printMessages", "true"
|
||||
|
|
|
@ -15,6 +15,7 @@ public class FileBrowserClipboard {
|
|||
@Value
|
||||
public static class Instance {
|
||||
UUID uuid;
|
||||
FileSystem.FileEntry baseDirectory;
|
||||
List<FileSystem.FileEntry> entries;
|
||||
}
|
||||
|
||||
|
@ -22,18 +23,18 @@ public class FileBrowserClipboard {
|
|||
public static Instance currentDragClipboard;
|
||||
|
||||
@SneakyThrows
|
||||
public static ClipboardContent startDrag(List<FileSystem.FileEntry> selected) {
|
||||
public static ClipboardContent startDrag(FileSystem.FileEntry base, List<FileSystem.FileEntry> selected) {
|
||||
var content = new ClipboardContent();
|
||||
var idea = UUID.randomUUID();
|
||||
currentDragClipboard = new Instance(idea, selected);
|
||||
currentDragClipboard = new Instance(idea, base, new ArrayList<>(selected));
|
||||
content.putString(idea.toString());
|
||||
return content;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static void startCopy(List<FileSystem.FileEntry> selected) {
|
||||
public static void startCopy(FileSystem.FileEntry base, List<FileSystem.FileEntry> selected) {
|
||||
var id = UUID.randomUUID();
|
||||
currentCopyClipboard = new Instance(id, new ArrayList<>(selected));
|
||||
currentCopyClipboard = new Instance(id, base, new ArrayList<>(selected));
|
||||
}
|
||||
|
||||
public static Instance retrieveCopy() {
|
||||
|
|
|
@ -55,9 +55,9 @@ final class FileContextMenu extends ContextMenu {
|
|||
|
||||
private final OpenFileSystemModel model;
|
||||
private final FileSystem.FileEntry entry;
|
||||
private final Property<String> editing;
|
||||
private final Property<FileSystem.FileEntry> editing;
|
||||
|
||||
public FileContextMenu(OpenFileSystemModel model, FileSystem.FileEntry entry, Property<String> editing) {
|
||||
public FileContextMenu(OpenFileSystemModel model, FileSystem.FileEntry entry, Property<FileSystem.FileEntry> editing) {
|
||||
super();
|
||||
this.model = model;
|
||||
this.entry = entry;
|
||||
|
@ -154,7 +154,7 @@ final class FileContextMenu extends ContextMenu {
|
|||
var rename = new MenuItem("Rename");
|
||||
rename.setOnAction(event -> {
|
||||
event.consume();
|
||||
editing.setValue(entry.getPath());
|
||||
editing.setValue(entry);
|
||||
});
|
||||
|
||||
getItems().addAll(new SeparatorMenuItem(), rename, delete);
|
||||
|
|
|
@ -5,7 +5,6 @@ package io.xpipe.app.browser;
|
|||
import atlantafx.base.theme.Styles;
|
||||
import atlantafx.base.theme.Tweaks;
|
||||
import io.xpipe.app.comp.base.LazyTextFieldComp;
|
||||
import io.xpipe.app.core.AppResources;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||
|
@ -13,6 +12,7 @@ import io.xpipe.app.util.Containers;
|
|||
import io.xpipe.app.util.HumanReadableFormat;
|
||||
import io.xpipe.core.impl.FileNames;
|
||||
import io.xpipe.core.store.FileSystem;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.ListChangeListener;
|
||||
|
@ -21,11 +21,11 @@ import javafx.geometry.Insets;
|
|||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.layout.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Comparator;
|
||||
|
@ -39,6 +39,8 @@ final class FileListComp extends AnchorPane {
|
|||
private static final PseudoClass HIDDEN = PseudoClass.getPseudoClass("hidden");
|
||||
private static final PseudoClass FOLDER = PseudoClass.getPseudoClass("folder");
|
||||
private static final PseudoClass DRAG = PseudoClass.getPseudoClass("drag");
|
||||
private static final PseudoClass DRAG_OVER = PseudoClass.getPseudoClass("drag-over");
|
||||
private static final PseudoClass DRAG_INTO_CURRENT = PseudoClass.getPseudoClass("drag-into-current");
|
||||
private static final String UNKNOWN = "unknown";
|
||||
|
||||
private final FileListModel fileList;
|
||||
|
@ -57,7 +59,7 @@ final class FileListComp extends AnchorPane {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
private TableView<FileSystem.FileEntry> createTable() {
|
||||
var editing = new SimpleObjectProperty<String>();
|
||||
var editing = new SimpleObjectProperty<FileSystem.FileEntry>();
|
||||
var filenameCol = new TableColumn<FileSystem.FileEntry, String>("Name");
|
||||
filenameCol.setCellValueFactory(param -> new SimpleStringProperty(
|
||||
param.getValue() != null
|
||||
|
@ -96,16 +98,15 @@ final class FileListComp extends AnchorPane {
|
|||
}
|
||||
|
||||
table.getSelectionModel().getSelectedItems().addListener((ListChangeListener<? super FileSystem.FileEntry>) c -> {
|
||||
fileList.getModel().getBrowserModel().getSelectedFiles().setAll(c.getList());
|
||||
fileList.getSelected().setAll(c.getList());
|
||||
fileList.getFileSystemModel().getBrowserModel().getSelectedFiles().setAll(c.getList());
|
||||
});
|
||||
|
||||
var draggedOverDirectory = new SimpleBooleanProperty();
|
||||
|
||||
table.setOnKeyPressed(event -> {
|
||||
if (event.isControlDown()
|
||||
&& event.getCode().equals(KeyCode.C)
|
||||
&& table.getSelectionModel().getSelectedItems().size() > 0) {
|
||||
FileBrowserClipboard.startCopy(table.getSelectionModel().getSelectedItems());
|
||||
FileBrowserClipboard.startCopy(fileList.getFileSystemModel().getCurrentDirectory(), table.getSelectionModel().getSelectedItems());
|
||||
event.consume();
|
||||
}
|
||||
|
||||
|
@ -113,15 +114,38 @@ final class FileListComp extends AnchorPane {
|
|||
var clipboard = FileBrowserClipboard.retrieveCopy();
|
||||
if (clipboard != null) {
|
||||
var files = clipboard.getEntries();
|
||||
var target = fileList.getModel().getCurrentDirectory();
|
||||
fileList.getModel().dropFilesIntoAsync(target, files, true);
|
||||
var target = fileList.getFileSystemModel().getCurrentDirectory();
|
||||
fileList.getFileSystemModel().dropFilesIntoAsync(target, files, true);
|
||||
event.consume();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var emptyEntry = new FileListEntry(table, null, fileList);
|
||||
table.setOnDragOver(event -> {
|
||||
emptyEntry.onDragOver(event);
|
||||
});
|
||||
table.setOnDragEntered(event -> {
|
||||
emptyEntry.onDragEntered(event);
|
||||
});
|
||||
table.setOnDragDetected(event -> {
|
||||
emptyEntry.startDrag(event);
|
||||
});
|
||||
table.setOnDragExited(event -> {
|
||||
emptyEntry.onDragExited(event);
|
||||
});
|
||||
table.setOnDragDropped(event -> {
|
||||
emptyEntry.onDragDrop(event);
|
||||
});
|
||||
|
||||
table.setRowFactory(param -> {
|
||||
TableRow<FileSystem.FileEntry> row = new TableRow<>();
|
||||
var listEntry = Bindings.createObjectBinding(() -> new FileListEntry(row, row.getItem(), fileList), row.itemProperty());
|
||||
|
||||
row.itemProperty().addListener((observable, oldValue, newValue) -> {
|
||||
row.pseudoClassStateChanged(DRAG, false);
|
||||
row.pseudoClassStateChanged(DRAG_OVER, false);
|
||||
});
|
||||
|
||||
row.addEventHandler(MouseEvent.MOUSE_CLICKED, t -> {
|
||||
t.consume();
|
||||
|
@ -129,7 +153,7 @@ final class FileListComp extends AnchorPane {
|
|||
return;
|
||||
}
|
||||
|
||||
var cm = new FileContextMenu(fileList.getModel(), row.getItem(), editing);
|
||||
var cm = new FileContextMenu(fileList.getFileSystemModel(), row.getItem(), editing);
|
||||
if (t.getButton() == MouseButton.SECONDARY) {
|
||||
cm.show(row, t.getScreenX(), t.getScreenY());
|
||||
}
|
||||
|
@ -141,113 +165,28 @@ final class FileListComp extends AnchorPane {
|
|||
}
|
||||
});
|
||||
|
||||
draggedOverDirectory.addListener((observable, oldValue, newValue) -> {
|
||||
row.pseudoClassStateChanged(DRAG, newValue);
|
||||
fileList.getDraggedOverDirectory().addListener((observable, oldValue, newValue) -> {
|
||||
row.pseudoClassStateChanged(DRAG_OVER, newValue != null && newValue == row.getItem());
|
||||
});
|
||||
|
||||
fileList.getDraggedOverEmpty().addListener((observable, oldValue, newValue) -> {
|
||||
table.pseudoClassStateChanged(DRAG_INTO_CURRENT, newValue);
|
||||
});
|
||||
|
||||
row.setOnDragEntered(event -> {
|
||||
listEntry.get().onDragEntered(event);
|
||||
});
|
||||
row.setOnDragOver(event -> {
|
||||
if (row.equals(event.getGestureSource())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (row.getItem() == null || !row.getItem().isDirectory()) {
|
||||
draggedOverDirectory.set(true);
|
||||
} else {
|
||||
row.pseudoClassStateChanged(DRAG, true);
|
||||
}
|
||||
event.acceptTransferModes(TransferMode.ANY);
|
||||
event.consume();
|
||||
listEntry.get().onDragOver(event);
|
||||
});
|
||||
|
||||
row.setOnDragDetected(event -> {
|
||||
if (row.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = AppResources.getResourceURL(AppResources.XPIPE_MODULE, "img/file_drag_icon.png")
|
||||
.orElseThrow();
|
||||
var image = new Image(url.toString(), 80, 80, true, false);
|
||||
|
||||
var selected = table.getSelectionModel().getSelectedItems();
|
||||
Dragboard db = row.startDragAndDrop(TransferMode.COPY);
|
||||
db.setContent(FileBrowserClipboard.startDrag(selected));
|
||||
db.setDragView(image, 30, 60);
|
||||
event.setDragDetect(true);
|
||||
event.consume();
|
||||
listEntry.get().startDrag(event);
|
||||
});
|
||||
|
||||
row.setOnDragExited(event -> {
|
||||
if (row.getItem() != null && row.getItem().isDirectory()) {
|
||||
row.pseudoClassStateChanged(DRAG, false);
|
||||
} else {
|
||||
draggedOverDirectory.set(false);
|
||||
}
|
||||
|
||||
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
||||
}
|
||||
|
||||
// if (event.getGestureSource() != null) {
|
||||
// try {
|
||||
// var f = Files.createTempFile(null, null);
|
||||
// var cc = new ClipboardContent();
|
||||
// cc.putFiles(List.of(f.toFile()));
|
||||
// Dragboard db = row.startDragAndDrop(TransferMode.COPY);
|
||||
// db.setContent(cc);
|
||||
// } catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// }
|
||||
listEntry.get().onDragExited(event);
|
||||
});
|
||||
//
|
||||
// row.setEventDispatcher((event, chain) -> {
|
||||
// if (event.getEventType().getName().equals("MOUSE_DRAGGED")) {
|
||||
// MouseEvent drag = (MouseEvent) event;
|
||||
//
|
||||
// if (drag.isDragDetect()) {
|
||||
// return chain.dispatchEvent(event);
|
||||
// }
|
||||
//
|
||||
// Rectangle area = new Rectangle(
|
||||
// App.getApp().getStage().getX(),
|
||||
// App.getApp().getStage().getY(),
|
||||
// App.getApp().getStage().getWidth(),
|
||||
// App.getApp().getStage().getHeight()
|
||||
// );
|
||||
// if (!area.intersects(drag.getScreenX(), drag.getScreenY(), 20, 20)) {
|
||||
// System.out.println("->Drag down");
|
||||
// drag.setDragDetect(true);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return chain.dispatchEvent(event);
|
||||
// });
|
||||
|
||||
row.setOnDragDropped(event -> {
|
||||
draggedOverDirectory.set(false);
|
||||
|
||||
// Accept drops from outside the app window
|
||||
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
||||
Dragboard db = event.getDragboard();
|
||||
var list = db.getFiles().stream().map(File::toPath).toList();
|
||||
var target = row.getItem() != null && row.getItem().isDirectory()
|
||||
? row.getItem()
|
||||
: fileList.getModel().getCurrentDirectory();
|
||||
fileList.getModel().dropLocalFilesIntoAsync(target, list);
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
// Accept drops from inside the app window
|
||||
if (event.getGestureSource() != null) {
|
||||
var files = FileBrowserClipboard.retrieveDrag(event.getDragboard())
|
||||
.getEntries();
|
||||
var target = row.getItem() != null
|
||||
? row.getItem()
|
||||
: fileList.getModel().getCurrentDirectory();
|
||||
fileList.getModel().dropFilesIntoAsync(target, files, false);
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
listEntry.get().onDragDrop(event);
|
||||
});
|
||||
|
||||
return row;
|
||||
|
@ -276,10 +215,10 @@ final class FileListComp extends AnchorPane {
|
|||
new LazyTextFieldComp(text).createStructure().get();
|
||||
private final ChangeListener<String> listener;
|
||||
|
||||
public FilenameCell(Property<String> editing) {
|
||||
public FilenameCell(Property<FileSystem.FileEntry> editing) {
|
||||
editing.addListener((observable, oldValue, newValue) -> {
|
||||
if (getTableRow().getItem() != null
|
||||
&& getTableRow().getItem().getPath().equals(newValue)) {
|
||||
&& getTableRow().getItem().equals(newValue)) {
|
||||
textField.requestFocus();
|
||||
}
|
||||
});
|
||||
|
|
164
app/src/main/java/io/xpipe/app/browser/FileListEntry.java
Normal file
164
app/src/main/java/io/xpipe/app/browser/FileListEntry.java
Normal file
|
@ -0,0 +1,164 @@
|
|||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.core.AppResources;
|
||||
import io.xpipe.core.store.FileSystem;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.input.Dragboard;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
@Getter
|
||||
public class FileListEntry {
|
||||
|
||||
public static final Timer DROP_TIMER = new Timer("dnd", true);
|
||||
|
||||
private final Node row;
|
||||
private final FileSystem.FileEntry item;
|
||||
private final FileListModel model;
|
||||
|
||||
private Point2D lastOver = new Point2D(-1, -1);
|
||||
private TimerTask activeTask;
|
||||
|
||||
public FileListEntry(Node row, FileSystem.FileEntry item, FileListModel model) {
|
||||
this.row = row;
|
||||
this.item = item;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
private boolean acceptsDrop(DragEvent event) {
|
||||
if (FileBrowserClipboard.currentDragClipboard == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prevent drag and drops of files into the current directory
|
||||
if (FileBrowserClipboard.currentDragClipboard
|
||||
.getBaseDirectory().getPath()
|
||||
.equals(model.getFileSystemModel().getCurrentDirectory().getPath()) && (item == null || !item.isDirectory())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prevent dropping items onto themselves
|
||||
if (item != null && FileBrowserClipboard.currentDragClipboard.getEntries().contains(item)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onDragDrop(DragEvent event) {
|
||||
model.getDraggedOverEmpty().setValue(false);
|
||||
model.getDraggedOverDirectory().setValue(null);
|
||||
|
||||
// Accept drops from outside the app window
|
||||
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
|
||||
Dragboard db = event.getDragboard();
|
||||
var list = db.getFiles().stream().map(File::toPath).toList();
|
||||
var target = item != null && item.isDirectory()
|
||||
? item
|
||||
: model.getFileSystemModel().getCurrentDirectory();
|
||||
model.getFileSystemModel().dropLocalFilesIntoAsync(target, list);
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
// Accept drops from inside the app window
|
||||
if (event.getGestureSource() != null) {
|
||||
var files = FileBrowserClipboard.retrieveDrag(event.getDragboard()).getEntries();
|
||||
var target = item != null
|
||||
? item
|
||||
: model.getFileSystemModel().getCurrentDirectory();
|
||||
model.getFileSystemModel().dropFilesIntoAsync(target, files, false);
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
}
|
||||
|
||||
public void onDragExited(DragEvent event) {
|
||||
if (item != null && item.isDirectory()) {
|
||||
model.getDraggedOverDirectory().setValue(null);
|
||||
} else {
|
||||
model.getDraggedOverEmpty().setValue(false);
|
||||
}
|
||||
event.consume();
|
||||
}
|
||||
|
||||
public void startDrag(MouseEvent event) {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = AppResources.getResourceURL(AppResources.XPIPE_MODULE, "img/file_drag_icon.png")
|
||||
.orElseThrow();
|
||||
var image = new Image(url.toString(), 80, 80, true, false);
|
||||
var selected = model.getSelected();
|
||||
Dragboard db = row.startDragAndDrop(TransferMode.COPY);
|
||||
db.setContent(FileBrowserClipboard.startDrag(model.getFileSystemModel().getCurrentDirectory(), selected));
|
||||
db.setDragView(image, 30, 60);
|
||||
event.setDragDetect(true);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
private void acceptDrag(DragEvent event) {
|
||||
if (item == null || !item.isDirectory()) {
|
||||
model.getDraggedOverEmpty().setValue(true);
|
||||
} else {
|
||||
model.getDraggedOverDirectory().setValue(item);
|
||||
}
|
||||
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
||||
}
|
||||
|
||||
private void handleHoverTimer(DragEvent event) {
|
||||
|
||||
if (item == null || !item.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastOver.getX() == event.getX() && lastOver.getY() == event.getY()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastOver = (new Point2D(event.getX(), event.getY()));
|
||||
activeTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (activeTask != this) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item != model.getDraggedOverDirectory().getValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
model.getFileSystemModel().cd(item.getPath());
|
||||
}
|
||||
};
|
||||
DROP_TIMER.schedule(activeTask, 1000);
|
||||
}
|
||||
|
||||
public void onDragEntered(DragEvent event) {
|
||||
event.consume();
|
||||
if (!acceptsDrop(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
acceptDrag(event);
|
||||
}
|
||||
|
||||
public void onDragOver(DragEvent event) {
|
||||
event.consume();
|
||||
if (!acceptsDrop(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
acceptDrag(event);
|
||||
handleHoverTimer(event);
|
||||
}
|
||||
}
|
|
@ -8,7 +8,10 @@ import io.xpipe.core.impl.FileNames;
|
|||
import io.xpipe.core.store.FileSystem;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -25,24 +28,28 @@ final class FileListModel {
|
|||
static final Predicate<FileSystem.FileEntry> PREDICATE_ANY = path -> true;
|
||||
static final Predicate<FileSystem.FileEntry> PREDICATE_NOT_HIDDEN = path -> true;
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final OpenFileSystemModel fileSystemModel;
|
||||
private final Property<Comparator<FileSystem.FileEntry>> comparatorProperty =
|
||||
new SimpleObjectProperty<>(FILE_TYPE_COMPARATOR);
|
||||
private final Property<List<FileSystem.FileEntry>> all = new SimpleObjectProperty<>(List.of());
|
||||
private final Property<List<FileSystem.FileEntry>> shown = new SimpleObjectProperty<>(List.of());
|
||||
private final ObjectProperty<Predicate<FileSystem.FileEntry>> predicateProperty =
|
||||
new SimpleObjectProperty<>(path -> true);
|
||||
private final ObservableList<FileSystem.FileEntry> selected = FXCollections.observableArrayList();
|
||||
|
||||
public FileListModel(OpenFileSystemModel model) {
|
||||
this.model = model;
|
||||
private final Property<FileSystem.FileEntry> draggedOverDirectory = new SimpleObjectProperty<FileSystem.FileEntry>();
|
||||
private final Property<Boolean> draggedOverEmpty = new SimpleBooleanProperty();
|
||||
|
||||
model.getFilter().addListener((observable, oldValue, newValue) -> {
|
||||
public FileListModel(OpenFileSystemModel fileSystemModel) {
|
||||
this.fileSystemModel = fileSystemModel;
|
||||
|
||||
fileSystemModel.getFilter().addListener((observable, oldValue, newValue) -> {
|
||||
refreshShown();
|
||||
});
|
||||
}
|
||||
|
||||
public FileBrowserModel.Mode getMode() {
|
||||
return model.getBrowserModel().getMode();
|
||||
return fileSystemModel.getBrowserModel().getMode();
|
||||
}
|
||||
|
||||
public void setAll(List<FileSystem.FileEntry> newFiles) {
|
||||
|
@ -56,9 +63,9 @@ final class FileListModel {
|
|||
}
|
||||
|
||||
private void refreshShown() {
|
||||
List<FileSystem.FileEntry> filtered = model.getFilter().getValue() != null ? all.getValue().stream().filter(entry -> {
|
||||
List<FileSystem.FileEntry> filtered = fileSystemModel.getFilter().getValue() != null ? all.getValue().stream().filter(entry -> {
|
||||
var name = FileNames.getFileName(entry.getPath()).toLowerCase(Locale.ROOT);
|
||||
var filterString = model.getFilter().getValue().toLowerCase(Locale.ROOT);
|
||||
var filterString = fileSystemModel.getFilter().getValue().toLowerCase(Locale.ROOT);
|
||||
return name.contains(filterString);
|
||||
}).toList() : all.getValue();
|
||||
|
||||
|
@ -72,11 +79,11 @@ final class FileListModel {
|
|||
}
|
||||
|
||||
public boolean rename(String filename, String newName) {
|
||||
var fullPath = FileNames.join(model.getCurrentPath().get(), filename);
|
||||
var newFullPath = FileNames.join(model.getCurrentPath().get(), newName);
|
||||
var fullPath = FileNames.join(fileSystemModel.getCurrentPath().get(), filename);
|
||||
var newFullPath = FileNames.join(fileSystemModel.getCurrentPath().get(), newName);
|
||||
try {
|
||||
model.getFileSystem().move(fullPath, newFullPath);
|
||||
model.refresh();
|
||||
fileSystemModel.getFileSystem().move(fullPath, newFullPath);
|
||||
fileSystemModel.refresh();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
|
@ -86,12 +93,12 @@ final class FileListModel {
|
|||
|
||||
public void onDoubleClick(FileSystem.FileEntry entry) {
|
||||
if (!entry.isDirectory() && getMode().equals(FileBrowserModel.Mode.SINGLE_FILE_CHOOSER)) {
|
||||
getModel().getBrowserModel().finishChooser();
|
||||
getFileSystemModel().getBrowserModel().finishChooser();
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
model.navigate(entry.getPath(), true);
|
||||
fileSystemModel.navigate(entry.getPath(), true);
|
||||
} else {
|
||||
FileOpener.openInTextEditor(entry);
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
ApplicationHelper.checkSupport(pc, executable, getDisplayName());
|
||||
|
||||
var toExecute = executable + " " + toCommand(name, command);
|
||||
// In order to fix this bug which also affects us: https://askubuntu.com/questions/1148475/launching-gnome-terminal-from-vscode
|
||||
toExecute = "GNOME_TERMINAL_SCREEN=\"\" nohup " + toExecute + " </dev/null &>/dev/null & disown";
|
||||
pc.executeSimpleCommand(toExecute);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,15 @@
|
|||
-fx-opacity: 0.6;
|
||||
}
|
||||
|
||||
.browser .table-row-cell:drag {
|
||||
-fx-background-color: -color-neutral-emphasis;
|
||||
.browser .table-directory-view .table-view:drag-into-current {
|
||||
-fx-border-color: -color-success-muted;
|
||||
-fx-border-width: 2px;
|
||||
}
|
||||
|
||||
.browser .table-row-cell:drag-over {
|
||||
-fx-background-color: -color-success-muted;
|
||||
}
|
||||
|
||||
.browser .table-row-cell:drag {
|
||||
-fx-background-color: -color-accent-muted;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
|
||||
.list-cell:empty {
|
||||
-fx-opacity: 0;
|
||||
-fx-pref-height: 1px;
|
||||
}
|
||||
|
||||
.storage-group-list-comp .list-cell {
|
||||
|
|
Loading…
Reference in a new issue