Merge branch 'browser'

This commit is contained in:
crschnick 2023-02-19 17:44:47 +00:00
parent b3a5b427fe
commit 211b516b7b
374 changed files with 4228 additions and 2058 deletions

View file

@ -1,5 +1,3 @@
import java.util.stream.Collectors
plugins { plugins {
id 'application' id 'application'
id "org.moditect.gradleplugin" version "1.0.0-rc3" id "org.moditect.gradleplugin" version "1.0.0-rc3"
@ -32,10 +30,14 @@ configurations {
} }
dependencies { dependencies {
compileOnly project(':api')
implementation project(':core') implementation project(':core')
implementation project(':extension')
implementation project(':beacon') implementation project(':beacon')
compileOnly 'org.hamcrest:hamcrest:2.2'
compileOnly 'org.junit.jupiter:junit-jupiter-api:5.9.0'
compileOnly 'org.junit.jupiter:junit-jupiter-params:5.9.0'
implementation 'net.java.dev.jna:jna-jpms:5.12.1' implementation 'net.java.dev.jna:jna-jpms:5.12.1'
implementation 'net.java.dev.jna:jna-platform-jpms:5.12.1' implementation 'net.java.dev.jna:jna-platform-jpms:5.12.1'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.13.0" implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: "2.13.0"
@ -46,6 +48,7 @@ dependencies {
implementation group: 'org.kordamp.ikonli', name: 'ikonli-materialdesign2-pack', version: "12.2.0" implementation group: 'org.kordamp.ikonli', name: 'ikonli-materialdesign2-pack', version: "12.2.0"
implementation group: 'org.kordamp.ikonli', name: 'ikonli-javafx', version: "12.2.0" implementation group: 'org.kordamp.ikonli', name: 'ikonli-javafx', version: "12.2.0"
implementation group: 'org.kordamp.ikonli', name: 'ikonli-material-pack', version: "12.2.0" implementation group: 'org.kordamp.ikonli', name: 'ikonli-material-pack', version: "12.2.0"
implementation group: 'org.kordamp.ikonli', name: 'ikonli-feather-pack', version: "12.2.0"
implementation name: 'preferencesfx-core-11.15.0' implementation name: 'preferencesfx-core-11.15.0'
implementation group: 'com.dlsc.formsfx', name: 'formsfx-core', version: '11.6.0' implementation group: 'com.dlsc.formsfx', name: 'formsfx-core', version: '11.6.0'
implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.0' implementation group: 'org.slf4j', name: 'slf4j-api', version: '2.0.0'
@ -67,7 +70,6 @@ sourceSets {
dependencies { dependencies {
testImplementation project(':api') testImplementation project(':api')
testImplementation project(':core') testImplementation project(':core')
testImplementation project(':extension')
} }
Arrays.stream(file("$rootDir/ext").list()) Arrays.stream(file("$rootDir/ext").list())
@ -87,12 +89,12 @@ List<String> jvmRunArgs = [
"--add-exports", "javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix", "--add-exports", "javafx.controls/com.sun.javafx.scene.control.behavior=com.jfoenix",
"--add-exports", "javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls", "--add-exports", "javafx.graphics/com.sun.javafx.scene.traversal=org.controlsfx.controls",
"--add-exports", "javafx.graphics/com.sun.javafx.scene=org.controlsfx.controls", "--add-exports", "javafx.graphics/com.sun.javafx.scene=org.controlsfx.controls",
"--add-exports", "org.apache.commons.lang3/org.apache.commons.lang3.math=io.xpipe.extension", "--add-exports", "org.apache.commons.lang3/org.apache.commons.lang3.math=io.xpipe.app",
"--add-opens", "java.base/java.lang.reflect=com.jfoenix", "--add-opens", "java.base/java.lang.reflect=com.jfoenix",
"--add-opens", "java.base/java.lang.reflect=com.jfoenix", "--add-opens", "java.base/java.lang.reflect=com.jfoenix",
"--add-opens", "java.base/java.lang=io.xpipe.core", "--add-opens", "java.base/java.lang=io.xpipe.core",
"--add-opens", "com.dustinredmond.fxtrayicon/com.dustinredmond.fxtrayicon=io.xpipe.app", "--add-opens", "com.dustinredmond.fxtrayicon/com.dustinredmond.fxtrayicon=io.xpipe.app",
"--add-opens", "net.synedra.validatorfx/net.synedra.validatorfx=io.xpipe.extension", "--add-opens", "net.synedra.validatorfx/net.synedra.validatorfx=io.xpipe.app",
"--add-opens", 'com.dlsc.preferencesfx/com.dlsc.preferencesfx.view=io.xpipe.app', "--add-opens", 'com.dlsc.preferencesfx/com.dlsc.preferencesfx.view=io.xpipe.app',
"-Xmx8g", "-Xmx8g",
"--enable-preview", "--enable-preview",
@ -102,9 +104,6 @@ List<String> jvmRunArgs = [
] ]
def extensionDirList = Arrays.stream(file("$rootDir/ext").list())
.map(l -> project(":$l").buildDir.toString() + "/libs_dev").filter {file(it).exists()}.collect(Collectors.joining(File.pathSeparator));
test { test {
jvmArgs += jvmRunArgs jvmArgs += jvmRunArgs
systemProperty 'io.xpipe.app.mode', 'background' systemProperty 'io.xpipe.app.mode', 'background'
@ -113,8 +112,8 @@ test {
systemProperty 'io.xpipe.app.writeSysOut', "true" systemProperty 'io.xpipe.app.writeSysOut', "true"
systemProperty 'io.xpipe.app.developerMode', "true" systemProperty 'io.xpipe.app.developerMode', "true"
systemProperty 'io.xpipe.app.logLevel', "trace" systemProperty 'io.xpipe.app.logLevel', "trace"
systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion
//systemProperty "io.xpipe.beacon.port", "21722" //systemProperty "io.xpipe.beacon.port", "21722"
systemProperty "io.xpipe.app.extensions", extensionDirList
} }
@ -133,14 +132,14 @@ application {
run { run {
systemProperty 'io.xpipe.app.mode', 'gui' systemProperty 'io.xpipe.app.mode', 'gui'
systemProperty 'io.xpipe.app.dataDir', "$projectDir/local6/" systemProperty 'io.xpipe.app.dataDir', "$projectDir/local_stage/"
systemProperty 'io.xpipe.app.writeLogs', "true" systemProperty 'io.xpipe.app.writeLogs', "true"
systemProperty 'io.xpipe.app.writeSysOut', "true" systemProperty 'io.xpipe.app.writeSysOut', "true"
systemProperty 'io.xpipe.app.developerMode', "true" systemProperty 'io.xpipe.app.developerMode', "true"
systemProperty 'io.xpipe.app.logLevel', "trace" systemProperty 'io.xpipe.app.logLevel', "trace"
systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion
// systemProperty "io.xpipe.beacon.port", "21724" // systemProperty "io.xpipe.beacon.port", "21724"
// systemProperty "io.xpipe.beacon.printMessages", "true" // systemProperty "io.xpipe.beacon.printMessages", "true"
systemProperty "io.xpipe.app.extensions", extensionDirList
// systemProperty 'io.xpipe.app.debugPlatform', "true" // systemProperty 'io.xpipe.app.debugPlatform', "true"
// systemProperty "io.xpipe.beacon.localProxy", "true" // systemProperty "io.xpipe.beacon.localProxy", "true"

View file

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: MIT */
package io.xpipe.app.browser;
import io.xpipe.app.storage.DataStoreEntry;
record Bookmark(DataStoreEntry entry) {
}

View file

@ -0,0 +1,40 @@
package io.xpipe.app.browser;
import com.jfoenix.controls.JFXButton;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.core.store.ShellStore;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Pos;
import javafx.scene.layout.Region;
final class BookmarkList extends SimpleComp {
private final BrowserModel model;
BookmarkList(BrowserModel model) {
this.model = model;
}
@Override
protected Region createSimple() {
var list = DataStorage.get().getStores().stream().filter(entry -> entry.getStore() instanceof ShellStore).map(entry -> new Bookmark(entry)).toList();
return new ListBoxViewComp<>(FXCollections.observableList(list), FXCollections.observableList(list), bookmark -> {
var imgView =
new PrettyImageComp(new SimpleStringProperty(bookmark.entry().getProvider().getDisplayIconFileName()), 16, 16).createRegion();
var button = new JFXButton(bookmark.entry().getName(), imgView);
button.setOnAction(event -> {
event.consume();
var fileSystem = ((ShellStore) bookmark.entry().getStore());
model.openFileSystem(fileSystem);
});
button.setAlignment(Pos.CENTER_LEFT);
return Comp.of(() -> button).grow(true, false);
}).createRegion();
}
}

View file

@ -0,0 +1,61 @@
package io.xpipe.app.browser;
import io.xpipe.core.store.FileSystem;
import io.xpipe.core.util.XPipeTempDirectory;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import lombok.SneakyThrows;
import lombok.Value;
import java.nio.file.Files;
import java.util.*;
public class BrowserClipboard {
@Value
public static class Instance {
UUID uuid;
List<FileSystem.FileEntry> entries;
}
public static Map<UUID, List<FileSystem.FileEntry>> CLIPBOARD = new HashMap<>();
public static Instance currentCopyClipboard;
public static Instance currentDragClipboard;
@SneakyThrows
public static ClipboardContent startDrag(List<FileSystem.FileEntry> selected) {
var content = new ClipboardContent();
var idea = UUID.randomUUID();
var file = XPipeTempDirectory.getLocal().resolve(idea.toString());
Files.createFile(file);
currentDragClipboard = new Instance(idea, selected);
content.putFiles(List.of(file.toFile()));
return content;
}
@SneakyThrows
public static void startCopy(List<FileSystem.FileEntry> selected) {
var idea = UUID.randomUUID();
currentCopyClipboard = new Instance(idea, new ArrayList<>(selected));
}
public static Instance retrieveCopy() {
var current = currentCopyClipboard;
return current;
}
public static Instance retrieveDrag(Dragboard dragboard) {
if (dragboard.getFiles().size() != 1) {
return null;
}
var idea = UUID.fromString(dragboard.getFiles().get(0).toPath().getFileName().toString());
if (idea.equals(currentDragClipboard.uuid)) {
var current = currentDragClipboard;
currentDragClipboard = null;
return current;
}
return null;
}
}

View file

@ -0,0 +1,186 @@
package io.xpipe.app.browser;
import atlantafx.base.controls.RingProgressIndicator;
import atlantafx.base.theme.Styles;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.storage.DataStorage;
import javafx.beans.binding.Bindings;
import javafx.collections.ListChangeListener;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.input.DragEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import java.util.HashMap;
import static atlantafx.base.theme.Styles.DENSE;
import static atlantafx.base.theme.Styles.toggleStyleClass;
import static javafx.scene.control.TabPane.TabClosingPolicy.ALL_TABS;
public class BrowserComp extends SimpleComp {
private static final double TAB_MIN_HEIGHT = 60;
private final BrowserModel model;
public BrowserComp(BrowserModel model) {
this.model = model;
}
@Override
protected Region createSimple() {
var bookmarksList = new BookmarkList(model).createRegion();
var splitPane = new SplitPane(bookmarksList, createTabs());
splitPane
.widthProperty()
.addListener(
// set sidebar width in pixels depending on split pane width
(obs, old, val) -> splitPane.setDividerPosition(0, 230 / splitPane.getWidth()));
return splitPane;
}
private Node createTabs() {
var stack = new StackPane();
var tabs = createTabPane();
stack.getChildren().add(tabs);
var map = new HashMap<OpenFileSystemModel, Tab>();
tabs.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.intValue() == -1) {
model.getSelected().setValue(null);
return;
}
model.getSelected().setValue(model.getOpenFileSystems().get(newValue.intValue()));
});
model.getOpenFileSystems().forEach(v -> {
var t = createTab(tabs, v);
map.put(v, t);
tabs.getTabs().add(t);
});
if (model.getOpenFileSystems().size() > 0) {
tabs.getSelectionModel().select(0);
}
model.getOpenFileSystems().addListener((ListChangeListener<? super OpenFileSystemModel>) c -> {
PlatformThread.runLaterBlocking(() -> {
while (c.next()) {
for (var r : c.getRemoved()) {
var t = map.remove(r);
tabs.getTabs().remove(t);
}
for (var a : c.getAddedSubList()) {
var t = createTab(tabs, a);
map.put(a, t);
tabs.getTabs().add(t);
}
}
});
});
model.getSelected().addListener((observable, oldValue, newValue) -> {
tabs.getSelectionModel().select(model.getOpenFileSystems().indexOf(newValue));
});
tabs.getTabs().addListener((ListChangeListener<? super Tab>) c -> {
while (c.next()) {
for (var r : c.getRemoved()) {
var source = map.entrySet().stream()
.filter(openFileSystemModelTabEntry ->
openFileSystemModelTabEntry.getValue().equals(r))
.findAny()
.orElseThrow();
model.closeFileSystem(source.getKey());
}
}
});
stack.getStyleClass().add("browser");
return stack;
}
private Node createSingular() {
var stack =
new StackPane(new OpenFileSystemComp(model.getOpenFileSystems().get(0)).createSimple());
return stack;
}
private TabPane createTabPane() {
var tabs = new TabPane();
tabs.setTabDragPolicy(TabPane.TabDragPolicy.REORDER);
tabs.setTabClosingPolicy(ALL_TABS);
Styles.toggleStyleClass(tabs, TabPane.STYLE_CLASS_FLOATING);
// tabs.setStyle("-fx-open-tab-animation:none;-fx-close-tab-animation:none;");
toggleStyleClass(tabs, DENSE);
tabs.setMinHeight(TAB_MIN_HEIGHT);
tabs.setTabMinWidth(Region.USE_COMPUTED_SIZE);
return tabs;
}
private Tab createTab(TabPane tabs, OpenFileSystemModel model) {
var tab = new Tab();
var ring = new RingProgressIndicator(0, false);
ring.setMinSize(14, 14);
ring.setPrefSize(14, 14);
ring.setMaxSize(14, 14);
ring.progressProperty()
.bind(Bindings.createDoubleBinding(
() -> model.getBusy().get() ? -1d : 0, PlatformThread.sync(model.getBusy())));
var name = Bindings.createStringBinding(
() -> {
return model.getStore().getValue() != null
? DataStorage.get()
.getEntryByStore(model.getStore().getValue())
.orElseThrow()
.getName()
: null;
},
model.getStore());
var image = Bindings.createStringBinding(
() -> {
return model.getStore().getValue() != null
? DataStorage.get()
.getEntryByStore(model.getStore().getValue())
.orElseThrow()
.getProvider()
.getDisplayIconFileName()
: null;
},
model.getStore());
var logo = new PrettyImageComp(image, 20, 20).createRegion();
var label = new Label();
label.textProperty().bind(name);
label.addEventHandler(DragEvent.DRAG_ENTERED, new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent mouseEvent) {
tabs.getSelectionModel().select(tab);
}
});
label.graphicProperty()
.bind(Bindings.createObjectBinding(
() -> {
return model.getBusy().get() ? ring : logo;
},
PlatformThread.sync(model.getBusy())));
tab.setGraphic(label);
tab.setContent(new OpenFileSystemComp(model).createSimple());
return tab;
}
}

View file

@ -0,0 +1,56 @@
package io.xpipe.app.browser;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.FileSystem;
import io.xpipe.core.store.ShellStore;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import lombok.Getter;
@Getter
public class BrowserModel {
public static final BrowserModel DEFAULT = new BrowserModel();
private final ObservableList<OpenFileSystemModel> openFileSystems = FXCollections.observableArrayList();
private final Property<OpenFileSystemModel> selected = new SimpleObjectProperty<>();
public OpenFileSystemModel getOpenModelFor(DataStore store) {
return openFileSystems.stream()
.filter(model -> model.getStore().equals(store))
.findFirst()
.orElseThrow();
}
public OpenFileSystemModel getOpenModelFor(FileSystem fileSystem) {
return openFileSystems.stream()
.filter(model -> model.getFileSystem().equals(fileSystem))
.findFirst()
.orElseThrow();
}
public void closeFileSystem(OpenFileSystemModel open) {
ThreadHelper.runAsync(() -> {
open.closeSync();
openFileSystems.remove(open);
});
}
public void openFileSystem(ShellStore store) {
var found = openFileSystems.stream()
.filter(fileSystemModel -> fileSystemModel.getStore().equals(store))
.findFirst();
if (found.isPresent()) {
selected.setValue(found.get());
return;
}
var model = new OpenFileSystemModel();
openFileSystems.add(model);
selected.setValue(model);
model.switchAsync(store);
}
}

View file

@ -0,0 +1,66 @@
/* SPDX-License-Identifier: MIT */
package io.xpipe.app.browser;
import io.xpipe.app.util.ExternalEditor;
import javafx.beans.property.Property;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
final class FileContextMenu extends ContextMenu {
private final OpenFileSystemModel model;
private final String path;
private final boolean directory;
private final Property<String> editing;
public FileContextMenu(OpenFileSystemModel model, String path, boolean directory, Property<String> editing) {
super();
this.model = model;
this.path = path;
this.directory = directory;
this.editing = editing;
createMenu();
}
private void createMenu() {
var cut = new MenuItem("Delete");
cut.setOnAction(event -> {
event.consume();
model.deleteAsync(path);
});
cut.setAccelerator(new KeyCodeCombination(KeyCode.DELETE));
var rename = new MenuItem("Rename");
rename.setOnAction(event -> {
event.consume();
editing.setValue(path);
});
rename.setAccelerator(new KeyCodeCombination(KeyCode.F2));
getItems().setAll(
new SeparatorMenuItem(),
cut,
rename
);
if (directory) {
var terminal = new MenuItem("Terminal");
terminal.setOnAction(event -> {
event.consume();
model.openTerminalAsync(path);
});
getItems().add(0, terminal);
} else {
var open = new MenuItem("Edit");
open.setOnAction(event -> {
event.consume();
ExternalEditor.get().openInEditor(model.getFileSystem(), path);
});
getItems().add(0, open);
}
}
}

View file

@ -0,0 +1,346 @@
/* SPDX-License-Identifier: MIT */
package io.xpipe.app.browser;
import atlantafx.base.theme.Styles;
import atlantafx.base.theme.Tweaks;
import io.xpipe.app.comp.base.LazyTextFieldComp;
import io.xpipe.app.core.AppResources;
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.util.Containers;
import io.xpipe.app.util.HumanReadableFormat;
import io.xpipe.core.impl.FileNames;
import io.xpipe.core.store.FileSystem;
import javafx.beans.property.*;
import javafx.beans.value.ChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.input.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import java.io.File;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Comparator;
import java.util.stream.Stream;
import static io.xpipe.app.util.HumanReadableFormat.byteCount;
import static javafx.scene.control.TableColumn.SortType.ASCENDING;
final class FileListComp extends AnchorPane {
private static final PseudoClass HIDDEN = PseudoClass.getPseudoClass("hidden");
private static final PseudoClass FOLDER = PseudoClass.getPseudoClass("folder");
private static final PseudoClass DRAG = PseudoClass.getPseudoClass("drag");
private static final String UNKNOWN = "unknown";
private final FileListModel fileList;
public FileListComp(FileListModel fileList) {
this.fileList = fileList;
TableView<FileSystem.FileEntry> table = createTable();
fileList.getComparatorProperty().bind(table.comparatorProperty());
getChildren().setAll(table);
getStyleClass().addAll("table-directory-view");
Containers.setAnchors(table, Insets.EMPTY);
}
@SuppressWarnings("unchecked")
private TableView<FileSystem.FileEntry> createTable() {
var editing = new SimpleObjectProperty<String>();
var filenameCol = new TableColumn<FileSystem.FileEntry, String>("Name");
filenameCol.setCellValueFactory(param -> new SimpleStringProperty(
param.getValue() != null
? FileNames.getFileName(param.getValue().getPath())
: null));
filenameCol.setComparator(Comparator.comparing(String::toLowerCase));
filenameCol.setSortType(ASCENDING);
filenameCol.setCellFactory(col -> new FilenameCell(editing));
var sizeCol = new TableColumn<FileSystem.FileEntry, Number>("Size");
sizeCol.setCellValueFactory(
param -> new SimpleLongProperty(param.getValue().getSize()));
sizeCol.setCellFactory(col -> new FileSizeCell());
var mtimeCol = new TableColumn<FileSystem.FileEntry, Instant>("Modified");
mtimeCol.setCellValueFactory(
param -> new SimpleObjectProperty<>(param.getValue().getDate()));
mtimeCol.setCellFactory(col -> new FileTimeCell());
mtimeCol.getStyleClass().add(Tweaks.ALIGN_RIGHT);
// ~
var table = new TableView<FileSystem.FileEntry>();
table.getStyleClass().add(Styles.STRIPED);
table.getColumns().setAll(filenameCol, sizeCol, mtimeCol);
table.getSortOrder().add(filenameCol);
table.setSortPolicy(param -> true);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
filenameCol.minWidthProperty().bind(table.widthProperty().multiply(0.5));
table.setOnKeyPressed(event -> {
if (event.isControlDown()
&& event.getCode().equals(KeyCode.C)
&& table.getSelectionModel().getSelectedItems().size() > 0) {
BrowserClipboard.startCopy(table.getSelectionModel().getSelectedItems());
event.consume();
}
if (event.isControlDown() && event.getCode().equals(KeyCode.V)) {
var clipboard = BrowserClipboard.retrieveCopy();
if (clipboard != null) {
var files = clipboard.getEntries();
var target = fileList.getModel().getCurrentDirectory();
fileList.getModel().dropFilesIntoAsync(target, files, true);
event.consume();
}
}
});
table.setRowFactory(param -> {
TableRow<FileSystem.FileEntry> row = new TableRow<>();
row.addEventHandler(MouseEvent.MOUSE_CLICKED, t -> {
t.consume();
if (row.isEmpty()) {
return;
}
var cm = new FileContextMenu(
fileList.getModel(),
row.getItem().getPath(),
row.getItem().isDirectory(),
editing);
if (t.getButton() == MouseButton.SECONDARY) {
cm.show(row, t.getScreenX(), t.getScreenY());
}
});
row.setOnMouseClicked(e -> {
if (e.getClickCount() == 2 && !row.isEmpty()) {
fileList.onClick(row.getItem());
}
});
row.setOnDragOver(event -> {
if (row.equals(event.getGestureSource())) {
return;
}
row.pseudoClassStateChanged(DRAG, true);
event.acceptTransferModes(TransferMode.ANY);
event.consume();
});
row.setOnDragDetected(event -> {
if (row.isEmpty()) {
return;
}
var url = AppResources.getResourceURL(AppResources.XPIPE_MODULE, "img/file_drag_icon.png")
.orElseThrow();
var image = new Image(url.toString(), 80, 80, true, false);
var selected = table.getSelectionModel().getSelectedItems();
Dragboard db = row.startDragAndDrop(TransferMode.COPY);
db.setContent(BrowserClipboard.startDrag(selected));
db.setDragView(image, 30, 60);
event.setDragDetect(true);
event.consume();
});
row.setOnDragExited(event -> {
row.pseudoClassStateChanged(DRAG, false);
event.consume();
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
row.pseudoClassStateChanged(DRAG, false);
event.consume();
}
// if (event.getGestureSource() != null) {
// try {
// var f = Files.createTempFile(null, null);
// var cc = new ClipboardContent();
// cc.putFiles(List.of(f.toFile()));
// Dragboard db = row.startDragAndDrop(TransferMode.COPY);
// db.setContent(cc);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// }
});
//
// row.setEventDispatcher((event, chain) -> {
// if (event.getEventType().getName().equals("MOUSE_DRAGGED")) {
// MouseEvent drag = (MouseEvent) event;
//
// if (drag.isDragDetect()) {
// return chain.dispatchEvent(event);
// }
//
// Rectangle area = new Rectangle(
// App.getApp().getStage().getX(),
// App.getApp().getStage().getY(),
// App.getApp().getStage().getWidth(),
// App.getApp().getStage().getHeight()
// );
// if (!area.intersects(drag.getScreenX(), drag.getScreenY(), 20, 20)) {
// System.out.println("->Drag down");
// drag.setDragDetect(true);
// }
// }
//
// return chain.dispatchEvent(event);
// });
row.setOnDragDropped(event -> {
// Accept drops from outside the app window
if (event.getGestureSource() == null && event.getDragboard().hasFiles()) {
event.setDropCompleted(true);
Dragboard db = event.getDragboard();
var list = db.getFiles().stream().map(File::toPath).toList();
var target = row.getItem() != null
? row.getItem()
: fileList.getModel().getCurrentDirectory();
fileList.getModel().dropLocalFilesIntoAsync(target, list);
}
// Accept drops from inside the app window
if (event.getGestureSource() != null) {
event.setDropCompleted(true);
var files = BrowserClipboard.retrieveDrag(event.getDragboard()).getEntries();
var target = row.getItem() != null
? row.getItem()
: fileList.getModel().getCurrentDirectory();
fileList.getModel().dropFilesIntoAsync(target, files, false);
}
event.consume();
});
return row;
});
BindingsHelper.bindContent(table.getItems(), fileList.getShown());
return table;
}
///////////////////////////////////////////////////////////////////////////
private class FilenameCell extends TableCell<FileSystem.FileEntry, String> {
private final StringProperty img = new SimpleStringProperty();
private final StringProperty text = new SimpleStringProperty();
private final Node imageView = new PrettyImageComp(img, 24, 24).createRegion();
private final StackPane textField =
new LazyTextFieldComp(text).createStructure().get();
private final ChangeListener<String> listener;
public FilenameCell(Property<String> editing) {
editing.addListener((observable, oldValue, newValue) -> {
if (getTableRow().getItem() != null
&& getTableRow().getItem().getPath().equals(newValue)) {
textField.requestFocus();
}
});
listener = (observable, oldValue, newValue) -> {
fileList.rename(oldValue, newValue);
textField.getScene().getRoot().requestFocus();
editing.setValue(null);
updateItem(getItem(), isEmpty());
};
}
@Override
protected void updateItem(String fullPath, boolean empty) {
super.updateItem(fullPath, empty);
text.removeListener(listener);
text.setValue(fullPath);
if (empty || getTableRow() == null || getTableRow().getItem() == null) {
img.set(null);
setGraphic(null);
} else {
var isDirectory = getTableRow().getItem().isDirectory();
var box = new HBox(imageView, textField);
box.setSpacing(10);
box.setAlignment(Pos.CENTER_LEFT);
HBox.setHgrow(textField, Priority.ALWAYS);
setGraphic(box);
if (!isDirectory) {
img.set("file_drag_icon.png");
} else {
img.set("folder_closed.svg");
}
pseudoClassStateChanged(FOLDER, isDirectory);
var fileName = FileNames.getFileName(fullPath);
var hidden = getTableRow().getItem().isHidden() || fileName.startsWith(".");
getTableRow().pseudoClassStateChanged(HIDDEN, hidden);
text.set(fileName);
text.addListener(listener);
}
}
}
private class FileSizeCell extends TableCell<FileSystem.FileEntry, Number> {
@Override
protected void updateItem(Number fileSize, boolean empty) {
super.updateItem(fileSize, empty);
if (empty || getTableRow() == null || getTableRow().getItem() == null) {
setText(null);
} else {
var path = getTableRow().getItem();
if (path.isDirectory()) {
if (true) {
setText("");
return;
}
try (Stream<FileSystem.FileEntry> stream =
path.getFileSystem().listFiles(path.getPath())) {
setText(stream.count() + " items");
} catch (Exception e) {
setText(UNKNOWN);
}
} else {
setText(byteCount(fileSize.longValue()));
}
}
}
}
private static class FileTimeCell extends TableCell<FileSystem.FileEntry, Instant> {
@Override
protected void updateItem(Instant fileTime, boolean empty) {
super.updateItem(fileTime, empty);
if (empty) {
setText(null);
} else {
setText(
fileTime != null
? HumanReadableFormat.date(
fileTime.atZone(ZoneId.systemDefault()).toLocalDateTime())
: UNKNOWN);
}
}
}
}

View file

@ -0,0 +1,81 @@
/* SPDX-License-Identifier: MIT */
package io.xpipe.app.browser;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.ExternalEditor;
import io.xpipe.core.impl.FileNames;
import io.xpipe.core.store.FileSystem;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import lombok.Getter;
import java.util.Comparator;
import java.util.function.Predicate;
@Getter
final class FileListModel {
static final Comparator<FileSystem.FileEntry> FILE_TYPE_COMPARATOR =
Comparator.comparing(path -> !path.isDirectory());
static final Predicate<FileSystem.FileEntry> PREDICATE_ANY = path -> true;
static final Predicate<FileSystem.FileEntry> PREDICATE_NOT_HIDDEN = path -> true;
private final OpenFileSystemModel model;
private final Property<Comparator<FileSystem.FileEntry>> comparatorProperty =
new SimpleObjectProperty<>(FILE_TYPE_COMPARATOR);
private final ObservableList<FileSystem.FileEntry> all = FXCollections.observableArrayList();
private final ObservableList<FileSystem.FileEntry> shown;
private final ObjectProperty<Predicate<FileSystem.FileEntry>> predicateProperty =
new SimpleObjectProperty<>(path -> true);
public FileListModel(OpenFileSystemModel model) {
this.model = model;
var filteredList = new FilteredList<>(all);
filteredList.predicateProperty().bind(predicateProperty);
var sortedList = new SortedList<>(filteredList);
sortedList
.comparatorProperty()
.bind(Bindings.createObjectBinding(
() -> {
Comparator<FileSystem.FileEntry> tableComparator = comparatorProperty.getValue();
return tableComparator != null
? FILE_TYPE_COMPARATOR.thenComparing(tableComparator)
: FILE_TYPE_COMPARATOR;
},
comparatorProperty));
shown = sortedList;
}
public boolean rename(String filename, String newName) {
var fullPath = FileNames.join(model.getCurrentPath().get(), filename);
var newFullPath = FileNames.join(model.getCurrentPath().get(), newName);
try {
model.getFileSystem().move(fullPath, newFullPath);
model.refresh();
return true;
} catch (Exception e) {
ErrorEvent.fromThrowable(e).handle();
return false;
}
}
public void onClick(FileSystem.FileEntry entry) {
if (entry.isDirectory()) {
model.navigate(entry.getPath(), true);
} else {
ExternalEditor.get().openInEditor(entry.getFileSystem(), entry.getPath());
}
}
public ObjectProperty<Predicate<FileSystem.FileEntry>> predicateProperty() {
return predicateProperty;
}
}

View file

@ -0,0 +1,135 @@
package io.xpipe.app.browser;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.impl.FileNames;
import io.xpipe.core.store.FileSystem;
import io.xpipe.core.store.ShellStore;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
public class FileSystemHelper {
private static OpenFileSystemModel local;
public static OpenFileSystemModel getLocal() throws Exception {
if (local == null) {
var model = new OpenFileSystemModel();
model.switchSync(ShellStore.local());
local = model;
}
return local;
}
public static FileSystem.FileEntry getLocal(Path file) throws Exception {
return new FileSystem.FileEntry(
getLocal().getFileSystem(),
file.toString(),
Files.getLastModifiedTime(file).toInstant(),
Files.isDirectory(file),
Files.isHidden(file),
Files.size(file));
}
public static void dropLocalFilesInto(FileSystem.FileEntry entry, List<Path> files) {
try {
var entries = files.stream()
.map(path -> {
try {
return getLocal(path);
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.toList();
dropFilesInto(entry, entries, false);
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).handle();
}
}
public static void dropFilesInto(
FileSystem.FileEntry target, List<FileSystem.FileEntry> files, boolean explicitCopy) {
if (files.size() == 0) {
return;
}
for (var file : files) {
if (file.getFileSystem().equals(target.getFileSystem())) {
dropFileAcrossSameFileSystem(target, file, explicitCopy);
} else {
dropFileAcrossFileSystems(target, file);
}
}
}
private static void dropFileAcrossSameFileSystem(
FileSystem.FileEntry target, FileSystem.FileEntry file, boolean explicitCopy) {
// Prevent dropping directory into itself
if (FileNames.startsWith(file.getPath(), target.getPath())) {
return;
}
try {
var sourceFile = file.getPath();
var targetFile = FileNames.join(target.getPath(), FileNames.getFileName(sourceFile));
if (explicitCopy) {
target.getFileSystem().copy(sourceFile, targetFile);
} else {
target.getFileSystem().move(sourceFile, targetFile);
}
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).handle();
}
}
private static void dropFileAcrossFileSystems(FileSystem.FileEntry target, FileSystem.FileEntry file) {
var flatFiles = new HashMap<FileSystem.FileEntry, String>();
// Prevent dropping directory into itself
if (file.getFileSystem().equals(target.getFileSystem())
&& FileNames.startsWith(file.getPath(), target.getPath())) {
return;
}
try {
if (file.isDirectory()) {
flatFiles.put(file, FileNames.getFileName(file.getPath()));
try (var stream = file.getFileSystem().listFilesRecursively(file.getPath())) {
stream.forEach(fileEntry -> {
flatFiles.put(fileEntry, FileNames.relativize(file.getPath(), fileEntry.getPath()));
});
}
} else {
flatFiles.put(file, FileNames.getFileName(file.getPath()));
}
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).handle();
return;
}
for (var e : flatFiles.entrySet()) {
var sourceFile = e.getKey();
var targetFile = FileNames.join(target.getPath(), e.getValue());
try {
if (sourceFile.getFileSystem().equals(target.getFileSystem())) {
throw new IllegalStateException();
}
if (sourceFile.isDirectory()) {
target.getFileSystem().mkdirs(targetFile);
} else {
try (var in = sourceFile.getFileSystem().openInput(sourceFile.getPath());
var out = target.getFileSystem().openOutput(targetFile)) {
in.transferTo(out);
}
}
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).handle();
}
}
}
}

View file

@ -0,0 +1,62 @@
/* SPDX-License-Identifier: MIT */
package io.xpipe.app.browser;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
final class NavigationHistory {
private final IntegerProperty cursor = new SimpleIntegerProperty(0);
private final List<String> history = new ArrayList<>();
private final BooleanBinding canGoBack = Bindings.createBooleanBinding(
() -> cursor.get() > 0 && history.size() > 1, cursor);
private final BooleanBinding canGoForth = Bindings.createBooleanBinding(
() -> cursor.get() < history.size() - 1, cursor);
public String getCurrent() {
return history.size() > 0 ? history.get(cursor.get()) : null;
}
public void append(String s) {
if (s == null) {
return;
}
var lastString = history.size() > 0 ? history.get(history.size() - 1) : null;
if (!Objects.equals(lastString, s)) {
history.add(s);
}
cursor.set(history.size() - 1);
}
public Optional<String> back() {
if (!canGoBack.get()) {
return Optional.empty();
}
cursor.set(cursor.get() - 1);
return Optional.of(history.get(cursor.get()));
}
public Optional<String> forth() {
if (!canGoForth.get()) {
return Optional.empty();
}
cursor.set(cursor.get() + 1);
return Optional.of(history.get(cursor.get()));
}
public BooleanBinding canGoBackProperty() {
return canGoBack;
}
public BooleanBinding canGoForthProperty() {
return canGoForth;
}
}

View file

@ -0,0 +1,124 @@
package io.xpipe.app.browser;
import atlantafx.base.controls.Spacer;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.TextFieldComp;
import io.xpipe.core.impl.FileNames;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import org.kordamp.ikonli.feather.Feather;
import org.kordamp.ikonli.javafx.FontIcon;
import static io.xpipe.app.browser.FileListModel.PREDICATE_NOT_HIDDEN;
import static io.xpipe.app.util.Controls.iconButton;
public class OpenFileSystemComp extends SimpleComp {
private final OpenFileSystemModel model;
public OpenFileSystemComp(OpenFileSystemModel model) {
this.model = model;
}
@Override
protected Region createSimple() {
var creatingProperty = new SimpleBooleanProperty();
var backBtn = iconButton(Feather.ARROW_LEFT, false);
backBtn.setOnAction(e -> model.back());
backBtn.disableProperty().bind(model.getHistory().canGoBackProperty().not());
var forthBtn = iconButton(Feather.ARROW_RIGHT, false);
forthBtn.setOnAction(e -> model.forth());
forthBtn.disableProperty().bind(model.getHistory().canGoForthProperty().not());
var path = new SimpleStringProperty(model.getCurrentPath().get());
var pathBar = new TextFieldComp(path, true).createRegion();
path.addListener((observable, oldValue, newValue) -> {
model.cd(newValue);
});
model.getCurrentPath().addListener((observable, oldValue, newValue) -> {
path.set(newValue);
});
HBox.setHgrow(pathBar, Priority.ALWAYS);
var refreshBtn = new Button(null, new FontIcon("mdmz-refresh"));
refreshBtn.setOnAction(e -> model.refresh());
var terminalBtn = new Button(null, new FontIcon("mdi2c-code-greater-than"));
terminalBtn.setOnAction(e -> model.openTerminalAsync(model.getCurrentPath().get()));
var addBtn = new Button(null, new FontIcon("mdmz-plus"));
addBtn.setOnAction(e -> {
creatingProperty.set(true);
});
var topBar = new ToolBar();
topBar.getItems().setAll(
backBtn,
forthBtn,
new Spacer(10),
pathBar,
refreshBtn,
terminalBtn,
addBtn
);
// ~
FileListComp directoryView = new FileListComp(model.getFileList());
var root = new VBox(topBar, directoryView);
VBox.setVgrow(directoryView, Priority.ALWAYS);
root.setPadding(Insets.EMPTY);
model.getFileList().predicateProperty().set(PREDICATE_NOT_HIDDEN);
var pane = new StackPane();
pane.getChildren().add(root);
var creation = createCreationWindow(creatingProperty);
var creationPain = new StackPane(creation);
creationPain.setAlignment(Pos.CENTER);
creationPain.setOnMouseClicked(event -> {
creatingProperty.set(false);
});
pane.getChildren().add(creationPain);
creationPain.visibleProperty().bind(creatingProperty);
creationPain.managedProperty().bind(creatingProperty);
return pane;
}
private Region createCreationWindow(BooleanProperty creating) {
var creationName = new TextField();
creating.addListener((observable, oldValue, newValue) -> {
if (!newValue) {
creationName.setText("");
}
});
var createFileButton = new Button("Create file");
createFileButton.setOnAction(event -> {
model.createFileAsync(FileNames.join(model.getCurrentPath().get(), creationName.getText()));
creating.set(false);
});
var createDirectoryButton = new Button("Create directory");
createDirectoryButton.setOnAction(event -> {
model.createDirectoryAsync(FileNames.join(model.getCurrentPath().get(), creationName.getText()));
creating.set(false);
});
var buttonBar = new ButtonBar();
buttonBar.getButtons().addAll(createFileButton, createDirectoryButton);
var creationContent = new VBox(creationName, buttonBar);
creationContent.setSpacing(15);
var creation = new TitledPane("New", creationContent);
creation.setMaxWidth(400);
creation.setCollapsible(false);
creationContent.setPadding(new Insets(15));
creation.getStyleClass().add("elevated-3");
return creation;
}
}

View file

@ -0,0 +1,224 @@
/* SPDX-License-Identifier: MIT */
package io.xpipe.app.browser;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.BusyProperty;
import io.xpipe.app.util.TerminalHelper;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.ConnectionFileSystem;
import io.xpipe.core.store.FileSystem;
import io.xpipe.core.store.FileSystemStore;
import io.xpipe.core.store.ShellStore;
import javafx.beans.property.*;
import lombok.Getter;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
@Getter
final class OpenFileSystemModel {
private Property<FileSystemStore> store = new SimpleObjectProperty<>();
private FileSystem fileSystem;
private List<String> roots;
private final FileListModel fileList;
private final ReadOnlyObjectWrapper<String> currentPath = new ReadOnlyObjectWrapper<>();
private final NavigationHistory history = new NavigationHistory();
private final BooleanProperty busy = new SimpleBooleanProperty();
public OpenFileSystemModel() {
fileList = new FileListModel(this);
}
public void refresh() {
BusyProperty.execute(busy, () -> {
cdSync(currentPath.get());
});
}
private void refreshInternal() {
cdSync(currentPath.get());
}
public FileSystem.FileEntry getCurrentDirectory() {
return new FileSystem.FileEntry(fileSystem, currentPath.get(), Instant.now(), true, false, 0);
}
public void cd(String path) {
ThreadHelper.runFailableAsync(() -> {
cdSync(path);
});
}
private boolean cdSync(String path) {
try (var ignored = new BusyProperty(busy)) {
if (!navigateTo(path)) {
return false;
}
currentPath.set(path);
if (!Objects.equals(history.getCurrent(), path)) {
history.append(path);
}
return true;
}
}
private boolean navigateTo(String dir) {
try {
List<FileSystem.FileEntry> newList;
if (dir != null) {
newList = getFileSystem().listFiles(dir).toList();
} else {
newList = getFileSystem().listRoots().stream()
.map(s -> new FileSystem.FileEntry(getFileSystem(), s, Instant.now(), true, false, 0))
.toList();
}
BindingsHelper.setContent(fileList.getAll(), newList);
return true;
} catch (Exception e) {
ErrorEvent.fromThrowable(e).handle();
return false;
}
}
public void dropLocalFilesIntoAsync(FileSystem.FileEntry entry, List<Path> files) {
ThreadHelper.runFailableAsync(() -> {
BusyProperty.execute(busy, () -> {
FileSystemHelper.dropLocalFilesInto(entry, files);
refreshInternal();
});
});
}
public void dropFilesIntoAsync(FileSystem.FileEntry target, List<FileSystem.FileEntry> files, boolean explicitCopy) {
ThreadHelper.runFailableAsync(() -> {
BusyProperty.execute(busy, () -> {
FileSystemHelper.dropFilesInto(target, files, explicitCopy);
refreshInternal();
});
});
}
public void createDirectoryAsync(String path) {
if (path.isBlank()) {
return;
}
ThreadHelper.runFailableAsync(() -> {
BusyProperty.execute(busy, () -> {
fileSystem.mkdirs(path);
refreshInternal();
});
});
}
public void createFileAsync(String path) {
if (path.isBlank()) {
return;
}
ThreadHelper.runFailableAsync(() -> {
BusyProperty.execute(busy, () -> {
fileSystem.touch(path);
refreshInternal();
});
});
}
public void deleteAsync(String path) {
ThreadHelper.runFailableAsync(() -> {
BusyProperty.execute(busy, () -> {
fileSystem.delete(path);
refreshInternal();
});
});
}
void closeSync() {
if (fileSystem == null) {
return;
}
try {
fileSystem.close();
} catch (IOException e) {
ErrorEvent.fromThrowable(e).handle();
}
fileSystem = null;
store = null;
}
public void switchSync(FileSystemStore fileSystem) throws Exception {
BusyProperty.execute(busy, () -> {
closeSync();
this.store.setValue(fileSystem);
var fs = fileSystem.createFileSystem();
fs.open();
this.fileSystem = fs;
var current = fs instanceof ConnectionFileSystem connectionFileSystem
? connectionFileSystem
.getShellProcessControl()
.executeStringSimpleCommand(connectionFileSystem
.getShellProcessControl()
.getShellType()
.getPrintWorkingDirectoryCommand())
: null;
cdSync(current);
});
}
public void switchAsync(FileSystemStore fileSystem) {
ThreadHelper.runFailableAsync(() -> {
switchSync(fileSystem);
});
}
public void openTerminalAsync(String directory) {
ThreadHelper.runFailableAsync(() -> {
BusyProperty.execute(busy, () -> {
if (store.getValue() instanceof ShellStore s) {
var connection = ((ConnectionFileSystem) fileSystem).getShellProcessControl();
var command = s.create()
.initWith(List.of(connection.getShellType().getCdCommand(directory)))
.prepareTerminalOpen();
TerminalHelper.open("", command);
}
});
});
}
///////////////////////////////////////////////////////////////////////////
// Properties //
///////////////////////////////////////////////////////////////////////////
public ReadOnlyObjectProperty<String> currentPathProperty() {
return currentPath.getReadOnlyProperty();
}
public NavigationHistory getHistory() {
return history;
}
///////////////////////////////////////////////////////////////////////////
// Commands //
///////////////////////////////////////////////////////////////////////////
public void back() {
history.back().ifPresent(currentPath::set);
}
public void forth() {
history.forth().ifPresent(currentPath::set);
}
public void navigate(String path, boolean saveInHistory) {
currentPath.set(path);
}
}

View file

@ -0,0 +1,57 @@
/* SPDX-License-Identifier: MIT */
package io.xpipe.app.browser;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
final class Utils {
private Utils() {
// Default constructor
}
public static long fileSize(Path path) {
if (path == null) {
return 0;
}
try {
return Files.size(path);
} catch (IOException e) {
return 0;
}
}
public static boolean isFileHidden(Path path) {
if (path == null) {
return false;
}
try {
return Files.isHidden(path);
} catch (IOException e) {
return false;
}
}
public static FileTime fileMTime(Path path, LinkOption... options) {
if (path == null) {
return null;
}
try {
return Files.getLastModifiedTime(path, options);
} catch (IOException e) {
return null;
}
}
public static String getMimeType(Path path) {
try {
return Files.probeContentType(path);
} catch (IOException e) {
return null;
}
}
}

View file

@ -1,24 +1,23 @@
package io.xpipe.app.comp; package io.xpipe.app.comp;
import io.xpipe.app.browser.BrowserComp;
import io.xpipe.app.browser.BrowserModel;
import io.xpipe.app.comp.about.AboutTabComp; import io.xpipe.app.comp.about.AboutTabComp;
import io.xpipe.app.comp.base.SideMenuBarComp; import io.xpipe.app.comp.base.SideMenuBarComp;
import io.xpipe.app.comp.storage.collection.SourceCollectionLayoutComp; import io.xpipe.app.comp.storage.collection.SourceCollectionLayoutComp;
import io.xpipe.app.comp.storage.store.StoreLayoutComp; import io.xpipe.app.comp.storage.store.StoreLayoutComp;
import io.xpipe.app.core.AppActionLinkDetector; import io.xpipe.app.core.*;
import io.xpipe.app.core.AppCache; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.core.AppProperties; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import lombok.SneakyThrows;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -40,21 +39,23 @@ public class AppLayoutComp extends Comp<CompStructure<BorderPane>> {
}); });
} }
@SneakyThrows
private List<SideMenuBarComp.Entry> createEntryList() { private List<SideMenuBarComp.Entry> createEntryList() {
var l = new ArrayList<>(List.of( var l = new ArrayList<>(List.of(
new SideMenuBarComp.Entry(I18n.observable("connections"), "mdi2c-connection", new StoreLayoutComp()), new SideMenuBarComp.Entry(AppI18n.observable("connections"), "mdi2c-connection", new StoreLayoutComp()),
new SideMenuBarComp.Entry(I18n.observable("data"), "mdsal-dvr", new SourceCollectionLayoutComp()), new SideMenuBarComp.Entry(AppI18n.observable("browser"), "mdi2f-file-cabinet", new BrowserComp(BrowserModel.DEFAULT)),
new SideMenuBarComp.Entry(AppI18n.observable("data"), "mdsal-dvr", new SourceCollectionLayoutComp()),
new SideMenuBarComp.Entry( new SideMenuBarComp.Entry(
I18n.observable("settings"), "mdsmz-miscellaneous_services", new PrefsComp(this)), AppI18n.observable("settings"), "mdsmz-miscellaneous_services", new PrefsComp(this)),
// new SideMenuBarComp.Entry(I18n.observable("help"), "mdi2b-book-open-variant", new // new SideMenuBarComp.Entry(AppI18n.observable("help"), "mdi2b-book-open-variant", new
// StorageLayoutComp()), // StorageLayoutComp()),
// new SideMenuBarComp.Entry(I18n.observable("account"), "mdi2a-account", new StorageLayoutComp()), // new SideMenuBarComp.Entry(AppI18n.observable("account"), "mdi2a-account", new StorageLayoutComp()),
new SideMenuBarComp.Entry(I18n.observable("about"), "mdi2p-package-variant", new AboutTabComp()))); new SideMenuBarComp.Entry(AppI18n.observable("about"), "mdi2p-package-variant", new AboutTabComp())));
if (AppProperties.get().isDeveloperMode()) { if (AppProperties.get().isDeveloperMode()) {
l.add(new SideMenuBarComp.Entry(I18n.observable("developer"), "mdi2b-book-open-variant", new l.add(new SideMenuBarComp.Entry(AppI18n.observable("developer"), "mdi2b-book-open-variant", new
DeveloperTabComp())); DeveloperTabComp()));
} }
// l.add(new SideMenuBarComp.Entry(I18n.observable("abc"), "mdi2b-book-open-variant", Comp.of(() -> { // l.add(new SideMenuBarComp.Entry(AppI18n.observable("abc"), "mdi2b-book-open-variant", Comp.of(() -> {
// var fi = new FontIcon("mdsal-dvr"); // var fi = new FontIcon("mdsal-dvr");
// fi.setIconSize(30); // fi.setIconSize(30);
// fi.setIconColor(Color.valueOf("#111C")); // fi.setIconColor(Color.valueOf("#111C"));

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp; package io.xpipe.app.comp;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.extension.I18n; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.event.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@ -14,11 +14,11 @@ public class DeveloperTabComp extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var button = new ButtonComp(I18n.observable("Throw exception"), null, () -> { var button = new ButtonComp(AppI18n.observable("Throw exception"), null, () -> {
throw new IllegalStateException(); throw new IllegalStateException();
}); });
var button2 = new ButtonComp(I18n.observable("Throw exception with file"), null, () -> { var button2 = new ButtonComp(AppI18n.observable("Throw exception with file"), null, () -> {
try { try {
throw new IllegalStateException(); throw new IllegalStateException();
} catch (Exception ex) { } catch (Exception ex) {
@ -29,11 +29,11 @@ public class DeveloperTabComp extends SimpleComp {
} }
}); });
var button3 = new ButtonComp(I18n.observable("Exit"), null, () -> { var button3 = new ButtonComp(AppI18n.observable("Exit"), null, () -> {
System.exit(0); System.exit(0);
}); });
var button4 = new ButtonComp(I18n.observable("Throw terminal exception"), null, () -> { var button4 = new ButtonComp(AppI18n.observable("Throw terminal exception"), null, () -> {
try { try {
throw new IllegalStateException(); throw new IllegalStateException();
} catch (Exception ex) { } catch (Exception ex) {
@ -41,7 +41,7 @@ public class DeveloperTabComp extends SimpleComp {
} }
}); });
var button5 = new ButtonComp(I18n.observable("Operation mode null"), null, OperationMode::close); var button5 = new ButtonComp(AppI18n.observable("Operation mode null"), null, OperationMode::close);
var box = new HBox( var box = new HBox(
button.createRegion(), button.createRegion(),

View file

@ -2,10 +2,10 @@ package io.xpipe.app.comp;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.prefs.ClearCacheAlert; import io.xpipe.app.prefs.ClearCacheAlert;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
@ -33,12 +33,12 @@ public class PrefsComp extends SimpleComp {
MasterDetailPane p = (MasterDetailPane) pfx.getCenter(); MasterDetailPane p = (MasterDetailPane) pfx.getCenter();
p.dividerPositionProperty().setValue(0.27); p.dividerPositionProperty().setValue(0.27);
var cancel = new ButtonComp(I18n.observable("cancel"), null, () -> { var cancel = new ButtonComp(AppI18n.observable("cancel"), null, () -> {
AppPrefs.get().cancel(); AppPrefs.get().cancel();
layout.selectedProperty().setValue(layout.getEntries().get(0)); layout.selectedProperty().setValue(layout.getEntries().get(0));
}) })
.createRegion(); .createRegion();
var apply = new ButtonComp(I18n.observable("apply"), null, () -> { var apply = new ButtonComp(AppI18n.observable("apply"), null, () -> {
AppPrefs.get().save(); AppPrefs.get().save();
layout.selectedProperty().setValue(layout.getEntries().get(0)); layout.selectedProperty().setValue(layout.getEntries().get(0));
}) })
@ -54,8 +54,8 @@ public class PrefsComp extends SimpleComp {
AnchorPane.setBottomAnchor(rightButtons, 15.0); AnchorPane.setBottomAnchor(rightButtons, 15.0);
AnchorPane.setRightAnchor(rightButtons, 55.0); AnchorPane.setRightAnchor(rightButtons, 55.0);
var clearCaches = new ButtonComp(I18n.observable("clearCaches"), null, ClearCacheAlert::show).createRegion(); var clearCaches = new ButtonComp(AppI18n.observable("clearCaches"), null, ClearCacheAlert::show).createRegion();
// var reload = new ButtonComp(I18n.observable("reload"), null, () -> OperationMode.reload()).createRegion(); // var reload = new ButtonComp(AppI18n.observable("reload"), null, () -> OperationMode.reload()).createRegion();
var leftButtons = new HBox(clearCaches); var leftButtons = new HBox(clearCaches);
leftButtons.setAlignment(Pos.CENTER); leftButtons.setAlignment(Pos.CENTER);
leftButtons.prefWidthProperty().bind(((Region) p.getDetailNode()).widthProperty()); leftButtons.prefWidthProperty().bind(((Region) p.getDetailNode()).widthProperty());

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.about; package io.xpipe.app.comp.about;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.util.DynamicOptionsBuilder;
import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import io.xpipe.extension.util.DynamicOptionsBuilder;
import javafx.scene.control.Hyperlink; import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
@ -36,16 +36,16 @@ public class AboutTabComp extends Comp<CompStructure<?>> {
private Comp<?> createLinks() { private Comp<?> createLinks() {
return new DynamicOptionsBuilder(false) return new DynamicOptionsBuilder(false)
.addTitle("links") .addTitle("links")
.addComp(I18n.observable("website"), hyperlink(Hyperlinks.WEBSITE), null) .addComp(AppI18n.observable("website"), hyperlink(Hyperlinks.WEBSITE), null)
.addComp(I18n.observable("documentation"), hyperlink(Hyperlinks.DOCUMENTATION), null) .addComp(AppI18n.observable("documentation"), hyperlink(Hyperlinks.DOCUMENTATION), null)
.addComp(I18n.observable("discord"), hyperlink(Hyperlinks.DISCORD), null) .addComp(AppI18n.observable("discord"), hyperlink(Hyperlinks.DISCORD), null)
.addComp(I18n.observable("slack"), hyperlink(Hyperlinks.SLACK), null) .addComp(AppI18n.observable("slack"), hyperlink(Hyperlinks.SLACK), null)
.addComp(I18n.observable("github"), hyperlink(Hyperlinks.GITHUB), null) .addComp(AppI18n.observable("github"), hyperlink(Hyperlinks.GITHUB), null)
.buildComp(); .buildComp();
} }
private Region createThirdPartyDeps() { private Region createThirdPartyDeps() {
var label = new Label(I18n.get("openSourceNotices"), new FontIcon("mdi2o-open-source-initiative")); var label = new Label(AppI18n.get("openSourceNotices"), new FontIcon("mdi2o-open-source-initiative"));
label.getStyleClass().add("open-source-header"); label.getStyleClass().add("open-source-header");
var list = createDepsList(); var list = createDepsList();
var box = new VBox(label, list); var box = new VBox(label, list);

View file

@ -1,15 +1,15 @@
package io.xpipe.app.comp.about; package io.xpipe.app.comp.about;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppLogs; import io.xpipe.app.core.AppLogs;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.UserReportComp; import io.xpipe.app.issue.UserReportComp;
import io.xpipe.app.util.DesktopHelper;
import io.xpipe.app.util.DynamicOptionsBuilder;
import io.xpipe.app.util.ExternalEditor; import io.xpipe.app.util.ExternalEditor;
import io.xpipe.core.util.XPipeInstallation; import io.xpipe.core.util.XPipeInstallation;
import io.xpipe.extension.I18n;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.util.DesktopHelper;
import io.xpipe.extension.util.DynamicOptionsBuilder;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
public class BrowseDirectoryComp extends SimpleComp { public class BrowseDirectoryComp extends SimpleComp {
@ -19,7 +19,7 @@ public class BrowseDirectoryComp extends SimpleComp {
return new DynamicOptionsBuilder(false) return new DynamicOptionsBuilder(false)
.addComp( .addComp(
"issueReporter", "issueReporter",
new ButtonComp(I18n.observable("reportIssue"), () -> { new ButtonComp(AppI18n.observable("reportIssue"), () -> {
var event = ErrorEvent.fromMessage("User Report"); var event = ErrorEvent.fromMessage("User Report");
if (AppLogs.get().isWriteToFile()) { if (AppLogs.get().isWriteToFile()) {
event.attachment(AppLogs.get().getSessionLogsDirectory()); event.attachment(AppLogs.get().getSessionLogsDirectory());
@ -29,7 +29,7 @@ public class BrowseDirectoryComp extends SimpleComp {
null) null)
.addComp( .addComp(
"logFile", "logFile",
new ButtonComp(I18n.observable("openCurrentLogFile"), () -> { new ButtonComp(AppI18n.observable("openCurrentLogFile"), () -> {
ExternalEditor.get() ExternalEditor.get()
.openInEditor(AppLogs.get() .openInEditor(AppLogs.get()
.getSessionLogsDirectory() .getSessionLogsDirectory()
@ -39,14 +39,14 @@ public class BrowseDirectoryComp extends SimpleComp {
null) null)
.addComp( .addComp(
"logFiles", "logFiles",
new ButtonComp(I18n.observable("openLogsDirectory"), () -> { new ButtonComp(AppI18n.observable("openLogsDirectory"), () -> {
DesktopHelper.browsePath(AppLogs.get().getSessionLogsDirectory()); DesktopHelper.browsePath(AppLogs.get().getSessionLogsDirectory());
}), }),
null) null)
.addComp( .addComp(
"installationFiles", "installationFiles",
new ButtonComp(I18n.observable("openInstallationDirectory"), () -> { new ButtonComp(AppI18n.observable("openInstallationDirectory"), () -> {
DesktopHelper.browsePath(XPipeInstallation.getLocalInstallationBasePath()); DesktopHelper.browsePath(XPipeInstallation.getCurrentInstallationBasePath());
}), }),
null) null)
.build(); .build();

View file

@ -2,12 +2,12 @@ package io.xpipe.app.comp.about;
import io.xpipe.app.core.App; import io.xpipe.app.core.App;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.AppProperties;
import io.xpipe.extension.I18n; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.LabelComp;
import io.xpipe.extension.fxcomps.impl.LabelComp; import io.xpipe.app.util.DynamicOptionsBuilder;
import io.xpipe.extension.util.DynamicOptionsBuilder;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@ -20,7 +20,7 @@ public class PropertiesComp extends SimpleComp {
var image = new ImageView(App.getApp().getIcon()); var image = new ImageView(App.getApp().getIcon());
image.setPreserveRatio(true); image.setPreserveRatio(true);
image.setFitHeight(40); image.setFitHeight(40);
var label = new Label(I18n.get("xPipeClient"), image); var label = new Label(AppI18n.get("xPipeClient"), image);
label.getStyleClass().add("header"); label.getStyleClass().add("header");
AppFont.setSize(label, 5); AppFont.setSize(label, 5);
return label; return label;
@ -29,16 +29,16 @@ public class PropertiesComp extends SimpleComp {
var section = new DynamicOptionsBuilder(false) var section = new DynamicOptionsBuilder(false)
.addComp(title, null) .addComp(title, null)
.addComp( .addComp(
I18n.observable("version"), AppI18n.observable("version"),
new LabelComp(AppProperties.get().getVersion() + " (x64)"), new LabelComp(AppProperties.get().getVersion() + " (x64)"),
null) null)
.addComp( .addComp(
I18n.observable("build"), AppI18n.observable("build"),
new LabelComp(AppProperties.get().getBuild()), new LabelComp(AppProperties.get().getBuild()),
null) null)
.addComp(I18n.observable("runtimeVersion"), new LabelComp(System.getProperty("java.vm.version")), null) .addComp(AppI18n.observable("runtimeVersion"), new LabelComp(System.getProperty("java.vm.version")), null)
.addComp( .addComp(
I18n.observable("virtualMachine"), AppI18n.observable("virtualMachine"),
new LabelComp(System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name")), new LabelComp(System.getProperty("java.vm.vendor") + " " + System.getProperty("java.vm.name")),
null) null)
.buildComp(); .buildComp();

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.about; package io.xpipe.app.comp.about;
import io.xpipe.app.core.AppFont; 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.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.*; import javafx.scene.control.*;

View file

@ -1,12 +1,11 @@
package io.xpipe.app.comp.about; package io.xpipe.app.comp.about;
import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.update.AppUpdater; import io.xpipe.app.update.AppUpdater;
import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.extension.I18n; import io.xpipe.app.util.XPipeDistributionType;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.util.XPipeDistributionType;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableBooleanValue;
@ -56,7 +55,7 @@ public class UpdateCheckComp extends SimpleComp {
return PlatformThread.sync(Bindings.createStringBinding( return PlatformThread.sync(Bindings.createStringBinding(
() -> { () -> {
if (AppUpdater.get().getDownloadedUpdate().getValue() != null) { if (AppUpdater.get().getDownloadedUpdate().getValue() != null) {
return I18n.get("updateRestart"); return AppI18n.get("updateRestart");
} }
if (AppUpdater.get().getLastUpdateCheckResult().getValue() != null if (AppUpdater.get().getLastUpdateCheckResult().getValue() != null
@ -64,7 +63,7 @@ public class UpdateCheckComp extends SimpleComp {
.getLastUpdateCheckResult() .getLastUpdateCheckResult()
.getValue() .getValue()
.isUpdate()) { .isUpdate()) {
return I18n.get( return AppI18n.get(
"updateAvailable", "updateAvailable",
AppUpdater.get() AppUpdater.get()
.getLastUpdateCheckResult() .getLastUpdateCheckResult()
@ -78,7 +77,7 @@ public class UpdateCheckComp extends SimpleComp {
.getLastUpdateCheckResult() .getLastUpdateCheckResult()
.getValue() .getValue()
.getCheckTime()), .getCheckTime()),
s -> I18n.get("lastChecked") + " " + s) s -> AppI18n.get("lastChecked") + " " + s)
.get(); .get();
} else { } else {
return null; return null;
@ -97,15 +96,15 @@ public class UpdateCheckComp extends SimpleComp {
.bind(Bindings.createStringBinding( .bind(Bindings.createStringBinding(
() -> { () -> {
if (updateReady.getValue()) { if (updateReady.getValue()) {
return I18n.get("updateReady"); return AppI18n.get("updateReady");
} }
if (updateAvailable.getValue()) { if (updateAvailable.getValue()) {
return XPipeDistributionType.get().supportsUpdate() return XPipeDistributionType.get().supportsUpdate()
? I18n.get("downloadUpdate") ? AppI18n.get("downloadUpdate")
: I18n.get("checkOutUpdate"); : AppI18n.get("checkOutUpdate");
} else { } else {
return I18n.get("checkForUpdates"); return AppI18n.get("checkForUpdates");
} }
}, },
updateAvailable, updateAvailable,

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.geometry.Rectangle2D; import javafx.geometry.Rectangle2D;
import javafx.scene.image.Image; import javafx.scene.image.Image;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.geometry.Pos; import javafx.geometry.Pos;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.event.ErrorEvent; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.issue.ErrorEvent;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.input.Dragboard; import javafx.scene.input.Dragboard;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppResources; import io.xpipe.app.core.AppResources;
import io.xpipe.app.ext.DownloadModuleInstall;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.LabelComp;
import io.xpipe.app.util.DynamicOptionsBuilder;
import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.extension.DownloadModuleInstall;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.LabelComp;
import io.xpipe.extension.util.DynamicOptionsBuilder;
import javafx.scene.control.Hyperlink; import javafx.scene.control.Hyperlink;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;
import javafx.scene.layout.Priority; import javafx.scene.layout.Priority;
@ -29,7 +29,7 @@ public class InstallExtensionComp extends SimpleComp {
protected Region createSimple() { protected Region createSimple() {
var builder = new DynamicOptionsBuilder(false); var builder = new DynamicOptionsBuilder(false);
builder.addTitle("installRequired"); builder.addTitle("installRequired");
var header = new LabelComp(I18n.observable("extensionInstallDescription")) var header = new LabelComp(AppI18n.observable("extensionInstallDescription"))
.apply(struc -> struc.get().setWrapText(true)); .apply(struc -> struc.get().setWrapText(true));
builder.addComp(header); builder.addComp(header);
@ -45,7 +45,7 @@ public class InstallExtensionComp extends SimpleComp {
if (install.getLicenseFile() != null) { if (install.getLicenseFile() != null) {
builder.addTitle("license"); builder.addTitle("license");
var changeNotice = new LabelComp(I18n.observable("extensionInstallLicenseNote")) var changeNotice = new LabelComp(AppI18n.observable("extensionInstallLicenseNote"))
.apply(struc -> struc.get().setWrapText(true)); .apply(struc -> struc.get().setWrapText(true));
builder.addComp(changeNotice); builder.addComp(changeNotice);

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.app.fxcomps.impl.TextAreaComp;
import io.xpipe.app.util.ExternalEditor; import io.xpipe.app.util.ExternalEditor;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.IconButtonComp;
import io.xpipe.extension.fxcomps.impl.TextAreaComp;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.event.EventHandler; import javafx.event.EventHandler;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.extension.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;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;

View file

@ -1,6 +1,6 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import javafx.beans.property.ListProperty; import javafx.beans.property.ListProperty;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.extension.util.PrettyListView; import io.xpipe.app.util.PrettyListView;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import com.jfoenix.controls.JFXSpinner; import com.jfoenix.controls.JFXSpinner;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.extension.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;

View file

@ -5,10 +5,10 @@ import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Document; import com.vladsch.flexmark.util.ast.Document;
import com.vladsch.flexmark.util.data.MutableDataSet; import com.vladsch.flexmark.util.data.MutableDataSet;
import io.xpipe.app.core.AppResources; import io.xpipe.app.core.AppResources;
import io.xpipe.extension.event.ErrorEvent; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.issue.ErrorEvent;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.extension.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableBooleanValue;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import com.jfoenix.controls.JFXTabPane; import com.jfoenix.controls.JFXTabPane;
import io.xpipe.extension.I18n; import io.xpipe.app.core.AppI18n;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.ReadOnlyProperty; import javafx.beans.property.ReadOnlyProperty;
@ -196,7 +196,7 @@ public abstract class MultiStepComp extends Comp<CompStructure<VBox>> {
buttons.getStyleClass().add("buttons"); buttons.getStyleClass().add("buttons");
buttons.setSpacing(5); buttons.setSpacing(5);
var helpButton = new ButtonComp(I18n.observable("help"), null, () -> { var helpButton = new ButtonComp(AppI18n.observable("help"), null, () -> {
getValue().help.run(); getValue().help.run();
}) })
.styleClass("help") .styleClass("help")
@ -213,10 +213,10 @@ public abstract class MultiStepComp extends Comp<CompStructure<VBox>> {
buttons.setAlignment(Pos.CENTER_RIGHT); buttons.setAlignment(Pos.CENTER_RIGHT);
var nextText = Bindings.createStringBinding( var nextText = Bindings.createStringBinding(
() -> isLastPage() ? I18n.get("finishStep") : I18n.get("nextStep"), currentStep); () -> isLastPage() ? AppI18n.get("finishStep") : AppI18n.get("nextStep"), currentStep);
var nextButton = new ButtonComp(nextText, null, comp::next).styleClass("next"); var nextButton = new ButtonComp(nextText, null, comp::next).styleClass("next");
var previousButton = new ButtonComp(I18n.observable("previousStep"), null, comp::previous) var previousButton = new ButtonComp(AppI18n.observable("previousStep"), null, comp::previous)
.styleClass("next") .styleClass("next")
.apply(struc -> struc.get() .apply(struc -> struc.get()
.disableProperty() .disableProperty()

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.augment.GrowAugment; import io.xpipe.app.fxcomps.augment.GrowAugment;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.css.PseudoClass; import javafx.css.PseudoClass;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.base; package io.xpipe.app.comp.base;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.scene.control.TitledPane; import javafx.scene.control.TitledPane;

View file

@ -1,12 +1,12 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppCache;
import io.xpipe.extension.DataSourceTarget; import io.xpipe.app.core.AppI18n;
import io.xpipe.extension.I18n; import io.xpipe.app.ext.DataSourceTarget;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.util.CustomComboBoxBuilder; import io.xpipe.app.util.CustomComboBoxBuilder;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
@ -65,24 +65,24 @@ public class DataSourceTargetChoiceComp extends Comp<CompStructure<ComboBox<Node
@Override @Override
public CompStructure<ComboBox<Node>> createBase() { public CompStructure<ComboBox<Node>> createBase() {
var addMoreLabel = new Label(I18n.get("addMore"), new FontIcon("mdmz-plus")); var addMoreLabel = new Label(AppI18n.get("addMore"), new FontIcon("mdmz-plus"));
var builder = new CustomComboBoxBuilder<DataSourceTarget>( var builder = new CustomComboBoxBuilder<DataSourceTarget>(
selectedApplication, app -> createLabel(app), new Label(""), v -> true); selectedApplication, app -> createLabel(app), new Label(""), v -> true);
// builder.addFilter((v, s) -> v.getName().getValue().toLowerCase().contains(s)); // builder.addFilter((v, s) -> v.getName().getValue().toLowerCase().contains(s));
builder.addHeader(I18n.get("programmingLanguages")); builder.addHeader(AppI18n.get("programmingLanguages"));
all.stream() all.stream()
.filter(p -> p.getCategory().equals(DataSourceTarget.Category.PROGRAMMING_LANGUAGE)) .filter(p -> p.getCategory().equals(DataSourceTarget.Category.PROGRAMMING_LANGUAGE))
.forEach(builder::add); .forEach(builder::add);
builder.addHeader(I18n.get("applications")); builder.addHeader(AppI18n.get("applications"));
all.stream() all.stream()
.filter(p -> p.getCategory().equals(DataSourceTarget.Category.APPLICATION)) .filter(p -> p.getCategory().equals(DataSourceTarget.Category.APPLICATION))
.forEach(builder::add); .forEach(builder::add);
builder.addHeader(I18n.get("other")); builder.addHeader(AppI18n.get("other"));
all.stream() all.stream()
.filter(p -> p.getCategory().equals(DataSourceTarget.Category.OTHER)) .filter(p -> p.getCategory().equals(DataSourceTarget.Category.OTHER))
.forEach(builder::add); .forEach(builder::add);

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.source.CollectionReadConnection; import io.xpipe.core.source.CollectionReadConnection;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@ -30,8 +30,8 @@ public class DsCollectionComp extends Comp<CompStructure<TreeView<String>>> {
if (con.getValue() != null) { if (con.getValue() != null) {
try { try {
con.getValue().listEntries().forEach(e -> { con.getValue().listEntries().forEach(e -> {
var item = new TreeItem<String>(e.getFileName()); // var item = new TreeItem<String>(e.getFileName());
c.add(item); // c.add(item);
}); });
} catch (Exception ex) { } catch (Exception ex) {
ErrorEvent.fromThrowable(ex).handle(); ErrorEvent.fromThrowable(ex).handle();

View file

@ -3,22 +3,22 @@ package io.xpipe.app.comp.source;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.core.AppWindowHelper;
import io.xpipe.app.ext.DataSourceTarget;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.DynamicOptionsComp;
import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.BusyProperty;
import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.source.DataSourceId; import io.xpipe.core.source.DataSourceId;
import io.xpipe.extension.DataSourceTarget;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.DynamicOptionsComp;
import io.xpipe.extension.fxcomps.impl.HorizontalComp;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener;
import io.xpipe.extension.util.BusyProperty;
import io.xpipe.extension.util.ThreadHelper;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.Property; import javafx.beans.property.Property;
@ -63,7 +63,7 @@ public class DsDataTransferComp extends SimpleComp {
Platform.runLater(() -> { Platform.runLater(() -> {
var loading = new SimpleBooleanProperty(); var loading = new SimpleBooleanProperty();
AppWindowHelper.sideWindow( AppWindowHelper.sideWindow(
I18n.get("pipeDataSource"), AppI18n.get("pipeDataSource"),
window -> { window -> {
var ms = new DsDataTransferComp(new SimpleObjectProperty<>(e)) var ms = new DsDataTransferComp(new SimpleObjectProperty<>(e))
.exclude(DataSourceTarget.byId("base.saveSource") .exclude(DataSourceTarget.byId("base.saveSource")
@ -156,7 +156,7 @@ public class DsDataTransferComp extends SimpleComp {
!= null); != null);
var setupGuideButton = new ButtonComp( var setupGuideButton = new ButtonComp(
I18n.observable("setupGuide"), new FontIcon("mdoal-integration_instructions"), () -> { AppI18n.observable("setupGuide"), new FontIcon("mdoal-integration_instructions"), () -> {
Hyperlinks.open(selectedTarget.getValue().getSetupGuideURL()); Hyperlinks.open(selectedTarget.getValue().getSetupGuideURL());
}) })
.apply(s -> s.get() .apply(s -> s.get()

View file

@ -1,18 +1,14 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.ext.DataSourceProviders;
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.prefs.AppPrefs;
import io.xpipe.app.util.JfxHelper; import io.xpipe.app.util.*;
import io.xpipe.core.source.DataSourceType; import io.xpipe.core.source.DataSourceType;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.DataSourceProviders;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.util.CustomComboBoxBuilder;
import io.xpipe.extension.util.SimpleValidator;
import io.xpipe.extension.util.Validatable;
import io.xpipe.extension.util.Validator;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
@ -37,16 +33,16 @@ public class DsProviderChoiceComp extends Comp<CompStructure<ComboBox<Node>>> im
DataSourceProvider.Category type, Property<DataSourceProvider<?>> provider, DataSourceType filter) { DataSourceProvider.Category type, Property<DataSourceProvider<?>> provider, DataSourceType filter) {
this.type = type; this.type = type;
this.provider = provider; this.provider = provider;
check = Validator.nonNull(validator, I18n.observable("provider"), provider); check = Validator.nonNull(validator, AppI18n.observable("provider"), provider);
this.filter = filter; this.filter = filter;
} }
private Region createDefaultNode() { private Region createDefaultNode() {
return switch (type) { return switch (type) {
case STREAM -> JfxHelper.createNamedEntry( case STREAM -> JfxHelper.createNamedEntry(
I18n.get("anyStream"), I18n.get("anyStreamDescription"), "file_icon.png"); AppI18n.get("anyStream"), AppI18n.get("anyStreamDescription"), "file_icon.png");
case DATABASE -> JfxHelper.createNamedEntry( case DATABASE -> JfxHelper.createNamedEntry(
I18n.get("selectQueryType"), I18n.get("selectQueryTypeDescription"), "db_icon.png"); AppI18n.get("selectQueryType"), AppI18n.get("selectQueryTypeDescription"), "db_icon.png");
}; };
} }

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.util.CustomComboBoxBuilder;
import io.xpipe.extension.util.CustomComboBoxBuilder;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;

View file

@ -2,12 +2,12 @@ package io.xpipe.app.comp.source;
import com.jfoenix.controls.JFXTextField; import com.jfoenix.controls.JFXTextField;
import io.xpipe.app.comp.storage.DataSourceTypeComp; import io.xpipe.app.comp.storage.DataSourceTypeComp;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.core.source.DataSourceId; import io.xpipe.core.source.DataSourceId;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.HorizontalComp;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.DataStructureNode;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.scene.control.TreeItem; import javafx.scene.control.TreeItem;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
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.fxcomps.util.SimpleChangeListener;
import io.xpipe.core.data.node.ArrayNode; import io.xpipe.core.data.node.ArrayNode;
import io.xpipe.core.data.node.DataStructureNode; import io.xpipe.core.data.node.DataStructureNode;
import io.xpipe.core.data.type.DataTypeVisitors; import io.xpipe.core.data.type.DataTypeVisitors;
import io.xpipe.core.data.type.TupleType; import io.xpipe.core.data.type.TupleType;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.LabelComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.core.source.TableMapping; import io.xpipe.core.source.TableMapping;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.LabelComp;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@ -34,7 +34,7 @@ public class DsTableMappingComp extends SimpleComp {
grid.add(new LabelComp("->").createRegion(), 1, i); grid.add(new LabelComp("->").createRegion(), 1, i);
var map = val.map(i).orElse(-1); var map = val.map(i).orElse(-1);
var output = var output =
new LabelComp(map != -1 ? val.getOutputType().getNames().get(map) : I18n.get("discarded")); new LabelComp(map != -1 ? val.getOutputType().getNames().get(map) : AppI18n.get("discarded"));
grid.add(output.createRegion(), 2, i); grid.add(output.createRegion(), 2, i);
if (i % 2 != 0) { if (i % 2 != 0) {

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.comp.storage.DataSourceTypeComp; import io.xpipe.app.comp.storage.DataSourceTypeComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.util.CustomComboBoxBuilder;
import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSource;
import io.xpipe.core.source.DataSourceType; import io.xpipe.core.source.DataSourceType;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.util.CustomComboBoxBuilder;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -35,7 +35,7 @@ public class DsTypeChoiceComp extends Comp<CompStructure<StackPane>> {
} }
private Region createLabel(DataSourceType p) { private Region createLabel(DataSourceType p) {
var l = new Label(I18n.get(p.name().toLowerCase()), new FontIcon(DataSourceTypeComp.ICONS.get(p))); var l = new Label(AppI18n.get(p.name().toLowerCase()), new FontIcon(DataSourceTypeComp.ICONS.get(p)));
l.setAlignment(Pos.CENTER); l.setAlignment(Pos.CENTER);
return l; return l;
} }

View file

@ -2,20 +2,20 @@ package io.xpipe.app.comp.source;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.BusyProperty;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.data.node.ArrayNode; import io.xpipe.core.data.node.ArrayNode;
import io.xpipe.core.data.node.TupleNode; import io.xpipe.core.data.node.TupleNode;
import io.xpipe.core.source.*; import io.xpipe.core.source.*;
import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataFlow;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.impl.HorizontalComp;
import io.xpipe.extension.fxcomps.impl.IconButtonComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import io.xpipe.extension.util.BusyProperty;
import io.xpipe.extension.util.ThreadHelper;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property; import javafx.beans.property.Property;

View file

@ -2,17 +2,17 @@ package io.xpipe.app.comp.source;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.core.AppWindowHelper;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.ext.DataSourceProviders;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSource;
import io.xpipe.core.source.DataSourceType; import io.xpipe.core.source.DataSourceType;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.DataSourceProviders;
import io.xpipe.extension.I18n;
import io.xpipe.extension.event.ErrorEvent;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
@ -70,7 +70,7 @@ public class GuiDsCreatorMultiStep<DI extends DataStore, DS extends DataSource<D
Platform.runLater(() -> { Platform.runLater(() -> {
var loading = new SimpleBooleanProperty(); var loading = new SimpleBooleanProperty();
var stage = AppWindowHelper.sideWindow( var stage = AppWindowHelper.sideWindow(
I18n.get("newDataSource"), AppI18n.get("newDataSource"),
window -> { window -> {
var ms = new GuiDsCreatorMultiStep<>( var ms = new GuiDsCreatorMultiStep<>(
window, null, sourceCollection, category, null, null, null, State.CREATE); window, null, sourceCollection, category, null, null, null, State.CREATE);
@ -93,7 +93,7 @@ public class GuiDsCreatorMultiStep<DI extends DataStore, DS extends DataSource<D
Platform.runLater(() -> { Platform.runLater(() -> {
var loading = new SimpleBooleanProperty(); var loading = new SimpleBooleanProperty();
var stage = AppWindowHelper.sideWindow( var stage = AppWindowHelper.sideWindow(
I18n.get("editDataSource"), AppI18n.get("editDataSource"),
window -> { window -> {
var ms = new GuiDsCreatorMultiStep<>( var ms = new GuiDsCreatorMultiStep<>(
window, window,
@ -122,7 +122,7 @@ public class GuiDsCreatorMultiStep<DI extends DataStore, DS extends DataSource<D
var provider = DataSourceProviders.byPreferredStore(store, null); var provider = DataSourceProviders.byPreferredStore(store, null);
Platform.runLater(() -> { Platform.runLater(() -> {
var stage = AppWindowHelper.sideWindow( var stage = AppWindowHelper.sideWindow(
I18n.get("newDataSource"), AppI18n.get("newDataSource"),
window -> { window -> {
var gui = new GuiDsCreatorMultiStep<>( var gui = new GuiDsCreatorMultiStep<>(
window, window,
@ -159,9 +159,9 @@ public class GuiDsCreatorMultiStep<DI extends DataStore, DS extends DataSource<D
private static void showCloseConfirmAlert(GuiDsCreatorMultiStep<?, ?> ms, Stage s) { private static void showCloseConfirmAlert(GuiDsCreatorMultiStep<?, ?> ms, Stage s) {
AppWindowHelper.showBlockingAlert(alert -> { AppWindowHelper.showBlockingAlert(alert -> {
alert.setTitle(I18n.get("confirmDsCreationAbortTitle")); alert.setTitle(AppI18n.get("confirmDsCreationAbortTitle"));
alert.setHeaderText(I18n.get("confirmDsCreationAbortHeader")); alert.setHeaderText(AppI18n.get("confirmDsCreationAbortHeader"));
alert.setContentText(I18n.get("confirmDsCreationAbortContent")); alert.setContentText(AppI18n.get("confirmDsCreationAbortContent"));
alert.setAlertType(Alert.AlertType.CONFIRMATION); alert.setAlertType(Alert.AlertType.CONFIRMATION);
}) })
.filter(b -> b.getButtonData().isDefaultButton()) .filter(b -> b.getButtonData().isDefaultButton())
@ -256,15 +256,15 @@ public class GuiDsCreatorMultiStep<DI extends DataStore, DS extends DataSource<D
@Override @Override
protected List<Entry> setup() { protected List<Entry> setup() {
var list = new ArrayList<Entry>(); var list = new ArrayList<Entry>();
list.add(new Entry(I18n.observable("selectInput"), createInputStep())); list.add(new Entry(AppI18n.observable("selectInput"), createInputStep()));
list.add(new Entry( list.add(new Entry(
I18n.observable("configure"), AppI18n.observable("configure"),
new GuiDsConfigStep(provider, store, baseSource, source, dataSourceType, loading))); new GuiDsConfigStep(provider, store, baseSource, source, dataSourceType, loading)));
switch (state) { switch (state) {
case EDIT -> {} case EDIT -> {}
case CREATE -> { case CREATE -> {
list.add( list.add(
new Entry(I18n.observable("target"), new GuiDsCreatorTransferStep(targetGroup, store, source))); new Entry(AppI18n.observable("target"), new GuiDsCreatorTransferStep(targetGroup, store, source)));
} }
} }
return list; return list;

View file

@ -3,12 +3,12 @@ package io.xpipe.app.comp.source;
import com.jfoenix.controls.JFXCheckBox; import com.jfoenix.controls.JFXCheckBox;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -37,7 +37,7 @@ public class GuiDsCreatorSaveStep extends MultiStepComp.Step<CompStructure<?>> {
var cb = new JFXCheckBox(); var cb = new JFXCheckBox();
cb.selectedProperty().bindBidirectional(storeForLaterUse); cb.selectedProperty().bindBidirectional(storeForLaterUse);
var label = new Label(I18n.get("storeForLaterUse")); var label = new Label(AppI18n.get("storeForLaterUse"));
label.setGraphic(cb); label.setGraphic(cb);
return label; return label;
}); });

View file

@ -2,15 +2,15 @@ package io.xpipe.app.comp.source;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.ext.DataSourceTarget;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSource;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataSourceTarget;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property; import javafx.beans.property.Property;

View file

@ -3,18 +3,18 @@ package io.xpipe.app.comp.source;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.comp.source.store.DsDbStoreChooserComp; import io.xpipe.app.comp.source.store.DsDbStoreChooserComp;
import io.xpipe.app.comp.source.store.DsStreamStoreChoiceComp; import io.xpipe.app.comp.source.store.DsStreamStoreChoiceComp;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.augment.GrowAugment;
import io.xpipe.app.fxcomps.impl.StackComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.util.BusyProperty;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSource;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.event.TrackEvent;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.augment.GrowAugment;
import io.xpipe.extension.fxcomps.impl.StackComp;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.util.BusyProperty;
import io.xpipe.extension.util.ThreadHelper;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property; import javafx.beans.property.Property;

View file

@ -3,15 +3,15 @@ package io.xpipe.app.comp.source;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.comp.storage.source.SourceEntryWrapper; import io.xpipe.app.comp.storage.source.SourceEntryWrapper;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.core.AppWindowHelper;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.LabelComp;
import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.core.source.TableMapping; import io.xpipe.core.source.TableMapping;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.LabelComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
@ -42,7 +42,7 @@ public class GuiDsTableMappingConfirmation extends SimpleComp {
var confirmed = new AtomicBoolean(); var confirmed = new AtomicBoolean();
AppWindowHelper.showAndWaitForWindow(() -> { AppWindowHelper.showAndWaitForWindow(() -> {
var stage = AppWindowHelper.sideWindow( var stage = AppWindowHelper.sideWindow(
I18n.get("confirmTableMappingTitle"), AppI18n.get("confirmTableMappingTitle"),
window -> { window -> {
var ms = new GuiDsTableMappingConfirmation(new SimpleObjectProperty<>(mapping)); var ms = new GuiDsTableMappingConfirmation(new SimpleObjectProperty<>(mapping));
var multi = new MultiStepComp() { var multi = new MultiStepComp() {
@ -78,7 +78,7 @@ public class GuiDsTableMappingConfirmation extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var header = new LabelComp(I18n.observable("confirmTableMapping")) var header = new LabelComp(AppI18n.observable("confirmTableMapping"))
.apply(struc -> struc.get().setWrapText(true)); .apply(struc -> struc.get().setWrapText(true));
var content = Comp.derive(new DsTableMappingComp(mapping), region -> { var content = Comp.derive(new DsTableMappingComp(mapping), region -> {
var box = new HBox(region); var box = new HBox(region);
@ -87,7 +87,7 @@ public class GuiDsTableMappingConfirmation extends SimpleComp {
return box; return box;
}) })
.apply(struc -> AppFont.normal(struc.get())); .apply(struc -> AppFont.normal(struc.get()));
var changeNotice = new LabelComp(I18n.observable("changeTableMapping")) var changeNotice = new LabelComp(AppI18n.observable("changeTableMapping"))
.apply(struc -> struc.get().setWrapText(true)); .apply(struc -> struc.get().setWrapText(true));
var changeButton = Comp.of(() -> { var changeButton = Comp.of(() -> {
var hl = new Hyperlink("Customizing Data Flows"); var hl = new Hyperlink("Customizing Data Flows");

View file

@ -1,23 +1,23 @@
package io.xpipe.app.comp.source; package io.xpipe.app.comp.source;
import io.xpipe.app.comp.base.ListViewComp; import io.xpipe.app.comp.base.ListViewComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.FilterComp;
import io.xpipe.app.fxcomps.impl.LabelComp;
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.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
import io.xpipe.app.util.SimpleValidator;
import io.xpipe.app.util.Validatable;
import io.xpipe.app.util.Validator;
import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSource;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.DataStoreProviders;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FilterComp;
import io.xpipe.extension.fxcomps.impl.LabelComp;
import io.xpipe.extension.fxcomps.impl.StackComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import io.xpipe.extension.fxcomps.util.BindingsHelper;
import io.xpipe.extension.util.SimpleValidator;
import io.xpipe.extension.util.Validatable;
import io.xpipe.extension.util.Validator;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -56,7 +56,7 @@ public class NamedSourceChoiceComp extends SimpleComp implements Validatable {
this.filter = filter; this.filter = filter;
this.selected = selected; this.selected = selected;
this.category = category; this.category = category;
check = Validator.nonNull(validator, I18n.observable("source"), selected); check = Validator.nonNull(validator, AppI18n.observable("source"), selected);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -125,7 +125,7 @@ public class NamedSourceChoiceComp extends SimpleComp implements Validatable {
var box = new VerticalComp(List.of(filterComp, view)); var box = new VerticalComp(List.of(filterComp, view));
var text = new LabelComp(I18n.observable("noMatchingSourceFound")) var text = new LabelComp(AppI18n.observable("noMatchingSourceFound"))
.apply(struc -> VBox.setVgrow(struc.get(), Priority.ALWAYS)); .apply(struc -> VBox.setVgrow(struc.get(), Priority.ALWAYS));
var notice = new VerticalComp(List.of(text)) var notice = new VerticalComp(List.of(text))
.apply(struc -> { .apply(struc -> {

View file

@ -1,16 +1,16 @@
package io.xpipe.app.comp.source.store; package io.xpipe.app.comp.source.store;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
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.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataStoreProvider;
import io.xpipe.extension.DataStoreProviders;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@ -59,7 +59,7 @@ public class DataStoreSelectorComp extends Comp<CompStructure<Button>> {
var graphic = provider != null ? provider.getDisplayIconFileName() : "file_icon.png"; var graphic = provider != null ? provider.getDisplayIconFileName() : "file_icon.png";
if (chosenStore.getValue() == null || !(chosenStore.getValue() instanceof FileStore f)) { if (chosenStore.getValue() == null || !(chosenStore.getValue() instanceof FileStore f)) {
return JfxHelper.createNamedEntry( return JfxHelper.createNamedEntry(
I18n.get("selectStreamStore"), I18n.get("openStreamStoreWizard"), graphic); AppI18n.get("selectStreamStore"), AppI18n.get("openStreamStoreWizard"), graphic);
} else { } else {
return JfxHelper.createNamedEntry( return JfxHelper.createNamedEntry(
f.getFileName().toString(), f.getFile().toString(), graphic); f.getFileName().toString(), f.getFile().toString(), graphic);

View file

@ -1,13 +1,13 @@
package io.xpipe.app.comp.source.store; package io.xpipe.app.comp.source.store;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.TabPaneComp;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.DataStoreProvider;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.TabPaneComp;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -40,7 +40,7 @@ public class DsDbStoreChooserComp extends SimpleComp {
provider); provider);
var connections = new TabPaneComp.Entry( var connections = new TabPaneComp.Entry(
I18n.observable("savedConnections"), AppI18n.observable("savedConnections"),
"mdi2m-monitor", "mdi2m-monitor",
NamedStoreChoiceComp.create(filter, input, DataStoreProvider.DataCategory.DATABASE) NamedStoreChoiceComp.create(filter, input, DataStoreProvider.DataCategory.DATABASE)
.styleClass("store-local-file-chooser")); .styleClass("store-local-file-chooser"));

View file

@ -3,11 +3,11 @@ package io.xpipe.app.comp.source.store;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane; import javafx.scene.control.ScrollPane;
@ -39,7 +39,7 @@ public class DsFileHistoryComp extends SimpleComp {
} }
previous.setFillWidth(true); previous.setFillWidth(true);
var label = new Label(I18n.get("recentFiles")); var label = new Label(AppI18n.get("recentFiles"));
AppFont.header(label); AppFont.header(label);
previous.getChildren().add(label); previous.getChildren().add(label);

View file

@ -1,13 +1,13 @@
package io.xpipe.app.comp.source.store; package io.xpipe.app.comp.source.store;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
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.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@ -33,7 +33,7 @@ public class DsLocalDirectoryBrowseComp extends Comp<CompStructure<Button>> {
button.setOnAction(e -> { button.setOnAction(e -> {
var dirChooser = new DirectoryChooser(); var dirChooser = new DirectoryChooser();
dirChooser.setTitle( dirChooser.setTitle(
I18n.get("browseDirectoryTitle", provider.getFileProvider().getFileName())); AppI18n.get("browseDirectoryTitle", provider.getFileProvider().getFileName()));
File file = dirChooser.showDialog(button.getScene().getWindow()); File file = dirChooser.showDialog(button.getScene().getWindow());
if (file != null && file.exists()) { if (file != null && file.exists()) {
chosenDir.setValue(file.toPath()); chosenDir.setValue(file.toPath());
@ -55,7 +55,7 @@ public class DsLocalDirectoryBrowseComp extends Comp<CompStructure<Button>> {
private Region getGraphic() { private Region getGraphic() {
var graphic = provider.getDisplayIconFileName(); var graphic = provider.getDisplayIconFileName();
if (chosenDir.getValue() == null) { if (chosenDir.getValue() == null) {
return JfxHelper.createNamedEntry(I18n.get("browse"), I18n.get("selectDirectoryFromComputer"), graphic); return JfxHelper.createNamedEntry(AppI18n.get("browse"), AppI18n.get("selectDirectoryFromComputer"), graphic);
} else { } else {
return JfxHelper.createNamedEntry( return JfxHelper.createNamedEntry(
chosenDir.getValue().getFileName().toString(), chosenDir.getValue().getFileName().toString(),

View file

@ -1,15 +1,15 @@
package io.xpipe.app.comp.source.store; package io.xpipe.app.comp.source.store;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
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.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.scene.control.Button; import javafx.scene.control.Button;
@ -69,16 +69,16 @@ public class DsLocalFileBrowseComp extends Comp<CompStructure<Button>> {
private FileChooser createChooser() { private FileChooser createChooser() {
FileChooser fileChooser = new FileChooser(); FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(I18n.get("browseFileTitle")); fileChooser.setTitle(AppI18n.get("browseFileTitle"));
if (!hasProvider()) { if (!hasProvider()) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), "*")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(AppI18n.get("anyFile"), "*"));
return fileChooser; return fileChooser;
} }
if (hasProvider()) { if (hasProvider()) {
provider.getValue().getFileProvider().getFileExtensions().forEach((key, value) -> { provider.getValue().getFileProvider().getFileExtensions().forEach((key, value) -> {
var name = I18n.get(key); var name = AppI18n.get(key);
if (value != null) { if (value != null) {
fileChooser fileChooser
.getExtensionFilters() .getExtensionFilters()
@ -90,7 +90,7 @@ public class DsLocalFileBrowseComp extends Comp<CompStructure<Button>> {
}); });
if (!provider.getValue().getFileProvider().getFileExtensions().containsValue(null)) { if (!provider.getValue().getFileProvider().getFileExtensions().containsValue(null)) {
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(I18n.get("anyFile"), "*")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter(AppI18n.get("anyFile"), "*"));
} }
} }
@ -100,7 +100,7 @@ public class DsLocalFileBrowseComp extends Comp<CompStructure<Button>> {
private Region getGraphic() { private Region getGraphic() {
var graphic = hasProvider() ? provider.getValue().getDisplayIconFileName() : "file_icon.png"; var graphic = hasProvider() ? provider.getValue().getDisplayIconFileName() : "file_icon.png";
if (chosenFile.getValue() == null || !(chosenFile.getValue() instanceof FileStore f) || f.getFile() == null) { if (chosenFile.getValue() == null || !(chosenFile.getValue() instanceof FileStore f) || f.getFile() == null) {
return JfxHelper.createNamedEntry(I18n.get("browse"), I18n.get("selectFileFromComputer"), graphic); return JfxHelper.createNamedEntry(AppI18n.get("browse"), AppI18n.get("selectFileFromComputer"), graphic);
} else { } else {
return JfxHelper.createNamedEntry( return JfxHelper.createNamedEntry(
f.getFileName().toString(), f.getFile().toString(), graphic); f.getFileName().toString(), f.getFile().toString(), graphic);

View file

@ -1,12 +1,13 @@
package io.xpipe.app.comp.source.store; package io.xpipe.app.comp.source.store;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.FileSystemStoreChoiceComp;
import io.xpipe.app.util.DynamicOptionsBuilder;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.FileSystem;
import io.xpipe.core.store.FileSystemStore; import io.xpipe.core.store.FileSystemStore;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FileSystemStoreChoiceComp;
import io.xpipe.extension.util.DynamicOptionsBuilder;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@ -25,8 +26,8 @@ public class DsRemoteFileChoiceComp extends SimpleComp {
var machine = new SimpleObjectProperty<FileSystemStore>(); var machine = new SimpleObjectProperty<FileSystemStore>();
var fileName = new SimpleStringProperty(); var fileName = new SimpleStringProperty();
return new DynamicOptionsBuilder(false) return new DynamicOptionsBuilder(false)
.addComp(I18n.observable("machine"), new FileSystemStoreChoiceComp(machine), machine) .addComp(AppI18n.observable("machine"), new FileSystemStoreChoiceComp(machine), machine)
.addString(I18n.observable("file"), fileName, true) .addString(AppI18n.observable("file"), fileName, true)
.bind( .bind(
() -> { () -> {
if (fileName.get() == null || machine.get() == null) { if (fileName.get() == null || machine.get() == null) {

View file

@ -1,14 +1,14 @@
package io.xpipe.app.comp.source.store; package io.xpipe.app.comp.source.store;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
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.prefs.AppPrefs;
import io.xpipe.app.util.CustomComboBoxBuilder;
import io.xpipe.app.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
import io.xpipe.extension.DataStoreProvider;
import io.xpipe.extension.DataStoreProviders;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.util.CustomComboBoxBuilder;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.ComboBox; import javafx.scene.control.ComboBox;
@ -29,7 +29,7 @@ public class DsStoreProviderChoiceComp extends Comp<CompStructure<ComboBox<Node>
private Region createDefaultNode() { private Region createDefaultNode() {
return JfxHelper.createNamedEntry( return JfxHelper.createNamedEntry(
I18n.get("selectType"), I18n.get("selectTypeDescription"), "machine_icon.png"); AppI18n.get("selectType"), AppI18n.get("selectTypeDescription"), "machine_icon.png");
} }
private List<DataStoreProvider> getProviders() { private List<DataStoreProvider> getProviders() {

View file

@ -2,25 +2,25 @@ package io.xpipe.app.comp.source.store;
import io.xpipe.app.comp.base.FileDropOverlayComp; import io.xpipe.app.comp.base.FileDropOverlayComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.ext.DataSourceProviders;
import io.xpipe.app.ext.DataStoreProvider;
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.TabPaneComp;
import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.SimpleValidator;
import io.xpipe.app.util.Validatable;
import io.xpipe.app.util.Validator;
import io.xpipe.app.util.XPipeDaemon;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.core.impl.LocalStore; import io.xpipe.core.impl.LocalStore;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.core.store.StreamDataStore; import io.xpipe.core.store.StreamDataStore;
import io.xpipe.extension.DataSourceProvider;
import io.xpipe.extension.DataSourceProviders;
import io.xpipe.extension.DataStoreProvider;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.augment.GrowAugment;
import io.xpipe.extension.fxcomps.impl.TabPaneComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener;
import io.xpipe.extension.util.SimpleValidator;
import io.xpipe.extension.util.Validatable;
import io.xpipe.extension.util.Validator;
import io.xpipe.extension.util.XPipeDaemon;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -64,7 +64,7 @@ public class DsStreamStoreChoiceComp extends SimpleComp implements Validatable {
this.showSaved = showSaved; this.showSaved = showSaved;
this.mode = mode; this.mode = mode;
validator = new SimpleValidator(); validator = new SimpleValidator();
check = Validator.nonNull(validator, I18n.observable("streamStore"), selected); check = Validator.nonNull(validator, AppI18n.observable("streamStore"), selected);
} }
@Override @Override
@ -78,12 +78,12 @@ public class DsStreamStoreChoiceComp extends SimpleComp implements Validatable {
? selected.getValue() ? selected.getValue()
: null); : null);
var browseComp = new DsLocalFileBrowseComp(provider, localStore, mode).apply(GrowAugment.create(true, false)); var browseComp = new DsLocalFileBrowseComp(provider, localStore, mode).apply(GrowAugment.create(true, false));
var dragAndDropLabel = Comp.of(() -> new Label(I18n.get("dragAndDropFilesHere"))) var dragAndDropLabel = Comp.of(() -> new Label(AppI18n.get("dragAndDropFilesHere")))
.apply(s -> s.get().setAlignment(Pos.CENTER)) .apply(s -> s.get().setAlignment(Pos.CENTER))
.apply(struc -> AppFont.small(struc.get())); .apply(struc -> AppFont.small(struc.get()));
// var historyComp = new DsFileHistoryComp(provider, chosenFile); // var historyComp = new DsFileHistoryComp(provider, chosenFile);
var local = new TabPaneComp.Entry( var local = new TabPaneComp.Entry(
I18n.observable("localFile"), AppI18n.observable("localFile"),
"mdi2m-monitor", "mdi2m-monitor",
new VerticalComp(List.of(browseComp, dragAndDropLabel)) new VerticalComp(List.of(browseComp, dragAndDropLabel))
.styleClass("store-local-file-chooser") .styleClass("store-local-file-chooser")
@ -108,18 +108,18 @@ public class DsStreamStoreChoiceComp extends SimpleComp implements Validatable {
? selected.getValue() ? selected.getValue()
: null); : null);
var remote = new TabPaneComp.Entry( var remote = new TabPaneComp.Entry(
I18n.observable("remote"), "mdi2e-earth", new DsRemoteFileChoiceComp(remoteStore)); AppI18n.observable("remote"), "mdi2e-earth", new DsRemoteFileChoiceComp(remoteStore));
var namedStore = new SimpleObjectProperty<DataStore>(isNamedStore ? selected.getValue() : null); var namedStore = new SimpleObjectProperty<DataStore>(isNamedStore ? selected.getValue() : null);
var named = new TabPaneComp.Entry( var named = new TabPaneComp.Entry(
I18n.observable("stored"), AppI18n.observable("stored"),
"mdrmz-storage", "mdrmz-storage",
NamedStoreChoiceComp.create(filter, namedStore, DataStoreProvider.DataCategory.STREAM)); NamedStoreChoiceComp.create(filter, namedStore, DataStoreProvider.DataCategory.STREAM));
var otherStore = new SimpleObjectProperty<DataStore>( var otherStore = new SimpleObjectProperty<DataStore>(
localStore.get() == null && remoteStore.get() == null && !isNamedStore ? selected.getValue() : null); localStore.get() == null && remoteStore.get() == null && !isNamedStore ? selected.getValue() : null);
var other = new TabPaneComp.Entry( var other = new TabPaneComp.Entry(
I18n.observable("other"), AppI18n.observable("other"),
"mdrmz-web_asset", "mdrmz-web_asset",
new DataStoreSelectorComp(DataStoreProvider.DataCategory.STREAM, otherStore)); new DataStoreSelectorComp(DataStoreProvider.DataCategory.STREAM, otherStore));

View file

@ -6,23 +6,23 @@ import io.xpipe.app.comp.base.MessageComp;
import io.xpipe.app.comp.base.MultiStepComp; import io.xpipe.app.comp.base.MultiStepComp;
import io.xpipe.app.core.AppExtensionManager; import io.xpipe.app.core.AppExtensionManager;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.core.AppWindowHelper;
import io.xpipe.app.core.mode.OperationMode; import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DownloadModuleInstall;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.augment.GrowAugment;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.ExceptionConverter;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.*;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataStoreProvider;
import io.xpipe.extension.DownloadModuleInstall;
import io.xpipe.extension.I18n;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.event.ExceptionConverter;
import io.xpipe.extension.event.TrackEvent;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.augment.GrowAugment;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener;
import io.xpipe.extension.util.*;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@ -83,8 +83,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
}); });
this.apply(r -> { this.apply(r -> {
r.get().setPrefWidth(AppFont.em(30)); r.get().setPrefWidth(AppFont.em(32));
r.get().setPrefHeight(AppFont.em(35)); r.get().setPrefHeight(AppFont.em(38));
}); });
} }
@ -121,7 +121,7 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
var name = "addConnection"; var name = "addConnection";
Platform.runLater(() -> { Platform.runLater(() -> {
var stage = AppWindowHelper.sideWindow( var stage = AppWindowHelper.sideWindow(
I18n.get(name), AppI18n.get(name),
window -> { window -> {
return new MultiStepComp() { return new MultiStepComp() {
@ -130,7 +130,7 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
@Override @Override
protected List<Entry> setup() { protected List<Entry> setup() {
return List.of(new Entry(I18n.observable("a"), creator)); return List.of(new Entry(AppI18n.observable("a"), creator));
} }
@Override @Override
@ -150,9 +150,9 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
private static boolean showInvalidConfirmAlert() { private static boolean showInvalidConfirmAlert() {
return AppWindowHelper.showBlockingAlert(alert -> { return AppWindowHelper.showBlockingAlert(alert -> {
alert.setTitle(I18n.get("confirmInvalidStoreTitle")); alert.setTitle(AppI18n.get("confirmInvalidStoreTitle"));
alert.setHeaderText(I18n.get("confirmInvalidStoreHeader")); alert.setHeaderText(AppI18n.get("confirmInvalidStoreHeader"));
alert.setContentText(I18n.get("confirmInvalidStoreContent")); alert.setContentText(AppI18n.get("confirmInvalidStoreContent"));
alert.setAlertType(Alert.AlertType.CONFIRMATION); alert.setAlertType(Alert.AlertType.CONFIRMATION);
}) })
.map(b -> b.getButtonData().isDefaultButton()) .map(b -> b.getButtonData().isDefaultButton())
@ -162,8 +162,8 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
private Region createStoreProperties(Comp<?> comp, Validator propVal) { private Region createStoreProperties(Comp<?> comp, Validator propVal) {
return new DynamicOptionsBuilder(false) return new DynamicOptionsBuilder(false)
.addComp((ObservableValue<String>) null, comp, input) .addComp((ObservableValue<String>) null, comp, input)
.addTitle(I18n.observable("properties")) .addTitle(AppI18n.observable("properties"))
.addString(I18n.observable("name"), name, false) .addString(AppI18n.observable("name"), name, false)
.nonNull(propVal) .nonNull(propVal)
.bind( .bind(
() -> { () -> {

View file

@ -3,22 +3,22 @@ package io.xpipe.app.comp.source.store;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.ListViewComp; import io.xpipe.app.comp.base.ListViewComp;
import io.xpipe.app.comp.storage.store.StoreViewState; import io.xpipe.app.comp.storage.store.StoreViewState;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.FilterComp;
import io.xpipe.app.fxcomps.impl.LabelComp;
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.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
import io.xpipe.app.util.SimpleValidator;
import io.xpipe.app.util.Validatable;
import io.xpipe.app.util.Validator;
import io.xpipe.core.store.DataStore; import io.xpipe.core.store.DataStore;
import io.xpipe.extension.DataStoreProvider;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FilterComp;
import io.xpipe.extension.fxcomps.impl.LabelComp;
import io.xpipe.extension.fxcomps.impl.StackComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp;
import io.xpipe.extension.fxcomps.util.BindingsHelper;
import io.xpipe.extension.util.SimpleValidator;
import io.xpipe.extension.util.Validatable;
import io.xpipe.extension.util.Validator;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -57,7 +57,7 @@ public class NamedStoreChoiceComp extends SimpleComp implements Validatable {
this.filter = filter; this.filter = filter;
this.selected = selected; this.selected = selected;
this.category = category; this.category = category;
check = Validator.nonNull(validator, I18n.observable("store"), selected); check = Validator.nonNull(validator, AppI18n.observable("store"), selected);
} }
public static NamedStoreChoiceComp create( public static NamedStoreChoiceComp create(
@ -139,9 +139,9 @@ public class NamedStoreChoiceComp extends SimpleComp implements Validatable {
var box = new VerticalComp(List.of(filterComp, view)); var box = new VerticalComp(List.of(filterComp, view));
var text = new LabelComp(I18n.observable("noMatchingStoreFound")) var text = new LabelComp(AppI18n.observable("noMatchingStoreFound"))
.apply(struc -> VBox.setVgrow(struc.get(), Priority.ALWAYS)); .apply(struc -> VBox.setVgrow(struc.get(), Priority.ALWAYS));
var addButton = new ButtonComp(I18n.observable("addStore"), null, () -> { var addButton = new ButtonComp(AppI18n.observable("addStore"), null, () -> {
GuiDsStoreCreator.showCreation(v -> v.getCategory().equals(category)); GuiDsStoreCreator.showCreation(v -> v.getCategory().equals(category));
}); });
var notice = new VerticalComp(List.of(text, addButton)) var notice = new VerticalComp(List.of(text, addButton))

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.storage; package io.xpipe.app.comp.storage;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.core.source.DataSourceType; import io.xpipe.core.source.DataSourceType;
import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataFlow;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.comp.storage; package io.xpipe.app.comp.storage;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSource;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;

View file

@ -1,6 +1,6 @@
package io.xpipe.app.comp.storage; package io.xpipe.app.comp.storage;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;

View file

@ -6,15 +6,14 @@ import io.xpipe.app.comp.base.LazyTextFieldComp;
import io.xpipe.app.comp.storage.source.SourceEntryWrapper; import io.xpipe.app.comp.storage.source.SourceEntryWrapper;
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.extension.I18n; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.event.TrackEvent; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.extension.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.extension.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.impl.PrettyImageComp; import io.xpipe.app.issue.TrackEvent;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -125,7 +124,7 @@ public class SourceCollectionComp extends SimpleComp {
infoIcon.setOpacity(0.75); infoIcon.setOpacity(0.75);
return new StackPane(infoIcon); return new StackPane(infoIcon);
}) })
.apply(new FancyTooltipAugment<>(I18n.observable("temporaryCollectionNote"))) .apply(new FancyTooltipAugment<>(AppI18n.observable("temporaryCollectionNote")))
.createRegion(); .createRegion();
var label = new Label(group.getName(), tempNote); var label = new Label(group.getName(), tempNote);
label.getStyleClass().add("temp"); label.getStyleClass().add("temp");

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.storage.collection; package io.xpipe.app.comp.storage.collection;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppWindowHelper; import io.xpipe.app.core.AppWindowHelper;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.augment.PopupMenuAugment;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.extension.I18n; import io.xpipe.app.util.DesktopHelper;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.augment.PopupMenuAugment;
import io.xpipe.extension.util.DesktopHelper;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.ContextMenu; import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
@ -28,9 +28,9 @@ public class SourceCollectionContextMenu<S extends CompStructure<?>> extends Pop
private void onDelete() { private void onDelete() {
if (group.getEntries().size() > 0) { if (group.getEntries().size() > 0) {
AppWindowHelper.showBlockingAlert(alert -> { AppWindowHelper.showBlockingAlert(alert -> {
alert.setTitle(I18n.get("confirmCollectionDeletionTitle")); alert.setTitle(AppI18n.get("confirmCollectionDeletionTitle"));
alert.setHeaderText(I18n.get("confirmCollectionDeletionHeader", group.getName())); alert.setHeaderText(AppI18n.get("confirmCollectionDeletionHeader", group.getName()));
alert.setContentText(I18n.get( alert.setContentText(AppI18n.get(
"confirmCollectionDeletionContent", "confirmCollectionDeletionContent",
group.getEntries().size())); group.getEntries().size()));
alert.setAlertType(Alert.AlertType.CONFIRMATION); alert.setAlertType(Alert.AlertType.CONFIRMATION);
@ -47,9 +47,9 @@ public class SourceCollectionContextMenu<S extends CompStructure<?>> extends Pop
private void onClean() { private void onClean() {
if (group.getEntries().size() > 0) { if (group.getEntries().size() > 0) {
AppWindowHelper.showBlockingAlert(alert -> { AppWindowHelper.showBlockingAlert(alert -> {
alert.setTitle(I18n.get("confirmCollectionDeletionTitle")); alert.setTitle(AppI18n.get("confirmCollectionDeletionTitle"));
alert.setHeaderText(I18n.get("confirmCollectionDeletionHeader", group.getName())); alert.setHeaderText(AppI18n.get("confirmCollectionDeletionHeader", group.getName()));
alert.setContentText(I18n.get( alert.setContentText(AppI18n.get(
"confirmCollectionDeletionContent", "confirmCollectionDeletionContent",
group.getEntries().size())); group.getEntries().size()));
alert.setAlertType(Alert.AlertType.CONFIRMATION); alert.setAlertType(Alert.AlertType.CONFIRMATION);
@ -72,13 +72,13 @@ public class SourceCollectionContextMenu<S extends CompStructure<?>> extends Pop
cm.getItems().add(name); cm.getItems().add(name);
cm.getItems().add(new SeparatorMenuItem()); cm.getItems().add(new SeparatorMenuItem());
{ {
var properties = new MenuItem(I18n.get("properties"), new FontIcon("mdi2a-application-cog")); var properties = new MenuItem(AppI18n.get("properties"), new FontIcon("mdi2a-application-cog"));
properties.setOnAction(e -> {}); properties.setOnAction(e -> {});
// cm.getItems().add(properties); // cm.getItems().add(properties);
} }
if (group.isRenameable()) { if (group.isRenameable()) {
var rename = new MenuItem(I18n.get("rename"), new FontIcon("mdal-edit")); var rename = new MenuItem(AppI18n.get("rename"), new FontIcon("mdal-edit"));
rename.setOnAction(e -> { rename.setOnAction(e -> {
renameTextField.requestFocus(); renameTextField.requestFocus();
}); });
@ -86,7 +86,7 @@ public class SourceCollectionContextMenu<S extends CompStructure<?>> extends Pop
} }
if (AppPrefs.get().developerMode().getValue()) { if (AppPrefs.get().developerMode().getValue()) {
var openDir = new MenuItem(I18n.get("openDir"), new FontIcon("mdal-edit")); var openDir = new MenuItem(AppI18n.get("openDir"), new FontIcon("mdal-edit"));
openDir.setOnAction(e -> { openDir.setOnAction(e -> {
DesktopHelper.browseFileInDirectory(group.getCollection().getDirectory()); DesktopHelper.browseFileInDirectory(group.getCollection().getDirectory());
}); });
@ -94,13 +94,13 @@ public class SourceCollectionContextMenu<S extends CompStructure<?>> extends Pop
} }
if (group.isDeleteable()) { if (group.isDeleteable()) {
var del = new MenuItem(I18n.get("delete"), new FontIcon("mdal-delete_outline")); var del = new MenuItem(AppI18n.get("delete"), new FontIcon("mdal-delete_outline"));
del.setOnAction(e -> { del.setOnAction(e -> {
onDelete(); onDelete();
}); });
cm.getItems().add(del); cm.getItems().add(del);
} else { } else {
var del = new MenuItem(I18n.get("clean"), new FontIcon("mdal-delete_outline")); var del = new MenuItem(AppI18n.get("clean"), new FontIcon("mdal-delete_outline"));
del.setOnAction(e -> { del.setOnAction(e -> {
onClean(); onClean();
}); });

View file

@ -2,9 +2,9 @@ package io.xpipe.app.comp.storage.collection;
import io.xpipe.app.comp.storage.DataSourceTypeComp; import io.xpipe.app.comp.storage.DataSourceTypeComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.core.source.DataSourceType; import io.xpipe.core.source.DataSourceType;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;
@ -18,38 +18,38 @@ public class SourceCollectionEmptyIntroComp extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var title = new Label(I18n.get("dataSourceIntroTitle")); var title = new Label(AppI18n.get("dataSourceIntroTitle"));
AppFont.setSize(title, 7); AppFont.setSize(title, 7);
title.getStyleClass().add("title-header"); title.getStyleClass().add("title-header");
var descFi = new FontIcon("mdi2i-information-outline"); var descFi = new FontIcon("mdi2i-information-outline");
var introDesc = new Label(I18n.get("dataSourceIntroDescription")); var introDesc = new Label(AppI18n.get("dataSourceIntroDescription"));
introDesc.heightProperty().addListener((c, o, n) -> { introDesc.heightProperty().addListener((c, o, n) -> {
descFi.iconSizeProperty().set(n.intValue()); descFi.iconSizeProperty().set(n.intValue());
}); });
var tableFi = new DataSourceTypeComp(DataSourceType.TABLE, null).createRegion(); var tableFi = new DataSourceTypeComp(DataSourceType.TABLE, null).createRegion();
var table = new Label(I18n.get("dataSourceIntroTable"), tableFi); var table = new Label(AppI18n.get("dataSourceIntroTable"), tableFi);
tableFi.prefWidthProperty().bind(table.heightProperty()); tableFi.prefWidthProperty().bind(table.heightProperty());
tableFi.prefHeightProperty().bind(table.heightProperty()); tableFi.prefHeightProperty().bind(table.heightProperty());
var structureFi = new DataSourceTypeComp(DataSourceType.STRUCTURE, null).createRegion(); var structureFi = new DataSourceTypeComp(DataSourceType.STRUCTURE, null).createRegion();
var structure = new Label(I18n.get("dataSourceIntroStructure"), structureFi); var structure = new Label(AppI18n.get("dataSourceIntroStructure"), structureFi);
structureFi.prefWidthProperty().bind(structure.heightProperty()); structureFi.prefWidthProperty().bind(structure.heightProperty());
structureFi.prefHeightProperty().bind(structure.heightProperty()); structureFi.prefHeightProperty().bind(structure.heightProperty());
var textFi = new DataSourceTypeComp(DataSourceType.TEXT, null).createRegion(); var textFi = new DataSourceTypeComp(DataSourceType.TEXT, null).createRegion();
var text = new Label(I18n.get("dataSourceIntroText"), textFi); var text = new Label(AppI18n.get("dataSourceIntroText"), textFi);
textFi.prefWidthProperty().bind(text.heightProperty()); textFi.prefWidthProperty().bind(text.heightProperty());
textFi.prefHeightProperty().bind(text.heightProperty()); textFi.prefHeightProperty().bind(text.heightProperty());
var binaryFi = new DataSourceTypeComp(DataSourceType.RAW, null).createRegion(); var binaryFi = new DataSourceTypeComp(DataSourceType.RAW, null).createRegion();
var binary = new Label(I18n.get("dataSourceIntroBinary"), binaryFi); var binary = new Label(AppI18n.get("dataSourceIntroBinary"), binaryFi);
binaryFi.prefWidthProperty().bind(binary.heightProperty()); binaryFi.prefWidthProperty().bind(binary.heightProperty());
binaryFi.prefHeightProperty().bind(binary.heightProperty()); binaryFi.prefHeightProperty().bind(binary.heightProperty());
var collectionFi = new DataSourceTypeComp(DataSourceType.COLLECTION, null).createRegion(); var collectionFi = new DataSourceTypeComp(DataSourceType.COLLECTION, null).createRegion();
var collection = new Label(I18n.get("dataSourceIntroCollection"), collectionFi); var collection = new Label(AppI18n.get("dataSourceIntroCollection"), collectionFi);
collectionFi.prefWidthProperty().bind(collection.heightProperty()); collectionFi.prefWidthProperty().bind(collection.heightProperty());
collectionFi.prefHeightProperty().bind(collection.heightProperty()); collectionFi.prefHeightProperty().bind(collection.heightProperty());

View file

@ -2,10 +2,10 @@ package io.xpipe.app.comp.storage.collection;
import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.comp.base.CountComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; import io.xpipe.app.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.extension.fxcomps.impl.FilterComp; import io.xpipe.app.fxcomps.impl.FilterComp;
import io.xpipe.extension.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.impl.IconButtonComp;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;

View file

@ -3,14 +3,14 @@ package io.xpipe.app.comp.storage.collection;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.storage.source.SourceEntryListComp; import io.xpipe.app.comp.storage.source.SourceEntryListComp;
import io.xpipe.app.comp.storage.source.SourceEntryListHeaderComp; import io.xpipe.app.comp.storage.source.SourceEntryListHeaderComp;
import io.xpipe.extension.I18n; import io.xpipe.app.core.AppI18n;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; import io.xpipe.app.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.extension.fxcomps.impl.StackComp; import io.xpipe.app.fxcomps.impl.StackComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.extension.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -49,7 +49,7 @@ public class SourceCollectionLayoutComp extends SimpleComp {
var filler = Comp.of(() -> new Region()); var filler = Comp.of(() -> new Region());
filler.styleClass("bar"); filler.styleClass("bar");
filler.styleClass("filler-bar"); filler.styleClass("filler-bar");
var button = new ButtonComp(I18n.observable("addCollection"), new FontIcon("mdi2f-folder-plus-outline"), () -> { var button = new ButtonComp(AppI18n.observable("addCollection"), new FontIcon("mdi2f-folder-plus-outline"), () -> {
SourceCollectionViewState.get().addNewCollection(); SourceCollectionViewState.get().addNewCollection();
}) })
.apply(new FancyTooltipAugment<>("addCollectionFolder")); .apply(new FancyTooltipAugment<>("addCollectionFolder"));

View file

@ -2,14 +2,14 @@ package io.xpipe.app.comp.storage.collection;
import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.StorageFilter;
import io.xpipe.app.comp.storage.source.SourceEntryWrapper; import io.xpipe.app.comp.storage.source.SourceEntryWrapper;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.StorageListener; import io.xpipe.app.storage.StorageListener;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.util.BindingsHelper;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
@ -80,7 +80,7 @@ public class SourceCollectionViewState {
public void addNewCollection() { public void addNewCollection() {
PlatformThread.runLaterIfNeeded(() -> { PlatformThread.runLaterIfNeeded(() -> {
var col = DataSourceCollection.createNew(I18n.get("newCollection")); var col = DataSourceCollection.createNew(AppI18n.get("newCollection"));
DataStorage.get().addCollection(col); DataStorage.get().addCollection(col);
allGroups.stream() allGroups.stream()
.filter(g -> g.getCollection().equals(col)) .filter(g -> g.getCollection().equals(col))

View file

@ -4,12 +4,12 @@ import io.xpipe.app.comp.source.GuiDsCreatorMultiStep;
import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.StorageFilter;
import io.xpipe.app.comp.storage.source.SourceEntryDisplayMode; import io.xpipe.app.comp.storage.source.SourceEntryDisplayMode;
import io.xpipe.app.comp.storage.source.SourceEntryWrapper; import io.xpipe.app.comp.storage.source.SourceEntryWrapper;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.storage.CollectionListener; import io.xpipe.app.storage.CollectionListener;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.core.impl.FileStore; import io.xpipe.core.impl.FileStore;
import io.xpipe.extension.DataSourceProvider;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;

View file

@ -7,17 +7,17 @@ import io.xpipe.app.comp.storage.DataSourceTypeComp;
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.core.AppResources; import io.xpipe.app.core.AppResources;
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.FancyTooltipAugment;
import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.app.fxcomps.impl.LabelComp;
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataFlow;
import io.xpipe.extension.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.augment.GrowAugment;
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.extension.fxcomps.impl.IconButtonComp;
import io.xpipe.extension.fxcomps.impl.LabelComp;
import io.xpipe.extension.fxcomps.impl.PrettyImageComp;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.css.PseudoClass; import javafx.css.PseudoClass;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.comp.storage.source; package io.xpipe.app.comp.storage.source;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.augment.PopupMenuAugment;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.extension.I18n; import io.xpipe.app.util.DesktopHelper;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.CompStructure;
import io.xpipe.extension.fxcomps.augment.PopupMenuAugment;
import io.xpipe.extension.util.DesktopHelper;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.scene.control.ContextMenu; import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem; import javafx.scene.control.MenuItem;
@ -57,28 +57,28 @@ public class SourceEntryContextMenu<S extends CompStructure<?>> extends PopupMen
cm.getItems().add(new SeparatorMenuItem()); cm.getItems().add(new SeparatorMenuItem());
} }
var properties = new MenuItem(I18n.get("properties"), new FontIcon("mdi2a-application-cog")); var properties = new MenuItem(AppI18n.get("properties"), new FontIcon("mdi2a-application-cog"));
properties.setOnAction(e -> {}); properties.setOnAction(e -> {});
// cm.getItems().add(properties); // cm.getItems().add(properties);
var rename = new MenuItem(I18n.get("rename"), new FontIcon("mdi2r-rename-box")); var rename = new MenuItem(AppI18n.get("rename"), new FontIcon("mdi2r-rename-box"));
rename.setOnAction(e -> { rename.setOnAction(e -> {
renameTextField.requestFocus(); renameTextField.requestFocus();
}); });
cm.getItems().add(rename); cm.getItems().add(rename);
var validate = new MenuItem(I18n.get("refresh"), new FontIcon("mdal-360")); var validate = new MenuItem(AppI18n.get("refresh"), new FontIcon("mdal-360"));
validate.setOnAction(event -> { validate.setOnAction(event -> {
DataStorage.get().refreshAsync(entry.getEntry(), true); DataStorage.get().refreshAsync(entry.getEntry(), true);
}); });
cm.getItems().add(validate); cm.getItems().add(validate);
var edit = new MenuItem(I18n.get("edit"), new FontIcon("mdal-edit")); var edit = new MenuItem(AppI18n.get("edit"), new FontIcon("mdal-edit"));
edit.setOnAction(event -> entry.editDialog()); edit.setOnAction(event -> entry.editDialog());
edit.disableProperty().bind(Bindings.equal(DataSourceEntry.State.LOAD_FAILED, entry.getState())); edit.disableProperty().bind(Bindings.equal(DataSourceEntry.State.LOAD_FAILED, entry.getState()));
cm.getItems().add(edit); cm.getItems().add(edit);
var del = new MenuItem(I18n.get("delete"), new FontIcon("mdal-delete_outline")); var del = new MenuItem(AppI18n.get("delete"), new FontIcon("mdal-delete_outline"));
del.setOnAction(e -> { del.setOnAction(e -> {
entry.delete(); entry.delete();
}); });
@ -87,7 +87,7 @@ public class SourceEntryContextMenu<S extends CompStructure<?>> extends PopupMen
if (AppPrefs.get().developerMode().getValue()) { if (AppPrefs.get().developerMode().getValue()) {
cm.getItems().add(new SeparatorMenuItem()); cm.getItems().add(new SeparatorMenuItem());
var openDir = new MenuItem(I18n.get("browseInternal"), new FontIcon("mdi2f-folder-open-outline")); var openDir = new MenuItem(AppI18n.get("browseInternal"), new FontIcon("mdi2f-folder-open-outline"));
openDir.setOnAction(e -> { openDir.setOnAction(e -> {
DesktopHelper.browsePath(entry.getEntry().getDirectory()); DesktopHelper.browsePath(entry.getEntry().getDirectory());
}); });

View file

@ -5,8 +5,8 @@ import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.comp.storage.collection.SourceCollectionEmptyIntroComp; import io.xpipe.app.comp.storage.collection.SourceCollectionEmptyIntroComp;
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper; import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableBooleanValue;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;

View file

@ -7,15 +7,15 @@ import io.xpipe.app.comp.storage.collection.SourceCollectionSortMode;
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper; import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.extension.DataSourceProvider; import io.xpipe.app.core.AppI18n;
import io.xpipe.extension.I18n; import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; import io.xpipe.app.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.extension.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.extension.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.extension.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
@ -188,7 +188,7 @@ public class SourceEntryListHeaderComp extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var label = new Label(I18n.get("none")); var label = new Label(AppI18n.get("none"));
if (SourceCollectionViewState.get().getSelectedGroup() != null) { if (SourceCollectionViewState.get().getSelectedGroup() != null) {
label.textProperty() label.textProperty()
.bind(SourceCollectionViewState.get().getSelectedGroup().nameProperty()); .bind(SourceCollectionViewState.get().getSelectedGroup().nameProperty());
@ -239,7 +239,7 @@ public class SourceEntryListHeaderComp extends SimpleComp {
private Comp<?> createActionsButtonBar() { private Comp<?> createActionsButtonBar() {
var newFile = new ButtonComp( var newFile = new ButtonComp(
I18n.observable(group != null ? "addStream" : "pipeStream"), AppI18n.observable(group != null ? "addStream" : "pipeStream"),
new FontIcon("mdi2f-file-plus-outline"), new FontIcon("mdi2f-file-plus-outline"),
() -> { () -> {
var selected = SourceCollectionViewState.get() var selected = SourceCollectionViewState.get()
@ -253,7 +253,7 @@ public class SourceEntryListHeaderComp extends SimpleComp {
.apply(new FancyTooltipAugment<>("addStreamDataSource")); .apply(new FancyTooltipAugment<>("addStreamDataSource"));
var newDb = new ButtonComp( var newDb = new ButtonComp(
I18n.observable(group != null ? "addDatabase" : "pipeDatabase"), AppI18n.observable(group != null ? "addDatabase" : "pipeDatabase"),
new FontIcon("mdi2d-database-plus-outline"), new FontIcon("mdi2d-database-plus-outline"),
() -> { () -> {
var selected = SourceCollectionViewState.get() var selected = SourceCollectionViewState.get()

View file

@ -4,16 +4,16 @@ import io.xpipe.app.comp.source.GuiDsCreatorMultiStep;
import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.StorageFilter;
import io.xpipe.app.comp.storage.collection.SourceCollectionViewState; import io.xpipe.app.comp.storage.collection.SourceCollectionViewState;
import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper; import io.xpipe.app.comp.storage.collection.SourceCollectionWrapper;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.DataSourceEntry; import io.xpipe.app.storage.DataSourceEntry;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.StorageElement; import io.xpipe.app.storage.StorageElement;
import io.xpipe.core.source.DataSource; import io.xpipe.core.source.DataSource;
import io.xpipe.core.store.DataFlow; import io.xpipe.core.store.DataFlow;
import io.xpipe.extension.DataStoreProviders;
import io.xpipe.extension.I18n;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.util.ActionProvider;
import javafx.beans.property.*; import javafx.beans.property.*;
import lombok.Value; import lombok.Value;
@ -94,7 +94,7 @@ public class SourceEntryWrapper implements StorageFilter.Filterable {
? entry.getInformation() != null ? entry.getInformation() != null
? entry.getInformation() ? entry.getInformation()
: entry.getProvider().getDisplayName() : entry.getProvider().getDisplayName()
: I18n.get("failedToLoad")); : AppI18n.get("failedToLoad"));
loading.setValue(entry.getState() == null || entry.getState() == DataSourceEntry.State.VALIDATING); loading.setValue(entry.getState() == null || entry.getState() == DataSourceEntry.State.VALIDATING);
actionProviders.clear(); actionProviders.clear();

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.storage.source; package io.xpipe.app.comp.storage.source;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Hyperlink; import javafx.scene.control.Hyperlink;
@ -18,30 +18,30 @@ public class SourceStorageEmptyIntroComp extends SimpleComp {
@Override @Override
public Region createSimple() { public Region createSimple() {
var title = new Label(I18n.get("introTitle")); var title = new Label(AppI18n.get("introTitle"));
AppFont.setSize(title, 7); AppFont.setSize(title, 7);
title.getStyleClass().add("title-header"); title.getStyleClass().add("title-header");
var descFi = new FontIcon("mdi2i-information-outline"); var descFi = new FontIcon("mdi2i-information-outline");
var introDesc = new Label(I18n.get("introDescription")); var introDesc = new Label(AppI18n.get("introDescription"));
introDesc.heightProperty().addListener((c, o, n) -> { introDesc.heightProperty().addListener((c, o, n) -> {
descFi.iconSizeProperty().set(n.intValue()); descFi.iconSizeProperty().set(n.intValue());
}); });
var fi = new FontIcon("mdi2f-folder-plus-outline"); var fi = new FontIcon("mdi2f-folder-plus-outline");
var addCollection = new Label(I18n.get("introCollection"), fi); var addCollection = new Label(AppI18n.get("introCollection"), fi);
addCollection.heightProperty().addListener((c, o, n) -> { addCollection.heightProperty().addListener((c, o, n) -> {
fi.iconSizeProperty().set(n.intValue()); fi.iconSizeProperty().set(n.intValue());
}); });
var pipeFi = new FontIcon("mdi2p-pipe-disconnected"); var pipeFi = new FontIcon("mdi2p-pipe-disconnected");
var pipe = new Label(I18n.get("introPipe"), pipeFi); var pipe = new Label(AppI18n.get("introPipe"), pipeFi);
pipe.heightProperty().addListener((c, o, n) -> { pipe.heightProperty().addListener((c, o, n) -> {
pipeFi.iconSizeProperty().set(n.intValue()); pipeFi.iconSizeProperty().set(n.intValue());
}); });
var dfi = new FontIcon("mdi2b-book-open-variant"); var dfi = new FontIcon("mdi2b-book-open-variant");
var documentation = new Label(I18n.get("introDocumentation"), dfi); var documentation = new Label(AppI18n.get("introDocumentation"), dfi);
documentation.heightProperty().addListener((c, o, n) -> { documentation.heightProperty().addListener((c, o, n) -> {
dfi.iconSizeProperty().set(n.intValue()); dfi.iconSizeProperty().set(n.intValue());
}); });

View file

@ -3,11 +3,11 @@ package io.xpipe.app.comp.storage.store;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.source.store.GuiDsStoreCreator; import io.xpipe.app.comp.source.store.GuiDsStoreCreator;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.extension.DataStoreProvider; import io.xpipe.app.core.AppI18n;
import io.xpipe.extension.I18n; import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment; import io.xpipe.app.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.extension.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.impl.VerticalComp;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyCombination;
@ -21,28 +21,28 @@ public class StoreCreationBarComp extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var newOtherStore = new ButtonComp( var newOtherStore = new ButtonComp(
I18n.observable("addOther"), new FontIcon("mdi2c-card-plus-outline"), () -> { AppI18n.observable("addOther"), new FontIcon("mdi2c-card-plus-outline"), () -> {
GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.OTHER)); GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.OTHER));
}) })
.shortcut(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN)) .shortcut(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN))
.apply(new FancyTooltipAugment<>("addOther")); .apply(new FancyTooltipAugment<>("addOther"));
var newStreamStore = new ButtonComp( var newStreamStore = new ButtonComp(
I18n.observable("addCommand"), new FontIcon("mdi2c-code-greater-than"), () -> { AppI18n.observable("addCommand"), new FontIcon("mdi2c-code-greater-than"), () -> {
GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.COMMAND)); GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.COMMAND));
}) })
.shortcut(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN)) .shortcut(new KeyCodeCombination(KeyCode.C, KeyCombination.SHORTCUT_DOWN))
.apply(new FancyTooltipAugment<>("addCommand")); .apply(new FancyTooltipAugment<>("addCommand"));
var newShellStore = new ButtonComp( var newShellStore = new ButtonComp(
I18n.observable("addHost"), new FontIcon("mdi2h-home-plus-outline"), () -> { AppI18n.observable("addHost"), new FontIcon("mdi2h-home-plus-outline"), () -> {
GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.HOST)); GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.HOST));
}) })
.shortcut(new KeyCodeCombination(KeyCode.H, KeyCombination.SHORTCUT_DOWN)) .shortcut(new KeyCodeCombination(KeyCode.H, KeyCombination.SHORTCUT_DOWN))
.apply(new FancyTooltipAugment<>("addHost")); .apply(new FancyTooltipAugment<>("addHost"));
var newDbStore = new ButtonComp( var newDbStore = new ButtonComp(
I18n.observable("addDatabase"), new FontIcon("mdi2d-database-plus-outline"), () -> { AppI18n.observable("addDatabase"), new FontIcon("mdi2d-database-plus-outline"), () -> {
GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.DATABASE)); GuiDsStoreCreator.showCreation(v -> v.getDisplayCategory().equals(DataStoreProvider.DisplayCategory.DATABASE));
}) })
.shortcut(new KeyCodeCombination(KeyCode.D, KeyCombination.SHORTCUT_DOWN)) .shortcut(new KeyCodeCombination(KeyCode.D, KeyCombination.SHORTCUT_DOWN))

View file

@ -5,22 +5,21 @@ 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.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.fxcomps.augment.GrowAugment;
import io.xpipe.app.fxcomps.augment.PopupMenuAugment;
import io.xpipe.app.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.extension.I18n; import io.xpipe.app.util.DesktopHelper;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.util.ThreadHelper;
import io.xpipe.extension.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.SimpleCompStructure;
import io.xpipe.extension.fxcomps.augment.GrowAugment;
import io.xpipe.extension.fxcomps.augment.PopupMenuAugment;
import io.xpipe.extension.fxcomps.impl.FancyTooltipAugment;
import io.xpipe.extension.fxcomps.impl.HorizontalComp;
import io.xpipe.extension.fxcomps.impl.IconButtonComp;
import io.xpipe.extension.fxcomps.impl.PrettyImageComp;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.fxcomps.util.SimpleChangeListener;
import io.xpipe.extension.util.DesktopHelper;
import io.xpipe.extension.util.ThreadHelper;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.css.PseudoClass; import javafx.css.PseudoClass;
@ -255,20 +254,20 @@ public class StoreEntryComp extends SimpleComp {
} }
if (AppPrefs.get().developerMode().getValue()) { if (AppPrefs.get().developerMode().getValue()) {
var browse = new MenuItem(I18n.get("browse"), new FontIcon("mdi2f-folder-open-outline")); var browse = new MenuItem(AppI18n.get("browse"), new FontIcon("mdi2f-folder-open-outline"));
browse.setOnAction( browse.setOnAction(
event -> DesktopHelper.browsePath(entry.getEntry().getDirectory())); event -> DesktopHelper.browsePath(entry.getEntry().getDirectory()));
contextMenu.getItems().add(browse); contextMenu.getItems().add(browse);
} }
var refresh = new MenuItem(I18n.get("refresh"), new FontIcon("mdal-360")); var refresh = new MenuItem(AppI18n.get("refresh"), new FontIcon("mdal-360"));
refresh.disableProperty().bind(entry.getRefreshable().not()); refresh.disableProperty().bind(entry.getRefreshable().not());
refresh.setOnAction(event -> { refresh.setOnAction(event -> {
DataStorage.get().refreshAsync(entry.getEntry(), true); DataStorage.get().refreshAsync(entry.getEntry(), true);
}); });
contextMenu.getItems().add(refresh); contextMenu.getItems().add(refresh);
var del = new MenuItem(I18n.get("delete"), new FontIcon("mdal-delete_outline")); var del = new MenuItem(AppI18n.get("delete"), new FontIcon("mdal-delete_outline"));
del.disableProperty().bind(entry.getDeletable().not()); del.disableProperty().bind(entry.getDeletable().not());
del.setOnAction(event -> entry.delete()); del.setOnAction(event -> entry.delete());
contextMenu.getItems().add(del); contextMenu.getItems().add(del);

View file

@ -1,10 +1,11 @@
package io.xpipe.app.comp.storage.store; package io.xpipe.app.comp.storage.store;
import atlantafx.base.theme.Styles;
import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.MultiContentComp; import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableBooleanValue;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@ -23,7 +24,7 @@ public class StoreEntryListComp extends SimpleComp {
var content = new ListBoxViewComp<>(filtered, topLevel, (StoreEntrySection e) -> { var content = new ListBoxViewComp<>(filtered, topLevel, (StoreEntrySection e) -> {
return e.comp(true); return e.comp(true);
}); });
return content.styleClass("store-list-comp"); return content.styleClass("store-list-comp").styleClass(Styles.STRIPED);
} }
@Override @Override

View file

@ -2,9 +2,9 @@ package io.xpipe.app.comp.storage.store;
import io.xpipe.app.comp.base.CountComp; import io.xpipe.app.comp.base.CountComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.FilterComp; import io.xpipe.app.fxcomps.impl.FilterComp;
import io.xpipe.extension.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;

View file

@ -2,11 +2,11 @@ package io.xpipe.app.comp.storage.store;
import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.StorageFilter;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.augment.GrowAugment; import io.xpipe.app.fxcomps.augment.GrowAugment;
import io.xpipe.extension.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.extension.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
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;

View file

@ -2,12 +2,12 @@ package io.xpipe.app.comp.storage.store;
import io.xpipe.app.comp.source.store.GuiDsStoreCreator; import io.xpipe.app.comp.source.store.GuiDsStoreCreator;
import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.StorageFilter;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.util.ActionProvider;
import javafx.beans.Observable; import javafx.beans.Observable;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.*; import javafx.beans.property.*;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.comp.storage.store; package io.xpipe.app.comp.storage.store;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.augment.GrowAugment; import io.xpipe.app.fxcomps.augment.GrowAugment;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;

View file

@ -1,6 +1,6 @@
package io.xpipe.app.comp.storage.store; package io.xpipe.app.comp.storage.store;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.storage.store; package io.xpipe.app.comp.storage.store;
import io.xpipe.extension.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.extension.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.extension.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.impl.VerticalComp;
import javafx.scene.layout.Priority; import javafx.scene.layout.Priority;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.storage.store; package io.xpipe.app.comp.storage.store;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.Hyperlinks;
import io.xpipe.extension.I18n;
import io.xpipe.extension.fxcomps.SimpleComp;
import javafx.geometry.Orientation; import javafx.geometry.Orientation;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Hyperlink; import javafx.scene.control.Hyperlink;
@ -18,36 +18,36 @@ public class StoreStorageEmptyIntroComp extends SimpleComp {
@Override @Override
public Region createSimple() { public Region createSimple() {
var title = new Label(I18n.get("storeIntroTitle")); var title = new Label(AppI18n.get("storeIntroTitle"));
AppFont.setSize(title, 7); AppFont.setSize(title, 7);
title.getStyleClass().add("title-header"); title.getStyleClass().add("title-header");
var descFi = new FontIcon("mdi2i-information-outline"); var descFi = new FontIcon("mdi2i-information-outline");
var introDesc = new Label(I18n.get("storeIntroDescription")); var introDesc = new Label(AppI18n.get("storeIntroDescription"));
introDesc.heightProperty().addListener((c, o, n) -> { introDesc.heightProperty().addListener((c, o, n) -> {
descFi.iconSizeProperty().set(n.intValue()); descFi.iconSizeProperty().set(n.intValue());
}); });
var mfi = new FontIcon("mdi2h-home-plus-outline"); var mfi = new FontIcon("mdi2h-home-plus-outline");
var machine = new Label(I18n.get("storeMachineDescription"), mfi); var machine = new Label(AppI18n.get("storeMachineDescription"), mfi);
machine.heightProperty().addListener((c, o, n) -> { machine.heightProperty().addListener((c, o, n) -> {
mfi.iconSizeProperty().set(n.intValue()); mfi.iconSizeProperty().set(n.intValue());
}); });
var dfi = new FontIcon("mdi2d-database-plus-outline"); var dfi = new FontIcon("mdi2d-database-plus-outline");
var database = new Label(I18n.get("storeDatabaseDescription"), dfi); var database = new Label(AppI18n.get("storeDatabaseDescription"), dfi);
database.heightProperty().addListener((c, o, n) -> { database.heightProperty().addListener((c, o, n) -> {
dfi.iconSizeProperty().set(n.intValue()); dfi.iconSizeProperty().set(n.intValue());
}); });
var fi = new FontIcon("mdi2c-card-plus-outline"); var fi = new FontIcon("mdi2c-card-plus-outline");
var stream = new Label(I18n.get("storeStreamDescription"), fi); var stream = new Label(AppI18n.get("storeStreamDescription"), fi);
stream.heightProperty().addListener((c, o, n) -> { stream.heightProperty().addListener((c, o, n) -> {
fi.iconSizeProperty().set(n.intValue()); fi.iconSizeProperty().set(n.intValue());
}); });
var dofi = new FontIcon("mdi2b-book-open-variant"); var dofi = new FontIcon("mdi2b-book-open-variant");
var documentation = new Label(I18n.get("introDocumentation"), dofi); var documentation = new Label(AppI18n.get("introDocumentation"), dofi);
documentation.heightProperty().addListener((c, o, n) -> { documentation.heightProperty().addListener((c, o, n) -> {
dofi.iconSizeProperty().set(n.intValue()); dofi.iconSizeProperty().set(n.intValue());
}); });

View file

@ -1,12 +1,12 @@
package io.xpipe.app.comp.storage.store; package io.xpipe.app.comp.storage.store;
import io.xpipe.app.comp.storage.StorageFilter; import io.xpipe.app.comp.storage.StorageFilter;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.DataSourceCollection; import io.xpipe.app.storage.DataSourceCollection;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.StorageListener; import io.xpipe.app.storage.StorageListener;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.util.BindingsHelper;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;

View file

@ -2,10 +2,10 @@ package io.xpipe.app.core;
import io.xpipe.app.Main; import io.xpipe.app.Main;
import io.xpipe.app.comp.AppLayoutComp; import io.xpipe.app.comp.AppLayoutComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.core.process.OsType; import io.xpipe.core.process.OsType;
import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.event.TrackEvent;
import io.xpipe.extension.fxcomps.util.PlatformThread;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.image.Image; import javafx.scene.image.Image;

View file

@ -1,7 +1,6 @@
package io.xpipe.app.core; package io.xpipe.app.core;
import io.xpipe.app.launcher.LauncherInput; import io.xpipe.app.launcher.LauncherInput;
import io.xpipe.extension.I18n;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.input.Clipboard; import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat; import javafx.scene.input.DataFormat;
@ -63,10 +62,10 @@ public class AppActionLinkDetector {
private static boolean showAlert() { private static boolean showAlert() {
var paste = AppWindowHelper.showBlockingAlert(alert -> { var paste = AppWindowHelper.showBlockingAlert(alert -> {
alert.setAlertType(Alert.AlertType.CONFIRMATION); alert.setAlertType(Alert.AlertType.CONFIRMATION);
alert.setTitle(I18n.get("clipboardActionDetectedTitle")); alert.setTitle(AppI18n.get("clipboardActionDetectedTitle"));
alert.setHeaderText(I18n.get("clipboardActionDetectedHeader")); alert.setHeaderText(AppI18n.get("clipboardActionDetectedHeader"));
alert.getDialogPane() alert.getDialogPane()
.setContent(AppWindowHelper.alertContentText(I18n.get("clipboardActionDetectedContent"))); .setContent(AppWindowHelper.alertContentText(AppI18n.get("clipboardActionDetectedContent")));
}) })
.map(buttonType -> buttonType.getButtonData().isDefaultButton()) .map(buttonType -> buttonType.getButtonData().isDefaultButton())
.orElse(false); .orElse(false);

View file

@ -1,18 +1,22 @@
package io.xpipe.app.core; package io.xpipe.app.core;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.JsonConfigHelper; import io.xpipe.app.util.JsonConfigHelper;
import io.xpipe.core.util.JacksonMapper; import io.xpipe.core.util.JacksonMapper;
import io.xpipe.extension.Cache;
import io.xpipe.extension.event.ErrorEvent;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.function.Supplier; import java.util.function.Supplier;
public class AppCache implements Cache { public class AppCache {
public static <T> Optional<T> getIfPresent(String key, Class<T> type) {
return Optional.ofNullable(get(key, type, () -> null));
}
public static UUID getCachedUserId() { public static UUID getCachedUserId() {
var id = get("userId", UUID.class, UUID::randomUUID); var id = get("userId", UUID.class, UUID::randomUUID);
@ -78,12 +82,10 @@ public class AppCache implements Cache {
} }
} }
@Override
public <T> T getValue(String key, Class<?> type, Supplier<T> notPresent) { public <T> T getValue(String key, Class<?> type, Supplier<T> notPresent) {
return get(key, type, notPresent); return get(key, type, notPresent);
} }
@Override
public <T> void updateValue(String key, T val) { public <T> void updateValue(String key, T val) {
update(key, val); update(key, val);
} }

View file

@ -1,6 +1,6 @@
package io.xpipe.app.core; package io.xpipe.app.core;
import io.xpipe.extension.event.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;

Some files were not shown because too many files have changed in this diff Show more