Rework for more file systems

This commit is contained in:
crschnick
2025-08-31 23:39:52 +00:00
parent 4ef0b40f9e
commit 78a5aa509f
15 changed files with 116 additions and 52 deletions
@@ -17,6 +17,10 @@ public class BrowseInNativeManagerActionProvider implements BrowserActionProvide
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return false;
}
return model.getFileSystem()
.getShell()
.orElseThrow()
@@ -17,6 +17,10 @@ public class ChgrpActionProvider implements BrowserActionProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return true;
}
var os = model.getFileSystem().getShell().orElseThrow().getOsType();
return os != OsType.WINDOWS && os != OsType.MACOS;
}
@@ -17,6 +17,10 @@ public class ChmodActionProvider implements BrowserActionProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return true;
}
return model.getFileSystem().getShell().orElseThrow().getOsType() != OsType.WINDOWS;
}
@@ -17,6 +17,10 @@ public class ChownActionProvider implements BrowserActionProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return true;
}
var os = model.getFileSystem().getShell().orElseThrow().getOsType();
return os != OsType.WINDOWS && os != OsType.MACOS;
}
@@ -13,6 +13,7 @@ import javafx.scene.layout.Region;
import javafx.util.Callback;
import atlantafx.base.controls.Breadcrumbs;
import lombok.val;
import java.util.ArrayList;
import java.util.List;
@@ -53,21 +54,21 @@ public class BrowserBreadcrumbBar extends SimpleComp {
}
var sc = model.getFileSystem().getShell();
if (sc.isEmpty()) {
breadcrumbs.setDividerFactory(item -> item != null && !item.isLast() ? new Label("/") : null);
} else {
breadcrumbs.setDividerFactory(item -> {
if (item == null) {
return null;
}
breadcrumbs.setDividerFactory(item -> {
if (item == null) {
return null;
}
if (item.isFirst() && item.getValue().equals("/")) {
return new Label("");
}
if (item.isFirst() && item.getValue().equals("/")) {
return new Label("");
}
return new Label(OsFileSystem.of(sc.get().getOsType()).getFileSystemSeparator());
});
}
if (sc.isEmpty()) {
return new Label("/");
}
return new Label(OsFileSystem.of(sc.get().getOsType()).getFileSystemSeparator());
});
var elements = createBreadcumbHierarchy(val);
var modifiedElements = new ArrayList<>(elements);
@@ -193,8 +193,8 @@ public final class BrowserFileListComp extends SimpleComp {
ownerCol.setVisible(newValue.doubleValue() > 1000);
}
var shell = fileList.getFileSystemModel().getFileSystem().getShell().orElseThrow();
if (!OsType.WINDOWS.equals(shell.getOsType()) && !OsType.MACOS.equals(shell.getOsType())) {
var shell = fileList.getFileSystemModel().getFileSystem().getShell();
if (shell.isEmpty() || (!OsType.WINDOWS.equals(shell.get().getOsType()) && !OsType.MACOS.equals(shell.get().getOsType()))) {
modeCol.setVisible(newValue.doubleValue() > 600);
}
@@ -579,9 +579,8 @@ public final class BrowserFileListComp extends SimpleComp {
ownerCol.setPrefWidth(0);
}
var shell =
fileList.getFileSystemModel().getFileSystem().getShell().orElseThrow();
if (OsType.WINDOWS.equals(shell.getOsType()) || OsType.MACOS.equals(shell.getOsType())) {
var shell = fileList.getFileSystemModel().getFileSystem().getShell();
if (shell.isPresent() && (OsType.WINDOWS.equals(shell.get().getOsType()) || OsType.MACOS.equals(shell.get().getOsType()))) {
modeCol.setVisible(false);
ownerCol.setVisible(false);
} else {
@@ -165,7 +165,10 @@ public final class BrowserFileSystemTabModel extends BrowserStoreSessionTab<File
}
this.fileSystem = fs;
this.cache = new BrowserFileSystemCache(this);
if (fs.getShell().isPresent()) {
this.cache = new BrowserFileSystemCache(this);
}
for (var a : ActionProvider.ALL) {
if (a instanceof BrowserMenuItemProvider ba) {
ba.init(this);
@@ -1,5 +1,6 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.SimpleTitledPaneComp;
import io.xpipe.app.comp.base.VerticalComp;
@@ -19,6 +20,7 @@ import javafx.scene.layout.VBox;
import lombok.SneakyThrows;
import java.util.ArrayList;
import java.util.List;
public class BrowserOverviewComp extends SimpleComp {
@@ -34,44 +36,48 @@ public class BrowserOverviewComp extends SimpleComp {
protected Region createSimple() {
// The open file system might have already been closed
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
var commonPlatform = FXCollections.<FileEntry>synchronizedObservableList(FXCollections.observableArrayList());
ThreadHelper.runFailableAsync(() -> {
var common = OsFileSystem.of(sc.getOsType()).determineInterestingPaths(sc).stream()
.map(s -> FileEntry.ofDirectory(model.getFileSystem(), s))
.filter(entry -> {
var fs = model.getFileSystem();
try {
return fs.directoryExists(entry.getPath());
} catch (Exception e) {
ErrorEventFactory.fromThrowable(e).handle();
return false;
}
})
.toList();
Platform.runLater(() -> {
commonPlatform.setAll(common);
});
});
var commonOverview = new BrowserFileOverviewComp(model, commonPlatform, false);
var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview, false)
.apply(struc -> VBox.setVgrow(struc.get(), Priority.NEVER));
var roots = model.getFileSystem().listRoots().stream()
.map(s -> FileEntry.ofDirectory(model.getFileSystem(), s))
.toList();
var rootsOverview = new BrowserFileOverviewComp(model, FXCollections.observableArrayList(roots), false);
var rootsPane = new SimpleTitledPaneComp(AppI18n.observable("roots"), rootsOverview, false);
var list = new ArrayList<Comp<?>>();
var recent = DerivedObservableList.wrap(model.getSavedState().getRecentDirectories(), true)
.mapped(s -> FileEntry.ofDirectory(model.getFileSystem(), s.getDirectory()))
.getList();
var recentOverview = new BrowserFileOverviewComp(model, recent, true);
var recentPane = new SimpleTitledPaneComp(AppI18n.observable("recent"), recentOverview, false);
list.add(recentPane);
var vbox = new VerticalComp(List.of(recentPane, commonPane, rootsPane)).styleClass("overview");
var sc = model.getFileSystem().getShell();
if (sc.isPresent()) {
var commonPlatform = FXCollections.<FileEntry>synchronizedObservableList(FXCollections.observableArrayList());
ThreadHelper.runFailableAsync(() -> {
var common = OsFileSystem.of(sc.get().getOsType()).determineInterestingPaths(sc.get()).stream().map(
s -> FileEntry.ofDirectory(model.getFileSystem(), s)).filter(entry -> {
var fs = model.getFileSystem();
try {
return fs.directoryExists(entry.getPath());
} catch (Exception e) {
ErrorEventFactory.fromThrowable(e).handle();
return false;
}
}).toList();
Platform.runLater(() -> {
commonPlatform.setAll(common);
});
});
var commonOverview = new BrowserFileOverviewComp(model, commonPlatform, false);
var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview, false).apply(
struc -> VBox.setVgrow(struc.get(), Priority.NEVER));
list.add(commonPane);
}
var roots = model.getFileSystem().listRoots().stream()
.map(s -> FileEntry.ofDirectory(model.getFileSystem(), s))
.toList();
var rootsOverview = new BrowserFileOverviewComp(model, FXCollections.observableArrayList(roots), false);
var rootsPane = new SimpleTitledPaneComp(AppI18n.observable("roots"), rootsOverview, false);
list.add(rootsPane);
var vbox = new VerticalComp(list).styleClass("overview");
var r = vbox.createRegion();
return r;
}
@@ -11,6 +11,10 @@ public interface BrowserApplicationPathMenuProvider extends BrowserMenuItemProvi
@Override
default void init(BrowserFileSystemTabModel model) {
if (model.getFileSystem().getShell().isEmpty()) {
return;
}
// Cache result for later calls
model.getCache().isApplicationInPath(getExecutable());
}
@@ -22,11 +22,11 @@ public class BrowserMenuProviders {
BrowserMenuItemProvider browserAction, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
return browserAction instanceof BrowserMenuLeafProvider
? List.of((BrowserMenuLeafProvider) browserAction)
: ((BrowserMenuBranchProvider) browserAction)
: browserAction.isApplicable(model, entries) ? ((BrowserMenuBranchProvider) browserAction)
.getBranchingActions(model, entries).stream()
.map(action -> getFlattened(action, model, entries))
.flatMap(List::stream)
.toList();
.toList() : List.of();
}
public static BrowserMenuLeafProvider byId(String id, BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
@@ -24,6 +24,10 @@ import java.util.stream.Stream;
public class ChgrpMenuProvider implements BrowserMenuBranchProvider {
private static List<BrowserMenuItemProvider> getLeafActions(BrowserFileSystemTabModel model, boolean recursive) {
if (model.getFileSystem().getShell().isEmpty()) {
return List.of(new CustomProvider(recursive));
}
List<BrowserMenuItemProvider> actions = Stream.<BrowserMenuItemProvider>concat(
model.getCache().getGroups().entrySet().stream()
.filter(e -> !e.getValue().equals("nohome")
@@ -54,6 +58,10 @@ public class ChgrpMenuProvider implements BrowserMenuBranchProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return true;
}
var os = model.getFileSystem().getShell().orElseThrow().getOsType();
return os != OsType.WINDOWS && os != OsType.MACOS;
}
@@ -53,6 +53,10 @@ public class ChmodMenuProvider implements BrowserMenuBranchProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return true;
}
return model.getFileSystem().getShell().orElseThrow().getOsType() != OsType.WINDOWS;
}
@@ -24,6 +24,10 @@ import java.util.stream.Stream;
public class ChownMenuProvider implements BrowserMenuBranchProvider {
private static List<BrowserMenuItemProvider> getLeafActions(BrowserFileSystemTabModel model, boolean recursive) {
if (model.getFileSystem().getShell().isEmpty()) {
return List.of(new CustomProvider(recursive));
}
var actions = Stream.<BrowserMenuItemProvider>concat(
model.getCache().getUsers().entrySet().stream()
.filter(e -> !e.getValue().equals("nohome")
@@ -53,6 +57,10 @@ public class ChownMenuProvider implements BrowserMenuBranchProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return true;
}
var os = model.getFileSystem().getShell().orElseThrow().getOsType();
return os != OsType.WINDOWS && os != OsType.MACOS;
}
@@ -19,8 +19,14 @@ import java.util.List;
public class CompressMenuProvider implements BrowserMenuBranchProvider {
@Override
public void init(BrowserFileSystemTabModel model) throws Exception {
if (model.getFileSystem().getShell().isEmpty()) {
return;
}
var sc = model.getFileSystem().getShell().orElseThrow();
var foundTar = CommandSupport.findProgram(sc, "tar");
@@ -49,6 +55,10 @@ public class CompressMenuProvider implements BrowserMenuBranchProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return false;
}
var ext = List.of("zip", "tar", "tar.gz", "tgz", "rar", "xar");
if (entries.stream().anyMatch(browserEntry -> ext.stream().anyMatch(s -> browserEntry
.getRawFileEntry()
@@ -4,6 +4,7 @@ import io.xpipe.app.browser.BrowserFullSessionModel;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.browser.menu.*;
import io.xpipe.app.browser.menu.impl.ChownMenuProvider;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppLayoutModel;
@@ -38,6 +39,10 @@ public class RunFileScriptMenuProvider implements BrowserMenuBranchProvider {
@Override
public boolean isApplicable(BrowserFileSystemTabModel model, List<BrowserEntry> entries) {
if (model.getFileSystem().getShell().isEmpty()) {
return false;
}
return model.getBrowserModel() instanceof BrowserFullSessionModel;
}