mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-05-24 16:26:21 -04:00
Refactor and cleanup
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.beacon.BeaconClientException;
|
||||
@@ -19,7 +19,7 @@ public class ConnectionBrowseExchangeImpl extends ConnectionBrowseExchange {
|
||||
if (!(e.getStore() instanceof FileSystemStore)) {
|
||||
throw new BeaconClientException("Not a file system connection");
|
||||
}
|
||||
BrowserSessionModel.DEFAULT.openFileSystemSync(
|
||||
BrowserFullSessionModel.DEFAULT.openFileSystemSync(
|
||||
e.ref(), msg.getDirectory() != null ? ignored -> msg.getDirectory() : null, null, true);
|
||||
AppLayoutModel.get().selectBrowser();
|
||||
return Response.builder().build();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.beacon.impl;
|
||||
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.launcher.LauncherInput;
|
||||
import io.xpipe.app.core.launcher.LauncherInput;
|
||||
import io.xpipe.app.util.PlatformState;
|
||||
import io.xpipe.beacon.BeaconServerException;
|
||||
import io.xpipe.beacon.api.DaemonOpenExchange;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
@@ -1,21 +1,21 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.browser.BrowserBookmarkComp;
|
||||
import io.xpipe.app.browser.BrowserBookmarkHeaderComp;
|
||||
import io.xpipe.app.browser.file.BrowserConnectionListComp;
|
||||
import io.xpipe.app.browser.file.BrowserConnectionListFilterComp;
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemComp;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabComp;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.comp.base.DialogComp;
|
||||
import io.xpipe.app.comp.base.LeftSplitPaneComp;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.impl.StackComp;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.StackComp;
|
||||
import io.xpipe.app.comp.base.VerticalComp;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.FileReference;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
@@ -37,12 +37,12 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BrowserChooserComp extends DialogComp {
|
||||
public class BrowserFileChooserSessionComp extends DialogComp {
|
||||
|
||||
private final Stage stage;
|
||||
private final BrowserFileChooserModel model;
|
||||
private final BrowserFileChooserSessionModel model;
|
||||
|
||||
public BrowserChooserComp(Stage stage, BrowserFileChooserModel model) {
|
||||
public BrowserFileChooserSessionComp(Stage stage, BrowserFileChooserSessionModel model) {
|
||||
this.stage = stage;
|
||||
this.model = model;
|
||||
}
|
||||
@@ -50,9 +50,9 @@ public class BrowserChooserComp extends DialogComp {
|
||||
public static void openSingleFile(
|
||||
Supplier<DataStoreEntryRef<? extends FileSystemStore>> store, Consumer<FileReference> file, boolean save) {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
var model = new BrowserFileChooserModel(OpenFileSystemModel.SelectionMode.SINGLE_FILE);
|
||||
var model = new BrowserFileChooserSessionModel(BrowserFileSystemTabModel.SelectionMode.SINGLE_FILE);
|
||||
DialogComp.showWindow(save ? "saveFileTitle" : "openFileTitle", stage -> {
|
||||
var comp = new BrowserChooserComp(stage, model);
|
||||
var comp = new BrowserFileChooserSessionComp(stage, model);
|
||||
comp.apply(struc -> struc.get().setPrefSize(1200, 700))
|
||||
.apply(struc -> AppFont.normal(struc.get()))
|
||||
.styleClass("browser")
|
||||
@@ -114,8 +114,8 @@ public class BrowserChooserComp extends DialogComp {
|
||||
});
|
||||
};
|
||||
|
||||
var bookmarkTopBar = new BrowserBookmarkHeaderComp();
|
||||
var bookmarksList = new BrowserBookmarkComp(
|
||||
var bookmarkTopBar = new BrowserConnectionListFilterComp();
|
||||
var bookmarksList = new BrowserConnectionListComp(
|
||||
BindingsHelper.map(model.getSelectedEntry(), v -> v.getEntry().get()),
|
||||
applicable,
|
||||
action,
|
||||
@@ -138,7 +138,7 @@ public class BrowserChooserComp extends DialogComp {
|
||||
model.getSelectedEntry().subscribe(selected -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
if (selected != null) {
|
||||
s.getChildren().setAll(new OpenFileSystemComp(selected, false).createRegion());
|
||||
s.getChildren().setAll(new BrowserFileSystemTabComp(selected, false).createRegion());
|
||||
} else {
|
||||
s.getChildren().clear();
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.FileReference;
|
||||
@@ -24,15 +24,15 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Getter
|
||||
public class BrowserFileChooserModel extends BrowserAbstractSessionModel<OpenFileSystemModel> {
|
||||
public class BrowserFileChooserSessionModel extends BrowserAbstractSessionModel<BrowserFileSystemTabModel> {
|
||||
|
||||
private final OpenFileSystemModel.SelectionMode selectionMode;
|
||||
private final BrowserFileSystemTabModel.SelectionMode selectionMode;
|
||||
private final ObservableList<BrowserEntry> fileSelection = FXCollections.observableArrayList();
|
||||
|
||||
@Setter
|
||||
private Consumer<List<FileReference>> onFinish;
|
||||
|
||||
public BrowserFileChooserModel(OpenFileSystemModel.SelectionMode selectionMode) {
|
||||
public BrowserFileChooserSessionModel(BrowserFileSystemTabModel.SelectionMode selectionMode) {
|
||||
this.selectionMode = selectionMode;
|
||||
selectedEntry.addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue == null) {
|
||||
@@ -48,7 +48,7 @@ public class BrowserFileChooserModel extends BrowserAbstractSessionModel<OpenFil
|
||||
public void finishChooser() {
|
||||
var chosen = new ArrayList<>(fileSelection);
|
||||
|
||||
synchronized (BrowserFileChooserModel.this) {
|
||||
synchronized (BrowserFileChooserSessionModel.this) {
|
||||
var open = selectedEntry.getValue();
|
||||
if (open != null) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
@@ -66,7 +66,7 @@ public class BrowserFileChooserModel extends BrowserAbstractSessionModel<OpenFil
|
||||
}
|
||||
|
||||
public void finishWithoutChoice() {
|
||||
synchronized (BrowserFileChooserModel.this) {
|
||||
synchronized (BrowserFileChooserSessionModel.this) {
|
||||
var open = selectedEntry.getValue();
|
||||
if (open != null) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
@@ -78,20 +78,20 @@ public class BrowserFileChooserModel extends BrowserAbstractSessionModel<OpenFil
|
||||
|
||||
public void openFileSystemAsync(
|
||||
DataStoreEntryRef<? extends FileSystemStore> store,
|
||||
FailableFunction<OpenFileSystemModel, String, Exception> path,
|
||||
FailableFunction<BrowserFileSystemTabModel, String, Exception> path,
|
||||
BooleanProperty externalBusy) {
|
||||
if (store == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
OpenFileSystemModel model;
|
||||
BrowserFileSystemTabModel model;
|
||||
|
||||
try (var b = new BooleanScope(externalBusy != null ? externalBusy : new SimpleBooleanProperty()).start()) {
|
||||
model = new OpenFileSystemModel(this, store, selectionMode);
|
||||
model = new BrowserFileSystemTabModel(this, store, selectionMode);
|
||||
model.init();
|
||||
// Prevent multiple calls from interfering with each other
|
||||
synchronized (BrowserFileChooserModel.this) {
|
||||
synchronized (BrowserFileChooserSessionModel.this) {
|
||||
selectedEntry.setValue(model);
|
||||
sessionEntries.add(model);
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.browser.BrowserBookmarkComp;
|
||||
import io.xpipe.app.browser.BrowserBookmarkHeaderComp;
|
||||
import io.xpipe.app.browser.BrowserTransferComp;
|
||||
import io.xpipe.app.browser.file.BrowserConnectionListComp;
|
||||
import io.xpipe.app.browser.file.BrowserConnectionListFilterComp;
|
||||
import io.xpipe.app.browser.file.BrowserTransferComp;
|
||||
import io.xpipe.app.comp.base.LoadingOverlayComp;
|
||||
import io.xpipe.app.comp.base.LeftSplitPaneComp;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.AnchorComp;
|
||||
import io.xpipe.app.fxcomps.impl.StackComp;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.AnchorComp;
|
||||
import io.xpipe.app.comp.base.StackComp;
|
||||
import io.xpipe.app.comp.base.VerticalComp;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import javafx.application.Platform;
|
||||
@@ -33,11 +33,11 @@ import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class BrowserSessionComp extends SimpleComp {
|
||||
public class BrowserFullSessionComp extends SimpleComp {
|
||||
|
||||
private final BrowserSessionModel model;
|
||||
private final BrowserFullSessionModel model;
|
||||
|
||||
public BrowserSessionComp(BrowserSessionModel model) {
|
||||
public BrowserFullSessionComp(BrowserFullSessionModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@@ -129,8 +129,8 @@ public class BrowserSessionComp extends SimpleComp {
|
||||
});
|
||||
};
|
||||
|
||||
var bookmarkTopBar = new BrowserBookmarkHeaderComp();
|
||||
var bookmarksList = new BrowserBookmarkComp(
|
||||
var bookmarkTopBar = new BrowserConnectionListFilterComp();
|
||||
var bookmarksList = new BrowserConnectionListComp(
|
||||
BindingsHelper.map(
|
||||
model.getSelectedEntry(),
|
||||
v -> v instanceof BrowserStoreSessionTab<?> st
|
||||
@@ -1,11 +1,10 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.browser.BrowserHomeTabModel;
|
||||
import io.xpipe.app.browser.BrowserSavedState;
|
||||
import io.xpipe.app.browser.BrowserSavedStateImpl;
|
||||
import io.xpipe.app.browser.BrowserTransferModel;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.browser.file.BrowserHistoryTabModel;
|
||||
import io.xpipe.app.browser.file.BrowserHistorySavedState;
|
||||
import io.xpipe.app.browser.file.BrowserHistorySavedStateImpl;
|
||||
import io.xpipe.app.browser.file.BrowserTransferModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
@@ -27,12 +26,12 @@ import lombok.Getter;
|
||||
import java.util.*;
|
||||
|
||||
@Getter
|
||||
public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSessionTab> {
|
||||
public class BrowserFullSessionModel extends BrowserAbstractSessionModel<BrowserSessionTab> {
|
||||
|
||||
public static final BrowserSessionModel DEFAULT = new BrowserSessionModel();
|
||||
public static final BrowserFullSessionModel DEFAULT = new BrowserFullSessionModel();
|
||||
|
||||
static {
|
||||
DEFAULT.getSessionEntries().add(new BrowserHomeTabModel(DEFAULT));
|
||||
DEFAULT.getSessionEntries().add(new BrowserHistoryTabModel(DEFAULT));
|
||||
}
|
||||
|
||||
private final BrowserTransferModel localTransfersStage = new BrowserTransferModel(this);
|
||||
@@ -66,7 +65,7 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
||||
}, globalPinnedTab, selectedEntry, splits);
|
||||
}
|
||||
|
||||
public BrowserSessionModel() {
|
||||
public BrowserFullSessionModel() {
|
||||
sessionEntries.addListener((ListChangeListener<? super BrowserSessionTab>) c -> {
|
||||
var v = globalPinnedTab.getValue();
|
||||
if (v != null && !c.getList().contains(v)) {
|
||||
@@ -125,7 +124,7 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
||||
});
|
||||
}
|
||||
|
||||
public void restoreState(BrowserSavedState state) {
|
||||
public void restoreState(BrowserHistorySavedState state) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
var l = new ArrayList<>(state.getEntries());
|
||||
l.forEach(e -> {
|
||||
@@ -136,7 +135,7 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
||||
});
|
||||
}
|
||||
|
||||
public void restoreStateAsync(BrowserSavedState.Entry e, BooleanProperty busy) {
|
||||
public void restoreStateAsync(BrowserHistorySavedState.Entry e, BooleanProperty busy) {
|
||||
var storageEntry = DataStorage.get().getStoreEntryIfPresent(e.getUuid());
|
||||
storageEntry.ifPresent(entry -> {
|
||||
openFileSystemAsync(entry.ref(), model -> e.getPath(), busy);
|
||||
@@ -144,7 +143,7 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
synchronized (BrowserSessionModel.this) {
|
||||
synchronized (BrowserFullSessionModel.this) {
|
||||
var all = new ArrayList<>(sessionEntries);
|
||||
for (var o : all) {
|
||||
// Don't close busy connections gracefully
|
||||
@@ -156,7 +155,7 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
||||
// Prevent blocking of shutdown
|
||||
closeAsync(o);
|
||||
}
|
||||
BrowserSavedStateImpl.get().save();
|
||||
BrowserHistorySavedStateImpl.get().save();
|
||||
}
|
||||
|
||||
// Delete all files
|
||||
@@ -165,7 +164,7 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
||||
|
||||
public void openFileSystemAsync(
|
||||
DataStoreEntryRef<? extends FileSystemStore> store,
|
||||
FailableFunction<OpenFileSystemModel, String, Exception> path,
|
||||
FailableFunction<BrowserFileSystemTabModel, String, Exception> path,
|
||||
BooleanProperty externalBusy) {
|
||||
if (store == null) {
|
||||
return;
|
||||
@@ -176,19 +175,19 @@ public class BrowserSessionModel extends BrowserAbstractSessionModel<BrowserSess
|
||||
});
|
||||
}
|
||||
|
||||
public OpenFileSystemModel openFileSystemSync(
|
||||
public BrowserFileSystemTabModel openFileSystemSync(
|
||||
DataStoreEntryRef<? extends FileSystemStore> store,
|
||||
FailableFunction<OpenFileSystemModel, String, Exception> path,
|
||||
FailableFunction<BrowserFileSystemTabModel, String, Exception> path,
|
||||
BooleanProperty externalBusy,
|
||||
boolean select)
|
||||
throws Exception {
|
||||
OpenFileSystemModel model;
|
||||
BrowserFileSystemTabModel model;
|
||||
try (var b = new BooleanScope(externalBusy != null ? externalBusy : new SimpleBooleanProperty()).start()) {
|
||||
try (var sessionBusy = new BooleanScope(busy).exclusive().start()) {
|
||||
model = new OpenFileSystemModel(this, store, OpenFileSystemModel.SelectionMode.ALL);
|
||||
model = new BrowserFileSystemTabModel(this, store, BrowserFileSystemTabModel.SelectionMode.ALL);
|
||||
model.init();
|
||||
// Prevent multiple calls from interfering with each other
|
||||
synchronized (BrowserSessionModel.this) {
|
||||
synchronized (BrowserFullSessionModel.this) {
|
||||
sessionEntries.add(model);
|
||||
if (select) {
|
||||
// The tab pane doesn't automatically select new tabs
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.storage.DataColor;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
@@ -8,8 +8,6 @@ import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableDoubleValue;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@@ -1,12 +1,11 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.fxcomps.impl.TooltipAugment;
|
||||
import io.xpipe.app.fxcomps.util.LabelGraphic;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.PrettyImageHelper;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.ContextMenuHelper;
|
||||
@@ -16,9 +15,7 @@ import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableDoubleValue;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.geometry.Insets;
|
||||
@@ -34,7 +31,6 @@ import atlantafx.base.theme.Styles;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static atlantafx.base.theme.Styles.DENSE;
|
||||
import static atlantafx.base.theme.Styles.toggleStyleClass;
|
||||
@@ -42,14 +38,14 @@ import static javafx.scene.control.TabPane.TabClosingPolicy.ALL_TABS;
|
||||
|
||||
public class BrowserSessionTabsComp extends SimpleComp {
|
||||
|
||||
private final BrowserSessionModel model;
|
||||
private final BrowserFullSessionModel model;
|
||||
private final ObservableDoubleValue leftPadding;
|
||||
private final DoubleProperty rightPadding;
|
||||
|
||||
@Getter
|
||||
private final DoubleProperty headerHeight;
|
||||
|
||||
public BrowserSessionTabsComp(BrowserSessionModel model, ObservableDoubleValue leftPadding, DoubleProperty rightPadding) {
|
||||
public BrowserSessionTabsComp(BrowserFullSessionModel model, ObservableDoubleValue leftPadding, DoubleProperty rightPadding) {
|
||||
this.model = model;
|
||||
this.leftPadding = leftPadding;
|
||||
this.rightPadding = rightPadding;
|
||||
@@ -398,7 +394,7 @@ public class BrowserSessionTabsComp extends SimpleComp {
|
||||
PlatformThread.sync(tabModel.getBusy())));
|
||||
}
|
||||
|
||||
if (tabModel.getBrowserModel() instanceof BrowserSessionModel sessionModel) {
|
||||
if (tabModel.getBrowserModel() instanceof BrowserFullSessionModel sessionModel) {
|
||||
var global = PlatformThread.sync(sessionModel.getGlobalPinnedTab());
|
||||
tab.textProperty().bind(Bindings.createStringBinding(() -> {
|
||||
return tabModel.getName() + (global.getValue() == tabModel ? " (" + AppI18n.get("pinned") + ")" : "");
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.xpipe.app.browser.session;
|
||||
package io.xpipe.app.browser;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.storage.DataColor;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.browser.action;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.util.ModuleLayerLoader;
|
||||
|
||||
@@ -18,25 +18,25 @@ public interface BrowserAction {
|
||||
|
||||
List<BrowserAction> ALL = new ArrayList<>();
|
||||
|
||||
static List<LeafAction> getFlattened(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
static List<BrowserLeafAction> getFlattened(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return ALL.stream()
|
||||
.map(browserAction -> getFlattened(browserAction, model, entries))
|
||||
.flatMap(List::stream)
|
||||
.toList();
|
||||
}
|
||||
|
||||
static List<LeafAction> getFlattened(
|
||||
BrowserAction browserAction, OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
return browserAction instanceof LeafAction
|
||||
? List.of((LeafAction) browserAction)
|
||||
: ((BranchAction) browserAction)
|
||||
static List<BrowserLeafAction> getFlattened(
|
||||
BrowserAction browserAction, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return browserAction instanceof BrowserLeafAction
|
||||
? List.of((BrowserLeafAction) browserAction)
|
||||
: ((BrowserBranchAction) browserAction)
|
||||
.getBranchingActions(model, entries).stream()
|
||||
.map(action -> getFlattened(action, model, entries))
|
||||
.flatMap(List::stream)
|
||||
.toList();
|
||||
}
|
||||
|
||||
static LeafAction byId(String id, OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
static BrowserLeafAction byId(String id, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return getFlattened(model, entries).stream()
|
||||
.filter(browserAction -> id.equals(browserAction.getId()))
|
||||
.findAny()
|
||||
@@ -52,15 +52,15 @@ public interface BrowserAction {
|
||||
: selected;
|
||||
}
|
||||
|
||||
MenuItem toMenuItem(OpenFileSystemModel model, List<BrowserEntry> selected);
|
||||
MenuItem toMenuItem(BrowserFileSystemTabModel model, List<BrowserEntry> selected);
|
||||
|
||||
default void init(OpenFileSystemModel model) throws Exception {}
|
||||
default void init(BrowserFileSystemTabModel model) throws Exception {}
|
||||
|
||||
default String getProFeatureId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
default Node getIcon(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
default Node getIcon(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -76,9 +76,9 @@ public interface BrowserAction {
|
||||
return false;
|
||||
}
|
||||
|
||||
ObservableValue<String> getName(OpenFileSystemModel model, List<BrowserEntry> entries);
|
||||
ObservableValue<String> getName(BrowserFileSystemTabModel model, List<BrowserEntry> entries);
|
||||
|
||||
default boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
default boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public interface BrowserAction {
|
||||
return true;
|
||||
}
|
||||
|
||||
default boolean isActive(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
default boolean isActive(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package io.xpipe.app.browser.action;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ApplicationPathAction extends BrowserAction {
|
||||
public interface BrowserApplicationPathAction extends BrowserAction {
|
||||
|
||||
String getExecutable();
|
||||
|
||||
@Override
|
||||
default void init(OpenFileSystemModel model) {
|
||||
default void init(BrowserFileSystemTabModel model) {
|
||||
// Cache result for later calls
|
||||
model.getCache().isApplicationInPath(getExecutable());
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isActive(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
default boolean isActive(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
return model.getCache().isApplicationInPath(getExecutable());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.browser.action;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.util.LicenseProvider;
|
||||
|
||||
import javafx.scene.control.Menu;
|
||||
@@ -11,9 +11,9 @@ import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BranchAction extends BrowserAction {
|
||||
public interface BrowserBranchAction extends BrowserAction {
|
||||
|
||||
default MenuItem toMenuItem(OpenFileSystemModel model, List<BrowserEntry> selected) {
|
||||
default MenuItem toMenuItem(BrowserFileSystemTabModel model, List<BrowserEntry> selected) {
|
||||
var m = new Menu(getName(model, selected).getValue() + " ...");
|
||||
for (var sub : getBranchingActions(model, selected)) {
|
||||
var subselected = resolveFilesIfNeeded(selected);
|
||||
@@ -37,5 +37,5 @@ public interface BranchAction extends BrowserAction {
|
||||
return m;
|
||||
}
|
||||
|
||||
List<? extends BrowserAction> getBranchingActions(OpenFileSystemModel model, List<BrowserEntry> entries);
|
||||
List<? extends BrowserAction> getBranchingActions(BrowserFileSystemTabModel model, List<BrowserEntry> entries);
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.browser.action;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.fxcomps.impl.TooltipAugment;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
|
||||
import io.xpipe.app.comp.base.TooltipAugment;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.LicenseProvider;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
@@ -17,11 +17,11 @@ import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LeafAction extends BrowserAction {
|
||||
public interface BrowserLeafAction extends BrowserAction {
|
||||
|
||||
void execute(OpenFileSystemModel model, List<BrowserEntry> entries) throws Exception;
|
||||
void execute(BrowserFileSystemTabModel model, List<BrowserEntry> entries) throws Exception;
|
||||
|
||||
default Button toButton(Region root, OpenFileSystemModel model, List<BrowserEntry> selected) {
|
||||
default Button toButton(Region root, BrowserFileSystemTabModel model, List<BrowserEntry> selected) {
|
||||
var b = new Button();
|
||||
b.setOnAction(event -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
@@ -66,7 +66,7 @@ public interface LeafAction extends BrowserAction {
|
||||
return b;
|
||||
}
|
||||
|
||||
default MenuItem toMenuItem(OpenFileSystemModel model, List<BrowserEntry> selected) {
|
||||
default MenuItem toMenuItem(BrowserFileSystemTabModel model, List<BrowserEntry> selected) {
|
||||
var name = getName(model, selected);
|
||||
var mi = new MenuItem();
|
||||
mi.textProperty().bind(BindingsHelper.map(name, s -> {
|
||||
@@ -1,8 +1,7 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import javafx.scene.Node;
|
||||
@@ -18,9 +17,9 @@ import java.util.ArrayList;
|
||||
|
||||
public class BrowserBreadcrumbBar extends SimpleComp {
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
|
||||
public BrowserBreadcrumbBar(OpenFileSystemModel model) {
|
||||
public BrowserBreadcrumbBar(BrowserFileSystemTabModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferMode;
|
||||
import io.xpipe.app.browser.file.LocalFileSystem;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
@@ -55,7 +52,7 @@ public class BrowserClipboard {
|
||||
|
||||
var entries = new ArrayList<BrowserEntry>();
|
||||
for (Path file : files) {
|
||||
entries.add(LocalFileSystem.getLocalBrowserEntry(file));
|
||||
entries.add(BrowserLocalFileSystem.getLocalBrowserEntry(file));
|
||||
}
|
||||
|
||||
currentCopyClipboard.setValue(
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.comp.store.*;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
@@ -19,7 +19,7 @@ import java.util.HashSet;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public final class BrowserBookmarkComp extends SimpleComp {
|
||||
public final class BrowserConnectionListComp extends SimpleComp {
|
||||
|
||||
private static final PseudoClass SELECTED = PseudoClass.getPseudoClass("selected");
|
||||
private final ObservableValue<DataStoreEntry> selected;
|
||||
@@ -28,7 +28,7 @@ public final class BrowserBookmarkComp extends SimpleComp {
|
||||
private final Property<StoreCategoryWrapper> category;
|
||||
private final Property<String> filter;
|
||||
|
||||
public BrowserBookmarkComp(
|
||||
public BrowserConnectionListComp(
|
||||
ObservableValue<DataStoreEntry> selected,
|
||||
Predicate<StoreEntryWrapper> applicable,
|
||||
BiConsumer<StoreEntryWrapper, BooleanProperty> action,
|
||||
@@ -1,11 +1,11 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.comp.store.StoreCategoryWrapper;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.FilterComp;
|
||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.FilterComp;
|
||||
import io.xpipe.app.comp.base.HorizontalComp;
|
||||
import io.xpipe.app.util.DataStoreCategoryChoiceComp;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
@@ -19,7 +19,7 @@ import lombok.Getter;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public final class BrowserBookmarkHeaderComp extends SimpleComp {
|
||||
public final class BrowserConnectionListFilterComp extends SimpleComp {
|
||||
|
||||
private final Property<StoreCategoryWrapper> category =
|
||||
new SimpleObjectProperty<>(StoreViewState.get().getActiveCategory().getValue());
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.util.InputHelper;
|
||||
|
||||
@@ -13,11 +12,11 @@ import java.util.List;
|
||||
|
||||
public final class BrowserContextMenu extends ContextMenu {
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
private final BrowserEntry source;
|
||||
private final boolean quickAccess;
|
||||
|
||||
public BrowserContextMenu(OpenFileSystemModel model, BrowserEntry source, boolean quickAccess) {
|
||||
public BrowserContextMenu(BrowserFileSystemTabModel model, BrowserEntry source, boolean quickAccess) {
|
||||
this.model = model;
|
||||
this.source = source;
|
||||
this.quickAccess = quickAccess;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.comp.base.LazyTextFieldComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
@@ -16,24 +14,16 @@ import io.xpipe.core.store.FileNames;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.geometry.Bounds;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.geometry.Side;
|
||||
import javafx.scene.AccessibleRole;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.skin.TableViewSkin;
|
||||
import javafx.scene.control.skin.VirtualFlow;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import atlantafx.base.controls.Spacer;
|
||||
import atlantafx.base.theme.Styles;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -82,7 +72,7 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||
: null));
|
||||
filenameCol.setComparator(Comparator.comparing(String::toLowerCase));
|
||||
filenameCol.setSortType(ASCENDING);
|
||||
filenameCol.setCellFactory(col -> new FilenameCell(fileList.getEditing(), col.getTableView()));
|
||||
filenameCol.setCellFactory(col -> new BrowserFileListNameCell(fileList, typedSelection, fileList.getEditing(), col.getTableView()));
|
||||
filenameCol.setReorderable(false);
|
||||
filenameCol.setResizable(false);
|
||||
|
||||
@@ -139,6 +129,31 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||
return true;
|
||||
});
|
||||
table.setFixedCellSize(32.0);
|
||||
|
||||
prepareColumnVisibility(table, ownerCol, filenameCol);
|
||||
prepareTableScrollFix(table);
|
||||
prepareTableSelectionModel(table);
|
||||
prepareTableShortcuts(table);
|
||||
prepareTableEntries(table);
|
||||
prepareTableChanges(table, filenameCol, mtimeCol, modeCol, ownerCol);
|
||||
prepareTypedSelectionModel(table);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private static void prepareTableScrollFix(TableView<BrowserEntry> table) {
|
||||
table.lookupAll(".scroll-bar").stream()
|
||||
.filter(node -> node.getPseudoClassStates().contains(PseudoClass.getPseudoClass("horizontal")))
|
||||
.findFirst()
|
||||
.ifPresent(node -> {
|
||||
Region region = (Region) node;
|
||||
region.setMinHeight(0);
|
||||
region.setPrefHeight(0);
|
||||
region.setMaxHeight(0);
|
||||
});
|
||||
}
|
||||
|
||||
private void prepareColumnVisibility(TableView<BrowserEntry> table, TableColumn<BrowserEntry, String> ownerCol, TableColumn<BrowserEntry, String> filenameCol) {
|
||||
var os = fileList.getFileSystemModel()
|
||||
.getFileSystem()
|
||||
.getShell()
|
||||
@@ -151,24 +166,6 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||
var width = getFilenameWidth(table);
|
||||
filenameCol.setPrefWidth(width);
|
||||
});
|
||||
|
||||
table.lookupAll(".scroll-bar").stream()
|
||||
.filter(node -> node.getPseudoClassStates().contains(PseudoClass.getPseudoClass("horizontal")))
|
||||
.findFirst()
|
||||
.ifPresent(node -> {
|
||||
Region region = (Region) node;
|
||||
region.setMinHeight(0);
|
||||
region.setPrefHeight(0);
|
||||
region.setMaxHeight(0);
|
||||
});
|
||||
|
||||
prepareTableSelectionModel(table);
|
||||
prepareTableShortcuts(table);
|
||||
prepareTableEntries(table);
|
||||
prepareTableChanges(table, filenameCol, mtimeCol, modeCol, ownerCol);
|
||||
prepareTypedSelectionModel(table);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
private double getFilenameWidth(TableView<?> tableView) {
|
||||
@@ -632,156 +629,4 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||
}
|
||||
}
|
||||
|
||||
private class FilenameCell extends TableCell<BrowserEntry, String> {
|
||||
|
||||
private final StringProperty img = new SimpleStringProperty();
|
||||
private final StringProperty text = new SimpleStringProperty();
|
||||
|
||||
private final BooleanProperty updating = new SimpleBooleanProperty();
|
||||
|
||||
public FilenameCell(Property<BrowserEntry> editing, TableView<BrowserEntry> tableView) {
|
||||
accessibleTextProperty()
|
||||
.bind(Bindings.createStringBinding(
|
||||
() -> {
|
||||
return getItem() != null ? getItem() : null;
|
||||
},
|
||||
itemProperty()));
|
||||
setAccessibleRole(AccessibleRole.TEXT);
|
||||
|
||||
var textField = new LazyTextFieldComp(text)
|
||||
.minWidth(USE_PREF_SIZE)
|
||||
.createStructure()
|
||||
.get();
|
||||
var quickAccess = new BrowserQuickAccessButtonComp(
|
||||
() -> getTableRow().getItem(), fileList.getFileSystemModel())
|
||||
.hide(Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
if (getTableRow() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var item = getTableRow().getItem();
|
||||
var notDir = item.getRawFileEntry().resolved().getKind() != FileKind.DIRECTORY;
|
||||
var isParentLink = item.getRawFileEntry()
|
||||
.equals(fileList.getFileSystemModel().getCurrentParentDirectory());
|
||||
return notDir || isParentLink;
|
||||
},
|
||||
itemProperty()))
|
||||
.focusTraversable(false)
|
||||
.createRegion();
|
||||
|
||||
editing.addListener((observable, oldValue, newValue) -> {
|
||||
if (getTableRow().getItem() != null && getTableRow().getItem().equals(newValue)) {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
textField.setDisable(false);
|
||||
textField.requestFocus();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ChangeListener<String> listener = (observable, oldValue, newValue) -> {
|
||||
if (updating.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getTableRow().requestFocus();
|
||||
var it = getTableRow().getItem();
|
||||
editing.setValue(null);
|
||||
ThreadHelper.runAsync(() -> {
|
||||
if (it == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var r = fileList.rename(it, newValue);
|
||||
Platform.runLater(() -> {
|
||||
updateItem(getItem(), isEmpty());
|
||||
fileList.getSelection().setAll(r);
|
||||
getTableView().scrollTo(r);
|
||||
});
|
||||
});
|
||||
};
|
||||
text.addListener(listener);
|
||||
|
||||
Node imageView = PrettyImageHelper.ofFixedSize(img, 24, 24).createRegion();
|
||||
HBox graphic = new HBox(imageView, new Spacer(5), quickAccess, new Spacer(1), textField);
|
||||
quickAccess.prefHeightProperty().bind(graphic.heightProperty());
|
||||
graphic.setAlignment(Pos.CENTER_LEFT);
|
||||
graphic.setPrefHeight(34);
|
||||
HBox.setHgrow(textField, Priority.ALWAYS);
|
||||
graphic.setAlignment(Pos.CENTER_LEFT);
|
||||
setGraphic(graphic);
|
||||
|
||||
InputHelper.onExactKeyCode(tableView, KeyCode.RIGHT, false, event -> {
|
||||
var selected = fileList.getSelection();
|
||||
if (selected.size() == 1 && selected.getFirst() == getTableRow().getItem()) {
|
||||
((ButtonBase) quickAccess).fire();
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
InputHelper.onExactKeyCode(tableView, KeyCode.SPACE, true, event -> {
|
||||
var selection = typedSelection.get() + " ";
|
||||
var found = fileList.getShown().getValue().stream()
|
||||
.filter(browserEntry ->
|
||||
browserEntry.getFileName().toLowerCase().startsWith(selection))
|
||||
.findFirst();
|
||||
// Ugly fix to prevent space from showing the menu when there is a file matching
|
||||
// Due to the table view input map, these events always get sent and consumed, not allowing us to
|
||||
// differentiate between these cases
|
||||
if (found.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selected = fileList.getSelection();
|
||||
// Only show one menu across all selected entries
|
||||
if (selected.size() > 0 && selected.getLast() == getTableRow().getItem()) {
|
||||
var cm = new BrowserContextMenu(
|
||||
fileList.getFileSystemModel(), getTableRow().getItem(), false);
|
||||
ContextMenuHelper.toggleShow(cm, this, Side.RIGHT);
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(String newName, boolean empty) {
|
||||
if (updating.get()) {
|
||||
super.updateItem(newName, empty);
|
||||
return;
|
||||
}
|
||||
|
||||
try (var ignored = new BooleanScope(updating).start()) {
|
||||
super.updateItem(newName, empty);
|
||||
if (empty || newName == null || getTableRow().getItem() == null) {
|
||||
// Don't set image as that would trigger image comp update
|
||||
// and cells are emptied on each change, leading to unnecessary changes
|
||||
// img.set(null);
|
||||
|
||||
// Visibility seems to be bugged, so use opacity
|
||||
setOpacity(0.0);
|
||||
} else {
|
||||
img.set(getTableRow().getItem().getIcon());
|
||||
|
||||
var isDirectory = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY;
|
||||
pseudoClassStateChanged(FOLDER, isDirectory);
|
||||
|
||||
var normalName = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.LINK
|
||||
? getTableRow().getItem().getFileName() + " -> "
|
||||
+ getTableRow()
|
||||
.getItem()
|
||||
.getRawFileEntry()
|
||||
.resolved()
|
||||
.getPath()
|
||||
: getTableRow().getItem().getFileName();
|
||||
var fileName = normalName;
|
||||
var hidden =
|
||||
getTableRow().getItem().getRawFileEntry().getInfo().explicitlyHidden()
|
||||
|| fileName.startsWith(".");
|
||||
getTableRow().pseudoClassStateChanged(HIDDEN, hidden);
|
||||
text.set(fileName);
|
||||
// Visibility seems to be bugged, so use opacity
|
||||
setOpacity(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.BrowserClipboard;
|
||||
import io.xpipe.app.browser.BrowserSelectionListComp;
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
|
||||
import javafx.geometry.Point2D;
|
||||
@@ -219,7 +217,7 @@ public class BrowserFileListCompEntry {
|
||||
return;
|
||||
}
|
||||
|
||||
if (model.getFileSystemModel().getBrowserModel() instanceof BrowserSessionModel sessionModel) {
|
||||
if (model.getFileSystemModel().getBrowserModel() instanceof BrowserFullSessionModel sessionModel) {
|
||||
sessionModel.getDraggingFiles().setValue(true);
|
||||
}
|
||||
var selected = model.getSelection();
|
||||
@@ -229,7 +227,7 @@ public class BrowserFileListCompEntry {
|
||||
selected,
|
||||
event.isAltDown() ? BrowserFileTransferMode.MOVE : BrowserFileTransferMode.NORMAL));
|
||||
|
||||
Image image = BrowserSelectionListComp.snapshot(selected);
|
||||
Image image = BrowserFileSelectionListComp.snapshot(selected);
|
||||
db.setDragView(image, -20, 15);
|
||||
|
||||
event.setDragDetect(true);
|
||||
@@ -237,7 +235,7 @@ public class BrowserFileListCompEntry {
|
||||
}
|
||||
|
||||
public void onDragDone(DragEvent event) {
|
||||
if (model.getFileSystemModel().getBrowserModel() instanceof BrowserSessionModel sessionModel) {
|
||||
if (model.getFileSystemModel().getBrowserModel() instanceof BrowserFullSessionModel sessionModel) {
|
||||
sessionModel.getDraggingFiles().setValue(false);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.impl.TextFieldComp;
|
||||
import io.xpipe.app.fxcomps.impl.TooltipAugment;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.base.TextFieldComp;
|
||||
import io.xpipe.app.comp.base.TooltipAugment;
|
||||
import io.xpipe.app.util.InputHelper;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
@@ -20,12 +19,12 @@ import javafx.scene.layout.HBox;
|
||||
import atlantafx.base.theme.Styles;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
public class BrowserFilterComp extends Comp<BrowserFilterComp.Structure> {
|
||||
public class BrowserFileListFilterComp extends Comp<BrowserFileListFilterComp.Structure> {
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
private final Property<String> filterString;
|
||||
|
||||
public BrowserFilterComp(OpenFileSystemModel model, Property<String> filterString) {
|
||||
public BrowserFileListFilterComp(BrowserFileSystemTabModel model, Property<String> filterString) {
|
||||
this.model = model;
|
||||
this.filterString = filterString;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
@@ -27,9 +26,9 @@ public final class BrowserFileListModel {
|
||||
static final Comparator<BrowserEntry> FILE_TYPE_COMPARATOR =
|
||||
Comparator.comparing(path -> path.getRawFileEntry().resolved().getKind() != FileKind.DIRECTORY);
|
||||
|
||||
private final OpenFileSystemModel.SelectionMode selectionMode;
|
||||
private final BrowserFileSystemTabModel.SelectionMode selectionMode;
|
||||
|
||||
private final OpenFileSystemModel fileSystemModel;
|
||||
private final BrowserFileSystemTabModel fileSystemModel;
|
||||
private final Property<Comparator<BrowserEntry>> comparatorProperty =
|
||||
new SimpleObjectProperty<>(FILE_TYPE_COMPARATOR);
|
||||
private final Property<List<BrowserEntry>> all = new SimpleObjectProperty<>(new ArrayList<>());
|
||||
@@ -40,7 +39,7 @@ public final class BrowserFileListModel {
|
||||
private final Property<Boolean> draggedOverEmpty = new SimpleBooleanProperty();
|
||||
private final Property<BrowserEntry> editing = new SimpleObjectProperty<>();
|
||||
|
||||
public BrowserFileListModel(OpenFileSystemModel.SelectionMode selectionMode, OpenFileSystemModel fileSystemModel) {
|
||||
public BrowserFileListModel(BrowserFileSystemTabModel.SelectionMode selectionMode, BrowserFileSystemTabModel fileSystemModel) {
|
||||
this.selectionMode = selectionMode;
|
||||
this.fileSystemModel = fileSystemModel;
|
||||
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import atlantafx.base.controls.Spacer;
|
||||
import io.xpipe.app.comp.base.LazyTextFieldComp;
|
||||
import io.xpipe.app.comp.base.PrettyImageHelper;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.ContextMenuHelper;
|
||||
import io.xpipe.app.util.InputHelper;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableStringValue;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.geometry.Side;
|
||||
import javafx.scene.AccessibleRole;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ButtonBase;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
|
||||
|
||||
private final BrowserFileListModel fileList;
|
||||
private final ObservableStringValue typedSelection;
|
||||
private final StringProperty img = new SimpleStringProperty();
|
||||
private final StringProperty text = new SimpleStringProperty();
|
||||
|
||||
private final BooleanProperty updating = new SimpleBooleanProperty();
|
||||
|
||||
public BrowserFileListNameCell(BrowserFileListModel fileList, ObservableStringValue typedSelection, Property<BrowserEntry> editing, TableView<BrowserEntry> tableView) {
|
||||
this.fileList = fileList;
|
||||
this.typedSelection = typedSelection;
|
||||
|
||||
accessibleTextProperty().bind(Bindings.createStringBinding(() -> {
|
||||
return getItem() != null ? getItem() : null;
|
||||
}, itemProperty()));
|
||||
setAccessibleRole(AccessibleRole.TEXT);
|
||||
|
||||
var textField = new LazyTextFieldComp(text).minWidth(USE_PREF_SIZE).createStructure().get();
|
||||
var quickAccess = createQuickAccessButton();
|
||||
setupShortcuts(tableView, (ButtonBase) quickAccess);
|
||||
setupRename(fileList, textField, editing);
|
||||
|
||||
Node imageView = PrettyImageHelper.ofFixedSize(img, 24, 24).createRegion();
|
||||
HBox graphic = new HBox(imageView, new Spacer(5), quickAccess, new Spacer(1), textField);
|
||||
quickAccess.prefHeightProperty().bind(graphic.heightProperty());
|
||||
graphic.setAlignment(Pos.CENTER_LEFT);
|
||||
graphic.setPrefHeight(34);
|
||||
HBox.setHgrow(textField, Priority.ALWAYS);
|
||||
graphic.setAlignment(Pos.CENTER_LEFT);
|
||||
setGraphic(graphic);
|
||||
}
|
||||
|
||||
private Region createQuickAccessButton() {
|
||||
var quickAccess = new BrowserQuickAccessButtonComp(() -> getTableRow().getItem(), fileList.getFileSystemModel()).hide(Bindings.createBooleanBinding(() -> {
|
||||
if (getTableRow() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var item = getTableRow().getItem();
|
||||
var notDir = item.getRawFileEntry().resolved().getKind() != FileKind.DIRECTORY;
|
||||
var isParentLink = item.getRawFileEntry().equals(fileList.getFileSystemModel().getCurrentParentDirectory());
|
||||
return notDir || isParentLink;
|
||||
}, itemProperty())).focusTraversable(false).createRegion();
|
||||
return quickAccess;
|
||||
}
|
||||
|
||||
private void setupShortcuts(TableView<BrowserEntry> tableView, ButtonBase quickAccess) {
|
||||
InputHelper.onExactKeyCode(tableView, KeyCode.RIGHT, false, event -> {
|
||||
var selected = fileList.getSelection();
|
||||
if (selected.size() == 1 && selected.getFirst() == getTableRow().getItem()) {
|
||||
quickAccess.fire();
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
InputHelper.onExactKeyCode(tableView, KeyCode.SPACE, true, event -> {
|
||||
var selection = typedSelection.get() + " ";
|
||||
var found = fileList.getShown().getValue().stream().filter(browserEntry -> browserEntry.getFileName().toLowerCase().startsWith(selection)).findFirst();
|
||||
// Ugly fix to prevent space from showing the menu when there is a file matching
|
||||
// Due to the table view input map, these events always get sent and consumed, not allowing us to
|
||||
// differentiate between these cases
|
||||
if (found.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var selected = fileList.getSelection();
|
||||
// Only show one menu across all selected entries
|
||||
if (selected.size() > 0 && selected.getLast() == getTableRow().getItem()) {
|
||||
var cm = new BrowserContextMenu(fileList.getFileSystemModel(), getTableRow().getItem(), false);
|
||||
ContextMenuHelper.toggleShow(cm, this, Side.RIGHT);
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupRename(BrowserFileListModel fileList, TextField textField, Property<BrowserEntry> editing) {
|
||||
ChangeListener<String> listener = (observable, oldValue, newValue) -> {
|
||||
if (updating.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getTableRow().requestFocus();
|
||||
var it = getTableRow().getItem();
|
||||
editing.setValue(null);
|
||||
ThreadHelper.runAsync(() -> {
|
||||
if (it == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var r = fileList.rename(it, newValue);
|
||||
Platform.runLater(() -> {
|
||||
updateItem(getItem(), isEmpty());
|
||||
fileList.getSelection().setAll(r);
|
||||
getTableView().scrollTo(r);
|
||||
});
|
||||
});
|
||||
};
|
||||
text.addListener(listener);
|
||||
|
||||
editing.addListener((observable, oldValue, newValue) -> {
|
||||
if (getTableRow().getItem() != null && getTableRow().getItem().equals(newValue)) {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
textField.setDisable(false);
|
||||
textField.requestFocus();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateItem(String newName, boolean empty) {
|
||||
if (updating.get()) {
|
||||
super.updateItem(newName, empty);
|
||||
return;
|
||||
}
|
||||
|
||||
try (var ignored = new BooleanScope(updating).start()) {
|
||||
super.updateItem(newName, empty);
|
||||
if (empty || newName == null || getTableRow().getItem() == null) {
|
||||
// Don't set image as that would trigger image comp update
|
||||
// and cells are emptied on each change, leading to unnecessary changes
|
||||
// img.set(null);
|
||||
|
||||
// Visibility seems to be bugged, so use opacity
|
||||
setOpacity(0.0);
|
||||
} else {
|
||||
img.set(getTableRow().getItem().getIcon());
|
||||
|
||||
var isDirectory = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY;
|
||||
pseudoClassStateChanged(PseudoClass.getPseudoClass("folder"), isDirectory);
|
||||
|
||||
var normalName = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.LINK ?
|
||||
getTableRow().getItem().getFileName() + " -> " + getTableRow().getItem().getRawFileEntry().resolved().getPath() :
|
||||
getTableRow().getItem().getFileName();
|
||||
var fileName = normalName;
|
||||
var hidden = getTableRow().getItem().getRawFileEntry().getInfo().explicitlyHidden() || fileName.startsWith(".");
|
||||
getTableRow().pseudoClassStateChanged(PseudoClass.getPseudoClass("hidden"), hidden);
|
||||
text.set(fileName);
|
||||
// Visibility seems to be bugged, so use opacity
|
||||
setOpacity(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
@@ -20,7 +19,7 @@ import java.util.Objects;
|
||||
|
||||
public class BrowserFileOpener {
|
||||
|
||||
private static OutputStream openFileOutput(OpenFileSystemModel model, FileEntry file, long totalBytes)
|
||||
private static OutputStream openFileOutput(BrowserFileSystemTabModel model, FileEntry file, long totalBytes)
|
||||
throws Exception {
|
||||
var fileSystem = model.getFileSystem();
|
||||
if (model.isClosed() || fileSystem.getShell().isEmpty()) {
|
||||
@@ -68,7 +67,7 @@ public class BrowserFileOpener {
|
||||
return Objects.hash(entry.getPath(), entry.getFileSystem(), entry.getKind(), entry.getInfo());
|
||||
}
|
||||
|
||||
public static void openWithAnyApplication(OpenFileSystemModel model, FileEntry entry) {
|
||||
public static void openWithAnyApplication(BrowserFileSystemTabModel model, FileEntry entry) {
|
||||
var file = entry.getPath();
|
||||
var key = calculateKey(entry);
|
||||
FileBridge.get()
|
||||
@@ -89,7 +88,7 @@ public class BrowserFileOpener {
|
||||
s -> FileOpener.openWithAnyApplication(s));
|
||||
}
|
||||
|
||||
public static void openInDefaultApplication(OpenFileSystemModel model, FileEntry entry) {
|
||||
public static void openInDefaultApplication(BrowserFileSystemTabModel model, FileEntry entry) {
|
||||
var file = entry.getPath();
|
||||
var key = calculateKey(entry);
|
||||
FileBridge.get()
|
||||
@@ -110,7 +109,7 @@ public class BrowserFileOpener {
|
||||
s -> FileOpener.openInDefaultApplication(s));
|
||||
}
|
||||
|
||||
public static void openInTextEditor(OpenFileSystemModel model, FileEntry entry) {
|
||||
public static void openInTextEditor(BrowserFileSystemTabModel model, FileEntry entry) {
|
||||
var editor = AppPrefs.get().externalEditor().getValue();
|
||||
if (editor == null) {
|
||||
return;
|
||||
@@ -1,13 +1,12 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.icon.BrowserIcons;
|
||||
import io.xpipe.app.comp.base.ListBoxViewComp;
|
||||
import io.xpipe.app.comp.base.VBoxViewComp;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.augment.GrowAugment;
|
||||
import io.xpipe.app.comp.base.HorizontalComp;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
@@ -25,7 +24,7 @@ import java.util.function.Function;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class BrowserFileOverviewComp extends SimpleComp {
|
||||
|
||||
OpenFileSystemModel model;
|
||||
BrowserFileSystemTabModel model;
|
||||
ObservableList<FileEntry> list;
|
||||
boolean grow;
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.comp.base.ListBoxViewComp;
|
||||
import io.xpipe.app.core.AppStyle;
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.PrettyImageHelper;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
@@ -31,17 +30,17 @@ import java.util.function.Function;
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AllArgsConstructor
|
||||
public class BrowserSelectionListComp extends SimpleComp {
|
||||
public class BrowserFileSelectionListComp extends SimpleComp {
|
||||
|
||||
ObservableList<BrowserEntry> list;
|
||||
Function<BrowserEntry, ObservableValue<String>> nameTransformation;
|
||||
|
||||
public BrowserSelectionListComp(ObservableList<BrowserEntry> list) {
|
||||
public BrowserFileSelectionListComp(ObservableList<BrowserEntry> list) {
|
||||
this(list, entry -> new SimpleStringProperty(entry.getFileName()));
|
||||
}
|
||||
|
||||
public static Image snapshot(ObservableList<BrowserEntry> list) {
|
||||
var r = new BrowserSelectionListComp(list).styleClass("drag").createRegion();
|
||||
var r = new BrowserFileSelectionListComp(list).styleClass("drag").createRegion();
|
||||
var scene = new Scene(r);
|
||||
AppWindowHelper.setupStylesheets(scene);
|
||||
AppStyle.addStylesheets(scene);
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.browser.fs;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.util.ShellControlCache;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
@@ -12,14 +12,14 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public class OpenFileSystemCache extends ShellControlCache {
|
||||
public class BrowserFileSystemCache extends ShellControlCache {
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
private final String username;
|
||||
private final Map<Integer, String> users = new LinkedHashMap<>();
|
||||
private final Map<Integer, String> groups = new LinkedHashMap<>();
|
||||
|
||||
public OpenFileSystemCache(OpenFileSystemModel model) throws Exception {
|
||||
public BrowserFileSystemCache(BrowserFileSystemTabModel model) throws Exception {
|
||||
super(model.getFileSystem().getShell().orElseThrow());
|
||||
this.model = model;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
@@ -11,9 +10,9 @@ import io.xpipe.core.store.FileSystem;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
public class FileSystemHelper {
|
||||
public class BrowserFileSystemHelper {
|
||||
|
||||
public static String adjustPath(OpenFileSystemModel model, String path) {
|
||||
public static String adjustPath(BrowserFileSystemTabModel model, String path) {
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -46,7 +45,7 @@ public class FileSystemHelper {
|
||||
return path;
|
||||
}
|
||||
|
||||
public static String evaluatePath(OpenFileSystemModel model, String path) throws Exception {
|
||||
public static String evaluatePath(BrowserFileSystemTabModel model, String path) throws Exception {
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -67,7 +66,7 @@ public class FileSystemHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public static String resolveDirectoryPath(OpenFileSystemModel model, String path, boolean allowRewrite)
|
||||
public static String resolveDirectoryPath(BrowserFileSystemTabModel model, String path, boolean allowRewrite)
|
||||
throws Exception {
|
||||
if (path == null) {
|
||||
return null;
|
||||
@@ -98,7 +97,7 @@ public class FileSystemHelper {
|
||||
return FileNames.toDirectory(resolved);
|
||||
}
|
||||
|
||||
public static void validateDirectoryPath(OpenFileSystemModel model, String path, boolean verifyExists)
|
||||
public static void validateDirectoryPath(BrowserFileSystemTabModel model, String path, boolean verifyExists)
|
||||
throws Exception {
|
||||
if (path == null) {
|
||||
return;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.browser.fs;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.BooleanBinding;
|
||||
@@ -9,7 +9,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class OpenFileSystemHistory {
|
||||
public final class BrowserFileSystemHistory {
|
||||
|
||||
private final IntegerProperty cursor = new SimpleIntegerProperty(-1);
|
||||
private final List<String> history = new ArrayList<>();
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.browser.fs;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
@@ -31,35 +31,35 @@ import java.util.stream.Collectors;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@JsonSerialize(using = OpenFileSystemSavedState.Serializer.class)
|
||||
@JsonDeserialize(using = OpenFileSystemSavedState.Deserializer.class)
|
||||
public class OpenFileSystemSavedState {
|
||||
@JsonSerialize(using = BrowserFileSystemSavedState.Serializer.class)
|
||||
@JsonDeserialize(using = BrowserFileSystemSavedState.Deserializer.class)
|
||||
public class BrowserFileSystemSavedState {
|
||||
|
||||
private static final Timer TIMEOUT_TIMER = new Timer(true);
|
||||
private static final int STORED = 15;
|
||||
|
||||
@Setter
|
||||
private OpenFileSystemModel model;
|
||||
private BrowserFileSystemTabModel model;
|
||||
|
||||
private String lastDirectory;
|
||||
|
||||
@NonNull
|
||||
private ObservableList<RecentEntry> recentDirectories;
|
||||
|
||||
public OpenFileSystemSavedState(String lastDirectory, @NonNull ObservableList<RecentEntry> recentDirectories) {
|
||||
public BrowserFileSystemSavedState(String lastDirectory, @NonNull ObservableList<RecentEntry> recentDirectories) {
|
||||
this.lastDirectory = lastDirectory;
|
||||
this.recentDirectories = recentDirectories;
|
||||
}
|
||||
|
||||
public OpenFileSystemSavedState() {
|
||||
public BrowserFileSystemSavedState() {
|
||||
lastDirectory = null;
|
||||
recentDirectories = FXCollections.observableList(new ArrayList<>(STORED));
|
||||
}
|
||||
|
||||
static OpenFileSystemSavedState loadForStore(OpenFileSystemModel model) {
|
||||
static BrowserFileSystemSavedState loadForStore(BrowserFileSystemTabModel model) {
|
||||
var state = AppCache.getNonNull(
|
||||
"fs-state-" + model.getEntry().get().getUuid(), OpenFileSystemSavedState.class, () -> {
|
||||
return new OpenFileSystemSavedState();
|
||||
"fs-state-" + model.getEntry().get().getUuid(), BrowserFileSystemSavedState.class, () -> {
|
||||
return new BrowserFileSystemSavedState();
|
||||
});
|
||||
state.setModel(model);
|
||||
return state;
|
||||
@@ -122,14 +122,14 @@ public class OpenFileSystemSavedState {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Serializer extends StdSerializer<OpenFileSystemSavedState> {
|
||||
public static class Serializer extends StdSerializer<BrowserFileSystemSavedState> {
|
||||
|
||||
protected Serializer() {
|
||||
super(OpenFileSystemSavedState.class);
|
||||
super(BrowserFileSystemSavedState.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(OpenFileSystemSavedState value, JsonGenerator gen, SerializerProvider provider)
|
||||
public void serialize(BrowserFileSystemSavedState value, JsonGenerator gen, SerializerProvider provider)
|
||||
throws IOException {
|
||||
var node = JsonNodeFactory.instance.objectNode();
|
||||
node.set("recentDirectories", JacksonMapper.getDefault().valueToTree(value.getRecentDirectories()));
|
||||
@@ -137,10 +137,10 @@ public class OpenFileSystemSavedState {
|
||||
}
|
||||
}
|
||||
|
||||
public static class Deserializer extends StdDeserializer<OpenFileSystemSavedState> {
|
||||
public static class Deserializer extends StdDeserializer<BrowserFileSystemSavedState> {
|
||||
|
||||
protected Deserializer() {
|
||||
super(OpenFileSystemSavedState.class);
|
||||
super(BrowserFileSystemSavedState.class);
|
||||
}
|
||||
|
||||
private static <T> Predicate<T> distinctBy(Function<? super T, ?> f) {
|
||||
@@ -150,7 +150,7 @@ public class OpenFileSystemSavedState {
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public OpenFileSystemSavedState deserialize(JsonParser p, DeserializationContext ctxt) {
|
||||
public BrowserFileSystemSavedState deserialize(JsonParser p, DeserializationContext ctxt) {
|
||||
var tree = (ObjectNode) JacksonMapper.getDefault().readTree(p);
|
||||
JavaType javaType = JacksonMapper.getDefault()
|
||||
.getTypeFactory()
|
||||
@@ -164,7 +164,7 @@ public class OpenFileSystemSavedState {
|
||||
.map(recentEntry -> new RecentEntry(FileNames.toDirectory(recentEntry.directory), recentEntry.time))
|
||||
.filter(distinctBy(recentEntry -> recentEntry.getDirectory()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
return new OpenFileSystemSavedState(null, FXCollections.observableList(cleaned));
|
||||
return new BrowserFileSystemSavedState(null, FXCollections.observableList(cleaned));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
package io.xpipe.app.browser.fs;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.BrowserFilterComp;
|
||||
import io.xpipe.app.browser.BrowserNavBar;
|
||||
import io.xpipe.app.browser.BrowserOverviewComp;
|
||||
import io.xpipe.app.browser.BrowserStatusBarComp;
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.file.BrowserContextMenu;
|
||||
import io.xpipe.app.browser.file.BrowserFileListComp;
|
||||
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||
import io.xpipe.app.comp.base.MultiContentComp;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.fxcomps.impl.TooltipAugment;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.comp.base.TooltipAugment;
|
||||
import io.xpipe.app.comp.base.VerticalComp;
|
||||
import io.xpipe.app.util.InputHelper;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
@@ -37,12 +31,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OpenFileSystemComp extends SimpleComp {
|
||||
public class BrowserFileSystemTabComp extends SimpleComp {
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
private final boolean showStatusBar;
|
||||
|
||||
public OpenFileSystemComp(OpenFileSystemModel model, boolean showStatusBar) {
|
||||
public BrowserFileSystemTabComp(BrowserFileSystemTabModel model, boolean showStatusBar) {
|
||||
this.model = model;
|
||||
this.showStatusBar = showStatusBar;
|
||||
}
|
||||
@@ -82,12 +76,12 @@ public class OpenFileSystemComp extends SimpleComp {
|
||||
menuButton.disableProperty().bind(model.getInOverview());
|
||||
menuButton.setAccessibleText("Directory options");
|
||||
|
||||
var filter = new BrowserFilterComp(model, model.getFilter()).createStructure();
|
||||
var filter = new BrowserFileListFilterComp(model, model.getFilter()).createStructure();
|
||||
|
||||
var topBar = new HBox();
|
||||
topBar.setAlignment(Pos.CENTER);
|
||||
topBar.getStyleClass().add("top-bar");
|
||||
var navBar = new BrowserNavBar(model).createStructure();
|
||||
var navBar = new BrowserNavBarComp(model).createStructure();
|
||||
filter.textField().prefHeightProperty().bind(navBar.get().heightProperty());
|
||||
AppFont.medium(navBar.get());
|
||||
topBar.getChildren()
|
||||
@@ -1,19 +1,12 @@
|
||||
package io.xpipe.app.browser.fs;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.BrowserSavedState;
|
||||
import io.xpipe.app.browser.BrowserSavedStateImpl;
|
||||
import io.xpipe.app.browser.BrowserTransferProgress;
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.file.BrowserFileListModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferMode;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferOperation;
|
||||
import io.xpipe.app.browser.file.FileSystemHelper;
|
||||
import io.xpipe.app.browser.session.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.session.BrowserStoreSessionTab;
|
||||
import io.xpipe.app.browser.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.BrowserStoreSessionTab;
|
||||
import io.xpipe.app.comp.base.ModalOverlayComp;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.ext.ShellStore;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
@@ -28,7 +21,6 @@ import io.xpipe.core.store.*;
|
||||
import io.xpipe.core.util.FailableConsumer;
|
||||
import io.xpipe.core.util.FailableRunnable;
|
||||
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
|
||||
@@ -46,21 +38,21 @@ import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystemStore> {
|
||||
public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<FileSystemStore> {
|
||||
|
||||
private final Property<String> filter = new SimpleStringProperty();
|
||||
private final BrowserFileListModel fileList;
|
||||
private final ReadOnlyObjectWrapper<String> currentPath = new ReadOnlyObjectWrapper<>();
|
||||
private final OpenFileSystemHistory history = new OpenFileSystemHistory();
|
||||
private final BrowserFileSystemHistory history = new BrowserFileSystemHistory();
|
||||
private final Property<ModalOverlayComp.OverlayContent> overlay = new SimpleObjectProperty<>();
|
||||
private final BooleanProperty inOverview = new SimpleBooleanProperty();
|
||||
private final Property<BrowserTransferProgress> progress = new SimpleObjectProperty<>();
|
||||
private final ObservableList<UUID> terminalRequests = FXCollections.observableArrayList();
|
||||
private FileSystem fileSystem;
|
||||
private OpenFileSystemSavedState savedState;
|
||||
private OpenFileSystemCache cache;
|
||||
private BrowserFileSystemSavedState savedState;
|
||||
private BrowserFileSystemCache cache;
|
||||
|
||||
public OpenFileSystemModel(
|
||||
public BrowserFileSystemTabModel(
|
||||
BrowserAbstractSessionModel<?> model,
|
||||
DataStoreEntryRef<? extends FileSystemStore> entry,
|
||||
SelectionMode selectionMode) {
|
||||
@@ -75,7 +67,7 @@ public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystem
|
||||
|
||||
@Override
|
||||
public Comp<?> comp() {
|
||||
return new OpenFileSystemComp(this, true);
|
||||
return new BrowserFileSystemTabComp(this, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,12 +97,12 @@ public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystem
|
||||
}
|
||||
this.fileSystem = fs;
|
||||
|
||||
this.cache = new OpenFileSystemCache(this);
|
||||
this.cache = new BrowserFileSystemCache(this);
|
||||
for (BrowserAction b : BrowserAction.ALL) {
|
||||
b.init(this);
|
||||
}
|
||||
});
|
||||
this.savedState = OpenFileSystemSavedState.loadForStore(this);
|
||||
this.savedState = BrowserFileSystemSavedState.loadForStore(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,8 +117,8 @@ public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystem
|
||||
&& savedState != null
|
||||
&& current != null) {
|
||||
savedState.cd(current.getPath(), false);
|
||||
BrowserSavedStateImpl.get()
|
||||
.add(new BrowserSavedState.Entry(getEntry().get().getUuid(), current.getPath()));
|
||||
BrowserHistorySavedStateImpl.get()
|
||||
.add(new BrowserHistorySavedState.Entry(getEntry().get().getUuid(), current.getPath()));
|
||||
}
|
||||
try {
|
||||
fileSystem.close();
|
||||
@@ -232,7 +224,7 @@ public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystem
|
||||
}
|
||||
|
||||
// Fix common issues with paths
|
||||
var adjustedPath = FileSystemHelper.adjustPath(this, path);
|
||||
var adjustedPath = BrowserFileSystemHelper.adjustPath(this, path);
|
||||
if (!Objects.equals(path, adjustedPath)) {
|
||||
return Optional.of(adjustedPath);
|
||||
}
|
||||
@@ -240,7 +232,7 @@ public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystem
|
||||
// Evaluate optional expressions
|
||||
String evaluatedPath;
|
||||
try {
|
||||
evaluatedPath = FileSystemHelper.evaluatePath(this, adjustedPath);
|
||||
evaluatedPath = BrowserFileSystemHelper.evaluatePath(this, adjustedPath);
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
return Optional.ofNullable(currentPath.get());
|
||||
@@ -287,7 +279,7 @@ public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystem
|
||||
// Evaluate optional links
|
||||
String resolvedPath;
|
||||
try {
|
||||
resolvedPath = FileSystemHelper.resolveDirectoryPath(this, evaluatedPath, customInput);
|
||||
resolvedPath = BrowserFileSystemHelper.resolveDirectoryPath(this, evaluatedPath, customInput);
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
return Optional.ofNullable(currentPath.get());
|
||||
@@ -298,7 +290,7 @@ public final class OpenFileSystemModel extends BrowserStoreSessionTab<FileSystem
|
||||
}
|
||||
|
||||
try {
|
||||
FileSystemHelper.validateDirectoryPath(this, resolvedPath, customInput);
|
||||
BrowserFileSystemHelper.validateDirectoryPath(this, resolvedPath, customInput);
|
||||
cdSyncWithoutCheck(path);
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).handle();
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.BrowserTransferProgress;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.store.*;
|
||||
|
||||
@@ -50,7 +49,7 @@ public class BrowserFileTransferOperation {
|
||||
}
|
||||
|
||||
try {
|
||||
return LocalFileSystem.getLocalFileEntry(path);
|
||||
return BrowserLocalFileSystem.getLocalFileEntry(path);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.core.process.OsType;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
@@ -9,7 +9,7 @@ import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface BrowserSavedState {
|
||||
public interface BrowserHistorySavedState {
|
||||
|
||||
void add(Entry entry);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
@@ -19,33 +19,33 @@ import lombok.Value;
|
||||
import java.util.List;
|
||||
|
||||
@Value
|
||||
@JsonDeserialize(using = BrowserSavedStateImpl.Deserializer.class)
|
||||
public class BrowserSavedStateImpl implements BrowserSavedState {
|
||||
@JsonDeserialize(using = BrowserHistorySavedStateImpl.Deserializer.class)
|
||||
public class BrowserHistorySavedStateImpl implements BrowserHistorySavedState {
|
||||
|
||||
@JsonSerialize(as = List.class)
|
||||
ObservableList<Entry> lastSystems;
|
||||
|
||||
public BrowserSavedStateImpl(List<Entry> lastSystems) {
|
||||
public BrowserHistorySavedStateImpl(List<Entry> lastSystems) {
|
||||
this.lastSystems = FXCollections.observableArrayList(lastSystems);
|
||||
}
|
||||
|
||||
private static BrowserSavedStateImpl INSTANCE;
|
||||
private static BrowserHistorySavedStateImpl INSTANCE;
|
||||
|
||||
public static BrowserSavedState get() {
|
||||
public static BrowserHistorySavedState get() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = load();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static BrowserSavedStateImpl load() {
|
||||
return AppCache.getNonNull("browser-state", BrowserSavedStateImpl.class, () -> {
|
||||
return new BrowserSavedStateImpl(FXCollections.observableArrayList());
|
||||
private static BrowserHistorySavedStateImpl load() {
|
||||
return AppCache.getNonNull("browser-state", BrowserHistorySavedStateImpl.class, () -> {
|
||||
return new BrowserHistorySavedStateImpl(FXCollections.observableArrayList());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(BrowserSavedState.Entry entry) {
|
||||
public synchronized void add(BrowserHistorySavedState.Entry entry) {
|
||||
lastSystems.removeIf(s -> s.getUuid().equals(entry.getUuid()));
|
||||
lastSystems.addFirst(entry);
|
||||
if (lastSystems.size() > 15) {
|
||||
@@ -63,15 +63,15 @@ public class BrowserSavedStateImpl implements BrowserSavedState {
|
||||
return lastSystems;
|
||||
}
|
||||
|
||||
public static class Deserializer extends StdDeserializer<BrowserSavedStateImpl> {
|
||||
public static class Deserializer extends StdDeserializer<BrowserHistorySavedStateImpl> {
|
||||
|
||||
protected Deserializer() {
|
||||
super(BrowserSavedStateImpl.class);
|
||||
super(BrowserHistorySavedStateImpl.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public BrowserSavedStateImpl deserialize(JsonParser p, DeserializationContext ctxt) {
|
||||
public BrowserHistorySavedStateImpl deserialize(JsonParser p, DeserializationContext ctxt) {
|
||||
var tree = (ObjectNode) JacksonMapper.getDefault().readTree(p);
|
||||
JavaType javaType =
|
||||
JacksonMapper.getDefault().getTypeFactory().constructCollectionLikeType(List.class, Entry.class);
|
||||
@@ -79,7 +79,7 @@ public class BrowserSavedStateImpl implements BrowserSavedState {
|
||||
if (ls == null) {
|
||||
ls = List.of();
|
||||
}
|
||||
return new BrowserSavedStateImpl(ls);
|
||||
return new BrowserHistorySavedStateImpl(ls);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.comp.base.ListBoxViewComp;
|
||||
import io.xpipe.app.comp.base.TileButtonComp;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||
import io.xpipe.app.fxcomps.impl.LabelComp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.fxcomps.impl.PrettySvgComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.HorizontalComp;
|
||||
import io.xpipe.app.comp.base.LabelComp;
|
||||
import io.xpipe.app.comp.base.PrettyImageHelper;
|
||||
import io.xpipe.app.comp.base.PrettySvgComp;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
@@ -35,17 +35,17 @@ import atlantafx.base.theme.Styles;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BrowserWelcomeComp extends SimpleComp {
|
||||
public class BrowserHistoryTabComp extends SimpleComp {
|
||||
|
||||
private final BrowserSessionModel model;
|
||||
private final BrowserFullSessionModel model;
|
||||
|
||||
public BrowserWelcomeComp(BrowserSessionModel model) {
|
||||
public BrowserHistoryTabComp(BrowserFullSessionModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var state = BrowserSavedStateImpl.get();
|
||||
var state = BrowserHistorySavedStateImpl.get();
|
||||
|
||||
var welcome = new BrowserGreetingComp().createSimple();
|
||||
|
||||
@@ -144,7 +144,7 @@ public class BrowserWelcomeComp extends SimpleComp {
|
||||
return layout;
|
||||
}
|
||||
|
||||
private Comp<?> entryButton(BrowserSavedState.Entry e, BooleanProperty disable) {
|
||||
private Comp<?> entryButton(BrowserHistorySavedState.Entry e, BooleanProperty disable) {
|
||||
var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid());
|
||||
var graphic = entry.get().getEffectiveIconFile();
|
||||
var view = PrettyImageHelper.ofFixedSize(graphic, 22, 16);
|
||||
@@ -167,7 +167,7 @@ public class BrowserWelcomeComp extends SimpleComp {
|
||||
.apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT));
|
||||
}
|
||||
|
||||
private Comp<?> dirButton(BrowserSavedState.Entry e, BooleanProperty disable) {
|
||||
private Comp<?> dirButton(BrowserHistorySavedState.Entry e, BooleanProperty disable) {
|
||||
return new ButtonComp(new SimpleStringProperty(e.getPath()), null, () -> {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
model.restoreStateAsync(e, disable);
|
||||
@@ -1,21 +1,21 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.session.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.browser.session.BrowserSessionTab;
|
||||
import io.xpipe.app.browser.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.browser.BrowserSessionTab;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.storage.DataColor;
|
||||
|
||||
public final class BrowserHomeTabModel extends BrowserSessionTab {
|
||||
public final class BrowserHistoryTabModel extends BrowserSessionTab {
|
||||
|
||||
public BrowserHomeTabModel(BrowserAbstractSessionModel<?> browserModel) {
|
||||
super(browserModel, AppI18n.get("overview"));
|
||||
public BrowserHistoryTabModel(BrowserAbstractSessionModel<?> browserModel) {
|
||||
super(browserModel, AppI18n.get("history"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comp<?> comp() {
|
||||
return new BrowserWelcomeComp((BrowserSessionModel) browserModel);
|
||||
return new BrowserHistoryTabComp((BrowserFullSessionModel) browserModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -8,7 +8,7 @@ import io.xpipe.core.store.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class LocalFileSystem {
|
||||
public class BrowserLocalFileSystem {
|
||||
|
||||
private static FileSystem localFileSystem;
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserContextMenu;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.icon.FileIconManager;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.fxcomps.impl.TextFieldComp;
|
||||
import io.xpipe.app.fxcomps.impl.TooltipAugment;
|
||||
import io.xpipe.app.browser.icon.BrowserIconManager;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.comp.base.PrettyImageHelper;
|
||||
import io.xpipe.app.comp.base.TextFieldComp;
|
||||
import io.xpipe.app.comp.base.TooltipAugment;
|
||||
import io.xpipe.app.util.BooleanScope;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
@@ -33,58 +31,16 @@ import javafx.scene.shape.Rectangle;
|
||||
import atlantafx.base.theme.Styles;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
public class BrowserNavBar extends Comp<BrowserNavBar.Structure> {
|
||||
public class BrowserNavBarComp extends Comp<BrowserNavBarComp.Structure> {
|
||||
|
||||
@Override
|
||||
public Structure createBase() {
|
||||
var path = new SimpleStringProperty(model.getCurrentPath().get());
|
||||
model.getCurrentPath().subscribe((newValue) -> {
|
||||
path.set(newValue);
|
||||
});
|
||||
path.addListener((observable, oldValue, newValue) -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
BooleanScope.executeExclusive(model.getBusy(), () -> {
|
||||
var changed = model.cdSyncOrRetry(newValue, true);
|
||||
changed.ifPresent(s -> Platform.runLater(() -> path.set(s)));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var pathBar = new TextFieldComp(path, true)
|
||||
.styleClass(Styles.CENTER_PILL)
|
||||
.styleClass("path-text")
|
||||
.apply(struc -> {
|
||||
struc.get().focusedProperty().subscribe(val -> {
|
||||
struc.get()
|
||||
.pseudoClassStateChanged(
|
||||
INVISIBLE,
|
||||
!val && !model.getInOverview().get());
|
||||
|
||||
if (val) {
|
||||
Platform.runLater(() -> {
|
||||
struc.get().end();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
model.getInOverview().subscribe(val -> {
|
||||
// Pseudo classes do not apply if set instantly before shown
|
||||
// If we start a new tab with a directory set, we have to set the pseudo class one pulse later
|
||||
Platform.runLater(() -> {
|
||||
struc.get()
|
||||
.pseudoClassStateChanged(
|
||||
INVISIBLE, !val && !struc.get().isFocused());
|
||||
});
|
||||
});
|
||||
|
||||
struc.get().setPromptText("Overview of " + model.getName());
|
||||
})
|
||||
.accessibleText("Current path");
|
||||
var pathBar = createPathBar();
|
||||
|
||||
var graphic = Bindings.createStringBinding(
|
||||
() -> {
|
||||
return model.getCurrentDirectory() != null
|
||||
? FileIconManager.getFileIcon(model.getCurrentDirectory())
|
||||
? BrowserIconManager.getFileIcon(model.getCurrentDirectory())
|
||||
: null;
|
||||
},
|
||||
model.getCurrentPath());
|
||||
@@ -154,6 +110,52 @@ public class BrowserNavBar extends Comp<BrowserNavBar.Structure> {
|
||||
return new Structure(topBox, pathRegion, historyButton);
|
||||
}
|
||||
|
||||
private Comp<CompStructure<TextField>> createPathBar() {
|
||||
var path = new SimpleStringProperty(model.getCurrentPath().get());
|
||||
model.getCurrentPath().subscribe((newValue) -> {
|
||||
path.set(newValue);
|
||||
});
|
||||
path.addListener((observable, oldValue, newValue) -> {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
BooleanScope.executeExclusive(model.getBusy(), () -> {
|
||||
var changed = model.cdSyncOrRetry(newValue, true);
|
||||
changed.ifPresent(s -> Platform.runLater(() -> path.set(s)));
|
||||
});
|
||||
});
|
||||
});
|
||||
var pathBar = new TextFieldComp(path, true)
|
||||
.styleClass(Styles.CENTER_PILL)
|
||||
.styleClass("path-text");
|
||||
pathBar.apply(struc -> {
|
||||
struc.get().focusedProperty().subscribe(val -> {
|
||||
struc.get()
|
||||
.pseudoClassStateChanged(
|
||||
INVISIBLE,
|
||||
!val && !model.getInOverview().get());
|
||||
|
||||
if (val) {
|
||||
Platform.runLater(() -> {
|
||||
struc.get().end();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
model.getInOverview().subscribe(val -> {
|
||||
// Pseudo classes do not apply if set instantly before shown
|
||||
// If we start a new tab with a directory set, we have to set the pseudo class one pulse later
|
||||
Platform.runLater(() -> {
|
||||
struc.get()
|
||||
.pseudoClassStateChanged(
|
||||
INVISIBLE, !val && !struc.get().isFocused());
|
||||
});
|
||||
});
|
||||
|
||||
struc.get().setPromptText("Overview of " + model.getName());
|
||||
})
|
||||
.accessibleText("Current path");
|
||||
return pathBar;
|
||||
}
|
||||
|
||||
public record Structure(HBox box, TextField textField, Button historyButton) implements CompStructure<HBox> {
|
||||
|
||||
@Override
|
||||
@@ -164,9 +166,9 @@ public class BrowserNavBar extends Comp<BrowserNavBar.Structure> {
|
||||
|
||||
private static final PseudoClass INVISIBLE = PseudoClass.getPseudoClass("invisible");
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
|
||||
public BrowserNavBar(OpenFileSystemModel model) {
|
||||
public BrowserNavBarComp(BrowserFileSystemTabModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserFileOverviewComp;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.comp.base.SimpleTitledPaneComp;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.VerticalComp;
|
||||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
@@ -25,9 +23,9 @@ import java.util.List;
|
||||
|
||||
public class BrowserOverviewComp extends SimpleComp {
|
||||
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
|
||||
public BrowserOverviewComp(OpenFileSystemModel model) {
|
||||
public BrowserOverviewComp(BrowserFileSystemTabModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.IconButtonComp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.base.IconButtonComp;
|
||||
import io.xpipe.app.util.InputHelper;
|
||||
|
||||
import javafx.scene.layout.Region;
|
||||
@@ -12,9 +11,9 @@ import java.util.function.Supplier;
|
||||
public class BrowserQuickAccessButtonComp extends SimpleComp {
|
||||
|
||||
private final Supplier<BrowserEntry> base;
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
|
||||
public BrowserQuickAccessButtonComp(Supplier<BrowserEntry> base, OpenFileSystemModel model) {
|
||||
public BrowserQuickAccessButtonComp(Supplier<BrowserEntry> base, BrowserFileSystemTabModel model) {
|
||||
this.base = base;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.icon.FileIconManager;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.browser.icon.BrowserIconManager;
|
||||
import io.xpipe.app.comp.base.PrettyImageHelper;
|
||||
import io.xpipe.app.util.BooleanAnimationTimer;
|
||||
import io.xpipe.app.util.InputHelper;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
@@ -32,13 +31,13 @@ import java.util.stream.Collectors;
|
||||
public class BrowserQuickAccessContextMenu extends ContextMenu {
|
||||
|
||||
private final Supplier<BrowserEntry> base;
|
||||
private final OpenFileSystemModel model;
|
||||
private final BrowserFileSystemTabModel model;
|
||||
private ContextMenu shownBrowserActionsMenu;
|
||||
private boolean expandBrowserActionMenuKey;
|
||||
private boolean keyBasedNavigation;
|
||||
private boolean closeBrowserActionMenuKey;
|
||||
|
||||
public BrowserQuickAccessContextMenu(Supplier<BrowserEntry> base, OpenFileSystemModel model) {
|
||||
public BrowserQuickAccessContextMenu(Supplier<BrowserEntry> base, BrowserFileSystemTabModel model) {
|
||||
this.base = base;
|
||||
this.model = model;
|
||||
|
||||
@@ -142,7 +141,7 @@ public class BrowserQuickAccessContextMenu extends ContextMenu {
|
||||
this.menu = new Menu(
|
||||
// Use original name, not the link target
|
||||
browserEntry.getRawFileEntry().getName(),
|
||||
PrettyImageHelper.ofFixedSize(FileIconManager.getFileIcon(browserEntry.getRawFileEntry()), 24, 24)
|
||||
PrettyImageHelper.ofFixedSize(BrowserIconManager.getFileIcon(browserEntry.getRawFileEntry()), 24, 24)
|
||||
.createRegion());
|
||||
createMenu();
|
||||
addInputListeners();
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserContextMenu;
|
||||
import io.xpipe.app.browser.file.BrowserFileListCompEntry;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||
import io.xpipe.app.fxcomps.impl.LabelComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.comp.base.HorizontalComp;
|
||||
import io.xpipe.app.comp.base.LabelComp;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.HumanReadableFormat;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
@@ -29,7 +26,7 @@ import java.util.List;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class BrowserStatusBarComp extends SimpleComp {
|
||||
|
||||
OpenFileSystemModel model;
|
||||
BrowserFileSystemTabModel model;
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
@@ -1,11 +1,11 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.session.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.browser.session.BrowserSessionTab;
|
||||
import io.xpipe.app.browser.BrowserAbstractSessionModel;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.browser.BrowserSessionTab;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.storage.DataColor;
|
||||
import io.xpipe.app.terminal.TerminalDockComp;
|
||||
import io.xpipe.app.terminal.TerminalDockModel;
|
||||
@@ -14,7 +14,6 @@ import io.xpipe.app.terminal.TerminalViewInstance;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -83,7 +82,7 @@ public final class BrowserTerminalDockTabModel extends BrowserSessionTab {
|
||||
public void onTerminalClosed(TerminalViewInstance instance) {
|
||||
terminals.remove(instance);
|
||||
if (terminals.isEmpty()) {
|
||||
((BrowserSessionModel) browserModel).unsplitTab(BrowserTerminalDockTabModel.this);
|
||||
((BrowserFullSessionModel) browserModel).unsplitTab(BrowserTerminalDockTabModel.this);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,13 +1,11 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.comp.base.*;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.augment.DragOverPseudoClassAugment;
|
||||
import io.xpipe.app.fxcomps.impl.*;
|
||||
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
@@ -17,6 +15,7 @@ import javafx.css.PseudoClass;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.input.Dragboard;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import javafx.scene.layout.Region;
|
||||
@@ -52,7 +51,7 @@ public class BrowserTransferComp extends SimpleComp {
|
||||
var binding = new DerivedObservableList<>(model.getItems(), true)
|
||||
.mapped(item -> item.getBrowserEntry())
|
||||
.getList();
|
||||
var list = new BrowserSelectionListComp(binding, entry -> {
|
||||
var list = new BrowserFileSelectionListComp(binding, entry -> {
|
||||
var sourceItem = model.getCurrentItems().stream()
|
||||
.filter(item -> item.getBrowserEntry() == entry)
|
||||
.findAny();
|
||||
@@ -106,8 +105,12 @@ public class BrowserTransferComp extends SimpleComp {
|
||||
.apply(struc -> struc.get().setMinHeight(200))
|
||||
.apply(struc -> struc.get().setMaxHeight(200));
|
||||
var stack = new StackComp(List.of(backgroundStack, listBox))
|
||||
.apply(DragOverPseudoClassAugment.create())
|
||||
.apply(struc -> {
|
||||
struc.get().addEventFilter(DragEvent.DRAG_ENTERED, event -> {
|
||||
struc.get().pseudoClassStateChanged(PseudoClass.getPseudoClass("drag-over"), true);
|
||||
});
|
||||
struc.get().addEventFilter(DragEvent.DRAG_EXITED, event -> struc.get()
|
||||
.pseudoClassStateChanged(PseudoClass.getPseudoClass("drag-over"), false));
|
||||
struc.get().setOnDragOver(event -> {
|
||||
// Accept drops from inside the app window
|
||||
if (event.getGestureSource() != null && event.getGestureSource() != struc.get()) {
|
||||
@@ -126,7 +129,7 @@ public class BrowserTransferComp extends SimpleComp {
|
||||
if (!(model.getBrowserSessionModel()
|
||||
.getSelectedEntry()
|
||||
.getValue()
|
||||
instanceof OpenFileSystemModel fileSystemModel)) {
|
||||
instanceof BrowserFileSystemTabModel fileSystemModel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -166,7 +169,7 @@ public class BrowserTransferComp extends SimpleComp {
|
||||
Dragboard db = struc.get().startDragAndDrop(TransferMode.COPY);
|
||||
db.setContent(cc);
|
||||
|
||||
Image image = BrowserSelectionListComp.snapshot(FXCollections.observableList(selected));
|
||||
Image image = BrowserFileSelectionListComp.snapshot(FXCollections.observableList(selected));
|
||||
db.setDragView(image, -20, 15);
|
||||
|
||||
event.setDragDetect(true);
|
||||
@@ -1,11 +1,6 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import io.xpipe.app.browser.file.BrowserEntry;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferMode;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferOperation;
|
||||
import io.xpipe.app.browser.file.LocalFileSystem;
|
||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.util.DesktopHelper;
|
||||
import io.xpipe.app.util.ShellTemp;
|
||||
@@ -34,11 +29,11 @@ public class BrowserTransferModel {
|
||||
|
||||
private static final Path TEMP = ShellTemp.getLocalTempDataDirectory("download");
|
||||
|
||||
BrowserSessionModel browserSessionModel;
|
||||
BrowserFullSessionModel browserSessionModel;
|
||||
ObservableList<Item> items = FXCollections.observableArrayList();
|
||||
ObservableBooleanValue empty = Bindings.createBooleanBinding(() -> items.isEmpty(), items);
|
||||
|
||||
public BrowserTransferModel(BrowserSessionModel browserSessionModel) {
|
||||
public BrowserTransferModel(BrowserFullSessionModel browserSessionModel) {
|
||||
this.browserSessionModel = browserSessionModel;
|
||||
var thread = ThreadHelper.createPlatformThread("file downloader", true, () -> {
|
||||
while (true) {
|
||||
@@ -96,7 +91,7 @@ public class BrowserTransferModel {
|
||||
}
|
||||
}
|
||||
|
||||
public void drop(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
public void drop(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
|
||||
synchronized (items) {
|
||||
entries.forEach(entry -> {
|
||||
var name = entry.getFileName();
|
||||
@@ -130,7 +125,7 @@ public class BrowserTransferModel {
|
||||
|
||||
try {
|
||||
var op = new BrowserFileTransferOperation(
|
||||
LocalFileSystem.getLocalFileEntry(TEMP),
|
||||
BrowserLocalFileSystem.getLocalFileEntry(TEMP),
|
||||
List.of(item.getBrowserEntry().getRawFileEntry()),
|
||||
BrowserFileTransferMode.COPY,
|
||||
false,
|
||||
@@ -190,13 +185,13 @@ public class BrowserTransferModel {
|
||||
|
||||
@Value
|
||||
public static class Item {
|
||||
OpenFileSystemModel openFileSystemModel;
|
||||
BrowserFileSystemTabModel openFileSystemModel;
|
||||
String name;
|
||||
BrowserEntry browserEntry;
|
||||
Path localFile;
|
||||
Property<BrowserTransferProgress> progress;
|
||||
|
||||
public Item(OpenFileSystemModel openFileSystemModel, String name, BrowserEntry browserEntry, Path localFile) {
|
||||
public Item(BrowserFileSystemTabModel openFileSystemModel, String name, BrowserEntry browserEntry, Path localFile) {
|
||||
this.openFileSystemModel = openFileSystemModel;
|
||||
this.name = name;
|
||||
this.browserEntry = browserEntry;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.browser;
|
||||
package io.xpipe.app.browser.file;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
@@ -63,7 +63,7 @@ public abstract class BrowserIconDirectoryType {
|
||||
var closedIcon = "browser/" + split[2].trim();
|
||||
var lightClosedIcon = split.length > 4 ? "browser/" + split[4].trim() : closedIcon;
|
||||
|
||||
ALL.add(new Simple(id, new IconVariant(lightClosedIcon, closedIcon), filter));
|
||||
ALL.add(new Simple(id, new BrowserIconVariant(lightClosedIcon, closedIcon), filter));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -84,10 +84,10 @@ public abstract class BrowserIconDirectoryType {
|
||||
@Getter
|
||||
private final String id;
|
||||
|
||||
private final IconVariant closed;
|
||||
private final BrowserIconVariant closed;
|
||||
private final Set<String> names;
|
||||
|
||||
public Simple(String id, IconVariant closed, Set<String> names) {
|
||||
public Simple(String id, BrowserIconVariant closed, Set<String> names) {
|
||||
this.id = id;
|
||||
this.closed = closed;
|
||||
this.names = names;
|
||||
|
||||
@@ -69,11 +69,11 @@ public abstract class BrowserIconFileType {
|
||||
public static class Simple extends BrowserIconFileType {
|
||||
|
||||
private final String id;
|
||||
private final IconVariant icon;
|
||||
private final BrowserIconVariant icon;
|
||||
private final Set<String> endings;
|
||||
|
||||
public Simple(String id, String lightIcon, String darkIcon, Set<String> endings) {
|
||||
this.icon = new IconVariant(lightIcon, darkIcon);
|
||||
this.icon = new BrowserIconVariant(lightIcon, darkIcon);
|
||||
this.id = id;
|
||||
this.endings = endings;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.xpipe.app.browser.icon;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
|
||||
public class FileIconManager {
|
||||
public class BrowserIconManager {
|
||||
|
||||
private static boolean loaded;
|
||||
|
||||
@@ -2,16 +2,16 @@ package io.xpipe.app.browser.icon;
|
||||
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
|
||||
public class IconVariant {
|
||||
public class BrowserIconVariant {
|
||||
|
||||
private final String lightIcon;
|
||||
private final String darkIcon;
|
||||
|
||||
public IconVariant(String icon) {
|
||||
public BrowserIconVariant(String icon) {
|
||||
this(icon, icon);
|
||||
}
|
||||
|
||||
public IconVariant(String lightIcon, String darkIcon) {
|
||||
public BrowserIconVariant(String lightIcon, String darkIcon) {
|
||||
this.lightIcon = lightIcon;
|
||||
this.darkIcon = darkIcon;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.browser.icon;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.base.PrettyImageHelper;
|
||||
import io.xpipe.core.store.FileEntry;
|
||||
|
||||
public class BrowserIcons {
|
||||
@@ -19,6 +19,6 @@ public class BrowserIcons {
|
||||
}
|
||||
|
||||
public static Comp<?> createIcon(FileEntry entry) {
|
||||
return PrettyImageHelper.ofFixedSizeSquare(FileIconManager.getFileIcon(entry), 24);
|
||||
return PrettyImageHelper.ofFixedSizeSquare(BrowserIconManager.getFileIcon(entry), 24);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package io.xpipe.app.fxcomps;
|
||||
package io.xpipe.app.comp;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.augment.Augment;
|
||||
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
||||
import io.xpipe.app.fxcomps.impl.TooltipAugment;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.augment.Augment;
|
||||
import io.xpipe.app.comp.augment.GrowAugment;
|
||||
import io.xpipe.app.comp.base.TooltipAugment;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.fxcomps;
|
||||
package io.xpipe.app.comp;
|
||||
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package io.xpipe.app.comp;
|
||||
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class DeveloperTabComp extends SimpleComp {
|
||||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var button = new ButtonComp(AppI18n.observable("Throw exception"), null, () -> {
|
||||
throw new IllegalStateException();
|
||||
});
|
||||
|
||||
var button2 = new ButtonComp(AppI18n.observable("Throw exception with file"), null, () -> {
|
||||
try {
|
||||
throw new IllegalStateException();
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex)
|
||||
.attachment(Path.of("extensions.txt"))
|
||||
.build()
|
||||
.handle();
|
||||
}
|
||||
});
|
||||
|
||||
var button3 = new ButtonComp(AppI18n.observable("Exit"), null, () -> {
|
||||
System.exit(0);
|
||||
});
|
||||
|
||||
var button6 = new ButtonComp(AppI18n.observable("Restart"), null, () -> {
|
||||
OperationMode.restart();
|
||||
});
|
||||
|
||||
var button4 = new ButtonComp(AppI18n.observable("Throw terminal exception"), null, () -> {
|
||||
try {
|
||||
throw new IllegalStateException();
|
||||
} catch (Exception ex) {
|
||||
ErrorEvent.fromThrowable(ex).terminal(true).build().handle();
|
||||
}
|
||||
});
|
||||
|
||||
var button5 = new ButtonComp(AppI18n.observable("Operation mode null"), null, OperationMode::close);
|
||||
|
||||
return new HBox(
|
||||
button.createRegion(),
|
||||
button2.createRegion(),
|
||||
button3.createRegion(),
|
||||
button4.createRegion(),
|
||||
button5.createRegion(),
|
||||
button6.createRegion());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.fxcomps;
|
||||
package io.xpipe.app.comp;
|
||||
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.xpipe.app.fxcomps;
|
||||
package io.xpipe.app.comp;
|
||||
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.fxcomps.augment;
|
||||
package io.xpipe.app.comp.augment;
|
||||
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.Region;
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.xpipe.app.fxcomps.augment;
|
||||
package io.xpipe.app.comp.augment;
|
||||
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.geometry.Side;
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.xpipe.app.fxcomps.augment;
|
||||
package io.xpipe.app.comp.augment;
|
||||
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.scene.Node;
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
package io.xpipe.app.comp;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.comp.base.MultiContentComp;
|
||||
import io.xpipe.app.comp.base.SideMenuBarComp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
|
||||
import io.xpipe.app.terminal.TerminalView;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Parent;
|
||||
@@ -1,62 +0,0 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.geometry.Rectangle2D;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class BackgroundImageComp extends Comp<CompStructure<Pane>> {
|
||||
|
||||
private final Image image;
|
||||
|
||||
public BackgroundImageComp(Image image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<Pane> createBase() {
|
||||
ImageView v = new ImageView(image);
|
||||
Pane pane = new Pane(v);
|
||||
v.fitWidthProperty().bind(pane.widthProperty());
|
||||
v.fitHeightProperty().bind(pane.heightProperty());
|
||||
if (image == null) {
|
||||
return new SimpleCompStructure<>(pane);
|
||||
}
|
||||
|
||||
double imageAspect = image.getWidth() / image.getHeight();
|
||||
ChangeListener<? super Number> cl = (c, o, n) -> {
|
||||
double paneAspect = pane.getWidth() / pane.getHeight();
|
||||
|
||||
double relViewportWidth;
|
||||
double relViewportHeight;
|
||||
|
||||
// Pane width too big for image
|
||||
if (paneAspect > imageAspect) {
|
||||
relViewportWidth = 1;
|
||||
double newImageHeight = pane.getWidth() / imageAspect;
|
||||
relViewportHeight = Math.min(1, pane.getHeight() / newImageHeight);
|
||||
}
|
||||
|
||||
// Height too big
|
||||
else {
|
||||
relViewportHeight = 1;
|
||||
double newImageWidth = pane.getHeight() * imageAspect;
|
||||
relViewportWidth = Math.min(1, pane.getWidth() / newImageWidth);
|
||||
}
|
||||
|
||||
v.setViewport(new Rectangle2D(
|
||||
((1 - relViewportWidth) / 2.0) * image.getWidth(),
|
||||
((1 - relViewportHeight) / 2.0) * image.getHeight(),
|
||||
image.getWidth() * relViewportWidth,
|
||||
image.getHeight() * relViewportHeight));
|
||||
};
|
||||
pane.widthProperty().addListener(cl);
|
||||
pane.heightProperty().addListener(cl);
|
||||
return new SimpleCompStructure<>(pane);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
|
||||
public class BigIconButton extends ButtonComp {
|
||||
|
||||
public BigIconButton(ObservableValue<String> name, Node graphic, Runnable listener) {
|
||||
super(name, graphic, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Structure createBase() {
|
||||
var vbox = new VBox();
|
||||
vbox.getStyleClass().add("vbox");
|
||||
vbox.setAlignment(Pos.CENTER);
|
||||
|
||||
var icon = new StackPane(getGraphic());
|
||||
icon.setAlignment(Pos.CENTER);
|
||||
icon.getStyleClass().add("icon");
|
||||
vbox.getChildren().add(icon);
|
||||
|
||||
var label = new Label();
|
||||
label.textProperty().bind(getName());
|
||||
label.getStyleClass().add("name");
|
||||
vbox.getChildren().add(label);
|
||||
|
||||
var b = new Button(null);
|
||||
b.accessibleTextProperty().bind(getName());
|
||||
b.setGraphic(vbox);
|
||||
b.setOnAction(e -> getListener().run());
|
||||
b.getStyleClass().add("big-icon-button-comp");
|
||||
return Structure.builder()
|
||||
.stack(vbox)
|
||||
.graphic(getGraphic())
|
||||
.graphicPane(icon)
|
||||
.text(label)
|
||||
.button(b)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Value
|
||||
@Builder
|
||||
public static class Structure implements CompStructure<Button> {
|
||||
Button button;
|
||||
VBox stack;
|
||||
Node graphic;
|
||||
StackPane graphicPane;
|
||||
Label text;
|
||||
|
||||
@Override
|
||||
public Button get() {
|
||||
return button;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.util.Translatable;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.collections.FXCollections;
|
||||
@@ -1,12 +1,11 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.browser.session.BrowserChooserComp;
|
||||
import io.xpipe.app.comp.base.ButtonComp;
|
||||
import io.xpipe.app.browser.BrowserFileChooserSessionComp;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.ContextualFileReference;
|
||||
@@ -67,7 +66,7 @@ public class ContextualFileReferenceChoiceComp extends Comp<CompStructure<HBox>>
|
||||
public CompStructure<HBox> createBase() {
|
||||
var path = previousFileReferences.isEmpty() ? createTextField() : createComboBox();
|
||||
var fileBrowseButton = new ButtonComp(null, new FontIcon("mdi2f-folder-open-outline"), () -> {
|
||||
BrowserChooserComp.openSingleFile(
|
||||
BrowserFileChooserSessionComp.openSingleFile(
|
||||
() -> fileSystem.getValue(),
|
||||
fileStore -> {
|
||||
if (fileStore == null) {
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
@@ -2,9 +2,9 @@ package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.window.AppWindowHelper;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.augment.ContextMenuAugment;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.core.util.FailableConsumer;
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppActionLinkDetector;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.layout.HBox;
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.LabelGraphic;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.LabelGraphic;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
@@ -1,9 +1,7 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.impl.IconButtonComp;
|
||||
import io.xpipe.app.fxcomps.impl.TextAreaComp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.util.FileOpener;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
|
||||
import javafx.scene.control.SplitPane;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.DerivedObservableList;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
|
||||
import javafx.beans.property.ListProperty;
|
||||
import javafx.geometry.Orientation;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.resources.AppResources;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.impl.IconButtonComp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.util.FileOpener;
|
||||
|
||||
import javafx.application.Platform;
|
||||
|
||||
@@ -2,9 +2,9 @@ package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.Property;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.comp.base.MarkdownComp;
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.binding.Bindings;
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppFont;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.Button;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.App;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.util.BindingsHelper;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.xpipe.app.fxcomps.impl;
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.comp.SimpleComp;
|
||||
import io.xpipe.app.util.PlatformThread;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.resources.AppImages;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user