mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 00:50:31 +00:00
Small fixes
This commit is contained in:
parent
44d33d32f4
commit
2a139d15c7
36 changed files with 136 additions and 197 deletions
|
@ -75,7 +75,7 @@ public class SideMenuBarComp extends Comp<CompStructure<VBox>> {
|
||||||
}
|
}
|
||||||
b.apply(new TooltipAugment<>(e.name(), shortcut));
|
b.apply(new TooltipAugment<>(e.name(), shortcut));
|
||||||
b.apply(struc -> {
|
b.apply(struc -> {
|
||||||
AppFont.setSize(struc.get(), 1);
|
AppFont.setSize(struc.get(), 2);
|
||||||
struc.get().pseudoClassStateChanged(selected, value.getValue().equals(e));
|
struc.get().pseudoClassStateChanged(selected, value.getValue().equals(e));
|
||||||
value.addListener((c, o, n) -> {
|
value.addListener((c, o, n) -> {
|
||||||
PlatformThread.runLaterIfNeeded(() -> {
|
PlatformThread.runLaterIfNeeded(() -> {
|
||||||
|
@ -118,7 +118,7 @@ public class SideMenuBarComp extends Comp<CompStructure<VBox>> {
|
||||||
.tooltipKey("updateAvailableTooltip")
|
.tooltipKey("updateAvailableTooltip")
|
||||||
.accessibleTextKey("updateAvailableTooltip");
|
.accessibleTextKey("updateAvailableTooltip");
|
||||||
b.apply(struc -> {
|
b.apply(struc -> {
|
||||||
AppFont.setSize(struc.get(), 1);
|
AppFont.setSize(struc.get(), 2);
|
||||||
});
|
});
|
||||||
b.hide(PlatformThread.sync(Bindings.createBooleanBinding(
|
b.hide(PlatformThread.sync(Bindings.createBooleanBinding(
|
||||||
() -> {
|
() -> {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package io.xpipe.app.comp.store;
|
package io.xpipe.app.comp.store;
|
||||||
|
|
||||||
|
import io.xpipe.app.core.AppFont;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
|
@ -15,8 +17,8 @@ public class DenseStoreEntryComp extends StoreEntryComp {
|
||||||
|
|
||||||
private final boolean showIcon;
|
private final boolean showIcon;
|
||||||
|
|
||||||
public DenseStoreEntryComp(StoreSection section, boolean showIcon, Comp<?> content) {
|
public DenseStoreEntryComp(StoreEntryWrapper entry, boolean showIcon, Comp<?> content) {
|
||||||
super(section, content);
|
super(entry, content);
|
||||||
this.showIcon = showIcon;
|
this.showIcon = showIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,15 +26,16 @@ public class DenseStoreEntryComp extends StoreEntryComp {
|
||||||
var information = new Label();
|
var information = new Label();
|
||||||
information.setGraphicTextGap(7);
|
information.setGraphicTextGap(7);
|
||||||
information.getStyleClass().add("information");
|
information.getStyleClass().add("information");
|
||||||
|
AppFont.header(information);
|
||||||
|
|
||||||
var state = getWrapper().getEntry().getProvider() != null
|
var state = wrapper.getEntry().getProvider() != null
|
||||||
? getWrapper().getEntry().getProvider().stateDisplay(getWrapper())
|
? wrapper.getEntry().getProvider().stateDisplay(wrapper)
|
||||||
: Comp.empty();
|
: Comp.empty();
|
||||||
information.setGraphic(state.createRegion());
|
information.setGraphic(state.createRegion());
|
||||||
|
|
||||||
var info = getWrapper().getEntry().getProvider() != null ? getWrapper().getEntry().getProvider().informationString(section) : new SimpleStringProperty();
|
var info = wrapper.getEntry().getProvider() != null ? wrapper.getEntry().getProvider().informationString(wrapper) : new SimpleStringProperty();
|
||||||
var summary = getWrapper().getSummary();
|
var summary = wrapper.getSummary();
|
||||||
if (getWrapper().getEntry().getProvider() != null) {
|
if (wrapper.getEntry().getProvider() != null) {
|
||||||
information
|
information
|
||||||
.textProperty()
|
.textProperty()
|
||||||
.bind(PlatformThread.sync(Bindings.createStringBinding(
|
.bind(PlatformThread.sync(Bindings.createStringBinding(
|
||||||
|
@ -40,7 +43,7 @@ public class DenseStoreEntryComp extends StoreEntryComp {
|
||||||
var val = summary.getValue();
|
var val = summary.getValue();
|
||||||
if (val != null
|
if (val != null
|
||||||
&& grid.isHover()
|
&& grid.isHover()
|
||||||
&& getWrapper().getEntry().getProvider().alwaysShowSummary()) {
|
&& wrapper.getEntry().getProvider().alwaysShowSummary()) {
|
||||||
return val;
|
return val;
|
||||||
} else {
|
} else {
|
||||||
return info.getValue();
|
return info.getValue();
|
||||||
|
@ -70,11 +73,11 @@ public class DenseStoreEntryComp extends StoreEntryComp {
|
||||||
return grid.getWidth() / 2.5;
|
return grid.getWidth() / 2.5;
|
||||||
},
|
},
|
||||||
grid.widthProperty()));
|
grid.widthProperty()));
|
||||||
var notes = new StoreNotesComp(getWrapper()).createRegion();
|
var notes = new StoreNotesComp(wrapper).createRegion();
|
||||||
|
|
||||||
if (showIcon) {
|
if (showIcon) {
|
||||||
var storeIcon = createIcon(28, 24);
|
var storeIcon = createIcon(30, 24);
|
||||||
grid.getColumnConstraints().add(new ColumnConstraints(38));
|
grid.getColumnConstraints().add(new ColumnConstraints(46));
|
||||||
grid.add(storeIcon, 0, 0);
|
grid.add(storeIcon, 0, 0);
|
||||||
GridPane.setHalignment(storeIcon, HPos.CENTER);
|
GridPane.setHalignment(storeIcon, HPos.CENTER);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,12 @@ import io.xpipe.app.fxcomps.Comp;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.geometry.VPos;
|
|
||||||
import javafx.scene.layout.*;
|
import javafx.scene.layout.*;
|
||||||
|
|
||||||
public class StandardStoreEntryComp extends StoreEntryComp {
|
public class StandardStoreEntryComp extends StoreEntryComp {
|
||||||
|
|
||||||
public StandardStoreEntryComp(StoreSection section, Comp<?> content) {
|
public StandardStoreEntryComp(StoreEntryWrapper entry, Comp<?> content) {
|
||||||
super(section, content);
|
super(entry, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,21 +20,20 @@ public class StandardStoreEntryComp extends StoreEntryComp {
|
||||||
|
|
||||||
protected Region createContent() {
|
protected Region createContent() {
|
||||||
var name = createName().createRegion();
|
var name = createName().createRegion();
|
||||||
var notes = new StoreNotesComp(getWrapper()).createRegion();
|
var notes = new StoreNotesComp(wrapper).createRegion();
|
||||||
|
|
||||||
var grid = new GridPane();
|
var grid = new GridPane();
|
||||||
grid.setHgap(6);
|
grid.setHgap(7);
|
||||||
grid.setVgap(0);
|
grid.setVgap(0);
|
||||||
|
|
||||||
var storeIcon = createIcon(46, 40);
|
var storeIcon = createIcon(50, 40);
|
||||||
grid.add(storeIcon, 0, 0, 1, 2);
|
grid.add(storeIcon, 0, 0, 1, 2);
|
||||||
grid.getColumnConstraints().add(new ColumnConstraints(56));
|
grid.getColumnConstraints().add(new ColumnConstraints(66));
|
||||||
|
|
||||||
var nameAndNotes = new HBox(name, notes);
|
var nameAndNotes = new HBox(name, notes);
|
||||||
nameAndNotes.setSpacing(1);
|
nameAndNotes.setSpacing(1);
|
||||||
nameAndNotes.setAlignment(Pos.CENTER_LEFT);
|
nameAndNotes.setAlignment(Pos.CENTER_LEFT);
|
||||||
grid.add(nameAndNotes, 1, 0);
|
grid.add(nameAndNotes, 1, 0);
|
||||||
GridPane.setValignment(nameAndNotes, VPos.CENTER);
|
|
||||||
grid.add(createSummary(), 1, 1);
|
grid.add(createSummary(), 1, 1);
|
||||||
var nameCC = new ColumnConstraints();
|
var nameCC = new ColumnConstraints();
|
||||||
nameCC.setMinWidth(100);
|
nameCC.setMinWidth(100);
|
||||||
|
|
|
@ -51,25 +51,21 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
App.getApp().getStage().widthProperty().divide(2.1).add(-100);
|
App.getApp().getStage().widthProperty().divide(2.1).add(-100);
|
||||||
public static final ObservableDoubleValue INFO_WITH_CONTENT_WIDTH =
|
public static final ObservableDoubleValue INFO_WITH_CONTENT_WIDTH =
|
||||||
App.getApp().getStage().widthProperty().divide(2.1).add(-200);
|
App.getApp().getStage().widthProperty().divide(2.1).add(-200);
|
||||||
protected final StoreSection section;
|
protected final StoreEntryWrapper wrapper;
|
||||||
protected final Comp<?> content;
|
protected final Comp<?> content;
|
||||||
|
|
||||||
public StoreEntryComp(StoreSection section, Comp<?> content) {
|
public StoreEntryComp(StoreEntryWrapper wrapper, Comp<?> content) {
|
||||||
this.section = section;
|
this.wrapper = wrapper;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StoreEntryWrapper getWrapper() {
|
|
||||||
return section.getWrapper();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StoreEntryComp create(StoreSection section, Comp<?> content, boolean preferLarge) {
|
public static StoreEntryComp create(StoreEntryWrapper entry, Comp<?> content, boolean preferLarge) {
|
||||||
var forceCondensed = AppPrefs.get() != null
|
var forceCondensed = AppPrefs.get() != null
|
||||||
&& AppPrefs.get().condenseConnectionDisplay().get();
|
&& AppPrefs.get().condenseConnectionDisplay().get();
|
||||||
if (!preferLarge || forceCondensed) {
|
if (!preferLarge || forceCondensed) {
|
||||||
return new DenseStoreEntryComp(section, true, content);
|
return new DenseStoreEntryComp(entry, true, content);
|
||||||
} else {
|
} else {
|
||||||
return new StandardStoreEntryComp(section, content);
|
return new StandardStoreEntryComp(entry, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +77,8 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
var forceCondensed = AppPrefs.get() != null
|
var forceCondensed = AppPrefs.get() != null
|
||||||
&& AppPrefs.get().condenseConnectionDisplay().get();
|
&& AppPrefs.get().condenseConnectionDisplay().get();
|
||||||
return forceCondensed
|
return forceCondensed
|
||||||
? new DenseStoreEntryComp(e, true, null)
|
? new DenseStoreEntryComp(e.getWrapper(), true, null)
|
||||||
: new StandardStoreEntryComp(e, null);
|
: new StandardStoreEntryComp(e.getWrapper(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,11 +95,11 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
button.setPadding(Insets.EMPTY);
|
button.setPadding(Insets.EMPTY);
|
||||||
button.setMaxWidth(5000);
|
button.setMaxWidth(5000);
|
||||||
button.setFocusTraversable(true);
|
button.setFocusTraversable(true);
|
||||||
button.accessibleTextProperty().bind(getWrapper().nameProperty());
|
button.accessibleTextProperty().bind(wrapper.nameProperty());
|
||||||
button.setOnAction(event -> {
|
button.setOnAction(event -> {
|
||||||
event.consume();
|
event.consume();
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
getWrapper().executeDefaultAction();
|
wrapper.executeDefaultAction();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
button.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
|
button.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
|
||||||
|
@ -136,10 +132,9 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
|
|
||||||
var loading = LoadingOverlayComp.noProgress(
|
var loading = LoadingOverlayComp.noProgress(
|
||||||
Comp.of(() -> button),
|
Comp.of(() -> button),
|
||||||
getWrapper().getEntry().getValidity().isUsable()
|
wrapper.getEntry().getValidity().isUsable()
|
||||||
? getWrapper().getBusy().or(getWrapper().getEntry().getProvider().busy(getWrapper()))
|
? wrapper.getBusy().or(wrapper.getEntry().getProvider().busy(wrapper))
|
||||||
: getWrapper().getBusy());
|
: wrapper.getBusy());
|
||||||
AppFont.normal(button);
|
|
||||||
return loading.createRegion();
|
return loading.createRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,14 +146,15 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
information
|
information
|
||||||
.textProperty()
|
.textProperty()
|
||||||
.bind(
|
.bind(
|
||||||
getWrapper().getEntry().getProvider() != null
|
wrapper.getEntry().getProvider() != null
|
||||||
? PlatformThread.sync(
|
? PlatformThread.sync(
|
||||||
getWrapper().getEntry().getProvider().informationString(section))
|
wrapper.getEntry().getProvider().informationString(wrapper))
|
||||||
: new SimpleStringProperty());
|
: new SimpleStringProperty());
|
||||||
information.getStyleClass().add("information");
|
information.getStyleClass().add("information");
|
||||||
|
AppFont.header(information);
|
||||||
|
|
||||||
var state = getWrapper().getEntry().getProvider() != null
|
var state = wrapper.getEntry().getProvider() != null
|
||||||
? getWrapper().getEntry().getProvider().stateDisplay(getWrapper())
|
? wrapper.getEntry().getProvider().stateDisplay(wrapper)
|
||||||
: Comp.empty();
|
: Comp.empty();
|
||||||
information.setGraphic(state.createRegion());
|
information.setGraphic(state.createRegion());
|
||||||
|
|
||||||
|
@ -167,14 +163,14 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
|
|
||||||
protected Label createSummary() {
|
protected Label createSummary() {
|
||||||
var summary = new Label();
|
var summary = new Label();
|
||||||
summary.textProperty().bind(getWrapper().getSummary());
|
summary.textProperty().bind(wrapper.getSummary());
|
||||||
summary.getStyleClass().add("summary");
|
summary.getStyleClass().add("summary");
|
||||||
AppFont.small(summary);
|
AppFont.small(summary);
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyState(Node node) {
|
protected void applyState(Node node) {
|
||||||
PlatformThread.sync(getWrapper().getValidity()).subscribe(val -> {
|
PlatformThread.sync(wrapper.getValidity()).subscribe(val -> {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case LOAD_FAILED -> {
|
case LOAD_FAILED -> {
|
||||||
node.pseudoClassStateChanged(FAILED, true);
|
node.pseudoClassStateChanged(FAILED, true);
|
||||||
|
@ -193,22 +189,24 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Comp<?> createName() {
|
protected Comp<?> createName() {
|
||||||
LabelComp name = new LabelComp(getWrapper().nameProperty());
|
LabelComp name = new LabelComp(wrapper.nameProperty());
|
||||||
name.apply(struc -> struc.get().setTextOverrun(OverrunStyle.CENTER_ELLIPSIS));
|
name.apply(struc -> struc.get().setTextOverrun(OverrunStyle.CENTER_ELLIPSIS))
|
||||||
|
.apply(struc -> struc.get().setPadding(new Insets(5, 5, 5, 0)));
|
||||||
|
name.apply(s -> AppFont.header(s.get()));
|
||||||
name.styleClass("name");
|
name.styleClass("name");
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Node createIcon(int w, int h) {
|
protected Node createIcon(int w, int h) {
|
||||||
var img = getWrapper().disabledProperty().get()
|
var img = wrapper.disabledProperty().get()
|
||||||
? "disabled_icon.png"
|
? "disabled_icon.png"
|
||||||
: getWrapper().getEntry()
|
: wrapper.getEntry()
|
||||||
.getProvider()
|
.getProvider()
|
||||||
.getDisplayIconFileName(getWrapper().getEntry().getStore());
|
.getDisplayIconFileName(wrapper.getEntry().getStore());
|
||||||
var imageComp = PrettyImageHelper.ofFixedSize(img, w, h);
|
var imageComp = PrettyImageHelper.ofFixedSize(img, w, h);
|
||||||
var storeIcon = imageComp.createRegion();
|
var storeIcon = imageComp.createRegion();
|
||||||
if (getWrapper().getValidity().getValue().isUsable()) {
|
if (wrapper.getValidity().getValue().isUsable()) {
|
||||||
new TooltipAugment<>(getWrapper().getEntry().getProvider().displayName(), null).augment(storeIcon);
|
new TooltipAugment<>(wrapper.getEntry().getProvider().displayName(), null).augment(storeIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
var stack = new StackPane(storeIcon);
|
var stack = new StackPane(storeIcon);
|
||||||
|
@ -222,7 +220,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Region createButtonBar() {
|
protected Region createButtonBar() {
|
||||||
var list = new DerivedObservableList<>(getWrapper().getActionProviders(), false);
|
var list = new DerivedObservableList<>(wrapper.getActionProviders(), false);
|
||||||
var buttons = list.mapped(actionProvider -> {
|
var buttons = list.mapped(actionProvider -> {
|
||||||
var button = buildButton(actionProvider);
|
var button = buildButton(actionProvider);
|
||||||
return button != null ? button.createRegion() : null;
|
return button != null ? button.createRegion() : null;
|
||||||
|
@ -241,8 +239,8 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
buttons.subscribe(update);
|
buttons.subscribe(update);
|
||||||
update.run();
|
update.run();
|
||||||
ig.setAlignment(Pos.CENTER_RIGHT);
|
ig.setAlignment(Pos.CENTER_RIGHT);
|
||||||
|
ig.setPadding(new Insets(5));
|
||||||
ig.getStyleClass().add("button-bar");
|
ig.getStyleClass().add("button-bar");
|
||||||
AppFont.medium(ig);
|
|
||||||
return ig;
|
return ig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,17 +249,17 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
var branch = p.getBranchDataStoreCallSite();
|
var branch = p.getBranchDataStoreCallSite();
|
||||||
var cs = leaf != null ? leaf : branch;
|
var cs = leaf != null ? leaf : branch;
|
||||||
|
|
||||||
if (cs == null || !cs.isMajor(getWrapper().getEntry().ref())) {
|
if (cs == null || !cs.isMajor(wrapper.getEntry().ref())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var button = new IconButtonComp(
|
var button = new IconButtonComp(
|
||||||
cs.getIcon(getWrapper().getEntry().ref()),
|
cs.getIcon(wrapper.getEntry().ref()),
|
||||||
leaf != null
|
leaf != null
|
||||||
? () -> {
|
? () -> {
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
getWrapper().runAction(
|
wrapper.runAction(
|
||||||
leaf.createAction(getWrapper().getEntry().ref()), leaf.showBusy());
|
leaf.createAction(wrapper.getEntry().ref()), leaf.showBusy());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
: null);
|
: null);
|
||||||
|
@ -278,8 +276,8 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
return cm;
|
return cm;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
button.accessibleText(cs.getName(getWrapper().getEntry().ref()).getValue());
|
button.accessibleText(cs.getName(wrapper.getEntry().ref()).getValue());
|
||||||
button.apply(new TooltipAugment<>(cs.getName(getWrapper().getEntry().ref()), null));
|
button.apply(new TooltipAugment<>(cs.getName(wrapper.getEntry().ref()), null));
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +298,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
AppFont.normal(contextMenu.getStyleableNode());
|
AppFont.normal(contextMenu.getStyleableNode());
|
||||||
|
|
||||||
var hasSep = false;
|
var hasSep = false;
|
||||||
for (var p : getWrapper().getActionProviders()) {
|
for (var p : wrapper.getActionProviders()) {
|
||||||
var item = buildMenuItemForAction(p);
|
var item = buildMenuItemForAction(p);
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -323,36 +321,36 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
|
|
||||||
var notes = new MenuItem(AppI18n.get("addNotes"), new FontIcon("mdi2n-note-text"));
|
var notes = new MenuItem(AppI18n.get("addNotes"), new FontIcon("mdi2n-note-text"));
|
||||||
notes.setOnAction(event -> {
|
notes.setOnAction(event -> {
|
||||||
getWrapper().getNotes().setValue(new StoreNotes(null, getDefaultNotes()));
|
wrapper.getNotes().setValue(new StoreNotes(null, getDefaultNotes()));
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
notes.visibleProperty().bind(BindingsHelper.map(getWrapper().getNotes(), s -> s.getCommited() == null));
|
notes.visibleProperty().bind(BindingsHelper.map(wrapper.getNotes(), s -> s.getCommited() == null));
|
||||||
contextMenu.getItems().add(notes);
|
contextMenu.getItems().add(notes);
|
||||||
|
|
||||||
if (AppPrefs.get().developerMode().getValue()) {
|
if (AppPrefs.get().developerMode().getValue()) {
|
||||||
var browse = new MenuItem(AppI18n.get("browseInternalStorage"), new FontIcon("mdi2f-folder-open-outline"));
|
var browse = new MenuItem(AppI18n.get("browseInternalStorage"), new FontIcon("mdi2f-folder-open-outline"));
|
||||||
browse.setOnAction(
|
browse.setOnAction(
|
||||||
event -> DesktopHelper.browsePathLocal(getWrapper().getEntry().getDirectory()));
|
event -> DesktopHelper.browsePathLocal(wrapper.getEntry().getDirectory()));
|
||||||
contextMenu.getItems().add(browse);
|
contextMenu.getItems().add(browse);
|
||||||
|
|
||||||
var copyId = new MenuItem(AppI18n.get("copyId"), new FontIcon("mdi2c-content-copy"));
|
var copyId = new MenuItem(AppI18n.get("copyId"), new FontIcon("mdi2c-content-copy"));
|
||||||
copyId.setOnAction(event ->
|
copyId.setOnAction(event ->
|
||||||
ClipboardHelper.copyText(getWrapper().getEntry().getUuid().toString()));
|
ClipboardHelper.copyText(wrapper.getEntry().getUuid().toString()));
|
||||||
contextMenu.getItems().add(copyId);
|
contextMenu.getItems().add(copyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DataStorage.get().isRootEntry(getWrapper().getEntry())) {
|
if (DataStorage.get().isRootEntry(wrapper.getEntry())) {
|
||||||
var color = new Menu(AppI18n.get("color"), new FontIcon("mdi2f-format-color-fill"));
|
var color = new Menu(AppI18n.get("color"), new FontIcon("mdi2f-format-color-fill"));
|
||||||
var none = new MenuItem("None");
|
var none = new MenuItem("None");
|
||||||
none.setOnAction(event -> {
|
none.setOnAction(event -> {
|
||||||
getWrapper().getEntry().setColor(null);
|
wrapper.getEntry().setColor(null);
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
color.getItems().add(none);
|
color.getItems().add(none);
|
||||||
Arrays.stream(DataStoreColor.values()).forEach(dataStoreColor -> {
|
Arrays.stream(DataStoreColor.values()).forEach(dataStoreColor -> {
|
||||||
MenuItem m = new MenuItem(DataStoreFormatter.capitalize(dataStoreColor.getId()));
|
MenuItem m = new MenuItem(DataStoreFormatter.capitalize(dataStoreColor.getId()));
|
||||||
m.setOnAction(event -> {
|
m.setOnAction(event -> {
|
||||||
getWrapper().getEntry().setColor(dataStoreColor);
|
wrapper.getEntry().setColor(dataStoreColor);
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
color.getItems().add(m);
|
color.getItems().add(m);
|
||||||
|
@ -360,10 +358,10 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
contextMenu.getItems().add(color);
|
contextMenu.getItems().add(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getWrapper().getEntry().getProvider() != null) {
|
if (wrapper.getEntry().getProvider() != null) {
|
||||||
var move = new Menu(AppI18n.get("moveTo"), new FontIcon("mdi2f-folder-move-outline"));
|
var move = new Menu(AppI18n.get("moveTo"), new FontIcon("mdi2f-folder-move-outline"));
|
||||||
StoreViewState.get()
|
StoreViewState.get()
|
||||||
.getSortedCategories(getWrapper().getCategory().getValue().getRoot())
|
.getSortedCategories(wrapper.getCategory().getValue().getRoot())
|
||||||
.getList()
|
.getList()
|
||||||
.forEach(storeCategoryWrapper -> {
|
.forEach(storeCategoryWrapper -> {
|
||||||
MenuItem m = new MenuItem();
|
MenuItem m = new MenuItem();
|
||||||
|
@ -371,12 +369,12 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
.setValue(" ".repeat(storeCategoryWrapper.getDepth())
|
.setValue(" ".repeat(storeCategoryWrapper.getDepth())
|
||||||
+ storeCategoryWrapper.getName().getValue());
|
+ storeCategoryWrapper.getName().getValue());
|
||||||
m.setOnAction(event -> {
|
m.setOnAction(event -> {
|
||||||
getWrapper().moveTo(storeCategoryWrapper.getCategory());
|
wrapper.moveTo(storeCategoryWrapper.getCategory());
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
if (storeCategoryWrapper.getParent() == null
|
if (storeCategoryWrapper.getParent() == null
|
||||||
|| storeCategoryWrapper.equals(
|
|| storeCategoryWrapper.equals(
|
||||||
getWrapper().getCategory().getValue())) {
|
wrapper.getCategory().getValue())) {
|
||||||
m.setDisable(true);
|
m.setDisable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,10 +386,10 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
var order = new Menu(AppI18n.get("order"), new FontIcon("mdal-bookmarks"));
|
var order = new Menu(AppI18n.get("order"), new FontIcon("mdal-bookmarks"));
|
||||||
var noOrder = new MenuItem(AppI18n.get("none"), new FontIcon("mdi2r-reorder-horizontal"));
|
var noOrder = new MenuItem(AppI18n.get("none"), new FontIcon("mdi2r-reorder-horizontal"));
|
||||||
noOrder.setOnAction(event -> {
|
noOrder.setOnAction(event -> {
|
||||||
getWrapper().setOrder(null);
|
wrapper.setOrder(null);
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
if (getWrapper().getEntry().getExplicitOrder() == null) {
|
if (wrapper.getEntry().getExplicitOrder() == null) {
|
||||||
noOrder.setDisable(true);
|
noOrder.setDisable(true);
|
||||||
}
|
}
|
||||||
order.getItems().add(noOrder);
|
order.getItems().add(noOrder);
|
||||||
|
@ -399,20 +397,20 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
|
|
||||||
var top = new MenuItem(AppI18n.get("stickToTop"), new FontIcon("mdi2o-order-bool-descending"));
|
var top = new MenuItem(AppI18n.get("stickToTop"), new FontIcon("mdi2o-order-bool-descending"));
|
||||||
top.setOnAction(event -> {
|
top.setOnAction(event -> {
|
||||||
getWrapper().setOrder(DataStoreEntry.Order.TOP);
|
wrapper.setOrder(DataStoreEntry.Order.TOP);
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
if (DataStoreEntry.Order.TOP.equals(getWrapper().getEntry().getExplicitOrder())) {
|
if (DataStoreEntry.Order.TOP.equals(wrapper.getEntry().getExplicitOrder())) {
|
||||||
top.setDisable(true);
|
top.setDisable(true);
|
||||||
}
|
}
|
||||||
order.getItems().add(top);
|
order.getItems().add(top);
|
||||||
|
|
||||||
var bottom = new MenuItem(AppI18n.get("stickToBottom"), new FontIcon("mdi2o-order-bool-ascending"));
|
var bottom = new MenuItem(AppI18n.get("stickToBottom"), new FontIcon("mdi2o-order-bool-ascending"));
|
||||||
bottom.setOnAction(event -> {
|
bottom.setOnAction(event -> {
|
||||||
getWrapper().setOrder(DataStoreEntry.Order.BOTTOM);
|
wrapper.setOrder(DataStoreEntry.Order.BOTTOM);
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
if (DataStoreEntry.Order.BOTTOM.equals(getWrapper().getEntry().getExplicitOrder())) {
|
if (DataStoreEntry.Order.BOTTOM.equals(wrapper.getEntry().getExplicitOrder())) {
|
||||||
bottom.setDisable(true);
|
bottom.setDisable(true);
|
||||||
}
|
}
|
||||||
order.getItems().add(bottom);
|
order.getItems().add(bottom);
|
||||||
|
@ -425,14 +423,14 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
del.disableProperty()
|
del.disableProperty()
|
||||||
.bind(Bindings.createBooleanBinding(
|
.bind(Bindings.createBooleanBinding(
|
||||||
() -> {
|
() -> {
|
||||||
return !getWrapper().getDeletable().get()
|
return !wrapper.getDeletable().get()
|
||||||
&& !AppPrefs.get()
|
&& !AppPrefs.get()
|
||||||
.developerDisableGuiRestrictions()
|
.developerDisableGuiRestrictions()
|
||||||
.get();
|
.get();
|
||||||
},
|
},
|
||||||
getWrapper().getDeletable(),
|
wrapper.getDeletable(),
|
||||||
AppPrefs.get().developerDisableGuiRestrictions()));
|
AppPrefs.get().developerDisableGuiRestrictions()));
|
||||||
del.setOnAction(event -> getWrapper().delete());
|
del.setOnAction(event -> wrapper.delete());
|
||||||
contextMenu.getItems().add(del);
|
contextMenu.getItems().add(del);
|
||||||
|
|
||||||
return contextMenu;
|
return contextMenu;
|
||||||
|
@ -443,12 +441,12 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
var branch = p.getBranchDataStoreCallSite();
|
var branch = p.getBranchDataStoreCallSite();
|
||||||
var cs = leaf != null ? leaf : branch;
|
var cs = leaf != null ? leaf : branch;
|
||||||
|
|
||||||
if (cs == null || cs.isMajor(getWrapper().getEntry().ref())) {
|
if (cs == null || cs.isMajor(wrapper.getEntry().ref())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var name = cs.getName(getWrapper().getEntry().ref());
|
var name = cs.getName(wrapper.getEntry().ref());
|
||||||
var icon = cs.getIcon(getWrapper().getEntry().ref());
|
var icon = cs.getIcon(wrapper.getEntry().ref());
|
||||||
var item = (leaf != null && leaf.canLinkTo()) || branch != null
|
var item = (leaf != null && leaf.canLinkTo()) || branch != null
|
||||||
? new Menu(null, new FontIcon(icon))
|
? new Menu(null, new FontIcon(icon))
|
||||||
: new MenuItem(null, new FontIcon(icon));
|
: new MenuItem(null, new FontIcon(icon));
|
||||||
|
@ -474,21 +472,21 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
run.textProperty().bind(AppI18n.observable("base.execute"));
|
run.textProperty().bind(AppI18n.observable("base.execute"));
|
||||||
run.setOnAction(event -> {
|
run.setOnAction(event -> {
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
getWrapper().runAction(leaf.createAction(getWrapper().getEntry().ref()), leaf.showBusy());
|
wrapper.runAction(leaf.createAction(wrapper.getEntry().ref()), leaf.showBusy());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
menu.getItems().add(run);
|
menu.getItems().add(run);
|
||||||
|
|
||||||
var sc = new MenuItem(null, new FontIcon("mdi2c-code-greater-than"));
|
var sc = new MenuItem(null, new FontIcon("mdi2c-code-greater-than"));
|
||||||
var url = "xpipe://action/" + p.getId() + "/" + getWrapper().getEntry().getUuid();
|
var url = "xpipe://action/" + p.getId() + "/" + wrapper.getEntry().getUuid();
|
||||||
sc.textProperty().bind(AppI18n.observable("base.createShortcut"));
|
sc.textProperty().bind(AppI18n.observable("base.createShortcut"));
|
||||||
sc.setOnAction(event -> {
|
sc.setOnAction(event -> {
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
DesktopShortcuts.create(
|
DesktopShortcuts.create(
|
||||||
url,
|
url,
|
||||||
getWrapper().nameProperty().getValue() + " ("
|
wrapper.nameProperty().getValue() + " ("
|
||||||
+ p.getLeafDataStoreCallSite()
|
+ p.getLeafDataStoreCallSite()
|
||||||
.getName(getWrapper().getEntry().ref())
|
.getName(wrapper.getEntry().ref())
|
||||||
.getValue() + ")");
|
.getValue() + ")");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -518,7 +516,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
|
|
||||||
event.consume();
|
event.consume();
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
getWrapper().runAction(leaf.createAction(getWrapper().getEntry().ref()), leaf.showBusy());
|
wrapper.runAction(leaf.createAction(wrapper.getEntry().ref()), leaf.showBusy());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.app.core.window;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
|
|
||||||
import javafx.animation.PauseTransition;
|
import javafx.animation.PauseTransition;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
|
@ -12,6 +13,8 @@ import javafx.stage.Stage;
|
||||||
import javafx.stage.StageStyle;
|
import javafx.stage.StageStyle;
|
||||||
import javafx.stage.Window;
|
import javafx.stage.Window;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
|
||||||
public class ModifiedStage extends Stage {
|
public class ModifiedStage extends Stage {
|
||||||
|
@ -20,8 +23,12 @@ public class ModifiedStage extends Stage {
|
||||||
return SystemUtils.IS_OS_WINDOWS_11;
|
return SystemUtils.IS_OS_WINDOWS_11;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static void init() {
|
public static void init() {
|
||||||
ObservableList<Window> list = Window.getWindows();
|
var windowsField = Window.class.getDeclaredField("windows");
|
||||||
|
windowsField.setAccessible(true);
|
||||||
|
ObservableList<Window> list = (ObservableList<Window>) windowsField.get(null);
|
||||||
list.addListener((ListChangeListener<Window>) c -> {
|
list.addListener((ListChangeListener<Window>) c -> {
|
||||||
if (c.next() && c.wasAdded()) {
|
if (c.next() && c.wasAdded()) {
|
||||||
var added = c.getAddedSubList().getFirst();
|
var added = c.getAddedSubList().getFirst();
|
||||||
|
|
|
@ -31,8 +31,6 @@ public interface DataStoreProvider {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
default void onParentRefresh(DataStoreEntry entry) {}
|
|
||||||
|
|
||||||
default void onChildrenRefresh(DataStoreEntry entry) {}
|
default void onChildrenRefresh(DataStoreEntry entry) {}
|
||||||
|
|
||||||
default ObservableBooleanValue busy(StoreEntryWrapper wrapper) {
|
default ObservableBooleanValue busy(StoreEntryWrapper wrapper) {
|
||||||
|
@ -87,7 +85,7 @@ public interface DataStoreProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
default StoreEntryComp customEntryComp(StoreSection s, boolean preferLarge) {
|
default StoreEntryComp customEntryComp(StoreSection s, boolean preferLarge) {
|
||||||
return StoreEntryComp.create(s, null, preferLarge);
|
return StoreEntryComp.create(s.getWrapper(), null, preferLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
default StoreSectionComp customSectionComp(StoreSection section, boolean topLevel) {
|
default StoreSectionComp customSectionComp(StoreSection section, boolean topLevel) {
|
||||||
|
@ -193,7 +191,7 @@ public interface DataStoreProvider {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default ObservableValue<String> informationString(StoreSection section) {
|
default ObservableValue<String> informationString(StoreEntryWrapper wrapper) {
|
||||||
return new SimpleStringProperty(null);
|
return new SimpleStringProperty(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public interface EnabledParentStoreProvider extends DataStoreProvider {
|
||||||
@Override
|
@Override
|
||||||
default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
||||||
return StoreEntryComp.create(sec, null, preferLarge);
|
return StoreEntryComp.create(sec.getWrapper(), null, preferLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
var enabled = StoreToggleComp.<StatefulDataStore<EnabledStoreState>>enableToggle(
|
var enabled = StoreToggleComp.<StatefulDataStore<EnabledStoreState>>enableToggle(
|
||||||
|
@ -35,6 +35,6 @@ public interface EnabledParentStoreProvider extends DataStoreProvider {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return StoreEntryComp.create(sec, enabled, preferLarge);
|
return StoreEntryComp.create(sec.getWrapper(), enabled, preferLarge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ public interface EnabledStoreProvider extends DataStoreProvider {
|
||||||
@Override
|
@Override
|
||||||
default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
||||||
return StoreEntryComp.create(sec, null, preferLarge);
|
return StoreEntryComp.create(sec.getWrapper(), null, preferLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
var enabled = StoreToggleComp.<StatefulDataStore<EnabledStoreState>>enableToggle(
|
var enabled = StoreToggleComp.<StatefulDataStore<EnabledStoreState>>enableToggle(
|
||||||
|
@ -20,6 +20,6 @@ public interface EnabledStoreProvider extends DataStoreProvider {
|
||||||
var state = s.getState().toBuilder().enabled(aBoolean).build();
|
var state = s.getState().toBuilder().enabled(aBoolean).build();
|
||||||
s.setState(state);
|
s.setState(state);
|
||||||
});
|
});
|
||||||
return StoreEntryComp.create(sec, enabled, preferLarge);
|
return StoreEntryComp.create(sec.getWrapper(), enabled, preferLarge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ public interface SingletonSessionStoreProvider extends DataStoreProvider {
|
||||||
@Override
|
@Override
|
||||||
default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
var t = createToggleComp(sec);
|
var t = createToggleComp(sec);
|
||||||
return StoreEntryComp.create(sec, t, preferLarge);
|
return StoreEntryComp.create(sec.getWrapper(), t, preferLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
default StoreToggleComp createToggleComp(StoreSection sec) {
|
default StoreToggleComp createToggleComp(StoreSection sec) {
|
||||||
|
|
|
@ -10,7 +10,9 @@ import io.xpipe.core.store.FixedChildStore;
|
||||||
import io.xpipe.core.store.LocalStore;
|
import io.xpipe.core.store.LocalStore;
|
||||||
import io.xpipe.core.store.StorePath;
|
import io.xpipe.core.store.StorePath;
|
||||||
import io.xpipe.core.util.UuidHelper;
|
import io.xpipe.core.util.UuidHelper;
|
||||||
|
|
||||||
import javafx.util.Pair;
|
import javafx.util.Pair;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
@ -343,14 +345,14 @@ public abstract class DataStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean refreshChildren(DataStoreEntry e, boolean throwOnFail) throws Exception {
|
public boolean refreshChildren(DataStoreEntry e, boolean throwOnFail) throws Exception {
|
||||||
if (!(e.getStore() instanceof FixedHierarchyStore h)) {
|
if (!(e.getStore() instanceof FixedHierarchyStore)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.incrementBusyCounter();
|
e.incrementBusyCounter();
|
||||||
List<? extends DataStoreEntryRef<? extends FixedChildStore>> newChildren;
|
List<? extends DataStoreEntryRef<? extends FixedChildStore>> newChildren;
|
||||||
try {
|
try {
|
||||||
newChildren = h.listChildren(e).stream().filter(dataStoreEntryRef -> dataStoreEntryRef != null && dataStoreEntryRef.get() != null).toList();
|
newChildren = ((FixedHierarchyStore) (e.getStore())).listChildren(e).stream().filter(dataStoreEntryRef -> dataStoreEntryRef != null && dataStoreEntryRef.get() != null).toList();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
if (throwOnFail) {
|
if (throwOnFail) {
|
||||||
throw ex;
|
throw ex;
|
||||||
|
@ -366,10 +368,6 @@ public abstract class DataStorage {
|
||||||
var toRemove = oldChildren.stream()
|
var toRemove = oldChildren.stream()
|
||||||
.filter(oc -> oc.getStore() instanceof FixedChildStore)
|
.filter(oc -> oc.getStore() instanceof FixedChildStore)
|
||||||
.filter(oc -> {
|
.filter(oc -> {
|
||||||
if (!oc.getValidity().isUsable()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var oid = ((FixedChildStore) oc.getStore()).getFixedId();
|
var oid = ((FixedChildStore) oc.getStore()).getFixedId();
|
||||||
if (oid.isEmpty()) {
|
if (oid.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -396,7 +394,6 @@ public abstract class DataStorage {
|
||||||
|
|
||||||
return oldChildren.stream()
|
return oldChildren.stream()
|
||||||
.filter(oc -> oc.getStore() instanceof FixedChildStore)
|
.filter(oc -> oc.getStore() instanceof FixedChildStore)
|
||||||
.filter(oc -> oc.getValidity().isUsable())
|
|
||||||
.filter(oc -> ((FixedChildStore) oc.getStore())
|
.filter(oc -> ((FixedChildStore) oc.getStore())
|
||||||
.getFixedId()
|
.getFixedId()
|
||||||
.isPresent())
|
.isPresent())
|
||||||
|
@ -410,7 +407,6 @@ public abstract class DataStorage {
|
||||||
.toList();
|
.toList();
|
||||||
var toUpdate = oldChildren.stream()
|
var toUpdate = oldChildren.stream()
|
||||||
.filter(oc -> oc.getStore() instanceof FixedChildStore)
|
.filter(oc -> oc.getStore() instanceof FixedChildStore)
|
||||||
.filter(oc -> oc.getValidity().isUsable())
|
|
||||||
.map(oc -> {
|
.map(oc -> {
|
||||||
var oid = ((FixedChildStore) oc.getStore()).getFixedId();
|
var oid = ((FixedChildStore) oc.getStore()).getFixedId();
|
||||||
if (oid.isEmpty()) {
|
if (oid.isEmpty()) {
|
||||||
|
@ -464,11 +460,10 @@ public abstract class DataStorage {
|
||||||
});
|
});
|
||||||
refreshEntries();
|
refreshEntries();
|
||||||
saveAsync();
|
saveAsync();
|
||||||
e.getProvider().onChildrenRefresh(e);
|
|
||||||
toAdd.forEach(dataStoreEntryRef ->
|
toAdd.forEach(dataStoreEntryRef ->
|
||||||
dataStoreEntryRef.get().getProvider().onParentRefresh(dataStoreEntryRef.getEntry()));
|
dataStoreEntryRef.get().getProvider().onChildrenRefresh(dataStoreEntryRef.getEntry()));
|
||||||
toUpdate.forEach(dataStoreEntryRef ->
|
toUpdate.forEach(dataStoreEntryRef ->
|
||||||
dataStoreEntryRef.getKey().getProvider().onParentRefresh(dataStoreEntryRef.getKey()));
|
dataStoreEntryRef.getKey().getProvider().onChildrenRefresh(dataStoreEntryRef.getKey()));
|
||||||
return !newChildren.isEmpty();
|
return !newChildren.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,11 @@ public abstract class UpdateHandler {
|
||||||
preparedUpdate.setValue(null);
|
preparedUpdate.setValue(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if file has been deleted
|
||||||
|
if (preparedUpdate.getValue() != null && preparedUpdate.getValue().getFile() != null && !Files.exists(preparedUpdate.getValue().getFile())) {
|
||||||
|
preparedUpdate.setValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
preparedUpdate.addListener((c, o, n) -> {
|
preparedUpdate.addListener((c, o, n) -> {
|
||||||
AppCache.update("preparedUpdate", n);
|
AppCache.update("preparedUpdate", n);
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,14 +37,6 @@
|
||||||
-fx-opacity: 0.5;
|
-fx-opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-entry-grid .name {
|
|
||||||
-fx-padding: 2 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-entry-grid.dense .name {
|
|
||||||
-fx-padding: 0 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-entry-grid .icon {
|
.store-entry-grid .icon {
|
||||||
-fx-background-color: -color-bg-overlay;
|
-fx-background-color: -color-bg-overlay;
|
||||||
-fx-background-radius: 5px;
|
-fx-background-radius: 5px;
|
||||||
|
@ -98,14 +90,6 @@
|
||||||
-fx-opacity: 0.2;
|
-fx-opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-entry-comp .button-bar {
|
|
||||||
-fx-padding: 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-entry-grid.dense .button-bar {
|
|
||||||
-fx-padding: 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.store-entry-comp .button-bar .button {
|
.store-entry-comp .button-bar .button {
|
||||||
-fx-padding: 6px;
|
-fx-padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-switch:has-graphic {
|
.toggle-switch:has-graphic {
|
||||||
-fx-font-size: 0.75em;
|
-fx-font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-layout .split-pane-divider {
|
.store-layout .split-pane-divider {
|
||||||
|
|
3
dist/changelogs/10.1.1_incremental.md
vendored
Normal file
3
dist/changelogs/10.1.1_incremental.md
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
- Fix terminal window closing instantly if connection failed, not showing error messages
|
||||||
|
- Fix file browser editor sometimes not applying changes
|
||||||
|
- Fix various smaller bugs
|
1
dist/changelogs/10.2_incremental.md
vendored
1
dist/changelogs/10.2_incremental.md
vendored
|
@ -1 +0,0 @@
|
||||||
- Rework UI sizing to allow more content to be shown
|
|
|
@ -2,7 +2,6 @@ package io.xpipe.ext.base.script;
|
||||||
|
|
||||||
import io.xpipe.app.comp.base.SystemStateComp;
|
import io.xpipe.app.comp.base.SystemStateComp;
|
||||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
|
||||||
import io.xpipe.app.comp.store.StoreViewState;
|
import io.xpipe.app.comp.store.StoreViewState;
|
||||||
import io.xpipe.app.ext.*;
|
import io.xpipe.app.ext.*;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
|
@ -77,8 +76,8 @@ public class ScriptGroupStoreProvider implements EnabledStoreProvider, DataStore
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObservableValue<String> informationString(StoreSection section) {
|
public ObservableValue<String> informationString(StoreEntryWrapper wrapper) {
|
||||||
ScriptGroupStore scriptStore = section.getWrapper().getEntry().getStore().asNeeded();
|
ScriptGroupStore scriptStore = wrapper.getEntry().getStore().asNeeded();
|
||||||
return new SimpleStringProperty(scriptStore.getDescription());
|
return new SimpleStringProperty(scriptStore.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import io.xpipe.app.comp.base.IntegratedTextAreaComp;
|
||||||
import io.xpipe.app.comp.base.ListSelectorComp;
|
import io.xpipe.app.comp.base.ListSelectorComp;
|
||||||
import io.xpipe.app.comp.base.SystemStateComp;
|
import io.xpipe.app.comp.base.SystemStateComp;
|
||||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
|
||||||
import io.xpipe.app.comp.store.StoreViewState;
|
import io.xpipe.app.comp.store.StoreViewState;
|
||||||
import io.xpipe.app.core.AppExtensionManager;
|
import io.xpipe.app.core.AppExtensionManager;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
|
@ -207,8 +206,8 @@ public class SimpleScriptStoreProvider implements EnabledParentStoreProvider, Da
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObservableValue<String> informationString(StoreSection section) {
|
public ObservableValue<String> informationString(StoreEntryWrapper wrapper) {
|
||||||
SimpleScriptStore scriptStore = section.getWrapper().getEntry().getStore().asNeeded();
|
SimpleScriptStore scriptStore = wrapper.getEntry().getStore().asNeeded();
|
||||||
return new SimpleStringProperty((scriptStore.getMinimumDialect() != null
|
return new SimpleStringProperty((scriptStore.getMinimumDialect() != null
|
||||||
? scriptStore.getMinimumDialect().getDisplayName() + " "
|
? scriptStore.getMinimumDialect().getDisplayName() + " "
|
||||||
: "")
|
: "")
|
||||||
|
|
|
@ -6,11 +6,9 @@ import io.xpipe.app.comp.store.StoreEntryComp;
|
||||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
import io.xpipe.app.comp.store.StoreSection;
|
||||||
import io.xpipe.app.comp.store.StoreViewState;
|
import io.xpipe.app.comp.store.StoreViewState;
|
||||||
import io.xpipe.app.core.AppI18n;
|
|
||||||
import io.xpipe.app.ext.DataStoreProvider;
|
import io.xpipe.app.ext.DataStoreProvider;
|
||||||
import io.xpipe.app.ext.DataStoreUsageCategory;
|
import io.xpipe.app.ext.DataStoreUsageCategory;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
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.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
|
@ -18,7 +16,6 @@ import io.xpipe.core.store.DataStore;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
|
|
||||||
public abstract class AbstractServiceGroupStoreProvider implements DataStoreProvider {
|
public abstract class AbstractServiceGroupStoreProvider implements DataStoreProvider {
|
||||||
|
|
||||||
|
@ -30,7 +27,7 @@ public abstract class AbstractServiceGroupStoreProvider implements DataStoreProv
|
||||||
@Override
|
@Override
|
||||||
public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
var t = createToggleComp(sec);
|
var t = createToggleComp(sec);
|
||||||
return StoreEntryComp.create(sec, t, preferLarge);
|
return StoreEntryComp.create(sec.getWrapper(), t, preferLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StoreToggleComp createToggleComp(StoreSection sec) {
|
private StoreToggleComp createToggleComp(StoreSection sec) {
|
||||||
|
@ -65,16 +62,6 @@ public abstract class AbstractServiceGroupStoreProvider implements DataStoreProv
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ObservableValue<String> informationString(StoreSection section) {
|
|
||||||
return Bindings.createStringBinding(() -> {
|
|
||||||
var all = section.getAllChildren().getList();
|
|
||||||
var shown = section.getShownChildren().getList();
|
|
||||||
var string = all.size() == shown.size() ? all.size() : shown.size() + "/" + all.size();
|
|
||||||
return all.size() > 0 ? (all.size() == 1 ? AppI18n.get("hasService", string) : AppI18n.get("hasServices", string)) : AppI18n.get("noServices");
|
|
||||||
}, section.getShownChildren().getList(), section.getAllChildren().getList(), AppPrefs.get().language());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comp<?> stateDisplay(StoreEntryWrapper w) {
|
public Comp<?> stateDisplay(StoreEntryWrapper w) {
|
||||||
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
|
return new SystemStateComp(new SimpleObjectProperty<>(SystemStateComp.State.SUCCESS));
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package io.xpipe.ext.base.service;
|
package io.xpipe.ext.base.service;
|
||||||
|
|
||||||
import io.xpipe.app.comp.base.SystemStateComp;
|
import io.xpipe.app.comp.base.SystemStateComp;
|
||||||
import io.xpipe.app.comp.store.DenseStoreEntryComp;
|
|
||||||
import io.xpipe.app.comp.store.StoreEntryComp;
|
import io.xpipe.app.comp.store.StoreEntryComp;
|
||||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
import io.xpipe.app.comp.store.StoreSection;
|
||||||
|
@ -81,7 +80,7 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
sec.getWrapper().getCache()));
|
sec.getWrapper().getCache()));
|
||||||
return new DenseStoreEntryComp(sec, true, toggle);
|
return StoreEntryComp.create(sec.getWrapper(), toggle, preferLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,8 +98,8 @@ public abstract class AbstractServiceStoreProvider implements SingletonSessionSt
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObservableValue<String> informationString(StoreSection section) {
|
public ObservableValue<String> informationString(StoreEntryWrapper wrapper) {
|
||||||
AbstractServiceStore s = section.getWrapper().getEntry().getStore().asNeeded();
|
AbstractServiceStore s = wrapper.getEntry().getStore().asNeeded();
|
||||||
if (s.getLocalPort() != null) {
|
if (s.getLocalPort() != null) {
|
||||||
return new SimpleStringProperty("Port " + s.getLocalPort() + " <- " + s.getRemotePort());
|
return new SimpleStringProperty("Port " + s.getLocalPort() + " <- " + s.getRemotePort());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package io.xpipe.ext.base.service;
|
package io.xpipe.ext.base.service;
|
||||||
|
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.storage.DataStoreEntry;
|
import io.xpipe.app.storage.DataStoreEntry;
|
||||||
|
|
||||||
|
@ -29,8 +29,8 @@ public class FixedServiceStoreProvider extends AbstractServiceStoreProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObservableValue<String> informationString(StoreSection section) {
|
public ObservableValue<String> informationString(StoreEntryWrapper wrapper) {
|
||||||
FixedServiceStore s = section.getWrapper().getEntry().getStore().asNeeded();
|
FixedServiceStore s = wrapper.getEntry().getStore().asNeeded();
|
||||||
return new SimpleStringProperty("Port " + s.getRemotePort());
|
return new SimpleStringProperty("Port " + s.getRemotePort());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.xpipe.ext.base.service;
|
package io.xpipe.ext.base.service;
|
||||||
|
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
|
||||||
|
@ -14,9 +15,9 @@ public class MappedServiceStoreProvider extends FixedServiceStoreProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObservableValue<String> informationString(StoreSection section) {
|
public ObservableValue<String> informationString(StoreEntryWrapper wrapper) {
|
||||||
MappedServiceStore s = section.getWrapper().getEntry().getStore().asNeeded();
|
MappedServiceStore s = wrapper.getEntry().getStore().asNeeded();
|
||||||
return new SimpleStringProperty("Port " + s.getRemotePort() + " -> " + s.getContainerPort());
|
return new SimpleStringProperty("Port " + s.getContainerPort() + " -> " + s.getRemotePort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
|
@ -167,6 +167,3 @@ customService.displayName=Service
|
||||||
customService.displayDescription=Tilføj en brugerdefineret tjeneste til tunnel og åben
|
customService.displayDescription=Tilføj en brugerdefineret tjeneste til tunnel og åben
|
||||||
fixedService.displayName=Service
|
fixedService.displayName=Service
|
||||||
fixedService.displayDescription=Brug en foruddefineret tjeneste
|
fixedService.displayDescription=Brug en foruddefineret tjeneste
|
||||||
noServices=Ingen tilgængelige tjenester
|
|
||||||
hasServices=$COUNT$ tilgængelige tjenester
|
|
||||||
hasService=$COUNT$ tilgængelig tjeneste
|
|
||||||
|
|
|
@ -158,6 +158,3 @@ customService.displayName=Dienst
|
||||||
customService.displayDescription=Einen benutzerdefinierten Dienst zum Tunnel hinzufügen und öffnen
|
customService.displayDescription=Einen benutzerdefinierten Dienst zum Tunnel hinzufügen und öffnen
|
||||||
fixedService.displayName=Dienst
|
fixedService.displayName=Dienst
|
||||||
fixedService.displayDescription=Einen vordefinierten Dienst verwenden
|
fixedService.displayDescription=Einen vordefinierten Dienst verwenden
|
||||||
noServices=Keine verfügbaren Dienste
|
|
||||||
hasServices=$COUNT$ verfügbare Dienste
|
|
||||||
hasService=$COUNT$ verfügbarer Dienst
|
|
||||||
|
|
|
@ -156,8 +156,5 @@ customService.displayName=Service
|
||||||
customService.displayDescription=Add a custom service to tunnel and open
|
customService.displayDescription=Add a custom service to tunnel and open
|
||||||
fixedService.displayName=Service
|
fixedService.displayName=Service
|
||||||
fixedService.displayDescription=Use a predefined service
|
fixedService.displayDescription=Use a predefined service
|
||||||
noServices=No available services
|
|
||||||
hasServices=$COUNT$ available services
|
|
||||||
hasService=$COUNT$ available service
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=Servicio
|
||||||
customService.displayDescription=Añade un servicio personalizado para tunelizar y abrir
|
customService.displayDescription=Añade un servicio personalizado para tunelizar y abrir
|
||||||
fixedService.displayName=Servicio
|
fixedService.displayName=Servicio
|
||||||
fixedService.displayDescription=Utilizar un servicio predefinido
|
fixedService.displayDescription=Utilizar un servicio predefinido
|
||||||
noServices=No hay servicios disponibles
|
|
||||||
hasServices=$COUNT$ servicios disponibles
|
|
||||||
hasService=$COUNT$ servicio disponible
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=Service
|
||||||
customService.displayDescription=Ajouter un service personnalisé au tunnel et à l'ouverture
|
customService.displayDescription=Ajouter un service personnalisé au tunnel et à l'ouverture
|
||||||
fixedService.displayName=Service
|
fixedService.displayName=Service
|
||||||
fixedService.displayDescription=Utiliser un service prédéfini
|
fixedService.displayDescription=Utiliser un service prédéfini
|
||||||
noServices=Aucun service disponible
|
|
||||||
hasServices=$COUNT$ services disponibles
|
|
||||||
hasService=$COUNT$ service disponible
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=Servizio
|
||||||
customService.displayDescription=Aggiungi un servizio personalizzato per il tunnel e l'apertura
|
customService.displayDescription=Aggiungi un servizio personalizzato per il tunnel e l'apertura
|
||||||
fixedService.displayName=Servizio
|
fixedService.displayName=Servizio
|
||||||
fixedService.displayDescription=Utilizzare un servizio predefinito
|
fixedService.displayDescription=Utilizzare un servizio predefinito
|
||||||
noServices=Nessun servizio disponibile
|
|
||||||
hasServices=$COUNT$ servizi disponibili
|
|
||||||
hasService=$COUNT$ servizio disponibile
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=サービス
|
||||||
customService.displayDescription=トンネルとオープンにカスタムサービスを追加する
|
customService.displayDescription=トンネルとオープンにカスタムサービスを追加する
|
||||||
fixedService.displayName=サービス
|
fixedService.displayName=サービス
|
||||||
fixedService.displayDescription=定義済みのサービスを使う
|
fixedService.displayDescription=定義済みのサービスを使う
|
||||||
noServices=利用可能なサービスはない
|
|
||||||
hasServices=$COUNT$ 利用可能なサービス
|
|
||||||
hasService=$COUNT$ 利用可能なサービス
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=Service
|
||||||
customService.displayDescription=Een aangepaste service toevoegen aan tunnel en openen
|
customService.displayDescription=Een aangepaste service toevoegen aan tunnel en openen
|
||||||
fixedService.displayName=Service
|
fixedService.displayName=Service
|
||||||
fixedService.displayDescription=Een vooraf gedefinieerde service gebruiken
|
fixedService.displayDescription=Een vooraf gedefinieerde service gebruiken
|
||||||
noServices=Geen beschikbare diensten
|
|
||||||
hasServices=$COUNT$ beschikbare diensten
|
|
||||||
hasService=$COUNT$ beschikbare dienst
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=Serviço
|
||||||
customService.displayDescription=Adiciona um serviço personalizado ao túnel e abre
|
customService.displayDescription=Adiciona um serviço personalizado ao túnel e abre
|
||||||
fixedService.displayName=Serviço
|
fixedService.displayName=Serviço
|
||||||
fixedService.displayDescription=Utiliza um serviço predefinido
|
fixedService.displayDescription=Utiliza um serviço predefinido
|
||||||
noServices=Não há serviços disponíveis
|
|
||||||
hasServices=$COUNT$ serviços disponíveis
|
|
||||||
hasService=$COUNT$ serviço disponível
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=Сервис
|
||||||
customService.displayDescription=Добавьте пользовательский сервис для туннелирования и открытия
|
customService.displayDescription=Добавьте пользовательский сервис для туннелирования и открытия
|
||||||
fixedService.displayName=Сервис
|
fixedService.displayName=Сервис
|
||||||
fixedService.displayDescription=Использовать предопределенный сервис
|
fixedService.displayDescription=Использовать предопределенный сервис
|
||||||
noServices=Нет доступных сервисов
|
|
||||||
hasServices=$COUNT$ доступные сервисы
|
|
||||||
hasService=$COUNT$ доступный сервис
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=Hizmet
|
||||||
customService.displayDescription=Tünele özel bir hizmet ekleyin ve açın
|
customService.displayDescription=Tünele özel bir hizmet ekleyin ve açın
|
||||||
fixedService.displayName=Hizmet
|
fixedService.displayName=Hizmet
|
||||||
fixedService.displayDescription=Önceden tanımlanmış bir hizmet kullanın
|
fixedService.displayDescription=Önceden tanımlanmış bir hizmet kullanın
|
||||||
noServices=Mevcut hizmet yok
|
|
||||||
hasServices=$COUNT$ mevcut hi̇zmetler
|
|
||||||
hasService=$COUNT$ mevcut hizmet
|
|
||||||
|
|
|
@ -156,6 +156,3 @@ customService.displayName=服务
|
||||||
customService.displayDescription=为隧道和开放添加自定义服务
|
customService.displayDescription=为隧道和开放添加自定义服务
|
||||||
fixedService.displayName=服务
|
fixedService.displayName=服务
|
||||||
fixedService.displayDescription=使用预定义服务
|
fixedService.displayDescription=使用预定义服务
|
||||||
noServices=无可用服务
|
|
||||||
hasServices=$COUNT$ 可用服务
|
|
||||||
hasService=$COUNT$ 可用服务
|
|
||||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
||||||
10.2-1
|
10.1.1
|
||||||
|
|
Loading…
Reference in a new issue