This commit is contained in:
crschnick 2024-03-27 18:19:03 +00:00
parent c475353c22
commit d3f4bd3044
20 changed files with 106 additions and 64 deletions

View file

@ -4,8 +4,8 @@ import atlantafx.base.controls.RingProgressIndicator;
import atlantafx.base.controls.Spacer; import atlantafx.base.controls.Spacer;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import io.xpipe.app.browser.icon.BrowserIconDirectoryType; import io.xpipe.app.browser.icon.BrowserIconDirectoryType;
import io.xpipe.app.browser.icon.FileIconManager;
import io.xpipe.app.browser.icon.BrowserIconFileType; import io.xpipe.app.browser.icon.BrowserIconFileType;
import io.xpipe.app.browser.icon.FileIconManager;
import io.xpipe.app.comp.base.MultiContentComp; import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.comp.base.SideSplitPaneComp; import io.xpipe.app.comp.base.SideSplitPaneComp;
import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.core.AppLayoutModel;

View file

@ -497,16 +497,27 @@ final class BrowserFileListComp extends SimpleComp {
itemProperty())); itemProperty()));
setAccessibleRole(AccessibleRole.TEXT); setAccessibleRole(AccessibleRole.TEXT);
var textField = new LazyTextFieldComp(text).minWidth(USE_PREF_SIZE).createStructure().get(); var textField = new LazyTextFieldComp(text)
var quickAccess = new BrowserQuickAccessButtonComp(() -> getTableRow().getItem(), fileList.getFileSystemModel()) .minWidth(USE_PREF_SIZE)
.hide(Bindings.createBooleanBinding(() -> { .createStructure()
var notDir = getTableRow().getItem().getRawFileEntry().getKind() != FileKind.DIRECTORY; .get();
var isParentLink = getTableRow() var quickAccess = new BrowserQuickAccessButtonComp(
.getItem() () -> getTableRow().getItem(), fileList.getFileSystemModel())
.getRawFileEntry() .hide(Bindings.createBooleanBinding(
.equals(fileList.getFileSystemModel().getCurrentParentDirectory()); () -> {
return notDir || isParentLink; var notDir = getTableRow()
}, itemProperty())).createRegion(); .getItem()
.getRawFileEntry()
.getKind()
!= FileKind.DIRECTORY;
var isParentLink = getTableRow()
.getItem()
.getRawFileEntry()
.equals(fileList.getFileSystemModel().getCurrentParentDirectory());
return notDir || isParentLink;
},
itemProperty()))
.createRegion();
editing.addListener((observable, oldValue, newValue) -> { editing.addListener((observable, oldValue, newValue) -> {
if (getTableRow().getItem() != null && getTableRow().getItem().equals(newValue)) { if (getTableRow().getItem() != null && getTableRow().getItem().equals(newValue)) {
@ -527,11 +538,7 @@ final class BrowserFileListComp extends SimpleComp {
text.addListener(listener); text.addListener(listener);
Node imageView = PrettyImageHelper.ofFixedSize(img, 24, 24).createRegion(); Node imageView = PrettyImageHelper.ofFixedSize(img, 24, 24).createRegion();
HBox graphic = new HBox(imageView, HBox graphic = new HBox(imageView, new Spacer(5), quickAccess, new Spacer(1), textField);
new Spacer(5),
quickAccess,
new Spacer(1),
textField);
quickAccess.prefHeightProperty().bind(graphic.heightProperty()); quickAccess.prefHeightProperty().bind(graphic.heightProperty());
graphic.setAlignment(Pos.CENTER_LEFT); graphic.setAlignment(Pos.CENTER_LEFT);
graphic.setPrefHeight(34); graphic.setPrefHeight(34);
@ -553,7 +560,7 @@ final class BrowserFileListComp extends SimpleComp {
// Don't set image as that would trigger image comp update // Don't set image as that would trigger image comp update
// and cells are emptied on each change, leading to unnecessary changes // and cells are emptied on each change, leading to unnecessary changes
// img.set(null); // img.set(null);
// Visibility seems to be bugged, so use opacity // Visibility seems to be bugged, so use opacity
setOpacity(0.0); setOpacity(0.0);
} else { } else {

View file

@ -74,7 +74,8 @@ public class BrowserQuickAccessButtonComp extends SimpleComp {
}); });
} }
private MenuItem createItem(ContextMenu contextMenu, FileSystem.FileEntry fileEntry, AtomicReference<ContextMenu> showingActionsMenu) { private MenuItem createItem(
ContextMenu contextMenu, FileSystem.FileEntry fileEntry, AtomicReference<ContextMenu> showingActionsMenu) {
var browserCm = new BrowserContextMenu(model, new BrowserEntry(fileEntry, model.getFileList(), false)); var browserCm = new BrowserContextMenu(model, new BrowserEntry(fileEntry, model.getFileList(), false));
browserCm.setOnAction(e -> { browserCm.setOnAction(e -> {
contextMenu.hide(); contextMenu.hide();
@ -165,7 +166,12 @@ public class BrowserQuickAccessButtonComp extends SimpleComp {
} }
private List<MenuItem> updateMenuItems( private List<MenuItem> updateMenuItems(
ContextMenu contextMenu, Menu m, FileSystem.FileEntry fileEntry, boolean updateInstantly, AtomicReference<ContextMenu> showingActionsMenu) throws Exception { ContextMenu contextMenu,
Menu m,
FileSystem.FileEntry fileEntry,
boolean updateInstantly,
AtomicReference<ContextMenu> showingActionsMenu)
throws Exception {
var newFiles = model.getFileSystem().listFiles(fileEntry.getPath()); var newFiles = model.getFileSystem().listFiles(fileEntry.getPath());
try (var s = newFiles) { try (var s = newFiles) {
var list = s.toList(); var list = s.toList();
@ -187,12 +193,20 @@ public class BrowserQuickAccessButtonComp extends SimpleComp {
return o1.getName().compareToIgnoreCase(o2.getName()); return o1.getName().compareToIgnoreCase(o2.getName());
}) })
.collect(Collectors.toMap( .collect(Collectors.toMap(
e -> e, e -> createItem(contextMenu, e, showingActionsMenu), (v1, v2) -> v2, LinkedHashMap::new)); e -> e,
e -> createItem(contextMenu, e, showingActionsMenu),
(v1, v2) -> v2,
LinkedHashMap::new));
var dirs = list.stream() var dirs = list.stream()
.filter(e -> e.getKind() == FileKind.DIRECTORY) .filter(e -> e.getKind() == FileKind.DIRECTORY)
.toList(); .toList();
if (dirs.size() == 1) { if (dirs.size() == 1) {
updateMenuItems(contextMenu, (Menu) menus.get(dirs.getFirst()), list.getFirst(), updateInstantly, showingActionsMenu); updateMenuItems(
contextMenu,
(Menu) menus.get(dirs.getFirst()),
list.getFirst(),
updateInstantly,
showingActionsMenu);
} }
newItems.addAll(menus.values()); newItems.addAll(menus.values());
} }

View file

@ -61,7 +61,8 @@ public interface LeafAction extends BrowserAction {
return b; return b;
} }
default MenuItem toMenuItem(OpenFileSystemModel model, List<BrowserEntry> selected, UnaryOperator<String> nameFunc) { default MenuItem toMenuItem(
OpenFileSystemModel model, List<BrowserEntry> selected, UnaryOperator<String> nameFunc) {
var name = nameFunc.apply(getName(model, selected)); var name = nameFunc.apply(getName(model, selected));
var mi = new MenuItem(name); var mi = new MenuItem(name);
mi.setOnAction(event -> { mi.setOnAction(event -> {

View file

@ -37,11 +37,16 @@ public class ErrorOverlayComp extends SimpleComp {
l.setEditable(false); l.setEditable(false);
return l; return l;
}); });
content.set(new ModalOverlayComp.OverlayContent("error", comp, Comp.of(() -> { content.set(new ModalOverlayComp.OverlayContent(
var graphic = new FontIcon("mdomz-warning"); "error",
graphic.setIconColor(Color.RED); comp,
return new StackPane(graphic); Comp.of(() -> {
}), null, () -> {})); var graphic = new FontIcon("mdomz-warning");
graphic.setIconColor(Color.RED);
return new StackPane(graphic);
}),
null,
() -> {}));
}); });
}); });
content.addListener((observable, oldValue, newValue) -> { content.addListener((observable, oldValue, newValue) -> {

View file

@ -43,7 +43,9 @@ public class ModalOverlayComp extends SimpleComp {
} }
if (newValue != null) { if (newValue != null) {
var l = new Label(AppI18n.get(newValue.titleKey), newValue.graphic != null ? newValue.graphic.createRegion() : null); var l = new Label(
AppI18n.get(newValue.titleKey),
newValue.graphic != null ? newValue.graphic.createRegion() : null);
l.setGraphicTextGap(6); l.setGraphicTextGap(6);
AppFont.normal(l); AppFont.normal(l);
var r = newValue.content.createRegion(); var r = newValue.content.createRegion();

View file

@ -53,9 +53,8 @@ public class OsLogoComp extends SimpleComp {
wrapper.getPersistentState(), wrapper.getPersistentState(),
state)); state));
var hide = BindingsHelper.map(img, s -> s != null); var hide = BindingsHelper.map(img, s -> s != null);
return new StackComp(List.of( return new StackComp(
new SystemStateComp(state).hide(hide), List.of(new SystemStateComp(state).hide(hide), new PrettyImageComp(img, 24, 24).visible(hide)))
new PrettyImageComp(img, 24, 24).visible(hide)))
.createRegion(); .createRegion();
} }

View file

@ -35,8 +35,7 @@ public class StoreIntroComp extends SimpleComp {
var scanPane = new StackPane(scanButton); var scanPane = new StackPane(scanButton);
scanPane.setAlignment(Pos.CENTER); scanPane.setAlignment(Pos.CENTER);
var img = new PrettySvgComp(new SimpleStringProperty("Wave.svg"), 80, 150) var img = new PrettySvgComp(new SimpleStringProperty("Wave.svg"), 80, 150).createRegion();
.createRegion();
var text = new VBox(title, introDesc); var text = new VBox(title, introDesc);
text.setSpacing(5); text.setSpacing(5);
text.setAlignment(Pos.CENTER_LEFT); text.setAlignment(Pos.CENTER_LEFT);

View file

@ -62,7 +62,9 @@ public class StoreQuickAccessButtonComp extends SimpleComp {
var graphic = var graphic =
w.getEntry().getProvider().getDisplayIconFileName(w.getEntry().getStore()); w.getEntry().getProvider().getDisplayIconFileName(w.getEntry().getStore());
if (c.isEmpty()) { if (c.isEmpty()) {
var item = new MenuItem(w.getName().getValue(), PrettyImageHelper.ofFixedSizeSquare(graphic, 16).createRegion()); var item = new MenuItem(
w.getName().getValue(),
PrettyImageHelper.ofFixedSizeSquare(graphic, 16).createRegion());
item.setOnAction(event -> { item.setOnAction(event -> {
action.accept(w); action.accept(w);
contextMenu.hide(); contextMenu.hide();
@ -79,7 +81,9 @@ public class StoreQuickAccessButtonComp extends SimpleComp {
items.add(recurse(contextMenu, sub)); items.add(recurse(contextMenu, sub));
} }
var m = new Menu(w.getName().getValue(), PrettyImageHelper.ofFixedSizeSquare(graphic, 16).createRegion()); var m = new Menu(
w.getName().getValue(),
PrettyImageHelper.ofFixedSizeSquare(graphic, 16).createRegion());
m.getItems().setAll(items); m.getItems().setAll(items);
m.setOnAction(event -> { m.setOnAction(event -> {
if (event.getTarget() == m) { if (event.getTarget() == m) {

View file

@ -64,7 +64,8 @@ public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
? provider.getDisplayIconFileName(section.getWrapper() ? provider.getDisplayIconFileName(section.getWrapper()
.getEntry() .getEntry()
.getStore()) .getStore())
: null, 16) : null,
16)
.createRegion()); .createRegion());
}) })
.apply(struc -> { .apply(struc -> {

View file

@ -317,13 +317,13 @@ public class AppLogs {
// Only change this when debugging the logs of other libraries // Only change this when debugging the logs of other libraries
return NOPLogger.NOP_LOGGER; return NOPLogger.NOP_LOGGER;
// // Don't use fully qualified class names // // Don't use fully qualified class names
// var normalizedName = FilenameUtils.getExtension(name); // var normalizedName = FilenameUtils.getExtension(name);
// if (normalizedName == null || normalizedName.isEmpty()) { // if (normalizedName == null || normalizedName.isEmpty()) {
// normalizedName = name; // normalizedName = name;
// } // }
// //
// return loggers.computeIfAbsent(normalizedName, s -> new Slf4jLogger()); // return loggers.computeIfAbsent(normalizedName, s -> new Slf4jLogger());
} }
}; };

View file

@ -18,7 +18,9 @@ public class AppSid {
return; return;
} }
var checkProcess = new ProcessBuilder("which", "setsid").redirectErrorStream(true).redirectOutput(ProcessBuilder.Redirect.DISCARD); var checkProcess = new ProcessBuilder("which", "setsid")
.redirectErrorStream(true)
.redirectOutput(ProcessBuilder.Redirect.DISCARD);
try { try {
var p = checkProcess.start(); var p = checkProcess.start();
if (p.waitFor(1000, TimeUnit.MILLISECONDS)) { if (p.waitFor(1000, TimeUnit.MILLISECONDS)) {
@ -34,7 +36,8 @@ public class AppSid {
} }
// Don't set this in development mode or debug mode // Don't set this in development mode or debug mode
if (AppProperties.get().isDevelopmentEnvironment() || AppLogs.get().getLogLevel().equals("trace")) { if (AppProperties.get().isDevelopmentEnvironment()
|| AppLogs.get().getLogLevel().equals("trace")) {
return; return;
} }

View file

@ -186,10 +186,12 @@ public class DataStoreChoiceComp<T extends DataStore> extends SimpleComp {
button.apply(struc -> { button.apply(struc -> {
struc.get().setMaxWidth(2000); struc.get().setMaxWidth(2000);
struc.get().setAlignment(Pos.CENTER_LEFT); struc.get().setAlignment(Pos.CENTER_LEFT);
Comp<?> graphic = new PrettySvgComp(Bindings.createStringBinding(() -> { Comp<?> graphic = new PrettySvgComp(
if (selected.getValue() == null) { Bindings.createStringBinding(
return null; () -> {
} if (selected.getValue() == null) {
return null;
}
return selected.getValue() return selected.getValue()
.get() .get()

View file

@ -56,7 +56,7 @@ public class LauncherCommand implements Callable<Integer> {
return 1; return 1;
}); });
cmd.setParameterExceptionHandler((ex, args1) -> { cmd.setParameterExceptionHandler((ex, args1) -> {
var event = ErrorEvent.fromThrowable(ex).term().build(); var event = ErrorEvent.fromThrowable(ex).term().expected().build();
// Print error in case we launched from the command-line // Print error in case we launched from the command-line
new LogErrorHandler().handle(event); new LogErrorHandler().handle(event);
event.handle(); event.handle();

View file

@ -257,8 +257,8 @@ public interface ExternalEditorType extends PrefsChoiceValue {
if (location.isEmpty()) { if (location.isEmpty()) {
location = determineInstallation(); location = determineInstallation();
if (location.isEmpty()) { if (location.isEmpty()) {
throw ErrorEvent.expected( throw ErrorEvent.expected(new IOException("Unable to find installation of "
new IOException("Unable to find installation of " + toTranslatedString().getValue())); + toTranslatedString().getValue()));
} }
} }

View file

@ -729,7 +729,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
if (location.isEmpty()) { if (location.isEmpty()) {
location = determineInstallation(); location = determineInstallation();
if (location.isEmpty()) { if (location.isEmpty()) {
throw new IOException("Unable to find installation of " + toTranslatedString().getValue()); throw new IOException("Unable to find installation of "
+ toTranslatedString().getValue());
} }
} }

View file

@ -64,7 +64,8 @@ public interface SecretQuery {
@Override @Override
public boolean requiresUserInteraction() { public boolean requiresUserInteraction() {
return original.requiresUserInteraction() || AppPrefs.get().alwaysConfirmElevation().getValue(); return original.requiresUserInteraction()
|| AppPrefs.get().alwaysConfirmElevation().getValue();
} }
}; };
} }

View file

@ -43,7 +43,8 @@ public class ShellTemp {
base = FileNames.join(temp, "xpipe"); base = FileNames.join(temp, "xpipe");
// We have to make sure that also other users can create files here // We have to make sure that also other users can create files here
// This command should work in all shells // This command should work in all shells
proc.command("chmod 777 " + proc.getShellDialect().fileArgument(base)).executeAndCheck(); proc.command("chmod 777 " + proc.getShellDialect().fileArgument(base))
.executeAndCheck();
var user = proc.getShellDialect().printUsernameCommand(proc).readStdoutOrThrow(); var user = proc.getShellDialect().printUsernameCommand(proc).readStdoutOrThrow();
base = FileNames.join(base, user); base = FileNames.join(base, user);
} else { } else {

View file

@ -31,7 +31,7 @@ public final class FilePath {
return value.contains(" ") ? "\"" + value + "\"" : value; return value.contains(" ") ? "\"" + value + "\"" : value;
} }
public FilePath toDirectory() { public FilePath toDirectory() {
if (value.endsWith("/") || value.endsWith("\\")) { if (value.endsWith("/") || value.endsWith("\\")) {
return new FilePath(value); return new FilePath(value);
} }
@ -43,7 +43,7 @@ public final class FilePath {
return new FilePath(value + "/"); return new FilePath(value + "/");
} }
public FilePath removeTrailingSlash() { public FilePath removeTrailingSlash() {
if (value.equals("/")) { if (value.equals("/")) {
return new FilePath(value); return new FilePath(value);
} }
@ -83,7 +83,7 @@ public final class FilePath {
return list; return list;
} }
public String getBaseName() { public String getBaseName() {
var split = value.lastIndexOf("."); var split = value.lastIndexOf(".");
if (split == -1) { if (split == -1) {
return value; return value;
@ -91,7 +91,7 @@ public final class FilePath {
return value.substring(0, split); return value.substring(0, split);
} }
public String getExtension() { public String getExtension() {
var name = FileNames.getFileName(value); var name = FileNames.getFileName(value);
var split = name.split("\\."); var split = name.split("\\.");
if (split.length == 0) { if (split.length == 0) {
@ -129,12 +129,14 @@ public final class FilePath {
return new FilePath(value.substring(0, value.length() - getFileName().length() - 1)); return new FilePath(value.substring(0, value.length() - getFileName().length() - 1));
} }
public boolean startsWith(FilePath start) { public boolean startsWith(FilePath start) {
return normalize().startsWith(start.normalize()); return normalize().startsWith(start.normalize());
} }
public FilePath relativize(FilePath base) { public FilePath relativize(FilePath base) {
return new FilePath(normalize().toString().substring(base.normalize().toDirectory().toString().length())); return new FilePath(normalize()
.toString()
.substring(base.normalize().toDirectory().toString().length()));
} }
public FilePath normalize() { public FilePath normalize() {
@ -147,14 +149,14 @@ public final class FilePath {
return Arrays.stream(split).filter(s -> !s.isEmpty()).toList(); return Arrays.stream(split).filter(s -> !s.isEmpty()).toList();
} }
public String toUnix() { public String toUnix() {
var joined = String.join("/", split()); var joined = String.join("/", split());
var prefix = value.startsWith("/") ? "/" : ""; var prefix = value.startsWith("/") ? "/" : "";
var suffix = value.endsWith("/") || value.endsWith("\\") ? "/" : ""; var suffix = value.endsWith("/") || value.endsWith("\\") ? "/" : "";
return prefix + joined + suffix; return prefix + joined + suffix;
} }
public String toWindows() { public String toWindows() {
var suffix = value.endsWith("/") || value.endsWith("\\") ? "\\" : ""; var suffix = value.endsWith("/") || value.endsWith("\\") ? "\\" : "";
return String.join("\\", split()) + suffix; return String.join("\\", split()) + suffix;
} }

View file

@ -3,8 +3,8 @@ package io.xpipe.ext.base.browser;
import io.xpipe.app.browser.BrowserEntry; import io.xpipe.app.browser.BrowserEntry;
import io.xpipe.app.browser.OpenFileSystemModel; import io.xpipe.app.browser.OpenFileSystemModel;
import io.xpipe.app.browser.action.BrowserAction; import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.browser.icon.BrowserIcons;
import io.xpipe.app.browser.icon.BrowserIconFileType; import io.xpipe.app.browser.icon.BrowserIconFileType;
import io.xpipe.app.browser.icon.BrowserIcons;
import javafx.scene.Node; import javafx.scene.Node;
import java.util.List; import java.util.List;