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.theme.Styles;
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.FileIconManager;
import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.comp.base.SideSplitPaneComp;
import io.xpipe.app.core.AppLayoutModel;

View file

@ -497,16 +497,27 @@ final class BrowserFileListComp extends SimpleComp {
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(() -> {
var notDir = getTableRow().getItem().getRawFileEntry().getKind() != FileKind.DIRECTORY;
var isParentLink = getTableRow()
.getItem()
.getRawFileEntry()
.equals(fileList.getFileSystemModel().getCurrentParentDirectory());
return notDir || isParentLink;
}, itemProperty())).createRegion();
var textField = new LazyTextFieldComp(text)
.minWidth(USE_PREF_SIZE)
.createStructure()
.get();
var quickAccess = new BrowserQuickAccessButtonComp(
() -> getTableRow().getItem(), fileList.getFileSystemModel())
.hide(Bindings.createBooleanBinding(
() -> {
var notDir = getTableRow()
.getItem()
.getRawFileEntry()
.getKind()
!= FileKind.DIRECTORY;
var isParentLink = getTableRow()
.getItem()
.getRawFileEntry()
.equals(fileList.getFileSystemModel().getCurrentParentDirectory());
return notDir || isParentLink;
},
itemProperty()))
.createRegion();
editing.addListener((observable, oldValue, newValue) -> {
if (getTableRow().getItem() != null && getTableRow().getItem().equals(newValue)) {
@ -527,11 +538,7 @@ final class BrowserFileListComp extends SimpleComp {
text.addListener(listener);
Node imageView = PrettyImageHelper.ofFixedSize(img, 24, 24).createRegion();
HBox graphic = new HBox(imageView,
new Spacer(5),
quickAccess,
new Spacer(1),
textField);
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);
@ -553,7 +560,7 @@ final class BrowserFileListComp extends SimpleComp {
// 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 {

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));
browserCm.setOnAction(e -> {
contextMenu.hide();
@ -165,7 +166,12 @@ public class BrowserQuickAccessButtonComp extends SimpleComp {
}
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());
try (var s = newFiles) {
var list = s.toList();
@ -187,12 +193,20 @@ public class BrowserQuickAccessButtonComp extends SimpleComp {
return o1.getName().compareToIgnoreCase(o2.getName());
})
.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()
.filter(e -> e.getKind() == FileKind.DIRECTORY)
.toList();
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());
}

View file

@ -61,7 +61,8 @@ public interface LeafAction extends BrowserAction {
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 mi = new MenuItem(name);
mi.setOnAction(event -> {

View file

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

View file

@ -43,7 +43,9 @@ public class ModalOverlayComp extends SimpleComp {
}
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);
AppFont.normal(l);
var r = newValue.content.createRegion();

View file

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

View file

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

View file

@ -62,7 +62,9 @@ public class StoreQuickAccessButtonComp extends SimpleComp {
var graphic =
w.getEntry().getProvider().getDisplayIconFileName(w.getEntry().getStore());
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 -> {
action.accept(w);
contextMenu.hide();
@ -79,7 +81,9 @@ public class StoreQuickAccessButtonComp extends SimpleComp {
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.setOnAction(event -> {
if (event.getTarget() == m) {

View file

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

View file

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

View file

@ -18,7 +18,9 @@ public class AppSid {
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 {
var p = checkProcess.start();
if (p.waitFor(1000, TimeUnit.MILLISECONDS)) {
@ -34,7 +36,8 @@ public class AppSid {
}
// 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;
}

View file

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

View file

@ -56,7 +56,7 @@ public class LauncherCommand implements Callable<Integer> {
return 1;
});
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
new LogErrorHandler().handle(event);
event.handle();

View file

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

View file

@ -729,7 +729,8 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
if (location.isEmpty()) {
location = determineInstallation();
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
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");
// We have to make sure that also other users can create files here
// 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();
base = FileNames.join(base, user);
} else {

View file

@ -31,7 +31,7 @@ public final class FilePath {
return value.contains(" ") ? "\"" + value + "\"" : value;
}
public FilePath toDirectory() {
public FilePath toDirectory() {
if (value.endsWith("/") || value.endsWith("\\")) {
return new FilePath(value);
}
@ -43,7 +43,7 @@ public final class FilePath {
return new FilePath(value + "/");
}
public FilePath removeTrailingSlash() {
public FilePath removeTrailingSlash() {
if (value.equals("/")) {
return new FilePath(value);
}
@ -83,7 +83,7 @@ public final class FilePath {
return list;
}
public String getBaseName() {
public String getBaseName() {
var split = value.lastIndexOf(".");
if (split == -1) {
return value;
@ -91,7 +91,7 @@ public final class FilePath {
return value.substring(0, split);
}
public String getExtension() {
public String getExtension() {
var name = FileNames.getFileName(value);
var split = name.split("\\.");
if (split.length == 0) {
@ -129,12 +129,14 @@ public final class FilePath {
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());
}
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() {
@ -147,14 +149,14 @@ public final class FilePath {
return Arrays.stream(split).filter(s -> !s.isEmpty()).toList();
}
public String toUnix() {
public String toUnix() {
var joined = String.join("/", split());
var prefix = value.startsWith("/") ? "/" : "";
var suffix = value.endsWith("/") || value.endsWith("\\") ? "/" : "";
return prefix + joined + suffix;
}
public String toWindows() {
public String toWindows() {
var suffix = value.endsWith("/") || value.endsWith("\\") ? "\\" : "";
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.OpenFileSystemModel;
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.BrowserIcons;
import javafx.scene.Node;
import java.util.List;