diff --git a/app/src/main/java/io/xpipe/app/hub/comp/DataStoreCategoryChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/DataStoreCategoryChoiceComp.java index c8074ba62..ab4afd5f1 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/DataStoreCategoryChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/DataStoreCategoryChoiceComp.java @@ -57,7 +57,7 @@ public class DataStoreCategoryChoiceComp extends SimpleRegionBuilder { if (!applyExternalInitially) { value.setValue(last); } - var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root).filtered(filter).getList()); + var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root, false).filtered(filter).getList()); box.setValue(value.getValue()); box.valueProperty().addListener((observable, oldValue, newValue) -> { value.setValue(newValue); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryComp.java index 792061d35..cec4d84e4 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryComp.java @@ -22,10 +22,7 @@ import javafx.beans.property.SimpleStringProperty; import javafx.css.PseudoClass; import javafx.geometry.Insets; import javafx.geometry.Pos; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.Menu; -import javafx.scene.control.MenuItem; -import javafx.scene.control.SeparatorMenuItem; +import javafx.scene.control.*; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyEvent; @@ -278,13 +275,18 @@ public class StoreCategoryComp extends SimpleRegionBuilder { if (category.canMove()) { var move = new Menu(AppI18n.get("moveTo"), new FontIcon("mdi2f-folder-move-outline")); StoreViewState.get() - .getSortedCategories(getCategory().getRoot()) + .getSortedCategories(getCategory().getRoot(), true) .getList() .forEach(storeCategoryWrapper -> { - MenuItem m = new MenuItem(); - m.textProperty() - .setValue(" ".repeat(storeCategoryWrapper.getDepth()) - + storeCategoryWrapper.getName().getValue()); + var m = new CustomMenuItem(); + + var l = new Label(); + l.setGraphic(PrettyImageHelper.ofFixedSizeSquare(storeCategoryWrapper.getIconFile().getValue(), 16) + .padding(new Insets(0, 0, 1, 0)).build()); + l.setText(storeCategoryWrapper.getName().getValue()); + l.setPadding(new Insets(0, 1, 1, storeCategoryWrapper.getDepth() * 10)); + m.setContent(l); + m.setOnAction(event -> { category.moveToParent(storeCategoryWrapper.getCategory()); event.consume(); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java index e120995ae..051878019 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreCategoryWrapper.java @@ -100,6 +100,16 @@ public class StoreCategoryWrapper { return cachedParent; } + public boolean isHierarchyExpanded() { + StoreCategoryWrapper current = this; + while ((current = current.getParent()) != null) { + if (!current.getExpanded().get()) { + return false; + } + }; + return true; + } + public void select() { PlatformThread.runLaterIfNeeded(() -> { StoreViewState.get().getActiveCategory().setValue(this); @@ -152,12 +162,17 @@ public class StoreCategoryWrapper { this.expanded.set(!expanded.getValue()); } - public void update() { + public synchronized void update() { // We are probably in shutdown then if (StoreViewState.get() == null) { return; } + // We received a delayed update after removal + if (!DataStorage.get().getStoreCategories().contains(category)) { + return; + } + // Avoid reupdating name when changed from the name property! var catName = translatedName(category.getName()); if (!catName.equals(name.getValue())) { diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryComp.java index 1005aed57..da7675c6a 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreEntryComp.java @@ -35,6 +35,7 @@ import javafx.scene.layout.Region; import atlantafx.base.layout.InputGroup; import atlantafx.base.theme.Styles; +import javafx.scene.layout.StackPane; import org.kordamp.ikonli.javafx.FontIcon; import java.lang.ref.WeakReference; @@ -644,13 +645,18 @@ public abstract class StoreEntryComp extends SimpleRegionBuilder { var move = new Menu(AppI18n.get("category"), new FontIcon("mdi2f-folder-move-outline")); StoreViewState.get() .getSortedCategories( - getWrapper().getCategory().getValue().getRoot()) + getWrapper().getCategory().getValue().getRoot(), true) .getList() .forEach(storeCategoryWrapper -> { - MenuItem m = new MenuItem(); - m.textProperty() - .setValue(" ".repeat(storeCategoryWrapper.getDepth()) - + storeCategoryWrapper.getName().getValue()); + var m = new CustomMenuItem(); + + var l = new Label(); + l.setGraphic(PrettyImageHelper.ofFixedSizeSquare(storeCategoryWrapper.getIconFile().getValue(), 16) + .padding(new Insets(0, 0, 1, 0)).build()); + l.setText(storeCategoryWrapper.getName().getValue()); + l.setPadding(new Insets(0, 1, 1, storeCategoryWrapper.getDepth() * 10)); + m.setContent(l); + m.setOnAction(event -> { getWrapper().moveTo(storeCategoryWrapper.getCategory()); event.consume(); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java index 83cfe21d1..b7db6ad1c 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreViewState.java @@ -565,7 +565,7 @@ public class StoreViewState { } } - public DerivedObservableList getSortedCategories(StoreCategoryWrapper root) { + public DerivedObservableList getSortedCategories(StoreCategoryWrapper root, boolean requireExpanded) { Comparator comparator = new Comparator<>() { @Override public int compare(StoreCategoryWrapper o1, StoreCategoryWrapper o2) { @@ -620,6 +620,7 @@ public class StoreViewState { }; return categories .filtered(cat -> root == null || cat.getRoot().equals(root)) + .filtered(storeCategoryWrapper -> !requireExpanded || storeCategoryWrapper.isHierarchyExpanded()) .sorted(comparator); } diff --git a/app/src/main/java/io/xpipe/app/process/ScriptHelper.java b/app/src/main/java/io/xpipe/app/process/ScriptHelper.java index d26a33c42..adaf32ae4 100644 --- a/app/src/main/java/io/xpipe/app/process/ScriptHelper.java +++ b/app/src/main/java/io/xpipe/app/process/ScriptHelper.java @@ -27,23 +27,27 @@ public class ScriptHelper { @SneakyThrows public static FilePath createExecScript(ShellDialect type, ShellControl processControl, String content) { + return createExecScript(type, processControl, content, true); + } + + @SneakyThrows + public static FilePath createExecScript(ShellDialect type, ShellControl processControl, String content, boolean log) { content = type.prepareScriptContent(processControl, content); var fileName = "xpipe-" + getScriptHash(processControl, content); var temp = processControl.getSystemTemporaryDirectory(); var file = temp.join(fileName + "." + type.getScriptFileEnding()); - return createExecScriptRaw(processControl, file, content); + return createExecScriptRaw(processControl, file, content, log); } @SneakyThrows - public static FilePath createExecScriptRaw(ShellControl processControl, FilePath file, String content) { + public static FilePath createExecScriptRaw(ShellControl processControl, FilePath file, String content, boolean log) { if (processControl.view().fileExists(file)) { return file; } - TrackEvent.withTrace("Writing exec script") - .tag("file", file) - .tag("content", content) - .handle(); + if (log) { + TrackEvent.withTrace("Writing exec script").tag("file", file).tag("content", content).handle(); + } processControl.view().writeScriptFile(file, content); return file; } diff --git a/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java b/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java index cc613be6e..c2e9fd457 100644 --- a/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java +++ b/app/src/main/java/io/xpipe/app/terminal/TerminalLauncher.java @@ -35,7 +35,7 @@ public class TerminalLauncher { var content = constructTerminalInitScript(t, processControl, workingDirectory, preInit, postInit, config, exit); var hash = ScriptHelper.getScriptHash(processControl, content); var file = t.getInitFileName(processControl, hash); - return ScriptHelper.createExecScriptRaw(processControl, file, content); + return ScriptHelper.createExecScriptRaw(processControl, file, content, true); } private static String constructTerminalInitScript( diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java index 2cfe03d6a..afc33fc99 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/RunFileScriptMenuProvider.java @@ -104,12 +104,13 @@ public class RunFileScriptMenuProvider implements BrowserMenuBranchProvider { return new BrowserMenuBranchProvider() { @Override public LabelGraphic getIcon() { - if (!hierarchy.isLeaf()) { - return null; + if (hierarchy.isLeaf()) { + return new LabelGraphic.ImageGraphic(hierarchy.getScript().get().getEffectiveIconFile(), 16); + } else { + var cat = hierarchy.getCategory(); + var icon = cat.getEffectiveIconFile(); + return new LabelGraphic.ImageGraphic(icon, 16); } - - return new LabelGraphic.CompGraphic(PrettyImageHelper.ofFixedSize( - hierarchy.getScript().get().getEffectiveIconFile(), 16, 16)); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptActionProviderMenu.java b/ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptActionProviderMenu.java index d24c04ae2..7011ade84 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptActionProviderMenu.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/RunScriptActionProviderMenu.java @@ -376,9 +376,11 @@ public class RunScriptActionProviderMenu implements HubBranchProvider w.getParent() != null && !w.getCategory().getUuid().equals(DataStorage.PREDEFINED_SCRIPTS_CATEGORY_UUID) && !w.getCategory().getUuid().equals(DataStorage.SCRIPT_SOURCES_CATEGORY_UUID)); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStoreSetup.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStoreSetup.java index 77fe3891a..6bf0468cb 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStoreSetup.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptStoreSetup.java @@ -117,7 +117,7 @@ public class ScriptStoreSetup { } var applicable = refs.stream() - .filter(ss -> ss.getStore().isCompatible(sc.getShellDialect())) + .filter(ss -> ss.getStore().isCompatible(sc)) .toList(); if (applicable.isEmpty()) { return null; diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16-dark.png index aa3f4daa0..d5d488320 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16-dark.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16-dark.png differ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16.png index 2c1f1a681..7f902f54f 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-16.png differ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24-dark.png index 845a115ce..3bcf888da 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24-dark.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24-dark.png differ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24.png index c37139e51..9437355d5 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-24.png differ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40-dark.png index 3a0dabed7..ea09a1d9b 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40-dark.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40-dark.png differ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40.png index 9f23298b1..f426b80f8 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-40.png differ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80-dark.png index f0a8a45e7..2f124d88f 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80-dark.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80-dark.png differ diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80.png index 3aee47645..609c282de 100644 Binary files a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80.png and b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/connectionsCategory_icon-80.png differ diff --git a/img/base/connectionsCategory_icon-dark.svg b/img/base/connectionsCategory_icon-dark.svg index 7f789e4cf..f7f4b0dee 100644 --- a/img/base/connectionsCategory_icon-dark.svg +++ b/img/base/connectionsCategory_icon-dark.svg @@ -23,11 +23,11 @@ inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:zoom="2.7891646" - inkscape:cx="98.595831" - inkscape:cy="115.98455" + inkscape:cx="161.33863" + inkscape:cy="124.23075" inkscape:window-width="1920" - inkscape:window-height="1009" - inkscape:window-x="-8" + inkscape:window-height="1057" + inkscape:window-x="1912" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="Layer_1" />identity + x="46.382923" + y="136.12308" /> diff --git a/img/base/connectionsCategory_icon.svg b/img/base/connectionsCategory_icon.svg index 8cd0201ab..4a6fab4e2 100644 --- a/img/base/connectionsCategory_icon.svg +++ b/img/base/connectionsCategory_icon.svg @@ -23,11 +23,11 @@ inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:zoom="2.7891646" - inkscape:cx="98.595831" - inkscape:cy="115.98455" + inkscape:cx="161.33863" + inkscape:cy="124.23075" inkscape:window-width="1920" - inkscape:window-height="1009" - inkscape:window-x="-8" + inkscape:window-height="1057" + inkscape:window-x="1912" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="Layer_1" />identity + x="46.382923" + y="136.12308" /> diff --git a/lang/strings/translations_en.properties b/lang/strings/translations_en.properties index 5670bca1c..541e9fdce 100644 --- a/lang/strings/translations_en.properties +++ b/lang/strings/translations_en.properties @@ -1499,7 +1499,8 @@ enpassVaultFileDescription=The local Enpass vault file. #context: No hierarchy, just a single level flat=Flat recursive=Recursive -rdpAllowListBlocked=The selected RemoteApp does not seem to be included in the RDP allow list for the server. +#force +rdpAllowListBlocked=The selected RemoteApp is not included in the RDP allow list for the server and can't be launched. psonoServerUrl=Server URL psonoServerUrlDescription=URL of the psono backend server psonoApiKey=API Key