From ded364ab7bfba262ac32329389819eb6301b16d4 Mon Sep 17 00:00:00 2001 From: crschnick Date: Thu, 22 Jan 2026 15:33:26 +0000 Subject: [PATCH] Rework --- .../file/BrowserConnectionListFilterComp.java | 3 +- .../xpipe/app/comp/base/ListSelectorComp.java | 5 +- .../hub/comp/DataStoreCategoryChoiceComp.java | 8 +- .../xpipe/app/hub/comp/StoreChoiceComp.java | 39 ++++++--- .../app/hub/comp/StoreChoicePopover.java | 16 ++-- .../app/hub/comp/StoreComboChoiceComp.java | 1 + .../ext/base/identity/IdentitySelectComp.java | 1 + .../ScriptCollectionSourceImportDialog.java | 78 +++++++++++++++++- ...riptCollectionSourceImportHubProvider.java | 2 +- .../ScriptCollectionSourceStoreProvider.java | 3 +- ext/base/src/main/java/module-info.java | 2 +- .../img/desktopApplication_icon-16-dark.png | Bin 442 -> 472 bytes .../img/desktopApplication_icon-16.png | Bin 451 -> 478 bytes .../img/desktopApplication_icon-24-dark.png | Bin 562 -> 602 bytes .../img/desktopApplication_icon-24.png | Bin 576 -> 607 bytes .../img/desktopApplication_icon-40-dark.png | Bin 772 -> 839 bytes .../img/desktopApplication_icon-40.png | Bin 783 -> 840 bytes .../img/desktopApplication_icon-80-dark.png | Bin 1292 -> 1391 bytes .../img/desktopApplication_icon-80.png | Bin 1331 -> 1430 bytes img/base/desktopApplication_icon-dark.svg | 13 +-- img/base/desktopApplication_icon.svg | 14 ++-- lang/strings/translations_en.properties | 4 + 22 files changed, 152 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java b/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java index 9478a9e65..c662c3bc0 100644 --- a/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java +++ b/app/src/main/java/io/xpipe/app/browser/file/BrowserConnectionListFilterComp.java @@ -32,7 +32,8 @@ public final class BrowserConnectionListFilterComp extends SimpleRegionBuilder { var category = new DataStoreCategoryChoiceComp( StoreViewState.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory(), - this.category) + this.category, + true) .style(Styles.LEFT_PILL) .apply(struc -> { AppFontSizes.base(struc); diff --git a/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java b/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java index 23ac2d8c5..be39bb8ea 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ListSelectorComp.java @@ -11,6 +11,7 @@ import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.geometry.Orientation; import javafx.geometry.Pos; +import javafx.scene.Node; import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; @@ -65,6 +66,7 @@ public class ListSelectorComp extends SimpleRegionBuilder { } vbox.getChildren().clear(); cbs.clear(); + var newChildren = new ArrayList(); for (var v : currentVals) { var cb = new CheckBox(null); if (disable.test(v)) { @@ -105,8 +107,9 @@ public class ListSelectorComp extends SimpleRegionBuilder { event.consume(); }); l.opacityProperty().bind(cb.opacityProperty()); - vbox.getChildren().add(l); + newChildren.add(l); } + vbox.getChildren().addAll(newChildren); if (showAllSelector.get()) { var allSelector = new CheckBox(null); 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 380ff3f81..fef12d79f 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 @@ -19,17 +19,20 @@ public class DataStoreCategoryChoiceComp extends SimpleRegionBuilder { private final StoreCategoryWrapper root; private final Property external; private final Property value; + private final boolean applyExternalInitially; public DataStoreCategoryChoiceComp( - StoreCategoryWrapper root, Property external, Property value) { + StoreCategoryWrapper root, Property external, Property value, boolean applyExternalInitially) { this.root = root; this.external = external; this.value = value; + this.applyExternalInitially = applyExternalInitially; } @Override protected Region createSimple() { var initialized = new SimpleBooleanProperty(); + var last = value.getValue(); external.subscribe(newValue -> { if (newValue == null) { value.setValue(root); @@ -44,6 +47,9 @@ public class DataStoreCategoryChoiceComp extends SimpleRegionBuilder { } initialized.set(true); }); + if (!applyExternalInitially) { + value.setValue(last); + } var box = new ComboBox<>(StoreViewState.get().getSortedCategories(root).getList()); box.setValue(value.getValue()); box.valueProperty().addListener((observable, oldValue, newValue) -> { diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java index a3905321f..47937cd07 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoiceComp.java @@ -22,6 +22,8 @@ import javafx.scene.layout.Region; import atlantafx.base.theme.Styles; import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.val; import org.int4.fx.builders.common.AbstractRegionBuilder; import io.xpipe.app.comp.BaseRegionBuilder; import org.kordamp.ikonli.javafx.FontIcon; @@ -33,22 +35,33 @@ public class StoreChoiceComp extends SimpleRegionBuilder { private final ObjectProperty> selected; - private final StoreChoicePopover popover; + private StoreChoicePopover popover; public StoreChoiceComp( DataStoreEntry self, ObjectProperty> selected, Class storeClass, Predicate> applicableCheck, - StoreCategoryWrapper initialCategory) { + StoreCategoryWrapper categoryRoot) { + this(self, selected, storeClass, applicableCheck, categoryRoot, null); + } + + public StoreChoiceComp( + DataStoreEntry self, + ObjectProperty> selected, + Class storeClass, + Predicate> applicableCheck, + StoreCategoryWrapper categoryRoot, + StoreCategoryWrapper explicitCategory) { this.selected = selected; this.popover = new StoreChoicePopover<>( self, selected, storeClass, applicableCheck, - initialCategory, - "selectConnection", + categoryRoot, + explicitCategory, + StoreViewState.get().getAllConnectionsCategory().equals(categoryRoot) ? "selectConnection" : "selectEntry", "noCompatibleConnection"); } @@ -60,13 +73,21 @@ public class StoreChoiceComp extends SimpleRegionBuilder { return DataStorage.get().getStoreEntryDisplayName(entry); } + protected String toGraphic(DataStoreEntry entry) { + if (entry == null) { + return null; + } + + return entry.getEffectiveIconFile(); + } + @Override protected Region createSimple() { var button = new ButtonComp( Bindings.createStringBinding( () -> { var val = selected.getValue(); - return val != null ? toName(val.get()) : null; + return toName(val != null ? val.get() : null); }, selected), () -> {}); @@ -84,12 +105,7 @@ public class StoreChoiceComp extends SimpleRegionBuilder { BaseRegionBuilder graphic = PrettyImageHelper.ofFixedSize( Bindings.createStringBinding( () -> { - var val = selected.getValue(); - if (val == null) { - return null; - } - - return val.get().getEffectiveIconFile(); + return toGraphic(selected.getValue() != null ? selected.getValue().get() : null); }, selected), 16, @@ -119,6 +135,7 @@ public class StoreChoiceComp extends SimpleRegionBuilder { AppFontSizes.xl(dropdownIcon); var pane = new AnchorPane(r, dropdownIcon); + r.prefHeightProperty().bind(pane.heightProperty()); pane.focusedProperty().addListener((observable, oldValue, newValue) -> { if (newValue) { r.requestFocus(); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java index a29141848..d0547414f 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreChoicePopover.java @@ -43,7 +43,8 @@ public class StoreChoicePopover { private final Property> selected; private final Class storeClass; private final Predicate> applicableCheck; - private final StoreCategoryWrapper initialCategory; + private final StoreCategoryWrapper rootCategory; + private final StoreCategoryWrapper explicitCategory; private final String titleKey; private final String noMatchKey; private Consumer consumer; @@ -74,9 +75,9 @@ public class StoreChoicePopover { if (popover == null || applicableCheck != null) { var cur = StoreViewState.get().getActiveCategory().getValue(); var selectedCategory = new SimpleObjectProperty<>( - initialCategory != null - ? (initialCategory.getRoot().equals(cur.getRoot()) ? cur : initialCategory) - : cur); + explicitCategory != null ? explicitCategory : (rootCategory != null + ? (rootCategory.getRoot().equals(cur.getRoot()) ? cur : rootCategory) + : cur)); var filterText = new SimpleStringProperty(); popover = new Popover(); Predicate applicable = storeEntryWrapper -> { @@ -101,7 +102,7 @@ public class StoreChoicePopover { var applicableMatch = StoreViewState.get().getCurrentTopLevelSection().anyMatches(applicable); if (!applicableMatch) { - selectedCategory.set(initialCategory); + selectedCategory.set(rootCategory); } var applicableCount = StoreViewState.get().getAllEntries().getList().stream() @@ -134,9 +135,10 @@ public class StoreChoicePopover { initialExpanded); var category = new DataStoreCategoryChoiceComp( - initialCategory != null ? initialCategory.getRoot() : null, + rootCategory != null ? rootCategory.getRoot() : null, StoreViewState.get().getActiveCategory(), - selectedCategory) + selectedCategory, + explicitCategory == null) .style(Styles.LEFT_PILL); var filter = new FilterComp(filterText).style(Styles.CENTER_PILL).hgrow(); diff --git a/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java b/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java index 8e19f0913..60c8ddf06 100644 --- a/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java +++ b/app/src/main/java/io/xpipe/app/hub/comp/StoreComboChoiceComp.java @@ -75,6 +75,7 @@ public class StoreComboChoiceComp extends SimpleRegionBuild storeClass, applicableCheck, initialCategory, + null, "selectConnection", "noCompatibleConnection"); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java index 65c39160a..c44c9d6c4 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/IdentitySelectComp.java @@ -302,6 +302,7 @@ public class IdentitySelectComp extends RegionBuilder { IdentityStore.class, null, StoreViewState.get().getAllIdentitiesCategory(), + null, "selectIdentity", "noCompatibleIdentity"); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java index 8da759245..b141ff1a4 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportDialog.java @@ -1,25 +1,38 @@ package io.xpipe.ext.base.script; +import io.xpipe.app.comp.RegionBuilder; import io.xpipe.app.comp.base.*; import io.xpipe.app.core.AppI18n; import io.xpipe.app.ext.ShellDialectChoiceComp; import io.xpipe.app.ext.ShellDialectIcons; +import io.xpipe.app.hub.comp.StoreChoiceComp; +import io.xpipe.app.hub.comp.StoreCreationDialog; +import io.xpipe.app.hub.comp.StoreViewState; import io.xpipe.app.issue.ErrorEventFactory; import io.xpipe.app.platform.DerivedObservableList; import io.xpipe.app.platform.LabelGraphic; +import io.xpipe.app.platform.OptionsBuilder; import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.storage.DataStorage; +import io.xpipe.app.storage.DataStoreEntry; +import io.xpipe.app.storage.DataStoreEntryRef; import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.ThreadHelper; +import io.xpipe.core.FilePath; +import io.xpipe.ext.base.desktop.DesktopBaseStore; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.*; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; import lombok.Getter; import org.kordamp.ikonli.javafx.FontIcon; import java.util.ArrayList; import java.util.List; +import java.util.UUID; public class ScriptCollectionSourceImportDialog { @@ -30,6 +43,7 @@ public class ScriptCollectionSourceImportDialog { private final StringProperty filter = new SimpleStringProperty(); private final BooleanProperty busy = new SimpleBooleanProperty(); private final IntegerProperty count = new SimpleIntegerProperty(); + private final ObjectProperty> targetGroup = new SimpleObjectProperty<>(); public ScriptCollectionSourceImportDialog(ScriptCollectionSource source) { this.source = source; @@ -45,6 +59,7 @@ public class ScriptCollectionSourceImportDialog { var filterField = new FilterComp(filter).hgrow(); // Ugly solution to focus the filter on show filterField.apply(r -> { + HBox.setHgrow(r, Priority.SOMETIMES); r.sceneProperty().subscribe(s -> { if (s != null) { Platform.runLater(() -> { @@ -81,7 +96,35 @@ public class ScriptCollectionSourceImportDialog { var stack = new StackComp(List.of(notFound, selector)); stack.prefWidth(600); - stack.prefHeight(700); + stack.prefHeight(650); + + var storeChoice = new StoreChoiceComp<>( + null, + targetGroup, + ScriptGroupStore.class, + null, + StoreViewState.get().getAllScriptsCategory(), + StoreViewState.get().getAllScriptsCategory()) { + @Override + protected String toName(DataStoreEntry entry) { + if (entry == null) { + return AppI18n.get("selectCategory"); + } else { + return super.toName(entry); + } + } + + @Override + protected String toGraphic(DataStoreEntry entry) { + if (entry == null) { + return "scriptGroup_icon.svg"; + } else { + return super.toGraphic(entry); + } + } + }; + storeChoice.hgrow(); + storeChoice.maxHeight(100); var modal = ModalOverlay.of( Bindings.createStringBinding(() -> { @@ -91,13 +134,42 @@ public class ScriptCollectionSourceImportDialog { null); modal.addButtonBarComp(refresh); modal.addButtonBarComp(filterField); + modal.addButtonBarComp(storeChoice); modal.addButton(ModalButton.ok(() -> { - + ThreadHelper.runAsync(() -> { + finish(); + }); })) - .augment(button -> button.disableProperty().bind(Bindings.isEmpty(selected))); + .augment(button -> button.disableProperty().bind(Bindings.isEmpty(selected).or(targetGroup.isNull()))); modal.show(); } + private void finish() { + var targetCat = DataStorage.get().getStoreCategory(targetGroup.getValue().get()); + StoreViewState.get().selectCategoryIntoViewIfNeeded(StoreViewState.get().getCategoryWrapper(targetCat)); + + var added = new ArrayList(); + for (ScriptCollectionSourceEntry e : selected) { + var name = FilePath.of(e.getName()).getBaseName().toString(); + var textSource = ScriptTextSource.SourceReference.builder().entry(e).build(); + + var alreadyAdded = DataStorage.get().getStoreEntries().stream().anyMatch(entry -> entry.getStore() instanceof ScriptStore ss && + textSource.equals(ss.getTextSource())); + if (alreadyAdded) { + continue; + } + + var store = ScriptStore.builder().textSource(textSource).group(targetGroup.get()).build(); + var entry = DataStoreEntry.createNew(name, store); + DataStorage.get().addStoreEntryIfNotPresent(entry); + added.add(entry); + } + + if (added.size() == 1) { + StoreCreationDialog.showEdit(added.getFirst()); + } + } + private void update() { if (filter.get() == null) { shown.setAll(available); diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportHubProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportHubProvider.java index 2774d0eb4..b076ebee8 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportHubProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceImportHubProvider.java @@ -29,7 +29,7 @@ public class ScriptCollectionSourceImportHubProvider implements HubLeafProvider< @Override public LabelGraphic getIcon(DataStoreEntryRef store) { - return new LabelGraphic.IconGraphic("mdi2f-file-undo-outline"); + return new LabelGraphic.IconGraphic("mdi2i-import"); } @Override diff --git a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStoreProvider.java b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStoreProvider.java index a85ce00b5..19656d170 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStoreProvider.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/script/ScriptCollectionSourceStoreProvider.java @@ -91,8 +91,9 @@ public class ScriptCollectionSourceStoreProvider implements DataStoreProvider { return Bindings.createStringBinding(() -> { var s = st.getState(); var summary = st.getSource().toSummary(); + var init = s.getEntries() != null; var format = new StoreStateFormat(List.of(), summary, - s.getEntries() != null ? AppI18n.get("scriptsContained", s.getEntries().size()) : null); + init ? AppI18n.get("scriptsContained", s.getEntries().size()) : null, !init ? AppI18n.get("notInitialized") : null); return format.format(); }, section.getWrapper().getPersistentState(), AppI18n.activeLanguage()); } diff --git a/ext/base/src/main/java/module-info.java b/ext/base/src/main/java/module-info.java index ceb9265fb..5c2864f83 100644 --- a/ext/base/src/main/java/module-info.java +++ b/ext/base/src/main/java/module-info.java @@ -34,7 +34,7 @@ open module io.xpipe.ext.base { requires com.sun.jna; requires javafx.base; requires javafx.graphics; - + provides ActionProvider with IdentityApplyHubLeafProvider, AbstractHostCreationActionProvider, diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-16-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-16-dark.png index 0772f1e34190e37e9c3fcadd5f407848c1c22f50..98c26d421badaa5cf3218b3b2a999e4b8e50e62e 100644 GIT binary patch delta 361 zcmV-v0ha!{1K0zQcz;VtL_t(Ijm40?FN0AO#-DS0RrMwMHY#EfNhOwwM5+X7#A*?L zg4hifACshABo;#}O}d#h5(bMwD(TXJfkYx5BuFGARjNK-?>!bm>rxhe+dVhW?>zSc z{|)Jev&rs_lUm2H4R(AL^eH}Xx2%y*f~902oOV06zuRgP(SMaB87^2m+6L8FUI}!r zHo1;MMe9%kz)jTOFF*r|gtoF^W!s8&8|RO+m3Oib?FbPl!vGPpb|Zrz1k_!`A2jB2 zdu0Ma6a<6LY+wG=YPr@4+T?}VDla`sP%nUT0hk3qh!w`o&C;N$6O0*YESL!ZBo<>` z&5uOEcfl(WZ(cO5BPvL$^UpbRTU1_cO;2s6gQzf4@3|{|n)j#6}VM}3ww7SDY00000NkvXX Hu0mjfQ@oxP delta 331 zcmV-R0kriNqpJsE!sX5r0CB{t-55 z6O$`qx3P=FEU`%}9SpVj+$7Y}s`_Y~dyl1twztZ{v%TlMzvrCyh5tsvid8SQX2=Ry zU-zIC>e^WC5R|u4QxW6jyQu~dfdsG-x&szj4lE#pSs9(B|`sFaeWW$M1G;}mj znFm@0m?;Q*WAE|f;d(qwkg4>uUUUJ`$DLVMYqdn6))X|!6=URzp)Y8`t=BSv+5rG+ z7fz4+9SB@vY(xjb-O%*S{;vhG>{S6Me4SNHLO(8ix|P~%jyv#nSp67W2IhL?^R8=0 dKVJ3E_ynBnUJ!vgv{nEB002ovPDHLkV1i4Fq|5*S diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-16.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-16.png index 695ea36888636de15b110300f6b1ac0be907a879..cbb2eb5ea6796557a5ddd4b836f9bd84d7395796 100644 GIT binary patch delta 367 zcmV-#0g(Q~1KtCWcz;nzL_t(Ijir;%N;;Q16*mhTcZ0{8lsH@crhT;S4FI zFp9)TX#i4Zn)`DXWw(3HCUOl5PPW^%d7;+H*}`5nvU=w?tDHHG3^$);r zl+8pIPeZ=PsMUOs08lY~aexyfgtlbGY`e&HGkx?{a-PZRu78J7 zW(y{xRYc+sm`E&5YN*9xs7lbKgioT)cdtp))@_5n<9qWy_ndRj73Um-NC!#-#%ETy z5(VdE4J6hp=&t2H5!l_>G=6hJVKzhMI#z15nA2EP`DU z)xcY>wNW6!WqR+m*nMUmHb)mk-4%$?qZ$#xVr?ZK&t~?+>kdGqHY*^tA*nyc^~DF6 z3~g%s!zER89_R#!pg1_5HK~hflkx$UD-rA04FG-Ko`^S%&3tb_>lt&UCb?46+d{iO zqi_ZE1VG`&yG;lEq}JV9Wf#%Asp{L&p8@HE_cBm!0l|3(=aqByZp)|(Pc4a6V6JZ# mij62d>-PV(iR~KrH+}&hRV`bR{>z4P|1ml z4)_}d0Q|1)+F?2IjF{5^WW==rf%A!qo}$c`QfRp8Kf-fKxsGWH$ZngAm@S zj_IH#z$NW=dpn&`c5oJ(zSH)n?OW!gwYkuj9G9EgYGneUH8A^kPJ$QXqg&e-8n8IB z@y~~N=`UF**B(a`X=PvFF0Qe2)?~i3UB?q7Y0000cz>lyL_t(YiS3g;PZUuUhMzO{?uR>J2??bl31p!Vf`y5-jfK%d zv>P?1<{4Zo5-trk2Uw2cE^%c-76)pekL<&k=okxI9{nJGOde2E;@FRC3K| zw-^LYM3bDxseepY^SN80F@O|oW&o)EGoW?xuD@>H4xSa#G#+@c_{;BD*A}qw+YcXC z^OXp7$(O_%3(ajH)4G4MR(h}M&QnFaT3bL?B|BNSqiMb%hUYDVbu2FYkT}Ub@C9%p z>_-tR{YwWwFEya=b$R6C-jz?XXS43~eJ?xF2ZFG1W;<&$ydRnN^`1MnApNQD2Z7|wG50000-sZEG!6d5E2a?B4}}IYDioJM+I@w={5u{n&nU^_tq7==g;d9#`Wg+-S4JX z=$X!+_xzso@*dtp%#2D(RFr-m2C7uR8UzbUWVg8aD9fPd}IWuph5k8ZA0R1F?Z zwJt0NL2q1ep&E=eo%Ux-WCj_bI-2u(zZ|e5h%cU(+*MM!A2bx1!M|vHqV@KCL$Cq> zUD@p1`4oBk5v3f}3^Vgh0%V+nOfYb~!F9P;SI77u(!inm9hiHljGGYyAR3@d&W~yxwA05c0KCHW`!Cx+ z>y(%H17~E88Tiot4UxVcCxereu1Yo?jZ@BX%GtS+y=tf&T{K1mK%>!nZ3lXE?AccO zObwQXKK#`XEB_yG(&SDHNx}{Yg17a#(&>^@5R_A#h{C*u~HqR3OWeRB8U_m zLKX9sby;wVTpp(=t3sZFrSd-phq(gfeji){*i+dcQ3 z?>pz7%Q-SLMhQ1k_U#Y|2RYQ|N>?R!4y>4$R8n0QFYaGxe}7O`59+njO`-X`#62R= zXh+3knH5MniRtBV)K&nF8&t=->t`}6_!qpNt4un@?*N3ZZBLU|YTD^lo;9-*f*?`$MU4z4aALC zoq>Km0@q)6I%n%~BN09;C;&J0%^w7!jrK;Z{K!e;zt1LH>k)_&3P->C!+9!5!DaaK zy3Hi9X9H)^kXQyh*c(T1x4PK;yrlxwh3`}Sw$bkcD@(?$&5{&}QaRj#`>l__(kA$y z@10-$l6DyaIFbvV@E+JH`o3NUx}X zwK53$w^1F7I#g1zf`2+xhaiO5vQq~M>QoVQFo=jOvLZ2+tR?#^OYR>xXJ>vLWNg(@ zc)K%du%Fv|@Avz?4{zSgn+N2{lV?s?wux761hz*R_GuC?v42ZO)hSY_^J^!Lyn18y z2@8fokfSTtzI@@8YYn^1GH?;0ZdB`R4)*K;04`c!Y(8 zpkPNwz0&QKH#?*D4+8LBk&Xj^ERq->A6ZfEmZQ+@U%zoM&qqb_n(bj1F9dRUN$loQ zxc0yuzvq_Oc7GG$$*yiDya(r-MK3sG4^pUJP8NJE(+pDVn83wZO0DSo&KjU+lRqg) zp&EC>tu@6ld<;7Lk{xyc44n`ks2Yj2;;OImLyM^Byr0~F2V)zvE^0EAUWUEiN7$i0%esc;hkBi- z4?dpEx~NGpkE7Nzm{SeQ6|0R5lfk!L0J`RiS(JM)lmA7KIdzM) zLTD}y0F3CfGcGeBjvzVQ#M%BO zjRQYLlBV2?V;3uHU`R&+qZ(kgTuTT@gQ1twQhU+)-hMl3=E;*MgTDyB%a)ZJ1bP4f N002ovPDHLkV1h@IR!#r_ delta 664 zcmV;J0%!fl280HXcz<_EL_t(oh3%J3NEBfhfS>Q1-F0#epcdiMh8DAsRG|dv4|U9*a5aB6c!Rc^BHD3`?6`LqC1zk5G+3t z7zaF?3{~_1Q^m!^W2cE4AfFyMjgs@8YwbaVk>Z_!6Ham}J9x$ipPE=&&N^AYC8#9k zi%qSDLbsFkH7Cis7RHX|$c9}#csnFbgPE@}+HChVYJUp8=-lLGbklv+ZI*);Zz3BE z=i6M@sQIEE+%SmPjZeXtrAeB>hHBK@!QPDkv-3UXuYjFzr1)V=ceUH9?)DYZ{llWv zG=MEc_MA5B3Iaq#g(D@ylW9^9LB~Ok*E#(jns*l4D3yWc6kJm<5}lZT1r9%0y~ffq zYrtsbSbvmSEmL}ZXnbj{68oou-4od*;L$;An(-3v;(rlT4Gbg4IO?SVl*qC_F8dM9 zCnxJQfEMd1+iz~4$szVLCkYy${k diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-40.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-40.png index 63e0fd80040043f18d0c712cfd3b8bedb3f38b81..fbe7044a2f6788f2faffd685da29352f5b739293 100644 GIT binary patch delta 732 zcmV<20wev82FM1Gcz?S|L_t(oh3%KiOBGQZ$G^XsJ9F=ynX9I~Fnef73&B-O3AD#Q zAk?Y{Eecu`7-ZeB7|?2wfkFt;!c_}5JytD*av37@!d{emr>GDW^*UXfd*`&cjcIpo zapun82!3|w@%x<*=bSlb4l%|MW`xxi_#f+nr4o9IG<<+(CW8U0YoQ^HgzvgNPY%w><>i91qSf|Pk(;_00csLFgkA76+FFNZ;}Nl zIGeeN_jY|rDh=W&dgKd;(xT@au7ZQPW(?+-;f zEESB63nYy5bQb_XB6|QpCJ3Lun3J>YK2LxE09Do9ra_FI1YiZCl_x`>V_SRYCwYQa zyo*z9i3R|tK-dEY(GM#I$^v*J=BTfxXZ8bcd}to-#aJ81Oqf|0ER|o*ILgeoRUnQ4 O0000#8 zx`lqXotZcDF*A8DqeO%tqc>XMUu+3_CGdh_w}Dgr>F$Pb0)IuOeLB`RE5ysa_ZFv{ zEz0q)xS({&G=>E(;m-+FMHuKBDnG={0u!cjUEs2t*#9K16c391>9aUqq@cnI^1f)T zMS)xehj(y#*2oa%y+2Np26gn;CkMgJ9rTIPmE;l8`t5H`KXQZRMBvj*;04#;!Ga2x zDv6y^i^SWpfPaeAs(ZdvW*C)*oA_11j|CMq%wz$KJ|F|G=39re{kg+t~pWio26foCa!uiT>0{;9R?{)}d5yDW5#-BxHF9El&9&WP=bo z?PRw=BiL@y{@DhJn(H}NNi9LooaJc_+a1g;2rr&hs`D{j_A>eQs+Ep6h_&i3 z4j5;!^c?`SPX5tdZ7B$ls1r}rt+rH?mRKqSa;Qb`2MBI0wnVrM!4xzR>FpXSzXA`B zruGne2Y*&y^Gm@@EgF8k@9v!0Y}-)5+~E8;@c3_If_TJh*c^fa-m<9^#MxRaf>QLy z#s;OoIvK73BFY+NC3E}CLbNW=odjrr&ij>;61f1hp#rz0s!->5jg-GT30m_mF6L7Q zfQu-45WN4L0R&YCK7|_UQFhq;>@+?w5BFAVjvO=-WVQso@)LuoyuQJ)q=x_i002ov JPDHLkV1gD=MsolF diff --git a/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-80-dark.png b/ext/base/src/main/resources/io/xpipe/ext/base/resources/img/desktopApplication_icon-80-dark.png index f345032da4bb084ce42ef171272446be0960c9a3..c0bb5ebffbdc8918c1ca765c5c827ffb9877f182 100644 GIT binary patch delta 1288 zcmV+j1^4=l3hxS#cz@zaL_t(|ob8)iY!p=($N%44cDuJ$p{P_Y3M~X{u-bst#FQ$g zK45$xl!%F%Ks8F_K?zhKaWQd4;Xw?bRS+MbYA{g~6JJV*!3#!e+CbG_5Q%N6fEsqY z?RIwO9G`Z>_F{K-JTomlzo#>2X3qbc-?lSfHambsB9TZW5`T$AB9Ta@802)|-uLdj z|Ds2IrB7FvM^y^M6lhM@FcBKSLn#0~c87KXot`4s@!-+f*DBxHbOMUd})2-{W z=N;g5fv06E%YOp^210X4dwkcSifz}<3m3TSP{p=ZpLUz*94BBPd>d4E9ywB4n4S|Z z@RtJGEIPwUE^CT*&Ir7j-WDow-@YaDyS>_tA~W2eS65c0$3g`r3iK7`6no<4!WEs0 z(_^tcSc;!tF_8L7Xodi;sHiyW(`JviKdvZxdVC%JeSg?z$Kks^ZZ7n!9dCb-G2XnU zMFAXYW3FeUK$}Q`Hjx5tA_dw+3baX1ec+{VdC=!G<|<6}i!LZ1OwQt=g24;)V$YD% z+2ac295fJFyavRc1CkHGB$a_VSzFE!fPsYHh(*dyD4g~Nws$(#ypJg`7Ac)I@Va^o z#H*)JuYc_UsFo3GW3Mgx!bq|wXNJ3@qC-dB1EYHu6$8q50IwDuE)2qB9*=sWfA`XW z=%`Tw$v_i;QqjTU;rIAciFZY(WC@H$%2ok*SahgU5XTc&BW3rB%uup7=vk3rEQ3%_-B?WB;GCdU0Z5MAwR4VDD=_sIDkT`l{s^Hh#ZsO2_BgNa(- zDb)H-Sv_^q(dVH@+kE;QtLGJ(Fw$e$NPp)+agz0?$5LP(lqAh#>9G`OkvYRGu{dPz zNN-Dl7SK7zvbgblU0r+T9ysY+XJM42TdLinf#AilKjK1>)ZA>5yosdr?tR6PqkI$bl`^ZcYn!; zh)twGn@E8+kpgWZ1=>Ukw22gGlZ-%JPdfhVPNxVNQDN7X5m=D$^#haiC#d%Lhr)e> zq885xq;R_d&<~=5T;yw!i)Y^hi8qN1a|I%y*OVnN7+~)M_)TP>lW^e2U_-~JA~UiC z(x&cV;(Rp$agm`8@i!-P9gXuX%76dGs5U0Jy{nZecm%*Dk-;M2zy(t9VA0Fxxc63d?1b} y5$_5F*h$*dJ?wTp5{X12kw_#Gi9{lne*tKtU;gb+jBx+}002ovPDHLkU;%>ioMr<6 delta 1188 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 zd|cdlKvaImycbIXv_x)k2}yT){7zidentityidentity + style="fill:#f38626;fill-opacity:1;stroke-width:0.333356" /> diff --git a/img/base/desktopApplication_icon.svg b/img/base/desktopApplication_icon.svg index d150e2bf9..f53571aed 100644 --- a/img/base/desktopApplication_icon.svg +++ b/img/base/desktopApplication_icon.svg @@ -22,9 +22,9 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" - inkscape:zoom="1.3945823" - inkscape:cx="-15.775333" - inkscape:cy="89.991103" + inkscape:zoom="0.9861186" + inkscape:cx="-11.154845" + inkscape:cy="-62.365723" inkscape:window-width="1920" inkscape:window-height="1009" inkscape:window-x="-8" @@ -37,7 +37,7 @@ id="title858">identityidentity + style="fill:#e1710c;fill-opacity:1;stroke-width:0.333356" + sodipodi:nodetypes="ccsssssccccssssssssssssssss" /> diff --git a/lang/strings/translations_en.properties b/lang/strings/translations_en.properties index 937d1529b..d185cbb11 100644 --- a/lang/strings/translations_en.properties +++ b/lang/strings/translations_en.properties @@ -74,6 +74,7 @@ customCommand=Custom command other=Other setLock=Set lock selectConnection=Select connection +selectEntry=Select entry createLock=Create passphrase changeLock=Change passphrase test=Test @@ -1928,3 +1929,6 @@ importScripts=Import scripts scriptsContained=$NUMBER$ scripts scriptSourceCollectionImportTitle=Import scripts from source ($COUNT$) noScriptsFound=No scripts found +tunnel=Tunnel +notInitialized=Not initialized +selectCategory=Select category ...