Fix many small issues

This commit is contained in:
crschnick 2023-02-12 16:48:07 +00:00
parent 2245dc8941
commit ec632cd7df
18 changed files with 131 additions and 40 deletions

View file

@ -55,8 +55,6 @@ public class DsStoreProviderChoiceComp extends Comp<CompStructure<ComboBox<Node>
@Override @Override
public CompStructure<ComboBox<Node>> createBase() { public CompStructure<ComboBox<Node>> createBase() {
var comboBox = new CustomComboBoxBuilder<>(provider, this::createGraphic, createDefaultNode(), v -> true); var comboBox = new CustomComboBoxBuilder<>(provider, this::createGraphic, createDefaultNode(), v -> true);
comboBox.add(null);
comboBox.addSeparator();
getProviders().stream() getProviders().stream()
.filter(p -> AppPrefs.get().developerShowHiddenProviders().get() || p.shouldShow()) .filter(p -> AppPrefs.get().developerShowHiddenProviders().get() || p.shouldShow())
.forEach(comboBox::add); .forEach(comboBox::add);

View file

@ -195,21 +195,14 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
} }
var d = n.guiDialog(input); var d = n.guiDialog(input);
if (d == null || d.getComp() == null) {
layout.setCenter(null);
validator.setValue(new SimpleValidator());
return;
}
var propVal = new SimpleValidator(); var propVal = new SimpleValidator();
var propR = createStoreProperties(d.getComp(), propVal); var propR = createStoreProperties(d == null || d.getComp() == null ? null : d.getComp(), propVal);
var box = new VBox(propR); var box = new VBox(propR);
box.setSpacing(7); box.setSpacing(7);
layout.setCenter(box); layout.setCenter(box);
validator.setValue(new ChainedValidator(List.of(d.getValidator(), propVal))); validator.setValue(new ChainedValidator(List.of(d != null && d.getValidator() != null ? d.getValidator() : new SimpleValidator(), propVal)));
} else { } else {
layout.setCenter(null); layout.setCenter(null);
validator.setValue(new SimpleValidator()); validator.setValue(new SimpleValidator());

View file

@ -152,9 +152,14 @@ public class StoreEntryComp extends SimpleComp {
button.setFocusTraversable(false); button.setFocusTraversable(false);
button.setOnAction(event -> { button.setOnAction(event -> {
event.consume(); event.consume();
if (entry.getEditable().get()) { ThreadHelper.runFailableAsync(() -> {
entry.editDialog(); var found = entry.getDefaultActionProvider().getValue();
} if (found != null) {
found.getDataStoreCallSite()
.createAction(entry.getEntry().getStore().asNeeded())
.execute();
}
});
}); });
return button; return button;
@ -164,7 +169,7 @@ public class StoreEntryComp extends SimpleComp {
var list = new ArrayList<Comp<?>>(); var list = new ArrayList<Comp<?>>();
for (var p : entry.getActionProviders().entrySet()) { for (var p : entry.getActionProviders().entrySet()) {
var actionProvider = p.getKey().getDataStoreCallSite(); var actionProvider = p.getKey().getDataStoreCallSite();
if (!actionProvider.isMajor()) { if (!actionProvider.isMajor() || p.getKey().equals(entry.getDefaultActionProvider().getValue())) {
continue; continue;
} }
@ -213,7 +218,7 @@ public class StoreEntryComp extends SimpleComp {
settingsButton.apply(s -> { settingsButton.apply(s -> {
s.get().prefWidthProperty().bind(Bindings.divide(s.get().heightProperty(), 1.35)); s.get().prefWidthProperty().bind(Bindings.divide(s.get().heightProperty(), 1.35));
}); });
settingsButton.apply(new FancyTooltipAugment<>("entrySettings")); settingsButton.apply(new FancyTooltipAugment<>("more"));
return settingsButton; return settingsButton;
} }
@ -263,11 +268,6 @@ public class StoreEntryComp extends SimpleComp {
}); });
contextMenu.getItems().add(refresh); contextMenu.getItems().add(refresh);
var edit = new MenuItem(I18n.get("edit"), new FontIcon("mdal-edit"));
edit.disableProperty().bind(entry.getEditable().not());
edit.setOnAction(event -> entry.editDialog());
contextMenu.getItems().add(edit);
var del = new MenuItem(I18n.get("delete"), new FontIcon("mdal-delete_outline")); var del = new MenuItem(I18n.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());

View file

@ -9,7 +9,7 @@ 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;
import java.util.Map; import java.util.LinkedHashMap;
public class StoreEntryListComp extends SimpleComp { public class StoreEntryListComp extends SimpleComp {
@ -28,13 +28,14 @@ public class StoreEntryListComp extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var map = Map.<Comp<?>, ObservableBooleanValue>of( var map = new LinkedHashMap<Comp<?>, ObservableBooleanValue>();
map.put(
createList(), createList(),
BindingsHelper.persist(Bindings.and( BindingsHelper.persist(
Bindings.not(StoreViewState.get().emptyProperty()), Bindings.not(Bindings.isEmpty(StoreViewState.get().getShownEntries()))));
Bindings.not(Bindings.isEmpty(StoreViewState.get().getShownEntries())))),
new StoreStorageEmptyIntroComp(), map.put(new StoreStorageEmptyIntroComp(), StoreViewState.get().emptyProperty());
StoreViewState.get().emptyProperty(), map.put(
new StoreNotFoundComp(), new StoreNotFoundComp(),
BindingsHelper.persist(Bindings.and( BindingsHelper.persist(Bindings.and(
Bindings.not(Bindings.isEmpty(StoreViewState.get().getAllEntries())), Bindings.not(Bindings.isEmpty(StoreViewState.get().getAllEntries())),

View file

@ -8,9 +8,11 @@ import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.extension.event.ErrorEvent; import io.xpipe.extension.event.ErrorEvent;
import io.xpipe.extension.fxcomps.util.PlatformThread; import io.xpipe.extension.fxcomps.util.PlatformThread;
import io.xpipe.extension.util.ActionProvider; import io.xpipe.extension.util.ActionProvider;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.beans.value.ObservableBooleanValue; import javafx.beans.value.ObservableBooleanValue;
import javafx.beans.value.ObservableValue;
import lombok.Getter; import lombok.Getter;
import java.time.Duration; import java.time.Duration;
@ -30,6 +32,7 @@ public class StoreEntryWrapper implements StorageFilter.Filterable {
private final StringProperty information = new SimpleStringProperty(); private final StringProperty information = new SimpleStringProperty();
private final StringProperty summary = new SimpleStringProperty(); private final StringProperty summary = new SimpleStringProperty();
private final Map<ActionProvider, ObservableBooleanValue> actionProviders; private final Map<ActionProvider, ObservableBooleanValue> actionProviders;
private final ObservableValue<ActionProvider> defaultActionProvider;
private final BooleanProperty editable = new SimpleBooleanProperty(); private final BooleanProperty editable = new SimpleBooleanProperty();
private final BooleanProperty renamable = new SimpleBooleanProperty(); private final BooleanProperty renamable = new SimpleBooleanProperty();
private final BooleanProperty refreshable = new SimpleBooleanProperty(); private final BooleanProperty refreshable = new SimpleBooleanProperty();
@ -65,6 +68,14 @@ public class StoreEntryWrapper implements StorageFilter.Filterable {
lastAccess); lastAccess);
actionProviders.put(dataStoreActionProvider, property); actionProviders.put(dataStoreActionProvider, property);
}); });
this.defaultActionProvider = Bindings.createObjectBinding(() -> {
var found = actionProviders.entrySet().stream()
.filter(e -> e.getValue().get())
.filter(e -> e.getKey().getDataStoreCallSite() != null
&& e.getKey().getDataStoreCallSite().isDefault())
.findFirst();
return found.map(p -> p.getKey()).orElse(null);
}, actionProviders.values().toArray(Observable[]::new));
setupListeners(); setupListeners();
update(); update();
} }

View file

@ -80,6 +80,7 @@ public class StoreStorageEmptyIntroComp extends SimpleComp {
var sp = new StackPane(v); var sp = new StackPane(v);
sp.setAlignment(Pos.CENTER); sp.setAlignment(Pos.CENTER);
sp.setPickOnBounds(false);
return sp; return sp;
} }
} }

View file

@ -30,7 +30,7 @@ public class AppPrefs {
private static ObservableBooleanValue bindDeveloperTrue(ObservableBooleanValue o) { private static ObservableBooleanValue bindDeveloperTrue(ObservableBooleanValue o) {
return Bindings.createBooleanBinding( return Bindings.createBooleanBinding(
() -> { () -> {
return AppPrefs.get().developerMode().getValue() || o.get(); return AppPrefs.get().developerMode().getValue() && o.get();
}, },
o, o,
AppPrefs.get().developerMode()); AppPrefs.get().developerMode());
@ -39,7 +39,7 @@ public class AppPrefs {
private static ObservableBooleanValue bindDeveloperFalse(ObservableBooleanValue o) { private static ObservableBooleanValue bindDeveloperFalse(ObservableBooleanValue o) {
return Bindings.createBooleanBinding( return Bindings.createBooleanBinding(
() -> { () -> {
return !AppPrefs.get().developerMode().getValue() || o.get(); return !AppPrefs.get().developerMode().getValue() && o.get();
}, },
o, o,
AppPrefs.get().developerMode()); AppPrefs.get().developerMode());

View file

@ -7,6 +7,7 @@ errorTypeOccured=An exception of type $TYPE$ was thrown
errorDetails=Show details errorDetails=Show details
target=Target target=Target
data=Data data=Data
more=More
pipeDataSource=Pipe Data Source pipeDataSource=Pipe Data Source
updateReadyTitle=Update Ready updateReadyTitle=Update Ready
updateReadyHeader=An update is ready to be installed updateReadyHeader=An update is ready to be installed

View file

@ -39,8 +39,8 @@ granted by this EULA.
### Privacy Notices ### Privacy Notices
The Software automatically communicates with its server for three purposes: (1) updating the Software; (2) sending error The Software automatically communicates with its server for two purposes: (1) updating the Software; (2) sending error
reports; and (3) sending anonymized usage data so we may improve the Software. If you would like to learn more about the reports; If you would like to learn more about the
specific information we send, please visit https://xpipe.io/privacy_policy. You may opt out of these features. specific information we send, please visit https://xpipe.io/privacy_policy. You may opt out of these features.
1. **Automatic Software Updates.** The Software communicates with its server (and sends information described at the URL 1. **Automatic Software Updates.** The Software communicates with its server (and sends information described at the URL
@ -48,7 +48,7 @@ specific information we send, please visit https://xpipe.io/privacy_policy. You
Software. You agree that the Software may automatically install any such improvements to the Software on your Software. You agree that the Software may automatically install any such improvements to the Software on your
computer without providing any further notice or receiving any additional consent. This feature may be disabled. computer without providing any further notice or receiving any additional consent. This feature may be disabled.
2. **Error Reports.** In order to help us improve the Software, when the Software encounters certain errors, it will 2. **Error Reports.** In order to help us improve the Software, when the Software encounters certain errors, it will
automatically send some information to its server about the error (as described at the URL above). This feature may send some information to its server about the error (as described at the URL above). This feature may
be disabled. be disabled.
### Open-Source Notices ### Open-Source Notices

View file

@ -45,9 +45,10 @@ public class LocalStoreProvider implements DataStoreProvider {
e.setConfiguration(StorageElement.Configuration.builder() e.setConfiguration(StorageElement.Configuration.builder()
.deletable(false) .deletable(false)
.editable(false) .editable(false)
.refreshable(false) .refreshable(true)
.renameable(false) .renameable(false)
.build()); .build());
e.refresh(true);
} }
@Override @Override

View file

@ -0,0 +1,70 @@
package io.xpipe.ext.base.actions;
import io.xpipe.app.comp.source.store.GuiDsStoreCreator;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.core.store.DataStore;
import io.xpipe.extension.I18n;
import io.xpipe.extension.util.ActionProvider;
import javafx.beans.value.ObservableValue;
import lombok.Value;
public class EditStoreAction implements ActionProvider {
@Value
static class Action implements ActionProvider.Action {
DataStoreEntry store;
@Override
public boolean requiresPlatform() {
return true;
}
@Override
public void execute() throws Exception {
GuiDsStoreCreator.showEdit(store);
}
}
@Override
public DataStoreCallSite<?> getDataStoreCallSite() {
return new DataStoreCallSite<DataStore>() {
@Override
public boolean isMajor() {
return true;
}
@Override
public boolean showIfDisabled() {
return false;
}
@Override
public ActionProvider.Action createAction(DataStore store) {
return new Action(DataStorage.get().getStore(store));
}
@Override
public Class<DataStore> getApplicableClass() {
return DataStore.class;
}
@Override
public boolean isApplicable(DataStore o) throws Exception {
return DataStorage.get().getStore(o).getConfiguration().isEditable();
}
@Override
public ObservableValue<String> getName(DataStore store) {
return I18n.observable("base.edit");
}
@Override
public String getIcon(DataStore store) {
return "mdal-edit";
}
};
}
}

View file

@ -23,6 +23,7 @@ open module io.xpipe.ext.base {
provides ActionProvider with provides ActionProvider with
AddStoreAction, AddStoreAction,
EditStoreAction,
StreamExportAction, StreamExportAction,
ShareStoreAction, ShareStoreAction,
FileBrowseAction, FileBrowseAction,

View file

@ -52,4 +52,7 @@ waitingForConsumer=Waiting for Consumer
waitingForProducer=Waiting for Producer waitingForProducer=Waiting for Producer
open=Open open=Open
closed=Closed closed=Closed
internalStream.displayName=Internal Stream internalStream.displayName=Internal Stream
local.displayName=Local machine
local.displayDescription=
edit=Edit

View file

@ -207,7 +207,7 @@ public abstract class CommandControlImpl extends ProcessControlImpl implements C
return read.get().trim(); return read.get().trim();
} else { } else {
throw new ProcessOutputException( throw new ProcessOutputException(
"Command returned with " + exitCode + ": " + readError.get().trim()); "Command returned with exit code " + exitCode + ": " + readError.get().trim());
} }
} }
@ -241,7 +241,7 @@ public abstract class CommandControlImpl extends ProcessControlImpl implements C
&& !(read.get().isEmpty() && !readError.get().isEmpty())); && !(read.get().isEmpty() && !readError.get().isEmpty()));
if (!success) { if (!success) {
throw new ProcessOutputException( throw new ProcessOutputException(
"Command returned with " + exitCode + ": " + readError.get().trim()); "Command returned with exit code " + exitCode + ": " + readError.get().trim());
} }
} }
} }

View file

@ -56,6 +56,11 @@ public class LaunchAction implements ActionProvider {
public DataStoreCallSite<?> getDataStoreCallSite() { public DataStoreCallSite<?> getDataStoreCallSite() {
return new DataStoreCallSite<LaunchableStore>() { return new DataStoreCallSite<LaunchableStore>() {
@Override
public boolean isDefault() {
return true;
}
@Override @Override
public boolean showIfDisabled() { public boolean showIfDisabled() {
return false; return false;

View file

@ -7,7 +7,7 @@ file.displayDescription=Specify a file input
inMemory.displayName=In Memory inMemory.displayName=In Memory
inMemory.displayDescription=Store binary data in memory inMemory.displayDescription=Store binary data in memory
shellCommand.displayName=Shell Opener Command shellCommand.displayName=Shell Opener Command
shellCommand.displayDescription=Open a shell with a custom command shellCommand.displayDescription=Open a shell through a custom command
shellEnvironment.displayName=Shell Environment shellEnvironment.displayName=Shell Environment
shellEnvironment.displayDescription=Run custom init commands on the shell connection shellEnvironment.displayDescription=Run custom init commands on the shell connection
shellEnvironment.informationFormat=$TYPE$ environment shellEnvironment.informationFormat=$TYPE$ environment

View file

@ -86,8 +86,10 @@ public class DynamicOptionsComp extends Comp<CompStructure<Pane>> {
pane.getChildren().add(line); pane.getChildren().add(line);
} else { } else {
compRegions.add(compRegion); if (compRegion != null) {
pane.getChildren().add(compRegion); compRegions.add(compRegion);
pane.getChildren().add(compRegion);
}
} }
} }

View file

@ -78,6 +78,10 @@ public interface ActionProvider {
Class<T> getApplicableClass(); Class<T> getApplicableClass();
default boolean isDefault() {
return false;
}
default boolean isMajor() { default boolean isMajor() {
return false; return false;
} }