mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
Interface improvements and fixes [release]
This commit is contained in:
parent
d879c13aa4
commit
1b23c833ed
19 changed files with 144 additions and 60 deletions
|
@ -3,7 +3,6 @@ package io.xpipe.app.comp.base;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.CompStructure;
|
import io.xpipe.app.fxcomps.CompStructure;
|
||||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
|
@ -67,7 +66,7 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (!listView.getChildren().equals(newShown)) {
|
if (!listView.getChildren().equals(newShown)) {
|
||||||
BindingsHelper.setContent(listView.getChildren(), newShown);
|
listView.getChildren().setAll(newShown);
|
||||||
listView.layout();
|
listView.layout();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class ListSelectorComp<T> extends SimpleComp {
|
||||||
vbox.getStyleClass().add("content");
|
vbox.getStyleClass().add("content");
|
||||||
for (var v : values) {
|
for (var v : values) {
|
||||||
var cb = new CheckBox(null);
|
var cb = new CheckBox(null);
|
||||||
|
cb.setSelected(selected.contains(v));
|
||||||
cb.selectedProperty().addListener((c, o, n) -> {
|
cb.selectedProperty().addListener((c, o, n) -> {
|
||||||
if (n) {
|
if (n) {
|
||||||
selected.add(v);
|
selected.add(v);
|
||||||
|
@ -35,8 +36,8 @@ public class ListSelectorComp<T> extends SimpleComp {
|
||||||
selected.remove(v);
|
selected.remove(v);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
cb.setSelected(selected.contains(v));
|
|
||||||
var l = new Label(toString.apply(v), cb);
|
var l = new Label(toString.apply(v), cb);
|
||||||
|
l.setOnMouseClicked(event -> cb.setSelected(!cb.isSelected()));
|
||||||
vbox.getChildren().add(l);
|
vbox.getChildren().add(l);
|
||||||
}
|
}
|
||||||
var sp = new ScrollPane(vbox);
|
var sp = new ScrollPane(vbox);
|
||||||
|
|
|
@ -82,8 +82,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.apply(r -> {
|
this.apply(r -> {
|
||||||
r.get().setPrefWidth(AppFont.em(32));
|
r.get().setPrefWidth(AppFont.em(36));
|
||||||
r.get().setPrefHeight(AppFont.em(38));
|
r.get().setPrefHeight(AppFont.em(42));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
|
||||||
ThreadHelper.runAsync(() -> {
|
ThreadHelper.runAsync(() -> {
|
||||||
e.applyChanges(newE);
|
e.applyChanges(newE);
|
||||||
if (!DataStorage.get().getStores().contains(e)) {
|
if (!DataStorage.get().getStores().contains(e)) {
|
||||||
DataStorage.get().addStore(e);
|
DataStorage.get().addStoreEntry(e);
|
||||||
|
ScanAlert.showIfNeeded(e.getStore());
|
||||||
}
|
}
|
||||||
DataStorage.get().refresh();
|
DataStorage.get().refresh();
|
||||||
});
|
});
|
||||||
|
@ -102,7 +103,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
|
||||||
public static void showCreation(Predicate<DataStoreProvider> filter) {
|
public static void showCreation(Predicate<DataStoreProvider> filter) {
|
||||||
show(null, null, null, filter, e -> {
|
show(null, null, null, filter, e -> {
|
||||||
try {
|
try {
|
||||||
DataStorage.get().addStore(e);
|
DataStorage.get().addStoreEntry(e);
|
||||||
|
ScanAlert.showIfNeeded(e.getStore());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ErrorEvent.fromThrowable(ex).handle();
|
ErrorEvent.fromThrowable(ex).handle();
|
||||||
}
|
}
|
||||||
|
@ -218,11 +220,6 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
|
||||||
return new LoadingOverlayComp(Comp.of(() -> layout), busy).createStructure();
|
return new LoadingOverlayComp(Comp.of(() -> layout), busy).createStructure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onContinue() {
|
|
||||||
ScanAlert.showIfNeeded(entry.getValue().getStore());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canContinue() {
|
public boolean canContinue() {
|
||||||
if (provider.getValue() != null) {
|
if (provider.getValue() != null) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.app.comp.base.LazyTextFieldComp;
|
||||||
import io.xpipe.app.comp.base.LoadingOverlayComp;
|
import io.xpipe.app.comp.base.LoadingOverlayComp;
|
||||||
import io.xpipe.app.core.AppFont;
|
import io.xpipe.app.core.AppFont;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
|
import io.xpipe.app.ext.ActionProvider;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||||
|
@ -161,6 +162,14 @@ public class StoreEntryComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
new PopupMenuAugment<>(false) {
|
||||||
|
@Override
|
||||||
|
protected ContextMenu createContextMenu() {
|
||||||
|
return StoreEntryComp.this.createContextMenu();
|
||||||
|
}
|
||||||
|
}.augment(new SimpleCompStructure<>(button));
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,9 +191,9 @@ public class StoreEntryComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
button.apply(new FancyTooltipAugment<>(
|
button.apply(new FancyTooltipAugment<>(
|
||||||
actionProvider.getName(entry.getEntry().getStore().asNeeded())));
|
actionProvider.getName(entry.getEntry().getStore().asNeeded())));
|
||||||
if (!actionProvider.showIfDisabled()) {
|
if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ONLY_SHOW_IF_ENABLED) {
|
||||||
button.hide(Bindings.not(p.getValue()));
|
button.hide(Bindings.not(p.getValue()));
|
||||||
} else {
|
} else if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ALWAYS_SHOW) {
|
||||||
button.disable(Bindings.not(p.getValue()));
|
button.disable(Bindings.not(p.getValue()));
|
||||||
}
|
}
|
||||||
list.add(button);
|
list.add(button);
|
||||||
|
@ -242,9 +251,10 @@ public class StoreEntryComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
item.textProperty().bind(name);
|
item.textProperty().bind(name);
|
||||||
item.disableProperty().bind(Bindings.not(p.getValue()));
|
if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ONLY_SHOW_IF_ENABLED) {
|
||||||
if (!actionProvider.showIfDisabled()) {
|
|
||||||
item.visibleProperty().bind(p.getValue());
|
item.visibleProperty().bind(p.getValue());
|
||||||
|
} else if (actionProvider.activeType() == ActionProvider.DataStoreCallSite.ActiveType.ALWAYS_SHOW) {
|
||||||
|
item.disableProperty().bind(Bindings.not(p.getValue()));
|
||||||
}
|
}
|
||||||
contextMenu.getItems().add(item);
|
contextMenu.getItems().add(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import io.xpipe.app.fxcomps.augment.GrowAugment;
|
||||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||||
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
@ -28,12 +29,17 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
||||||
public static ObservableList<StoreEntrySection> createTopLevels() {
|
public static ObservableList<StoreEntrySection> createTopLevels() {
|
||||||
var filtered = BindingsHelper.filteredContentBinding(
|
var filtered = BindingsHelper.filteredContentBinding(
|
||||||
StoreViewState.get().getAllEntries(),
|
StoreViewState.get().getAllEntries(),
|
||||||
storeEntryWrapper -> !storeEntryWrapper.getEntry().getState().isUsable()
|
storeEntryWrapper -> {
|
||||||
|| storeEntryWrapper
|
if (!storeEntryWrapper.getEntry().getState().isUsable()) {
|
||||||
.getEntry()
|
return true;
|
||||||
.getProvider()
|
}
|
||||||
.getParent(storeEntryWrapper.getEntry().getStore())
|
|
||||||
== null);
|
var parent = storeEntryWrapper
|
||||||
|
.getEntry()
|
||||||
|
.getProvider()
|
||||||
|
.getParent(storeEntryWrapper.getEntry().getStore());
|
||||||
|
return parent == null || (DataStorage.get().getStoreEntryIfPresent(parent).isEmpty());
|
||||||
|
});
|
||||||
var topLevel = BindingsHelper.mappedContentBinding(filtered, storeEntryWrapper -> create(storeEntryWrapper));
|
var topLevel = BindingsHelper.mappedContentBinding(filtered, storeEntryWrapper -> create(storeEntryWrapper));
|
||||||
var ordered = BindingsHelper.orderedContentBinding(
|
var ordered = BindingsHelper.orderedContentBinding(
|
||||||
topLevel,
|
topLevel,
|
||||||
|
@ -101,7 +107,7 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
||||||
new HorizontalComp(topEntryList),
|
new HorizontalComp(topEntryList),
|
||||||
new HorizontalComp(List.of(spacer, content))
|
new HorizontalComp(List.of(spacer, content))
|
||||||
.apply(struc -> struc.get().setFillHeight(true))
|
.apply(struc -> struc.get().setFillHeight(true))
|
||||||
.hide(Bindings.size(children).isEqualTo(0))));
|
.hide(BindingsHelper.persist(Bindings.size(children).isEqualTo(0)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.apache.commons.io.FilenameUtils;
|
||||||
import org.ocpsoft.prettytime.PrettyTime;
|
import org.ocpsoft.prettytime.PrettyTime;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.FileVisitResult;
|
import java.nio.file.FileVisitResult;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -37,6 +38,7 @@ public class AppI18n {
|
||||||
|
|
||||||
private static final Pattern VAR_PATTERN = Pattern.compile("\\$\\w+?\\$");
|
private static final Pattern VAR_PATTERN = Pattern.compile("\\$\\w+?\\$");
|
||||||
private Map<String, String> translations;
|
private Map<String, String> translations;
|
||||||
|
private Map<String, String> markdownDocumentations;
|
||||||
private PrettyTime prettyTime;
|
private PrettyTime prettyTime;
|
||||||
private static AppI18n INSTANCE = new AppI18n();
|
private static AppI18n INSTANCE = new AppI18n();
|
||||||
|
|
||||||
|
@ -189,6 +191,10 @@ private static AppI18n INSTANCE = new AppI18n();
|
||||||
return name.endsWith(ending);
|
return name.endsWith(ending);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMarkdownDocumentation(String name) {
|
||||||
|
return markdownDocumentations.getOrDefault(name, "");
|
||||||
|
}
|
||||||
|
|
||||||
private void load() {
|
private void load() {
|
||||||
TrackEvent.info("Loading translations ...");
|
TrackEvent.info("Loading translations ...");
|
||||||
|
|
||||||
|
@ -210,6 +216,10 @@ private static AppI18n INSTANCE = new AppI18n();
|
||||||
return FileVisitResult.CONTINUE;
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!file.getFileName().toString().endsWith(".properties")) {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
fileCounter.incrementAndGet();
|
fileCounter.incrementAndGet();
|
||||||
try (var in = Files.newInputStream(file)) {
|
try (var in = Files.newInputStream(file)) {
|
||||||
var props = new Properties();
|
var props = new Properties();
|
||||||
|
@ -233,6 +243,39 @@ private static AppI18n INSTANCE = new AppI18n();
|
||||||
.handle();
|
.handle();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
markdownDocumentations = new HashMap<>();
|
||||||
|
for (var module : AppExtensionManager.getInstance().getContentModules()) {
|
||||||
|
AppResources.with(module.getName(), "lang", basePath -> {
|
||||||
|
if (!Files.exists(basePath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var moduleName = FilenameUtils.getExtension(module.getName());
|
||||||
|
Files.walkFileTree(basePath, new SimpleFileVisitor<Path>() {
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
if (!matchesLocale(file)) {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file.getFileName().toString().endsWith(".md")) {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = file.getFileName().toString().substring(0, file.getFileName().toString().lastIndexOf("_"));
|
||||||
|
try (var in = Files.newInputStream(file)) {
|
||||||
|
var usedPrefix = moduleName + ":";
|
||||||
|
markdownDocumentations.put(usedPrefix + name, new String(in.readAllBytes(), StandardCharsets.UTF_8));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ErrorEvent.fromThrowable(ex).omitted(true).build().handle();
|
||||||
|
}
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.prettyTime = new PrettyTime(
|
this.prettyTime = new PrettyTime(
|
||||||
AppPrefs.get() != null
|
AppPrefs.get() != null
|
||||||
? AppPrefs.get().language.getValue().getLocale()
|
? AppPrefs.get().language.getValue().getLocale()
|
||||||
|
|
|
@ -75,6 +75,12 @@ public interface ActionProvider {
|
||||||
|
|
||||||
public static interface DataStoreCallSite<T extends DataStore> {
|
public static interface DataStoreCallSite<T extends DataStore> {
|
||||||
|
|
||||||
|
enum ActiveType {
|
||||||
|
ONLY_SHOW_IF_ENABLED,
|
||||||
|
ALWAYS_SHOW,
|
||||||
|
ALWAYS_ENABLE
|
||||||
|
}
|
||||||
|
|
||||||
Action createAction(T store);
|
Action createAction(T store);
|
||||||
|
|
||||||
Class<T> getApplicableClass();
|
Class<T> getApplicableClass();
|
||||||
|
@ -95,8 +101,8 @@ public interface ActionProvider {
|
||||||
|
|
||||||
String getIcon(T store);
|
String getIcon(T store);
|
||||||
|
|
||||||
default boolean showIfDisabled() {
|
default ActiveType activeType() {
|
||||||
return true;
|
return ActiveType.ONLY_SHOW_IF_ENABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.ComboBox;
|
import javafx.scene.control.ComboBox;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
@ -55,10 +56,12 @@ public class ChoicePaneComp extends Comp<CompStructure<VBox>> {
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
vbox.getChildren().remove(1);
|
vbox.getChildren().remove(1);
|
||||||
} else {
|
} else {
|
||||||
|
var region = n.comp().createRegion();
|
||||||
|
region.setPadding(new Insets(0, 0, 0, 10));
|
||||||
if (vbox.getChildren().size() == 1) {
|
if (vbox.getChildren().size() == 1) {
|
||||||
vbox.getChildren().add(n.comp().createRegion());
|
vbox.getChildren().add(region);
|
||||||
} else {
|
} else {
|
||||||
vbox.getChildren().set(1, n.comp().createRegion());
|
vbox.getChildren().set(1, region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.xpipe.app.fxcomps.impl;
|
||||||
|
|
||||||
import atlantafx.base.controls.Popover;
|
import atlantafx.base.controls.Popover;
|
||||||
import atlantafx.base.controls.Spacer;
|
import atlantafx.base.controls.Spacer;
|
||||||
|
import io.xpipe.app.comp.base.MarkdownComp;
|
||||||
import io.xpipe.app.core.AppFont;
|
import io.xpipe.app.core.AppFont;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.CompStructure;
|
import io.xpipe.app.fxcomps.CompStructure;
|
||||||
|
@ -10,8 +11,10 @@ import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import javafx.beans.Observable;
|
import javafx.beans.Observable;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Orientation;
|
import javafx.geometry.Orientation;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
|
@ -76,16 +79,21 @@ public class OptionsComp extends Comp<CompStructure<Pane>> {
|
||||||
description.managedProperty().bind(PlatformThread.sync(compRegion.managedProperty()));
|
description.managedProperty().bind(PlatformThread.sync(compRegion.managedProperty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.longDescription() != null) {
|
if (entry.longDescriptionSource() != null) {
|
||||||
var popover = new Popover(new Label(entry.longDescription().getValue()));
|
var markDown = new MarkdownComp(entry.longDescriptionSource(), s -> s)
|
||||||
|
.apply(struc -> struc.get().setMaxWidth(500))
|
||||||
|
.apply(struc -> struc.get().setMaxHeight(400));
|
||||||
|
var popover = new Popover(markDown.createRegion());
|
||||||
popover.setCloseButtonEnabled(false);
|
popover.setCloseButtonEnabled(false);
|
||||||
popover.setHeaderAlwaysVisible(false);
|
popover.setHeaderAlwaysVisible(false);
|
||||||
popover.setDetachable(true);
|
popover.setDetachable(true);
|
||||||
AppFont.small(popover.getContentNode());
|
AppFont.small(popover.getContentNode());
|
||||||
|
|
||||||
var descriptionHover = new Label("?");
|
var descriptionHover = new Button("... ?");
|
||||||
|
descriptionHover.setPadding(new Insets(0, 6, 0, 6));
|
||||||
|
descriptionHover.getStyleClass().add("long-description");
|
||||||
AppFont.header(descriptionHover);
|
AppFont.header(descriptionHover);
|
||||||
descriptionHover.setOnMouseClicked(e -> popover.show(descriptionHover));
|
descriptionHover.setOnAction(e -> popover.show(descriptionHover));
|
||||||
|
|
||||||
var descriptionBox = new HBox(description, new Spacer(Orientation.HORIZONTAL), descriptionHover);
|
var descriptionBox = new HBox(description, new Spacer(Orientation.HORIZONTAL), descriptionHover);
|
||||||
HBox.setHgrow(descriptionBox, Priority.ALWAYS);
|
HBox.setHgrow(descriptionBox, Priority.ALWAYS);
|
||||||
|
@ -159,5 +167,5 @@ public class OptionsComp extends Comp<CompStructure<Pane>> {
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Entry(String key, ObservableValue<String> description, ObservableValue<String> longDescription, ObservableValue<String> name, Comp<?> comp) {}
|
public record Entry(String key, ObservableValue<String> description, String longDescriptionSource, ObservableValue<String> name, Comp<?> comp) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ public abstract class LauncherInput {
|
||||||
|
|
||||||
if (scheme.equalsIgnoreCase("xpipe")) {
|
if (scheme.equalsIgnoreCase("xpipe")) {
|
||||||
var action = uri.getAuthority();
|
var action = uri.getAuthority();
|
||||||
var args = Arrays.asList(uri.getPath().split("/"));
|
var args = Arrays.asList(uri.getPath().substring(1).split("/"));
|
||||||
var found = ActionProvider.ALL.stream()
|
var found = ActionProvider.ALL.stream()
|
||||||
.filter(actionProvider -> actionProvider.getLauncherCallSite() != null
|
.filter(actionProvider -> actionProvider.getLauncherCallSite() != null
|
||||||
&& actionProvider
|
&& actionProvider
|
||||||
|
|
|
@ -339,31 +339,41 @@ public abstract class DataStorage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void propagateUpdate() throws Exception {
|
private void propagateUpdate() {
|
||||||
for (DataStoreEntry dataStoreEntry : getStores()) {
|
for (DataStoreEntry dataStoreEntry : getStores()) {
|
||||||
dataStoreEntry.refresh(false);
|
dataStoreEntry.simpleRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var dataStoreEntry : sourceEntries) {
|
for (var e : sourceEntries) {
|
||||||
dataStoreEntry.refresh(false);
|
e.simpleRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addStore(@NonNull DataStoreEntry e) {
|
public void addStoreEntry(@NonNull DataStoreEntry e) {
|
||||||
if (getStoreIfPresent(e.getName()).isPresent()) {
|
if (getStoreIfPresent(e.getName()).isPresent()) {
|
||||||
throw new IllegalArgumentException("Store with name " + e.getName() + " already exists");
|
throw new IllegalArgumentException("Store with name " + e.getName() + " already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
e.setDirectory(getStoresDir().resolve(e.getUuid().toString()));
|
e.setDirectory(getStoresDir().resolve(e.getUuid().toString()));
|
||||||
this.storeEntries.add(e);
|
this.storeEntries.add(e);
|
||||||
|
propagateUpdate();
|
||||||
save();
|
save();
|
||||||
|
|
||||||
this.listeners.forEach(l -> l.onStoreAdd(e));
|
this.listeners.forEach(l -> l.onStoreAdd(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addStoreIfNotPresent(@NonNull String name, DataStore store) {
|
||||||
|
if (getStoreEntryIfPresent(store).isPresent()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var e = DataStoreEntry.createNew(UUID.randomUUID(), createUniqueStoreEntryName(name), store);
|
||||||
|
addStoreEntry(e);
|
||||||
|
}
|
||||||
|
|
||||||
public DataStoreEntry addStore(@NonNull String name, DataStore store) {
|
public DataStoreEntry addStore(@NonNull String name, DataStore store) {
|
||||||
var e = DataStoreEntry.createNew(UUID.randomUUID(), createUniqueStoreEntryName(name), store);
|
var e = DataStoreEntry.createNew(UUID.randomUUID(), createUniqueStoreEntryName(name), store);
|
||||||
addStore(e);
|
addStoreEntry(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.xpipe.app.storage;
|
package io.xpipe.app.storage;
|
||||||
|
|
||||||
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
@ -38,9 +38,12 @@ public abstract class StorageElement {
|
||||||
return elementState;
|
return elementState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
public void simpleRefresh() {
|
public void simpleRefresh() {
|
||||||
refresh(false);
|
try {
|
||||||
|
refresh(false);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ErrorEvent.fromThrowable(e).handle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void refresh(boolean deep) throws Exception;
|
public abstract void refresh(boolean deep) throws Exception;
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class OptionsBuilder {
|
||||||
|
|
||||||
private ObservableValue<String> name;
|
private ObservableValue<String> name;
|
||||||
private ObservableValue<String> description;
|
private ObservableValue<String> description;
|
||||||
private ObservableValue<String> longDescription;
|
private String longDescription;
|
||||||
private Comp<?> comp;
|
private Comp<?> comp;
|
||||||
|
|
||||||
private void finishCurrent() {
|
private void finishCurrent() {
|
||||||
|
@ -106,7 +106,7 @@ public class OptionsBuilder {
|
||||||
|
|
||||||
public OptionsBuilder longDescription(String descriptionKey) {
|
public OptionsBuilder longDescription(String descriptionKey) {
|
||||||
finishCurrent();
|
finishCurrent();
|
||||||
longDescription = AppI18n.observable(descriptionKey);
|
longDescription = AppI18n.getInstance().getMarkdownDocumentation(descriptionKey);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,12 @@ public class ScanAlert {
|
||||||
alert.setTitle(AppI18n.get("scanAlertTitle"));
|
alert.setTitle(AppI18n.get("scanAlertTitle"));
|
||||||
alert.setWidth(300);
|
alert.setWidth(300);
|
||||||
var content = new VerticalComp(List.of(
|
var content = new VerticalComp(List.of(
|
||||||
new LabelComp(AppI18n.get("scanAlertHeader")).apply(struc -> struc.get().setWrapText(true)),
|
new LabelComp(AppI18n.get("scanAlertHeader"))
|
||||||
|
.apply(struc -> struc.get().setWrapText(true)),
|
||||||
new ListSelectorComp<>(
|
new ListSelectorComp<>(
|
||||||
applicable, scanOperation -> AppI18n.get(scanOperation.getNameKey()), selected)))
|
applicable,
|
||||||
|
scanOperation -> AppI18n.get(scanOperation.getNameKey()),
|
||||||
|
selected)))
|
||||||
.apply(struc -> struc.get().setSpacing(15))
|
.apply(struc -> struc.get().setSpacing(15))
|
||||||
.styleClass("window-content")
|
.styleClass("window-content")
|
||||||
.createRegion();
|
.createRegion();
|
||||||
|
@ -51,12 +54,12 @@ public class ScanAlert {
|
||||||
buttonType -> {
|
buttonType -> {
|
||||||
if (buttonType.isPresent()
|
if (buttonType.isPresent()
|
||||||
&& buttonType.get().getButtonData().isDefaultButton()) {
|
&& buttonType.get().getButtonData().isDefaultButton()) {
|
||||||
try (var ignored = new BusyProperty(busy)) {
|
for (var a : selected) {
|
||||||
for (var a : applicable) {
|
try (var ignored = new BusyProperty(busy)) {
|
||||||
a.getScanner().run();
|
a.getScanner().run();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ErrorEvent.fromThrowable(ex).handle();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
|
||||||
ErrorEvent.fromThrowable(ex).handle();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class LocalStoreProvider implements DataStoreProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
var e = DataStoreEntry.createNew(UUID.randomUUID(), "Local Machine", new LocalStore());
|
var e = DataStoreEntry.createNew(UUID.randomUUID(), "Local Machine", new LocalStore());
|
||||||
DataStorage.get().addStore(e);
|
DataStorage.get().addStoreEntry(e);
|
||||||
e.setConfiguration(StorageElement.Configuration.builder()
|
e.setConfiguration(StorageElement.Configuration.builder()
|
||||||
.deletable(false)
|
.deletable(false)
|
||||||
.editable(false)
|
.editable(false)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class AddStoreAction implements ActionProvider {
|
||||||
return new LauncherCallSite() {
|
return new LauncherCallSite() {
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "addStore";
|
return "add";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -37,8 +37,8 @@ public class EditStoreAction implements ActionProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean showIfDisabled() {
|
public ActiveType activeType() {
|
||||||
return false;
|
return ActiveType.ALWAYS_ENABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -43,11 +43,6 @@ public class ShareStoreAction implements ActionProvider {
|
||||||
public DataStoreCallSite<?> getDataStoreCallSite() {
|
public DataStoreCallSite<?> getDataStoreCallSite() {
|
||||||
return new DataStoreCallSite<DataStore>() {
|
return new DataStoreCallSite<DataStore>() {
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showIfDisabled() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionProvider.Action createAction(DataStore store) {
|
public ActionProvider.Action createAction(DataStore store) {
|
||||||
return new Action(store);
|
return new Action(store);
|
||||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
||||||
0.5.3
|
0.5.4
|
Loading…
Reference in a new issue