mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-06-28 11:00:28 +12:00
Various small fixes [release]
This commit is contained in:
parent
b7fa352ae5
commit
3ec708ef37
|
@ -136,7 +136,7 @@ run {
|
||||||
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', "debug"
|
||||||
systemProperty 'io.xpipe.app.fullVersion', rootProject.fullVersion
|
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"
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class DataStoreSelectorComp extends Comp<CompStructure<Button>> {
|
||||||
AppI18n.get("selectStreamStore"), AppI18n.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.getPath().toString(), graphic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,11 +65,11 @@ 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.getPath() == null) {
|
||||||
return JfxHelper.createNamedEntry(AppI18n.get("browse"), AppI18n.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.getPath().toString(), graphic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class DsRemoteFileChoiceComp extends SimpleComp {
|
||||||
|
|
||||||
return FileStore.builder()
|
return FileStore.builder()
|
||||||
.fileSystem(machine.get())
|
.fileSystem(machine.get())
|
||||||
.file(fileName.get())
|
.path(fileName.get())
|
||||||
.build();
|
.build();
|
||||||
},
|
},
|
||||||
store)
|
store)
|
||||||
|
|
|
@ -85,6 +85,12 @@ public class GuiDsStoreCreator extends MultiStepComp.Step<CompStructure<?>> {
|
||||||
r.get().setPrefWidth(AppFont.em(36));
|
r.get().setPrefWidth(AppFont.em(36));
|
||||||
r.get().setPrefHeight(AppFont.em(42));
|
r.get().setPrefHeight(AppFont.em(42));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.validator.addListener((observable, oldValue, newValue) -> {
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
newValue.validate();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showEdit(DataStoreEntry e) {
|
public static void showEdit(DataStoreEntry e) {
|
||||||
|
|
|
@ -155,7 +155,7 @@ public class StoreEntryComp extends SimpleComp {
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
var found = entry.getDefaultActionProvider().getValue();
|
var found = entry.getDefaultActionProvider().getValue();
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
found.getDataStoreCallSite()
|
found
|
||||||
.createAction(entry.getEntry().getStore().asNeeded())
|
.createAction(entry.getEntry().getStore().asNeeded())
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,7 @@ 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 javafx.beans.Observable;
|
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.beans.value.ObservableValue;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
@ -31,7 +28,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, BooleanProperty> actionProviders;
|
private final Map<ActionProvider, BooleanProperty> actionProviders;
|
||||||
private final ObservableValue<ActionProvider> defaultActionProvider;
|
private final Property<ActionProvider.DefaultDataStoreCallSite<?>> 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();
|
||||||
|
@ -54,16 +51,7 @@ public class StoreEntryWrapper implements StorageFilter.Filterable {
|
||||||
.forEach(dataStoreActionProvider -> {
|
.forEach(dataStoreActionProvider -> {
|
||||||
actionProviders.put(dataStoreActionProvider, new SimpleBooleanProperty(true));
|
actionProviders.put(dataStoreActionProvider, new SimpleBooleanProperty(true));
|
||||||
});
|
});
|
||||||
this.defaultActionProvider = Bindings.createObjectBinding(
|
this.defaultActionProvider = new SimpleObjectProperty<>();
|
||||||
() -> {
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -126,6 +114,7 @@ public class StoreEntryWrapper implements StorageFilter.Filterable {
|
||||||
actionProviders.keySet().forEach(dataStoreActionProvider -> {
|
actionProviders.keySet().forEach(dataStoreActionProvider -> {
|
||||||
if (!isInStorage()) {
|
if (!isInStorage()) {
|
||||||
actionProviders.get(dataStoreActionProvider).set(false);
|
actionProviders.get(dataStoreActionProvider).set(false);
|
||||||
|
defaultActionProvider.setValue(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +127,12 @@ public class StoreEntryWrapper implements StorageFilter.Filterable {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultProvider = ActionProvider.ALL.stream()
|
||||||
|
.filter(e -> e.getDefaultDataStoreCallSite() != null
|
||||||
|
&& e.getDefaultDataStoreCallSite().isApplicable(entry.getStore().asNeeded()))
|
||||||
|
.findFirst().map(ActionProvider::getDefaultDataStoreCallSite).orElse(null);
|
||||||
|
this.defaultActionProvider.setValue(defaultProvider);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
actionProviders
|
actionProviders
|
||||||
.get(dataStoreActionProvider)
|
.get(dataStoreActionProvider)
|
||||||
|
|
|
@ -68,11 +68,26 @@ public interface ActionProvider {
|
||||||
default DataStoreCallSite<?> getDataStoreCallSite() {
|
default DataStoreCallSite<?> getDataStoreCallSite() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
default DefaultDataStoreCallSite<?> getDefaultDataStoreCallSite() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
default DataSourceCallSite<?> getDataSourceCallSite() {
|
default DataSourceCallSite<?> getDataSourceCallSite() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static interface DefaultDataStoreCallSite<T extends DataStore> {
|
||||||
|
|
||||||
|
Action createAction(T store);
|
||||||
|
|
||||||
|
Class<T> getApplicableClass();
|
||||||
|
|
||||||
|
default boolean isApplicable(T o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static interface DataStoreCallSite<T extends DataStore> {
|
public static interface DataStoreCallSite<T extends DataStore> {
|
||||||
|
|
||||||
enum ActiveType {
|
enum ActiveType {
|
||||||
|
@ -85,10 +100,6 @@ public interface ActionProvider {
|
||||||
|
|
||||||
Class<T> getApplicableClass();
|
Class<T> getApplicableClass();
|
||||||
|
|
||||||
default boolean isDefault() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean isMajor() {
|
default boolean isMajor() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,12 @@ public class FileStoreChoiceComp extends SimpleComp {
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var fileProperty = new SimpleStringProperty(
|
var fileProperty = new SimpleStringProperty(
|
||||||
selected.getValue() != null ? selected.getValue().getFile() : null);
|
selected.getValue() != null ? selected.getValue().getPath() : null);
|
||||||
fileProperty.addListener((observable, oldValue, newValue) -> {
|
fileProperty.addListener((observable, oldValue, newValue) -> {
|
||||||
setSelected(selected.getValue().getFileSystem(), newValue);
|
setSelected(selected.getValue().getFileSystem(), newValue);
|
||||||
});
|
});
|
||||||
selected.addListener((observable, oldValue, newValue) -> {
|
selected.addListener((observable, oldValue, newValue) -> {
|
||||||
fileProperty.setValue(newValue.getFile());
|
fileProperty.setValue(newValue.getPath());
|
||||||
});
|
});
|
||||||
|
|
||||||
var fileSystemChoiceComp = new FileSystemStoreChoiceComp(selected).grow(false, true).styleClass(Styles.LEFT_PILL);
|
var fileSystemChoiceComp = new FileSystemStoreChoiceComp(selected).grow(false, true).styleClass(Styles.LEFT_PILL);
|
||||||
|
|
|
@ -51,12 +51,12 @@ public class FileSystemStoreChoiceComp extends SimpleComp {
|
||||||
fileSystemProperty.addListener((observable, oldValue, newValue) -> {
|
fileSystemProperty.addListener((observable, oldValue, newValue) -> {
|
||||||
selected.setValue(FileStore.builder()
|
selected.setValue(FileStore.builder()
|
||||||
.fileSystem(newValue)
|
.fileSystem(newValue)
|
||||||
.file(selected.getValue() != null ? selected.getValue().getFile() : null)
|
.path(selected.getValue() != null ? selected.getValue().getPath() : null)
|
||||||
.build());
|
.build());
|
||||||
});
|
});
|
||||||
|
|
||||||
selected.addListener((observable, oldValue, newValue) -> {
|
selected.addListener((observable, oldValue, newValue) -> {
|
||||||
fileSystemProperty.setValue(newValue.getFileSystem());
|
fileSystemProperty.setValue(newValue != null?newValue.getFileSystem():null);
|
||||||
});
|
});
|
||||||
|
|
||||||
var comboBox =
|
var comboBox =
|
||||||
|
|
|
@ -7,8 +7,8 @@ import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.core.AppWindowHelper;
|
import io.xpipe.app.core.AppWindowHelper;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
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.util.JfxHelper;
|
import io.xpipe.app.util.JfxHelper;
|
||||||
|
import javafx.application.Platform;
|
||||||
import javafx.geometry.Orientation;
|
import javafx.geometry.Orientation;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Separator;
|
import javafx.scene.control.Separator;
|
||||||
|
@ -20,6 +20,8 @@ import javafx.stage.Stage;
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import static atlantafx.base.theme.Styles.ACCENT;
|
import static atlantafx.base.theme.Styles.ACCENT;
|
||||||
|
@ -37,27 +39,67 @@ public class ErrorHandlerComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showAndWait(ErrorEvent event) {
|
public static void showAndWait(ErrorEvent event) {
|
||||||
PlatformThread.runLaterIfNeededBlocking(() -> {
|
if (Platform.isFxApplicationThread()) {
|
||||||
synchronized (showing) {
|
showAndWaitWithPlatformThread(event);
|
||||||
if (!showing.get()) {
|
} else {
|
||||||
showing.set(true);
|
showAndWaitWithOtherThread(event);
|
||||||
var window = AppWindowHelper.sideWindow(
|
}
|
||||||
AppI18n.get("errorHandler"), w -> new ErrorHandlerComp(event, w), true, null);
|
}
|
||||||
window.setOnHidden(e -> {
|
|
||||||
showing.set(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// An exception is thrown when show and wait is called
|
public static void showAndWaitWithPlatformThread(ErrorEvent event) {
|
||||||
// within an animation or layout processing task
|
var finishLatch = new CountDownLatch(1);
|
||||||
try {
|
if (!showing.get()) {
|
||||||
window.showAndWait();
|
showing.set(true);
|
||||||
} catch (Throwable t) {
|
var window = AppWindowHelper.sideWindow(
|
||||||
window.show();
|
AppI18n.get("errorHandler"), w -> new ErrorHandlerComp(event, w), true, null);
|
||||||
t.printStackTrace();
|
window.setOnHidden(e -> {
|
||||||
}
|
showing.set(false);
|
||||||
|
finishLatch.countDown();
|
||||||
|
});
|
||||||
|
|
||||||
|
// An exception is thrown when show and wait is called
|
||||||
|
// within an animation or layout processing task, so use show
|
||||||
|
try {
|
||||||
|
window.show();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showAndWaitWithOtherThread(ErrorEvent event) {
|
||||||
|
var showLatch = new CountDownLatch(1);
|
||||||
|
var finishLatch = new CountDownLatch(1);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
if (!showing.get()) {
|
||||||
|
showing.set(true);
|
||||||
|
var window = AppWindowHelper.sideWindow(
|
||||||
|
AppI18n.get("errorHandler"), w -> new ErrorHandlerComp(event, w), true, null);
|
||||||
|
window.setOnHidden(e -> {
|
||||||
|
showing.set(false);
|
||||||
|
finishLatch.countDown();
|
||||||
|
});
|
||||||
|
|
||||||
|
// An exception is thrown when show and wait is called
|
||||||
|
// within an animation or layout processing task, so use show
|
||||||
|
try {
|
||||||
|
showLatch.countDown();
|
||||||
|
window.show();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Only wait for a certain time in case we somehow deadlocked the platform thread
|
||||||
|
if (showLatch.await(5, TimeUnit.SECONDS)) {
|
||||||
|
finishLatch.await();
|
||||||
|
} else {
|
||||||
|
TrackEvent.error("Platform thread in error handler was timed out");
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Region createActionComp(ErrorAction a) {
|
private Region createActionComp(ErrorAction a) {
|
||||||
|
|
|
@ -367,30 +367,32 @@ public abstract class DataStorage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void propagateUpdate() {
|
private void propagateUpdate() {
|
||||||
for (DataStoreEntry dataStoreEntry : getStoreEntries()) {
|
for (DataStoreEntry dataStoreEntry : getStoreEntries()) {
|
||||||
dataStoreEntry.simpleRefresh();
|
dataStoreEntry.simpleRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var e : sourceEntries) {
|
for (var e : getSourceEntries()) {
|
||||||
e.simpleRefresh();
|
e.simpleRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void addStoreEntry(@NonNull DataStoreEntry e) {
|
public void addStoreEntry(@NonNull DataStoreEntry e) {
|
||||||
if (getStoreEntryIfPresent(e.getName()).isPresent()) {
|
if (getStoreEntryIfPresent(e.getName()).isPresent()) {
|
||||||
throw new IllegalArgumentException("Store with name " + e.getName() + " already exists");
|
throw new IllegalArgumentException("Store with name " + e.getName() + " already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
e.setDirectory(getStoresDir().resolve(e.getUuid().toString()));
|
synchronized (this) {
|
||||||
this.storeEntries.add(e);
|
e.setDirectory(getStoresDir().resolve(e.getUuid().toString()));
|
||||||
|
this.storeEntries.add(e);
|
||||||
|
}
|
||||||
propagateUpdate();
|
propagateUpdate();
|
||||||
save();
|
save();
|
||||||
|
|
||||||
this.listeners.forEach(l -> l.onStoreAdd(e));
|
this.listeners.forEach(l -> l.onStoreAdd(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void addStoreEntryIfNotPresent(@NonNull String name, DataStore store) {
|
public void addStoreEntryIfNotPresent(@NonNull String name, DataStore store) {
|
||||||
if (getStoreEntryIfPresent(store).isPresent()) {
|
if (getStoreEntryIfPresent(store).isPresent()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -399,21 +401,22 @@ public abstract class DataStorage {
|
||||||
addStoreEntry(e);
|
addStoreEntry(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized DataStoreEntry addStoreEntry(@NonNull String name, DataStore store) {
|
public DataStoreEntry addStoreEntry(@NonNull String name, DataStore store) {
|
||||||
var e = DataStoreEntry.createNew(UUID.randomUUID(), createUniqueStoreEntryName(name), store);
|
var e = DataStoreEntry.createNew(UUID.randomUUID(), createUniqueStoreEntryName(name), store);
|
||||||
addStoreEntry(e);
|
addStoreEntry(e);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void deleteStoreEntry(@NonNull DataStoreEntry store) {
|
public void deleteStoreEntry(@NonNull DataStoreEntry store) {
|
||||||
if (!store.getConfiguration().isDeletable()) {
|
if (!store.getConfiguration().isDeletable()) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.storeEntries.remove(store);
|
synchronized (this) {
|
||||||
|
this.storeEntries.remove(store);
|
||||||
|
}
|
||||||
propagateUpdate();
|
propagateUpdate();
|
||||||
save();
|
save();
|
||||||
|
|
||||||
this.listeners.forEach(l -> l.onStoreRemove(store));
|
this.listeners.forEach(l -> l.onStoreRemove(store));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +424,7 @@ public abstract class DataStorage {
|
||||||
this.listeners.add(l);
|
this.listeners.add(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized DataSourceCollection createOrGetCollection(String name) {
|
public DataSourceCollection createOrGetCollection(String name) {
|
||||||
return getCollectionForName(name).orElseGet(() -> {
|
return getCollectionForName(name).orElseGet(() -> {
|
||||||
var col = DataSourceCollection.createNew(name);
|
var col = DataSourceCollection.createNew(name);
|
||||||
addCollection(col);
|
addCollection(col);
|
||||||
|
@ -460,8 +463,8 @@ public abstract class DataStorage {
|
||||||
|
|
||||||
public abstract void load();
|
public abstract void load();
|
||||||
|
|
||||||
public synchronized void refresh() {
|
public void refresh() {
|
||||||
storeEntries.forEach(entry -> {
|
getStoreEntries().forEach(entry -> {
|
||||||
entry.simpleRefresh();
|
entry.simpleRefresh();
|
||||||
});
|
});
|
||||||
save();
|
save();
|
||||||
|
|
|
@ -26,11 +26,11 @@ import java.util.regex.Pattern;
|
||||||
public class FileStore extends JacksonizedValue implements FilenameStore, StreamDataStore {
|
public class FileStore extends JacksonizedValue implements FilenameStore, StreamDataStore {
|
||||||
|
|
||||||
FileSystemStore fileSystem;
|
FileSystemStore fileSystem;
|
||||||
String file;
|
String path;
|
||||||
|
|
||||||
public FileStore(FileSystemStore fileSystem, String file) {
|
public FileStore(FileSystemStore fileSystem, String path) {
|
||||||
this.fileSystem = fileSystem;
|
this.fileSystem = fileSystem;
|
||||||
this.file = file;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileStore local(Path p) {
|
public static FileStore local(Path p) {
|
||||||
|
@ -45,9 +45,9 @@ public class FileStore extends JacksonizedValue implements FilenameStore, Stream
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getParent() {
|
public String getParent() {
|
||||||
var matcher = Pattern.compile("^(.+?)[^\\\\/]+$").matcher(file);
|
var matcher = Pattern.compile("^(.+?)[^\\\\/]+$").matcher(path);
|
||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
throw new IllegalArgumentException("Unable to determine parent of " + file);
|
throw new IllegalArgumentException("Unable to determine parent of " + path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return matcher.group(1);
|
return matcher.group(1);
|
||||||
|
@ -62,17 +62,17 @@ public class FileStore extends JacksonizedValue implements FilenameStore, Stream
|
||||||
if (fileSystem == null) {
|
if (fileSystem == null) {
|
||||||
throw new ValidationException("File system is missing");
|
throw new ValidationException("File system is missing");
|
||||||
}
|
}
|
||||||
if (file == null) {
|
if (path == null) {
|
||||||
throw new ValidationException("File is missing");
|
throw new ValidationException("File is missing");
|
||||||
}
|
}
|
||||||
if (!FileNames.isAbsolute(file)) {
|
if (!FileNames.isAbsolute(path)) {
|
||||||
throw new ValidationException("File path is not absolute");
|
throw new ValidationException("File path is not absolute");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream openInput() throws Exception {
|
public InputStream openInput() throws Exception {
|
||||||
return fileSystem.createFileSystem().open().openInput(file);
|
return fileSystem.createFileSystem().open().openInput(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,17 +81,17 @@ public class FileStore extends JacksonizedValue implements FilenameStore, Stream
|
||||||
throw new IOException("Unable to create directory: " + getParent());
|
throw new IOException("Unable to create directory: " + getParent());
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileSystem.createFileSystem().open().openOutput(file);
|
return fileSystem.createFileSystem().open().openOutput(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canOpen() throws Exception {
|
public boolean canOpen() throws Exception {
|
||||||
return fileSystem.createFileSystem().open().exists(file);
|
return fileSystem.createFileSystem().open().exists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
var split = file.split("[\\\\/]");
|
var split = path.split("[\\\\/]");
|
||||||
if (split.length == 0) {
|
if (split.length == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,10 @@ public class FileStoreProvider implements DataStoreProvider {
|
||||||
FileStore s = store.asNeeded();
|
FileStore s = store.asNeeded();
|
||||||
var local = s.getFileSystem() instanceof LocalStore;
|
var local = s.getFileSystem() instanceof LocalStore;
|
||||||
if (local) {
|
if (local) {
|
||||||
return fileNameString(s.getFile(), length);
|
return fileNameString(s.getPath(), length);
|
||||||
} else {
|
} else {
|
||||||
var machineString = DataStoreFormatter.toName(s.getFileSystem(), length / 2);
|
var machineString = DataStoreFormatter.toName(s.getFileSystem(), length / 2);
|
||||||
var fileString = fileNameString(s.getFile(), length - machineString.length() - 3);
|
var fileString = fileNameString(s.getPath(), length - machineString.length() - 3);
|
||||||
return String.format("%s @ %s", fileString, machineString);
|
return String.format("%s @ %s", fileString, machineString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,10 +70,10 @@ public class FileStoreProvider implements DataStoreProvider {
|
||||||
public Dialog dialogForStore(DataStore store) {
|
public Dialog dialogForStore(DataStore store) {
|
||||||
FileStore fileStore = store.asNeeded();
|
FileStore fileStore = store.asNeeded();
|
||||||
var machineQuery = DialogHelper.machineQuery(fileStore.getFileSystem());
|
var machineQuery = DialogHelper.machineQuery(fileStore.getFileSystem());
|
||||||
var fileQuery = DialogHelper.fileQuery(fileStore.getFile());
|
var fileQuery = DialogHelper.fileQuery(fileStore.getPath());
|
||||||
return Dialog.chain(machineQuery, fileQuery).evaluateTo(() -> FileStore.builder()
|
return Dialog.chain(machineQuery, fileQuery).evaluateTo(() -> FileStore.builder()
|
||||||
.fileSystem(machineQuery.getResult())
|
.fileSystem(machineQuery.getResult())
|
||||||
.file(fileQuery.getResult())
|
.path(fileQuery.getResult())
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,12 @@ public class AddStoreAction implements ActionProvider {
|
||||||
return new LauncherCallSite() {
|
return new LauncherCallSite() {
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "add";
|
return "addStore";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Action createAction(List<String> args) throws Exception {
|
public Action createAction(List<String> args) throws Exception {
|
||||||
var storeString = SecretValue.ofSecret(args.get(1));
|
var storeString = SecretValue.ofSecret(args.get(0));
|
||||||
var store = JacksonMapper.parse(storeString.getSecretValue(), DataStore.class);
|
var store = JacksonMapper.parse(storeString.getSecretValue(), DataStore.class);
|
||||||
return new Action(store);
|
return new Action(store);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,27 @@ public class EditStoreAction implements ActionProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DefaultDataStoreCallSite<?> getDefaultDataStoreCallSite() {
|
||||||
|
return new DefaultDataStoreCallSite<DataStore>() {
|
||||||
|
@Override
|
||||||
|
public boolean isApplicable(DataStore o) {
|
||||||
|
return DataStorage.get().getStoreEntryIfPresent(o).orElseThrow().getState().equals(DataStoreEntry.State.INCOMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionProvider.Action createAction(DataStore store) {
|
||||||
|
return new Action(DataStorage.get().getStoreEntryIfPresent(store).orElseThrow());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<DataStore> getApplicableClass() {
|
||||||
|
return DataStore.class;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataStoreCallSite<?> getDataStoreCallSite() {
|
public DataStoreCallSite<?> getDataStoreCallSite() {
|
||||||
return new DataStoreCallSite<DataStore>() {
|
return new DataStoreCallSite<DataStore>() {
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class FileBrowseAction implements ActionProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
DesktopHelper.browseFileInDirectory(Path.of(store.getFile()));
|
DesktopHelper.browseFileInDirectory(Path.of(store.getPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public class FileBrowseAction implements ActionProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isApplicable(FileStore o) throws Exception {
|
public boolean isApplicable(FileStore o) throws Exception {
|
||||||
return o.getFileSystem().equals(new LocalStore()) && Files.exists(Path.of(o.getFile()));
|
return o.getFileSystem().equals(new LocalStore()) && Files.exists(Path.of(o.getPath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class FileEditAction implements ActionProvider {
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
if (store.getFileSystem().equals(new LocalStore())) {
|
if (store.getFileSystem().equals(new LocalStore())) {
|
||||||
FileOpener.openInTextEditor(store.getFile());
|
FileOpener.openInTextEditor(store.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class ShareStoreAction implements ActionProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String create(DataStore store) {
|
public static String create(DataStore store) {
|
||||||
return "xpipe://add/store/" + SecretValue.encrypt(store.toString()).getEncryptedValue();
|
return "xpipe://addStore/" + SecretValue.encrypt(store.toString()).getEncryptedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue