diff --git a/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java b/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java index e5c64e30..483279ad 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/StoreToggleComp.java @@ -5,17 +5,18 @@ import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.storage.DataStoreEntry; import io.xpipe.app.util.ThreadHelper; - +import io.xpipe.core.store.DataStore; import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ObservableBooleanValue; import javafx.scene.layout.Region; - import lombok.AllArgsConstructor; import lombok.Setter; +import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Function; @AllArgsConstructor public class StoreToggleComp extends SimpleComp { @@ -28,6 +29,19 @@ public class StoreToggleComp extends SimpleComp { @Setter private ObservableBooleanValue customVisibility = new SimpleBooleanProperty(true); + public static StoreToggleComp simpleToggle(String nameKey, StoreSection section, Function initial, BiConsumer setter) { + return new StoreToggleComp(nameKey, section,new SimpleBooleanProperty(initial.apply(section.getWrapper().getEntry().getStore().asNeeded())),v -> { + setter.accept(section.getWrapper().getEntry().getStore().asNeeded(),v); + }); + } + + public static StoreToggleComp childrenToggle(String nameKey, StoreSection section, Function initial, BiConsumer setter) { + return new StoreToggleComp(nameKey, section,new SimpleBooleanProperty(initial.apply(section.getWrapper().getEntry().getStore().asNeeded())),v -> { + setter.accept(section.getWrapper().getEntry().getStore().asNeeded(),v); + section.getWrapper().refreshChildren(); + }); + } + public StoreToggleComp(String nameKey, StoreSection section, boolean initial, Consumer onChange) { this.nameKey = nameKey; this.section = section; diff --git a/app/src/main/java/io/xpipe/app/storage/DataStorage.java b/app/src/main/java/io/xpipe/app/storage/DataStorage.java index 7c21ff3f..3188f6af 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStorage.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStorage.java @@ -446,6 +446,10 @@ public abstract class DataStorage { public void deleteChildren(DataStoreEntry e) { var c = getDeepStoreChildren(e); + if (c.isEmpty()) { + return; + } + c.forEach(entry -> entry.finalizeEntry()); this.storeEntriesSet.removeAll(c); this.listeners.forEach(l -> l.onStoreRemove(c.toArray(DataStoreEntry[]::new))); @@ -461,6 +465,9 @@ public abstract class DataStorage { return c.stream(); }) .toList(); + if (toDelete.isEmpty()) { + return; + } toDelete.forEach(entry -> entry.finalizeEntry()); toDelete.forEach(this.storeEntriesSet::remove); @@ -525,6 +532,10 @@ public abstract class DataStorage { } public void addStoreEntriesIfNotPresent(@NonNull DataStoreEntry... es) { + if (es.length == 0) { + return; + } + for (DataStoreEntry e : es) { if (storeEntriesSet.contains(e) || getStoreEntryIfPresent(e.getStore(), false).isPresent()) { diff --git a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java index a30e4020..a1773558 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -456,17 +456,23 @@ public class DataStoreEntry extends StorageElement { return false; } - store = DataStorageParser.storeFromNode(storeNode); - if (store == null) { + var newStore = DataStorageParser.storeFromNode(storeNode); + if (newStore == null) { + store = null; validity = Validity.LOAD_FAILED; - return false; + return true; } - var newComplete = store.isComplete(); + var newComplete = newStore.isComplete(); if (!newComplete) { + validity = Validity.INCOMPLETE; + store = newStore; return false; } + if (!newStore.equals(store)) { + store = newStore; + } validity = Validity.COMPLETE; // Don't count this as modification as this is done always notifyUpdate(false, false); @@ -482,17 +488,23 @@ public class DataStoreEntry extends StorageElement { return false; } - store = DataStorageParser.storeFromNode(storeNode); - if (store == null) { + var newStore = DataStorageParser.storeFromNode(storeNode); + if (newStore == null) { + store = null; validity = Validity.LOAD_FAILED; - return false; + return true; } - var newComplete = store.isComplete(); + var newComplete = newStore.isComplete(); if (newComplete) { + validity = Validity.COMPLETE; + store = newStore; return false; } + if (!newStore.equals(store)) { + store = newStore; + } validity = Validity.INCOMPLETE; notifyUpdate(false, false); return true; diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java index 8da4056d..1a0a952b 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptGroupStoreProvider.java @@ -25,18 +25,17 @@ public class ScriptGroupStoreProvider implements DataStoreProvider { @Override public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { - ScriptGroupStore s = sec.getWrapper().getEntry().getStore().asNeeded(); if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { return new DenseStoreEntryComp(sec.getWrapper(), true, null); } - var def = new StoreToggleComp("base.isDefaultGroup", sec, s.getState().isDefault(), aBoolean -> { + var def = StoreToggleComp.simpleToggle("base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> { var state = s.getState(); state.setDefault(aBoolean); s.setState(state); }); - var bring = new StoreToggleComp("base.bringToShells", sec, s.getState().isBringToShell(), aBoolean -> { + var bring = StoreToggleComp.simpleToggle("base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> { var state = s.getState(); state.setBringToShell(aBoolean); s.setState(state); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java index 15d5b0e4..5041961e 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/SimpleScriptStoreProvider.java @@ -50,25 +50,25 @@ public class SimpleScriptStoreProvider implements DataStoreProvider { @Override public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) { - SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded(); if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) { return new DenseStoreEntryComp(sec.getWrapper(), true, null); } - var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry()); - - var def = new StoreToggleComp("base.isDefault", sec, s.getState().isDefault(), aBoolean -> { + var def = StoreToggleComp.simpleToggle("base.isDefaultGroup", sec, s -> s.getState().isDefault(), (s, aBoolean) -> { var state = s.getState(); state.setDefault(aBoolean); s.setState(state); }); - var bring = new StoreToggleComp("base.bringToShells", sec, s.getState().isBringToShell(), aBoolean -> { + var bring = StoreToggleComp.simpleToggle("base.bringToShells", sec, s -> s.getState().isBringToShell(), (s, aBoolean) -> { var state = s.getState(); state.setBringToShell(aBoolean); s.setState(state); }); + SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded(); + var groupWrapper = StoreViewState.get().getEntryWrapper(s.getGroup().getEntry()); + // Disable selection if parent group is already made default def.disable(BindingsHelper.map(groupWrapper.getPersistentState(), o -> { ScriptStore.State state = (ScriptStore.State) o;