mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Desktop rework
This commit is contained in:
parent
d9e23b9ebf
commit
dd3ccf37d3
27 changed files with 1215 additions and 42 deletions
|
@ -6,7 +6,6 @@ import io.xpipe.app.fxcomps.SimpleComp;
|
|||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.core.process.ShellStoreState;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.layout.Region;
|
||||
|
@ -25,16 +24,14 @@ public class SystemStateComp extends SimpleComp {
|
|||
|
||||
@Override
|
||||
protected Region createSimple() {
|
||||
var icon = PlatformThread.sync(Bindings.createStringBinding(
|
||||
() -> {
|
||||
return state.getValue() == State.FAILURE
|
||||
? "mdi2l-lightning-bolt"
|
||||
: state.getValue() == State.SUCCESS ? "mdal-check" : "mdsmz-remove";
|
||||
},
|
||||
state));
|
||||
var fi = new FontIcon();
|
||||
fi.getStyleClass().add("inner-icon");
|
||||
icon.subscribe(val -> fi.setIconLiteral(val));
|
||||
state.subscribe(s -> {
|
||||
var i = s == State.FAILURE
|
||||
? "mdi2l-lightning-bolt"
|
||||
: s == State.SUCCESS ? "mdal-check" : "mdsmz-remove";
|
||||
PlatformThread.runLaterIfNeeded(() -> fi.setIconLiteral(i));
|
||||
});
|
||||
|
||||
var border = new FontIcon("mdi2c-circle-outline");
|
||||
border.getStyleClass().add("outer-icon");
|
||||
|
|
|
@ -27,7 +27,7 @@ public class StoreCreationMenu {
|
|||
menu.getItems().add(category("addHost", "mdi2h-home-plus", DataStoreProvider.CreationCategory.HOST, "ssh"));
|
||||
|
||||
menu.getItems()
|
||||
.add(category("addVisual", "mdi2c-camera-plus", DataStoreProvider.CreationCategory.VISUAL, null));
|
||||
.add(category("addDesktop", "mdi2c-camera-plus", DataStoreProvider.CreationCategory.DESKSTOP, null));
|
||||
|
||||
menu.getItems()
|
||||
.add(category("addShell", "mdi2t-text-box-multiple", DataStoreProvider.CreationCategory.SHELL, null));
|
||||
|
|
|
@ -24,7 +24,6 @@ import javafx.beans.value.ObservableValue;
|
|||
import java.util.List;
|
||||
|
||||
public interface DataStoreProvider {
|
||||
|
||||
default boolean editByDefault() {
|
||||
return false;
|
||||
}
|
||||
|
@ -208,6 +207,6 @@ public interface DataStoreProvider {
|
|||
TUNNEL,
|
||||
SCRIPT,
|
||||
CLUSTER,
|
||||
VISUAL;
|
||||
DESKSTOP;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package io.xpipe.app.ext;
|
||||
|
||||
import io.xpipe.app.comp.base.StoreToggleComp;
|
||||
import io.xpipe.app.comp.base.SystemStateComp;
|
||||
import io.xpipe.app.comp.store.StoreEntryComp;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.comp.store.StoreSection;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.core.store.SingletonToggleSessionStore;
|
||||
import io.xpipe.core.store.ToggleSessionState;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
|
||||
public interface SingletonToggleSessionStoreProvider extends DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public default StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||
SingletonToggleSessionStore<?> s = sec.getWrapper().getEntry().getStore().asNeeded();
|
||||
|
||||
var enabled = new SimpleBooleanProperty();
|
||||
sec.getWrapper().getPersistentState().subscribe((newValue) -> {
|
||||
var rdps = (ToggleSessionState) newValue;
|
||||
enabled.set(rdps.getEnabled() != null ? rdps.getEnabled() : false);
|
||||
});
|
||||
|
||||
var t = new StoreToggleComp(null, sec, enabled, aBoolean -> {
|
||||
var state = s.getState();
|
||||
if (state.getEnabled() != aBoolean) {
|
||||
state.setEnabled(aBoolean);
|
||||
s.setState(state);
|
||||
sec.getWrapper().getEntry().validate();
|
||||
}
|
||||
});
|
||||
return StoreEntryComp.create(sec.getWrapper(), t, preferLarge);
|
||||
}
|
||||
|
||||
public default Comp<?> stateDisplay(StoreEntryWrapper w) {
|
||||
SingletonToggleSessionStore<?> st = w.getEntry().getStore().asNeeded();
|
||||
return new SystemStateComp(
|
||||
Bindings.createObjectBinding(
|
||||
() -> {
|
||||
ToggleSessionState s = (ToggleSessionState) w.getPersistentState().getValue();
|
||||
if (s.getEnabled() == null || !s.getEnabled()) {
|
||||
return SystemStateComp.State.OTHER;
|
||||
}
|
||||
|
||||
return s.getRunning() != null && s.getRunning()
|
||||
? SystemStateComp.State.SUCCESS
|
||||
: SystemStateComp.State.FAILURE;
|
||||
},
|
||||
w.getPersistentState(),
|
||||
w.getCache()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void storageInit() {
|
||||
for (DataStoreEntry e : DataStorage.get().getStoreEntries()) {
|
||||
if (getStoreClasses().stream()
|
||||
.anyMatch(aClass ->
|
||||
e.getStore() != null && e.getStore().getClass().equals(aClass))) {
|
||||
SingletonToggleSessionStore<?> tunnelStore = e.getStore().asNeeded();
|
||||
var state = tunnelStore.getState();
|
||||
state.setEnabled(false);
|
||||
tunnelStore.setState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -51,6 +51,7 @@ public class ChoiceComp<T> extends Comp<CompStructure<ComboBox<T>>> {
|
|||
@Override
|
||||
public CompStructure<ComboBox<T>> createBase() {
|
||||
var cb = new ComboBox<T>();
|
||||
cb.setMaxWidth(2000);
|
||||
cb.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(T object) {
|
||||
|
|
|
@ -34,7 +34,7 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue {
|
|||
return getId();
|
||||
}
|
||||
|
||||
public static class MacApplication extends ExternalApplicationType {
|
||||
public static abstract class MacApplication extends ExternalApplicationType {
|
||||
|
||||
protected final String applicationName;
|
||||
|
||||
|
|
|
@ -431,6 +431,10 @@ public class DataStoreEntry extends StorageElement {
|
|||
}
|
||||
|
||||
public void validateOrThrow() throws Throwable {
|
||||
if (store == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
store.checkComplete();
|
||||
setInRefresh(true);
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.xpipe.app.util.CommandSupport;
|
|||
import io.xpipe.app.util.LocalShell;
|
||||
import io.xpipe.core.process.*;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.core.util.FailableFunction;
|
||||
import lombok.Getter;
|
||||
import lombok.Value;
|
||||
import lombok.With;
|
||||
|
@ -18,7 +19,6 @@ import java.util.ArrayList;
|
|||
import java.util.Base64;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||
|
||||
|
@ -152,6 +152,18 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
.envrironment("GNOME_TERMINAL_SCREEN", sc -> "");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand() {
|
||||
return launchConfiguration -> {
|
||||
var toExecute = CommandBuilder.of()
|
||||
.add(executable, "-v", "--title")
|
||||
.addQuoted(launchConfiguration.getColoredTitle())
|
||||
.add("--")
|
||||
.addFile(launchConfiguration.getScriptFile());
|
||||
return toExecute.buildSimple();
|
||||
};
|
||||
}
|
||||
};
|
||||
ExternalTerminalType KONSOLE = new SimplePathType("app.konsole", "konsole", true) {
|
||||
|
||||
|
@ -551,6 +563,17 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
.addQuoted("Warp.app")
|
||||
.addFile(configuration.getScriptFile()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand() {
|
||||
return launchConfiguration -> {
|
||||
var toExecute = CommandBuilder.of()
|
||||
.add("open", "-a")
|
||||
.addQuoted("Warp.app")
|
||||
.addFile(launchConfiguration.getScriptFile());
|
||||
return toExecute.buildSimple();
|
||||
};
|
||||
}
|
||||
};
|
||||
ExternalTerminalType CUSTOM = new CustomTerminalType();
|
||||
List<ExternalTerminalType> WINDOWS_TERMINALS = List.of(
|
||||
|
@ -588,24 +611,31 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
WezTerminalType.WEZTERM_MAC_OS,
|
||||
MACOS_TERMINAL);
|
||||
|
||||
@SuppressWarnings("TrivialFunctionalExpressionUsage")
|
||||
List<ExternalTerminalType> ALL = ((Supplier<List<ExternalTerminalType>>) () -> {
|
||||
var all = new ArrayList<ExternalTerminalType>();
|
||||
if (OsType.getLocal().equals(OsType.WINDOWS)) {
|
||||
all.addAll(WINDOWS_TERMINALS);
|
||||
}
|
||||
if (OsType.getLocal().equals(OsType.LINUX)) {
|
||||
all.addAll(LINUX_TERMINALS);
|
||||
}
|
||||
if (OsType.getLocal().equals(OsType.MACOS)) {
|
||||
all.addAll(MACOS_TERMINALS);
|
||||
}
|
||||
// Prefer with tabs
|
||||
all.sort(Comparator.comparingInt(o -> (o.supportsTabs() ? -1 : 0)));
|
||||
all.add(CUSTOM);
|
||||
return all;
|
||||
})
|
||||
.get();
|
||||
List<ExternalTerminalType> APPLICABLE = getTypes(OsType.getLocal(), false, true);
|
||||
|
||||
List<ExternalTerminalType> ALL = getTypes(null, false, true);
|
||||
|
||||
static List<ExternalTerminalType> getTypes(OsType osType, boolean remote, boolean custom) {
|
||||
var all = new ArrayList<ExternalTerminalType>();
|
||||
if (osType == null || osType.equals(OsType.WINDOWS)) {
|
||||
all.addAll(WINDOWS_TERMINALS);
|
||||
}
|
||||
if (osType == null || osType.equals(OsType.LINUX)) {
|
||||
all.addAll(LINUX_TERMINALS);
|
||||
}
|
||||
if (osType == null || osType.equals(OsType.MACOS)) {
|
||||
all.addAll(MACOS_TERMINALS);
|
||||
}
|
||||
if (remote) {
|
||||
all.removeIf(externalTerminalType -> externalTerminalType.remoteLaunchCommand() == null);
|
||||
}
|
||||
// Prefer recommended
|
||||
all.sort(Comparator.comparingInt(o -> (o.isRecommended() ? -1 : 0)));
|
||||
if (custom) {
|
||||
all.add(CUSTOM);
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
static ExternalTerminalType determineDefault(ExternalTerminalType existing) {
|
||||
// Check for incompatibility with fallback shell
|
||||
|
@ -618,7 +648,7 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
return existing;
|
||||
}
|
||||
|
||||
return ALL.stream()
|
||||
return APPLICABLE.stream()
|
||||
.filter(externalTerminalType -> !externalTerminalType.equals(CUSTOM))
|
||||
.filter(terminalType -> terminalType.isAvailable())
|
||||
.findFirst()
|
||||
|
@ -641,6 +671,10 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
|
||||
default void launch(LaunchConfiguration configuration) throws Exception {}
|
||||
|
||||
default FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand() {
|
||||
return null;
|
||||
}
|
||||
|
||||
abstract class WindowsType extends ExternalApplicationType.WindowsType implements ExternalTerminalType {
|
||||
|
||||
public WindowsType(String id, String executable) {
|
||||
|
@ -715,6 +749,18 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
|||
launch(configuration.getColoredTitle(), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FailableFunction<LaunchConfiguration, String, Exception> remoteLaunchCommand() {
|
||||
return launchConfiguration -> {
|
||||
var args = toCommand(launchConfiguration);
|
||||
args.add(0, executable);
|
||||
if (explicityAsync) {
|
||||
args = launchConfiguration.getScriptDialect().launchAsnyc(args);
|
||||
}
|
||||
return args.buildSimple();
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract CommandBuilder toCommand(LaunchConfiguration configuration) throws Exception;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.app.storage;
|
||||
package io.xpipe.app.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
|
@ -6,8 +6,8 @@ import com.fasterxml.jackson.databind.*;
|
|||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.xpipe.app.util.PasswordLockSecretValue;
|
||||
import io.xpipe.app.util.VaultKeySecretValue;
|
||||
import io.xpipe.app.storage.*;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.core.store.LocalStore;
|
||||
import io.xpipe.core.util.EncryptedSecretValue;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
|
@ -16,7 +16,7 @@ import io.xpipe.core.util.SecretValue;
|
|||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class StorageJacksonModule extends SimpleModule {
|
||||
public class AppJacksonModule extends SimpleModule {
|
||||
|
||||
@Override
|
||||
public void setupModule(SetupContext context) {
|
||||
|
@ -29,6 +29,8 @@ public class StorageJacksonModule extends SimpleModule {
|
|||
addDeserializer(ContextualFileReference.class, new LocalFileReferenceDeserializer());
|
||||
addSerializer(DataStoreSecret.class, new DataStoreSecretSerializer());
|
||||
addDeserializer(DataStoreSecret.class, new DataStoreSecretDeserializer());
|
||||
addSerializer(ExternalTerminalType.class, new ExternalTerminalTypeSerializer());
|
||||
addDeserializer(ExternalTerminalType.class, new ExternalTerminalTypeDeserializer());
|
||||
|
||||
context.addSerializers(_serializers);
|
||||
context.addDeserializers(_deserializers);
|
||||
|
@ -51,6 +53,24 @@ public class StorageJacksonModule extends SimpleModule {
|
|||
}
|
||||
}
|
||||
|
||||
public static class ExternalTerminalTypeSerializer extends JsonSerializer<ExternalTerminalType> {
|
||||
|
||||
@Override
|
||||
public void serialize(ExternalTerminalType value, JsonGenerator jgen, SerializerProvider provider)
|
||||
throws IOException {
|
||||
jgen.writeString(value.getId());
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExternalTerminalTypeDeserializer extends JsonDeserializer<ExternalTerminalType> {
|
||||
|
||||
@Override
|
||||
public ExternalTerminalType deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
var id = p.getValueAsString();
|
||||
return ExternalTerminalType.ALL.stream().filter(terminalType -> terminalType.getId().equals(id)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DataStoreSecretSerializer extends JsonSerializer<DataStoreSecret> {
|
||||
|
||||
@Override
|
|
@ -7,7 +7,7 @@ import io.xpipe.app.ext.*;
|
|||
import io.xpipe.app.issue.EventHandler;
|
||||
import io.xpipe.app.issue.EventHandlerImpl;
|
||||
import io.xpipe.app.storage.DataStateProviderImpl;
|
||||
import io.xpipe.app.storage.StorageJacksonModule;
|
||||
import io.xpipe.app.util.AppJacksonModule;
|
||||
import io.xpipe.app.util.LicenseProvider;
|
||||
import io.xpipe.app.util.ProxyManagerProviderImpl;
|
||||
import io.xpipe.app.util.TerminalLauncher;
|
||||
|
@ -114,8 +114,7 @@ open module io.xpipe.app {
|
|||
uses LicenseProvider;
|
||||
uses io.xpipe.app.util.LicensedFeature;
|
||||
|
||||
provides Module with
|
||||
StorageJacksonModule;
|
||||
provides Module with AppJacksonModule;
|
||||
provides ModuleLayerLoader with
|
||||
MessageExchangeImpls.Loader,
|
||||
DataStoreProviders.Loader,
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
public interface SingletonSessionStore<T extends SingletonSessionStore.Session> extends InternalCacheDataStore {
|
||||
|
||||
static abstract class Session {
|
||||
|
||||
public abstract boolean isRunning();
|
||||
|
||||
public abstract void start() throws Exception;
|
||||
|
||||
public abstract void stop() throws Exception;
|
||||
}
|
||||
|
||||
void onSessionUpdate(boolean active);
|
||||
|
||||
T newSession() throws Exception;
|
||||
|
||||
Class<?> getSessionClass();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default T getSession() {
|
||||
return (T) getCache("session", getSessionClass(), null);
|
||||
}
|
||||
|
||||
default void startIfNeeded() throws Exception {
|
||||
var s = getSession();
|
||||
if (s != null) {
|
||||
if (s.isRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
s.start();
|
||||
return;
|
||||
}
|
||||
|
||||
s = newSession();
|
||||
s.start();
|
||||
setCache("session", s);
|
||||
onSessionUpdate(true);
|
||||
}
|
||||
|
||||
|
||||
default void stopIfNeeded() throws Exception {
|
||||
var ex = getSession();
|
||||
setCache("session", null);
|
||||
if (ex != null) {
|
||||
ex.stop();
|
||||
onSessionUpdate(false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
public interface SingletonToggleSessionStore<T extends SingletonSessionStore.Session> extends SingletonSessionStore<T>, StatefulDataStore<ToggleSessionState>, ValidatableStore {
|
||||
|
||||
@Override
|
||||
default Class<ToggleSessionState> getStateClass() {
|
||||
return ToggleSessionState.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void onSessionUpdate(boolean active) {
|
||||
var c = getState();
|
||||
c.setRunning(active);
|
||||
if (!active) {
|
||||
c.setEnabled(false);
|
||||
} else {
|
||||
c.setEnabled(true);
|
||||
}
|
||||
setState(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public default void validate() throws Exception {
|
||||
if (getState().getEnabled() != null) {
|
||||
if (getState().getEnabled()) {
|
||||
startIfNeeded();
|
||||
} else {
|
||||
stopIfNeeded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
public class ToggleSessionState extends DataStoreState {
|
||||
|
||||
Boolean enabled;
|
||||
Boolean running;
|
||||
|
||||
@Override
|
||||
public void merge(DataStoreState newer) {
|
||||
var state = (ToggleSessionState) newer;
|
||||
enabled = useNewer(enabled, state.enabled);
|
||||
running = useNewer(running, state.running);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package io.xpipe.ext.base.desktop;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.storage.ContextualFileReference;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
@Getter
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
@JsonTypeName("desktopApplication")
|
||||
public class DesktopApplicationStore extends JacksonizedValue implements DataStore {
|
||||
|
||||
private final DataStoreEntryRef<DesktopBaseStore> desktop;
|
||||
private final ContextualFileReference path;
|
||||
private final String arguments;
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
Validators.nonNull(desktop);
|
||||
Validators.isType(desktop, DesktopBaseStore.class);
|
||||
Validators.nonNull(path);
|
||||
}
|
||||
|
||||
public String getFullCommand() {
|
||||
var builder = CommandBuilder.of().addFile(path.toAbsoluteFilePath(null)).add(arguments != null ? " " + arguments : "");
|
||||
builder = desktop.getStore().getUsedDialect().launchAsnyc(builder);
|
||||
return builder.buildSimple();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package io.xpipe.ext.base.desktop;
|
||||
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.ext.GuiDialog;
|
||||
import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp;
|
||||
import io.xpipe.app.storage.ContextualFileReference;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.util.DataStoreFormatter;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DesktopApplicationStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public ActionProvider.Action browserAction(BrowserSessionModel sessionModel, DataStoreEntry store, BooleanProperty busy) {
|
||||
DesktopApplicationStore s = store.getStore().asNeeded();
|
||||
return new ActionProvider.Action() {
|
||||
@Override
|
||||
public boolean requiresJavaFXPlatform() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
s.getDesktop().getStore().runScript(store.getName(), s.getDesktop().getStore().getUsedDialect(), s.getFullCommand());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionProvider.Action launchAction(DataStoreEntry store) {
|
||||
DesktopApplicationStore s = store.getStore().asNeeded();
|
||||
return new ActionProvider.Action() {
|
||||
@Override
|
||||
public boolean requiresJavaFXPlatform() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
s.getDesktop().getStore().runScript(store.getName(), s.getDesktop().getStore().getUsedDialect(), s.getFullCommand());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreationCategory getCreationCategory() {
|
||||
return CreationCategory.DESKSTOP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreEntry getDisplayParent(DataStoreEntry store) {
|
||||
DesktopApplicationStore s = store.getStore().asNeeded();
|
||||
return s.getDesktop().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiDialog guiDialog(DataStoreEntry entry, Property<DataStore> store) {
|
||||
DesktopApplicationStore st = (DesktopApplicationStore) store.getValue();
|
||||
var host = new SimpleObjectProperty<>(st.getDesktop());
|
||||
var path = new SimpleStringProperty(st.getPath() != null ? st.getPath().toAbsoluteFilePath(null) : null);
|
||||
var args = new SimpleStringProperty(st.getArguments() != null ? st.getArguments() : null);
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("desktopEnvironmentBase")
|
||||
.addComp(
|
||||
new DataStoreChoiceComp<>(
|
||||
DataStoreChoiceComp.Mode.HOST,
|
||||
entry,
|
||||
host,
|
||||
DesktopBaseStore.class,
|
||||
desktopStoreDataStoreEntryRef -> desktopStoreDataStoreEntryRef.getStore().supportsDesktopAccess(),
|
||||
StoreViewState.get().getAllConnectionsCategory()),
|
||||
host)
|
||||
.nonNull()
|
||||
.nameAndDescription("desktopApplicationPath")
|
||||
.addString(path)
|
||||
.nonNull()
|
||||
.nameAndDescription("desktopApplicationArguments")
|
||||
.addString(args)
|
||||
.bind(
|
||||
() -> {
|
||||
return DesktopApplicationStore.builder().desktop(host.get()).path(ContextualFileReference.of(path.get())).arguments(args.get()).build();
|
||||
},
|
||||
store)
|
||||
.buildDialog();
|
||||
}
|
||||
|
||||
public String summaryString(StoreEntryWrapper wrapper) {
|
||||
DesktopApplicationStore s = wrapper.getEntry().getStore().asNeeded();
|
||||
return DataStoreFormatter.toApostropheName(s.getDesktop().get()) + " config";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayIconFileName(DataStore store) {
|
||||
return "base:desktopApplication_icon.svg";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore() {
|
||||
return DesktopApplicationStore.builder().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleNames() {
|
||||
return List.of("desktopApplication");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getStoreClasses() {
|
||||
return List.of(DesktopApplicationStore.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package io.xpipe.ext.base.desktop;
|
||||
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellDialect;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
|
||||
public interface DesktopBaseStore extends DataStore {
|
||||
|
||||
boolean supportsDesktopAccess();
|
||||
|
||||
void runScript(String name, ShellDialect dialect, String script) throws Exception;
|
||||
|
||||
void runTerminal(String name, ExternalTerminalType terminalType, ShellDialect dialect, String script) throws Exception;
|
||||
|
||||
ShellDialect getUsedDialect();
|
||||
|
||||
OsType getUsedOsType();
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package io.xpipe.ext.base.desktop;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.app.util.Validators;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellDialect;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import io.xpipe.ext.base.SelfReferentialStore;
|
||||
import io.xpipe.ext.base.script.ScriptStore;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
@JsonTypeName("desktopEnvironment")
|
||||
public class DesktopEnvironmentStore extends JacksonizedValue implements DesktopBaseStore, DataStore, SelfReferentialStore {
|
||||
|
||||
private final DataStoreEntryRef<DesktopBaseStore> base;
|
||||
private final ExternalTerminalType terminal;
|
||||
private final ShellDialect dialect;
|
||||
private final List<DataStoreEntryRef<ScriptStore>> scripts;
|
||||
private final String initScript;
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
Validators.nonNull(base);
|
||||
Validators.isType(base, DesktopBaseStore.class);
|
||||
Validators.nonNull(terminal);
|
||||
Validators.nonNull(dialect);
|
||||
}
|
||||
|
||||
public List<DataStoreEntryRef<ScriptStore>> getEffectiveScripts() {
|
||||
return scripts != null
|
||||
? scripts.stream().filter(scriptStore -> scriptStore != null).toList()
|
||||
: List.of();
|
||||
}
|
||||
|
||||
public String getMergedInitCommands(String command) {
|
||||
var f = ScriptStore.flatten(scripts);
|
||||
var filtered = f.stream().filter(simpleScriptStore -> simpleScriptStore.getMinimumDialect().isCompatibleTo(dialect) && simpleScriptStore.getExecutionType().runInTerminal()).toList();
|
||||
var initCommands = Stream.concat(filtered.stream().map(simpleScriptStore -> simpleScriptStore.getCommands()), command != null ? Stream.of(command) : Stream.of()).toList();
|
||||
var joined = String.join(dialect.getNewLine().getNewLineString(), initCommands);
|
||||
return !joined.isBlank() ? joined : null;
|
||||
}
|
||||
|
||||
public void launch(String n, String commands) throws Exception {
|
||||
var fullName = n + " [" + getSelfEntry().getName() + "]";
|
||||
base.getStore().runScript(fullName, dialect, getMergedInitCommands(commands));
|
||||
}
|
||||
|
||||
public void launchSelf() throws Exception {
|
||||
var fullName = getSelfEntry().getName();
|
||||
base.getStore().runTerminal(fullName, terminal, dialect, getMergedInitCommands(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsDesktopAccess() {
|
||||
return base.getStore().supportsDesktopAccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runScript(String name, ShellDialect dialect, String script) throws Exception {
|
||||
base.getStore().runScript(name, dialect, script);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTerminal(String name, ExternalTerminalType terminalType, ShellDialect dialect, String script) throws Exception {
|
||||
base.getStore().runTerminal(name,terminalType,dialect,script);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShellDialect getUsedDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OsType getUsedOsType() {
|
||||
return base != null ? base.getStore().getUsedOsType() : null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package io.xpipe.ext.base.desktop;
|
||||
|
||||
import io.xpipe.app.browser.session.BrowserSessionModel;
|
||||
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
|
||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.comp.store.StoreViewState;
|
||||
import io.xpipe.app.core.AppExtensionManager;
|
||||
import io.xpipe.app.ext.ActionProvider;
|
||||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.app.ext.GuiDialog;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.impl.ChoiceComp;
|
||||
import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp;
|
||||
import io.xpipe.app.fxcomps.impl.DataStoreListChoiceComp;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.app.util.DataStoreFormatter;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.ext.base.script.ScriptStore;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DesktopEnvironmentStoreProvider implements DataStoreProvider {
|
||||
|
||||
@Override
|
||||
public ActionProvider.Action browserAction(BrowserSessionModel sessionModel, DataStoreEntry store, BooleanProperty busy) {
|
||||
return launchAction(store);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionProvider.Action launchAction(DataStoreEntry store) {
|
||||
DesktopEnvironmentStore s = store.getStore().asNeeded();
|
||||
return new ActionProvider.Action() {
|
||||
@Override
|
||||
public boolean requiresJavaFXPlatform() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
s.launchSelf();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreationCategory getCreationCategory() {
|
||||
return CreationCategory.DESKSTOP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreEntry getDisplayParent(DataStoreEntry store) {
|
||||
DesktopEnvironmentStore s = store.getStore().asNeeded();
|
||||
return s.getBase().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public GuiDialog guiDialog(DataStoreEntry entry, Property<DataStore> store) {
|
||||
DesktopEnvironmentStore st = (DesktopEnvironmentStore) store.getValue();
|
||||
var host = new SimpleObjectProperty<>(st.getBase());
|
||||
var terminal = new SimpleObjectProperty<>(st.getTerminal());
|
||||
var dialect = new SimpleObjectProperty<>(st.getDialect());
|
||||
var scripts = new SimpleListProperty<>(FXCollections.observableArrayList(new ArrayList<>(st.getEffectiveScripts())));
|
||||
var initScript = new SimpleStringProperty(st.getInitScript());
|
||||
|
||||
|
||||
Comp<?> dialectChoice = (Comp<?>) Class.forName(
|
||||
AppExtensionManager.getInstance()
|
||||
.getExtendedLayer()
|
||||
.findModule("io.xpipe.ext.proc")
|
||||
.orElseThrow(),
|
||||
"io.xpipe.ext.proc.ShellDialectChoiceComp")
|
||||
.getDeclaredConstructor(Property.class)
|
||||
.newInstance(dialect);
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("desktopHost")
|
||||
.addComp(
|
||||
new DataStoreChoiceComp<>(
|
||||
DataStoreChoiceComp.Mode.HOST,
|
||||
entry,
|
||||
host,
|
||||
DesktopBaseStore.class,
|
||||
desktopStoreDataStoreEntryRef -> desktopStoreDataStoreEntryRef.getStore().supportsDesktopAccess(),
|
||||
StoreViewState.get().getAllConnectionsCategory()),
|
||||
host)
|
||||
.nonNull()
|
||||
.nameAndDescription("desktopTerminal")
|
||||
.addComp(ChoiceComp.ofTranslatable(terminal, ExternalTerminalType.getTypes(st.getUsedOsType(), true, false),true), terminal)
|
||||
.nonNull()
|
||||
.nameAndDescription("desktopShellDialect")
|
||||
.addComp(dialectChoice, dialect)
|
||||
.nonNull()
|
||||
.nameAndDescription("desktopSnippets")
|
||||
.addComp(
|
||||
new DataStoreListChoiceComp<>(
|
||||
scripts,
|
||||
ScriptStore.class,
|
||||
scriptStore -> !scripts.contains(scriptStore),
|
||||
StoreViewState.get().getAllScriptsCategory()),
|
||||
scripts)
|
||||
.nameAndDescription("desktopInitScript")
|
||||
.longDescription("proc:environmentScript")
|
||||
.addComp(
|
||||
new IntegratedTextAreaComp(
|
||||
initScript,
|
||||
false,
|
||||
"commands",
|
||||
Bindings.createStringBinding(
|
||||
() -> {
|
||||
return dialect.getValue() != null
|
||||
? dialect
|
||||
.getValue()
|
||||
.getScriptFileEnding()
|
||||
: "sh";
|
||||
},
|
||||
dialect)),
|
||||
initScript)
|
||||
.bind(
|
||||
() -> {
|
||||
return DesktopEnvironmentStore.builder().base(host.get()).terminal(terminal.get()).dialect(dialect.get()).scripts(scripts.get()).initScript(initScript.get()).build();
|
||||
},
|
||||
store)
|
||||
.buildDialog();
|
||||
}
|
||||
|
||||
public String summaryString(StoreEntryWrapper wrapper) {
|
||||
DesktopEnvironmentStore s = wrapper.getEntry().getStore().asNeeded();
|
||||
return DataStoreFormatter.toApostropheName(s.getBase().get()) + " environment";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayIconFileName(DataStore store) {
|
||||
return "base:desktopEnvironment_icon.svg";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore() {
|
||||
return DesktopEnvironmentStore.builder().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getPossibleNames() {
|
||||
return List.of("desktopEnvironment");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getStoreClasses() {
|
||||
return List.of(DesktopEnvironmentStore.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -3,8 +3,10 @@ import io.xpipe.app.ext.ActionProvider;
|
|||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.ext.base.action.*;
|
||||
import io.xpipe.ext.base.browser.*;
|
||||
import io.xpipe.ext.base.desktop.DesktopEnvironmentStoreProvider;
|
||||
import io.xpipe.ext.base.script.ScriptGroupStoreProvider;
|
||||
import io.xpipe.ext.base.script.SimpleScriptStoreProvider;
|
||||
import io.xpipe.ext.base.desktop.DesktopApplicationStoreProvider;
|
||||
import io.xpipe.ext.base.store.StorePauseAction;
|
||||
import io.xpipe.ext.base.store.StoreStartAction;
|
||||
import io.xpipe.ext.base.store.StoreStopAction;
|
||||
|
@ -14,6 +16,7 @@ open module io.xpipe.ext.base {
|
|||
exports io.xpipe.ext.base.action;
|
||||
exports io.xpipe.ext.base.script;
|
||||
exports io.xpipe.ext.base.store;
|
||||
exports io.xpipe.ext.base.desktop;
|
||||
|
||||
requires java.desktop;
|
||||
requires io.xpipe.core;
|
||||
|
@ -64,6 +67,6 @@ open module io.xpipe.ext.base {
|
|||
DeleteStoreChildrenAction,
|
||||
BrowseStoreAction;
|
||||
provides DataStoreProvider with
|
||||
SimpleScriptStoreProvider,
|
||||
SimpleScriptStoreProvider, DesktopEnvironmentStoreProvider, DesktopApplicationStoreProvider,
|
||||
ScriptGroupStoreProvider;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 188.2 188.2"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="desktopApplication_icon-dark.svg"
|
||||
width="188.2"
|
||||
height="188.2"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs29" /><sodipodi:namedview
|
||||
id="namedview27"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.6738281"
|
||||
inkscape:cx="94.095684"
|
||||
inkscape:cy="93.796968"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{display:none;fill:#0C0C0C;}
|
||||
.st1{fill:#AC55FF;}
|
||||
</style>
|
||||
<rect
|
||||
class="st0"
|
||||
width="512"
|
||||
height="512"
|
||||
id="rect4"
|
||||
x="-161.89999"
|
||||
y="-161.89999" />
|
||||
<g
|
||||
id="g24"
|
||||
transform="translate(-161.9,-161.9)"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<g
|
||||
id="g10"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="m 214.8,242.5 c -1.6,-1.4 -4.1,-1.2 -5.5,0.4 -1.3,1.5 -1.3,3.6 0,5.1 l 23.6,23.6 -23.6,23.6 c -1.6,1.4 -1.8,3.9 -0.4,5.5 1.4,1.6 3.9,1.8 5.5,0.4 0.2,-0.1 0.3,-0.3 0.4,-0.4 l 26.4,-26.4 c 1.5,-1.5 1.5,-4 0,-5.5 z"
|
||||
id="path6"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="m 211.9,302.5 c -1.2,0 -2.4,-0.5 -3.3,-1.5 -0.7,-0.9 -1.1,-2 -1,-3.1 0.1,-1.1 0.6,-2.2 1.5,-2.9 l 23.3,-23.3 -23.3,-23.3 c -1.4,-1.6 -1.4,-4 0,-5.6 1.5,-1.8 4.2,-2 6,-0.5 v 0 l 26.4,26.4 c 1.7,1.7 1.7,4.4 0,6 L 215.1,301 c -0.1,0.1 -0.3,0.3 -0.4,0.4 -0.9,0.7 -1.8,1.1 -2.8,1.1 z m 0.4,-60.6 c -1,0 -2,0.4 -2.7,1.2 -1.1,1.3 -1.1,3.3 0,4.6 l 23.8,23.8 -23.8,23.9 c -0.7,0.6 -1.2,1.5 -1.2,2.4 -0.1,0.9 0.2,1.9 0.8,2.6 1.3,1.5 3.5,1.7 5,0.4 0.1,-0.1 0.3,-0.2 0.4,-0.4 L 241,274 c 1.4,-1.4 1.4,-3.6 0,-5 l -26.3,-26.3 c -0.8,-0.5 -1.6,-0.8 -2.4,-0.8 z"
|
||||
id="path8"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g16"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="m 306.8,295 h -54.7 c -2.2,0 -3.9,1.7 -3.9,3.9 0,2.2 1.7,3.9 3.9,3.9 h 54.7 c 2.2,0 3.9,-1.7 3.9,-3.9 0,-2.1 -1.8,-3.9 -3.9,-3.9 z"
|
||||
id="path12"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="m 306.8,303.2 h -54.7 c -2.4,0 -4.3,-1.9 -4.3,-4.3 0,-2.4 1.9,-4.3 4.3,-4.3 h 54.7 c 2.4,0 4.3,1.9 4.3,4.3 0,2.4 -2,4.3 -4.3,4.3 z m -54.7,-7.8 c -1.9,0 -3.5,1.6 -3.5,3.5 0,1.9 1.6,3.5 3.5,3.5 h 54.7 c 1.9,0 3.5,-1.6 3.5,-3.5 0,-1.9 -1.6,-3.5 -3.5,-3.5 z"
|
||||
id="path14"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g22"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="M 326.3,162.3 H 185.7 c -12.9,0 -23.4,10.5 -23.4,23.4 v 140.6 c 0,12.9 10.5,23.4 23.4,23.4 h 140.6 c 12.9,0 23.4,-10.5 23.4,-23.4 V 185.7 c 0,-12.9 -10.5,-23.4 -23.4,-23.4 z m -140.6,7.8 h 140.6 c 8.6,0 15.6,7 15.6,15.6 v 15.6 H 170.1 v -15.6 c 0,-8.6 7,-15.6 15.6,-15.6 z M 326.3,341.9 H 185.7 c -8.6,0 -15.6,-7 -15.6,-15.6 V 209.1 h 171.8 v 117.1 c 0,8.7 -7,15.7 -15.6,15.7 z"
|
||||
id="path18"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="M 326.3,350.1 H 185.7 c -13.1,0 -23.8,-10.7 -23.8,-23.8 V 185.7 c 0,-13.1 10.7,-23.8 23.8,-23.8 h 140.6 c 13.1,0 23.8,10.7 23.8,23.8 v 140.6 c 0,13.1 -10.7,23.8 -23.8,23.8 z M 185.7,162.7 c -12.7,0 -23.1,10.3 -23.1,23.1 v 140.6 c 0,12.7 10.3,23.1 23.1,23.1 h 140.6 c 12.7,0 23.1,-10.3 23.1,-23.1 V 185.7 c 0,-12.7 -10.3,-23.1 -23.1,-23.1 H 185.7 Z M 326.3,342.3 H 185.7 c -8.8,0 -16,-7.2 -16,-16 V 208.8 h 172.5 v 117.5 c 0.1,8.8 -7.1,16 -15.9,16 z M 170.5,209.5 v 116.8 c 0,8.4 6.8,15.2 15.2,15.2 h 140.6 c 8.4,0 15.2,-6.8 15.2,-15.2 V 209.5 Z m 171.8,-7.8 H 169.7 v -16 c 0,-8.8 7.2,-16 16,-16 h 140.6 c 8.8,0 16,7.2 16,16 z M 170.5,201 h 171 v -15.2 c 0,-8.4 -6.8,-15.2 -15.2,-15.2 H 185.7 c -8.4,0 -15.2,6.8 -15.2,15.2 z"
|
||||
id="path20"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 188.2 188.2"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="desktopApplication_icon.svg"
|
||||
width="188.2"
|
||||
height="188.2"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs29" /><sodipodi:namedview
|
||||
id="namedview27"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.6738281"
|
||||
inkscape:cx="94.095684"
|
||||
inkscape:cy="93.796968"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{display:none;fill:#0C0C0C;}
|
||||
.st1{fill:#AC55FF;}
|
||||
</style>
|
||||
<rect
|
||||
class="st0"
|
||||
width="512"
|
||||
height="512"
|
||||
id="rect4"
|
||||
x="-161.89999"
|
||||
y="-161.89999" />
|
||||
<g
|
||||
id="g24"
|
||||
transform="translate(-161.9,-161.9)"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<g
|
||||
id="g10"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="m 214.8,242.5 c -1.6,-1.4 -4.1,-1.2 -5.5,0.4 -1.3,1.5 -1.3,3.6 0,5.1 l 23.6,23.6 -23.6,23.6 c -1.6,1.4 -1.8,3.9 -0.4,5.5 1.4,1.6 3.9,1.8 5.5,0.4 0.2,-0.1 0.3,-0.3 0.4,-0.4 l 26.4,-26.4 c 1.5,-1.5 1.5,-4 0,-5.5 z"
|
||||
id="path6"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="m 211.9,302.5 c -1.2,0 -2.4,-0.5 -3.3,-1.5 -0.7,-0.9 -1.1,-2 -1,-3.1 0.1,-1.1 0.6,-2.2 1.5,-2.9 l 23.3,-23.3 -23.3,-23.3 c -1.4,-1.6 -1.4,-4 0,-5.6 1.5,-1.8 4.2,-2 6,-0.5 v 0 l 26.4,26.4 c 1.7,1.7 1.7,4.4 0,6 L 215.1,301 c -0.1,0.1 -0.3,0.3 -0.4,0.4 -0.9,0.7 -1.8,1.1 -2.8,1.1 z m 0.4,-60.6 c -1,0 -2,0.4 -2.7,1.2 -1.1,1.3 -1.1,3.3 0,4.6 l 23.8,23.8 -23.8,23.9 c -0.7,0.6 -1.2,1.5 -1.2,2.4 -0.1,0.9 0.2,1.9 0.8,2.6 1.3,1.5 3.5,1.7 5,0.4 0.1,-0.1 0.3,-0.2 0.4,-0.4 L 241,274 c 1.4,-1.4 1.4,-3.6 0,-5 l -26.3,-26.3 c -0.8,-0.5 -1.6,-0.8 -2.4,-0.8 z"
|
||||
id="path8"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g16"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="m 306.8,295 h -54.7 c -2.2,0 -3.9,1.7 -3.9,3.9 0,2.2 1.7,3.9 3.9,3.9 h 54.7 c 2.2,0 3.9,-1.7 3.9,-3.9 0,-2.1 -1.8,-3.9 -3.9,-3.9 z"
|
||||
id="path12"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="m 306.8,303.2 h -54.7 c -2.4,0 -4.3,-1.9 -4.3,-4.3 0,-2.4 1.9,-4.3 4.3,-4.3 h 54.7 c 2.4,0 4.3,1.9 4.3,4.3 0,2.4 -2,4.3 -4.3,4.3 z m -54.7,-7.8 c -1.9,0 -3.5,1.6 -3.5,3.5 0,1.9 1.6,3.5 3.5,3.5 h 54.7 c 1.9,0 3.5,-1.6 3.5,-3.5 0,-1.9 -1.6,-3.5 -3.5,-3.5 z"
|
||||
id="path14"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g22"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="M 326.3,162.3 H 185.7 c -12.9,0 -23.4,10.5 -23.4,23.4 v 140.6 c 0,12.9 10.5,23.4 23.4,23.4 h 140.6 c 12.9,0 23.4,-10.5 23.4,-23.4 V 185.7 c 0,-12.9 -10.5,-23.4 -23.4,-23.4 z m -140.6,7.8 h 140.6 c 8.6,0 15.6,7 15.6,15.6 v 15.6 H 170.1 v -15.6 c 0,-8.6 7,-15.6 15.6,-15.6 z M 326.3,341.9 H 185.7 c -8.6,0 -15.6,-7 -15.6,-15.6 V 209.1 h 171.8 v 117.1 c 0,8.7 -7,15.7 -15.6,15.7 z"
|
||||
id="path18"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="M 326.3,350.1 H 185.7 c -13.1,0 -23.8,-10.7 -23.8,-23.8 V 185.7 c 0,-13.1 10.7,-23.8 23.8,-23.8 h 140.6 c 13.1,0 23.8,10.7 23.8,23.8 v 140.6 c 0,13.1 -10.7,23.8 -23.8,23.8 z M 185.7,162.7 c -12.7,0 -23.1,10.3 -23.1,23.1 v 140.6 c 0,12.7 10.3,23.1 23.1,23.1 h 140.6 c 12.7,0 23.1,-10.3 23.1,-23.1 V 185.7 c 0,-12.7 -10.3,-23.1 -23.1,-23.1 H 185.7 Z M 326.3,342.3 H 185.7 c -8.8,0 -16,-7.2 -16,-16 V 208.8 h 172.5 v 117.5 c 0.1,8.8 -7.1,16 -15.9,16 z M 170.5,209.5 v 116.8 c 0,8.4 6.8,15.2 15.2,15.2 h 140.6 c 8.4,0 15.2,-6.8 15.2,-15.2 V 209.5 Z m 171.8,-7.8 H 169.7 v -16 c 0,-8.8 7.2,-16 16,-16 h 140.6 c 8.8,0 16,7.2 16,16 z M 170.5,201 h 171 v -15.2 c 0,-8.4 -6.8,-15.2 -15.2,-15.2 H 185.7 c -8.4,0 -15.2,6.8 -15.2,15.2 z"
|
||||
id="path20"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 205.60609 122.97245"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="desktopCommand_icon-dark.svg"
|
||||
width="205.60609"
|
||||
height="122.97245"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
inkscape:export-filename="C:\Projects\xpipe\xpipex\ext\proc\src\main\resources\io\xpipe\ext\proc\resources\img\command_icon-16.png"
|
||||
inkscape:export-xdpi="7.8066268"
|
||||
inkscape:export-ydpi="7.8066268"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs21" /><sodipodi:namedview
|
||||
id="namedview19"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.3671504"
|
||||
inkscape:cx="-23.445912"
|
||||
inkscape:cy="2.1122443"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{fill:#0C0C0C;}
|
||||
.st1{fill:#AC55FF;}
|
||||
</style>
|
||||
|
||||
<g
|
||||
id="g16"
|
||||
transform="matrix(0.81,0,0,0.81,-104.55448,-145.88493)"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<g
|
||||
id="g8"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="m 166.9,196.4 c -3.3,-2.8 -8.2,-2.4 -11,0.8 -2.5,2.9 -2.5,7.2 0,10.1 l 47,47.1 -47,47.1 c -3.3,2.8 -3.6,7.7 -0.8,11 2.8,3.3 7.7,3.6 11,0.8 0.3,-0.3 0.6,-0.5 0.8,-0.8 l 52.6,-52.6 c 3,-3 3,-7.9 0,-11 z"
|
||||
id="path6"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g14"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="M 350.3,301.2 H 241.2 c -4.3,0 -7.8,3.5 -7.8,7.8 0,4.3 3.5,7.8 7.8,7.8 h 109.1 c 4.3,0 7.8,-3.5 7.8,-7.8 0,-4.3 -3.5,-7.8 -7.8,-7.8 z"
|
||||
id="path10"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="M 350.3,317.5 H 241.2 c -4.7,0 -8.5,-3.8 -8.5,-8.5 0,-4.7 3.8,-8.5 8.5,-8.5 h 109.1 c 4.7,0 8.5,3.8 8.5,8.5 0,4.7 -3.8,8.5 -8.5,8.5 z M 241.2,301.9 c -3.9,0 -7,3.2 -7,7 0,3.8 3.2,7 7,7 h 109.1 c 3.9,0 7,-3.2 7,-7 0,-3.8 -3.2,-7 -7,-7 z"
|
||||
id="path12"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 205.60609 122.97245"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="desktopCommand_icon.svg"
|
||||
width="205.60609"
|
||||
height="122.97245"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
inkscape:export-filename="C:\Projects\xpipe\xpipex\ext\proc\src\main\resources\io\xpipe\ext\proc\resources\img\command_icon-16.png"
|
||||
inkscape:export-xdpi="7.8066268"
|
||||
inkscape:export-ydpi="7.8066268"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs21" /><sodipodi:namedview
|
||||
id="namedview19"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.3671504"
|
||||
inkscape:cx="-23.445912"
|
||||
inkscape:cy="2.1122443"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{fill:#0C0C0C;}
|
||||
.st1{fill:#AC55FF;}
|
||||
</style>
|
||||
|
||||
<g
|
||||
id="g16"
|
||||
transform="matrix(0.81,0,0,0.81,-104.55448,-145.88493)"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<g
|
||||
id="g8"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="m 166.9,196.4 c -3.3,-2.8 -8.2,-2.4 -11,0.8 -2.5,2.9 -2.5,7.2 0,10.1 l 47,47.1 -47,47.1 c -3.3,2.8 -3.6,7.7 -0.8,11 2.8,3.3 7.7,3.6 11,0.8 0.3,-0.3 0.6,-0.5 0.8,-0.8 l 52.6,-52.6 c 3,-3 3,-7.9 0,-11 z"
|
||||
id="path6"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="g14"
|
||||
style="fill:#ba6600;fill-opacity:1">
|
||||
<path
|
||||
class="st1"
|
||||
d="M 350.3,301.2 H 241.2 c -4.3,0 -7.8,3.5 -7.8,7.8 0,4.3 3.5,7.8 7.8,7.8 h 109.1 c 4.3,0 7.8,-3.5 7.8,-7.8 0,-4.3 -3.5,-7.8 -7.8,-7.8 z"
|
||||
id="path10"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="st1"
|
||||
d="M 350.3,317.5 H 241.2 c -4.7,0 -8.5,-3.8 -8.5,-8.5 0,-4.7 3.8,-8.5 8.5,-8.5 h 109.1 c 4.7,0 8.5,3.8 8.5,8.5 0,4.7 -3.8,8.5 -8.5,8.5 z M 241.2,301.9 c -3.9,0 -7,3.2 -7,7 0,3.8 3.2,7 7,7 h 109.1 c 3.9,0 7,-3.2 7,-7 0,-3.8 -3.2,-7 -7,-7 z"
|
||||
id="path12"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="Layer_1"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 204.68 206.97"
|
||||
version="1.1"
|
||||
sodipodi:docname="desktopEnvironment_icon-dark.svg"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview15"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0703483"
|
||||
inkscape:cx="21.493968"
|
||||
inkscape:cy="104.33027"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">.cls-1{fill:#ac55ff;}</style>
|
||||
</defs>
|
||||
<title
|
||||
id="title6">shell environment v2</title>
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M215.09,242.25l0,0a4.28,4.28,0,0,0-6,6.05l23.32,23.34-23.3,23.32a4.28,4.28,0,0,0-.47,6,4.29,4.29,0,0,0,6,.46,4.56,4.56,0,0,0,.44-.44l26.36-26.36a4.29,4.29,0,0,0,0-6Z"
|
||||
transform="translate(-161.92 -143.11)"
|
||||
id="path8"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M306.76,294.67H252.1a4.28,4.28,0,1,0,0,8.56h54.66a4.28,4.28,0,0,0,0-8.56Z"
|
||||
transform="translate(-161.92 -143.11)"
|
||||
id="path10"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M366.61,182.47a39.37,39.37,0,0,0-72.94-20.55h-108a23.83,23.83,0,0,0-23.8,23.8V326.28a23.83,23.83,0,0,0,23.8,23.8H326.28a23.83,23.83,0,0,0,23.8-23.8V214.52A39.31,39.31,0,0,0,366.61,182.47Zm-45.39,10.44,8.52-22.41a1.89,1.89,0,0,1,2-1.46,1.86,1.86,0,0,1,1.85,1.81,3.62,3.62,0,0,1-.28,1.18l-8.52,22.41a1.94,1.94,0,0,1-3.81-.36A3.57,3.57,0,0,1,321.22,192.91ZM317.88,176a1.86,1.86,0,0,1,2,1.92c0,.82-.18,1.61-1.68,2.25l-11.47,5,11.47,5c1.5.65,1.68,1.43,1.68,2.25a1.86,1.86,0,0,1-2,1.92,4.19,4.19,0,0,1-2-.5l-14.5-6.66a2.22,2.22,0,0,1,0-4.06l14.5-6.66A4.19,4.19,0,0,1,317.88,176Zm-147.4,9.7a15.26,15.26,0,0,1,15.24-15.24h104A39.48,39.48,0,0,0,292.5,201h-122Zm171,140.56a15.26,15.26,0,0,1-15.24,15.24H185.72a15.26,15.26,0,0,1-15.24-15.24V209.52H298.67a39.33,39.33,0,0,0,42.85,9.63Zm11.56-139-14.5,6.66a4.21,4.21,0,0,1-2,.5,1.86,1.86,0,0,1-2-1.92c0-.82.18-1.6,1.67-2.25l11.47-5-11.47-5c-1.49-.64-1.67-1.43-1.67-2.25a1.86,1.86,0,0,1,2-1.92,4.21,4.21,0,0,1,2,.5l14.5,6.66a2.23,2.23,0,0,1,0,4.06Z"
|
||||
transform="translate(-161.92 -143.11)"
|
||||
id="path12"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<metadata
|
||||
id="metadata923">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title>shell environment v2</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
id="Layer_1"
|
||||
data-name="Layer 1"
|
||||
viewBox="0 0 204.68 206.97"
|
||||
version="1.1"
|
||||
sodipodi:docname="desktopEnvironment_icon.svg"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview15"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.0703483"
|
||||
inkscape:cx="21.493968"
|
||||
inkscape:cy="104.33027"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1057"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<style
|
||||
id="style2">.cls-1{fill:#ac55ff;}</style>
|
||||
</defs>
|
||||
<title
|
||||
id="title6">shell environment v2</title>
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M215.09,242.25l0,0a4.28,4.28,0,0,0-6,6.05l23.32,23.34-23.3,23.32a4.28,4.28,0,0,0-.47,6,4.29,4.29,0,0,0,6,.46,4.56,4.56,0,0,0,.44-.44l26.36-26.36a4.29,4.29,0,0,0,0-6Z"
|
||||
transform="translate(-161.92 -143.11)"
|
||||
id="path8"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M306.76,294.67H252.1a4.28,4.28,0,1,0,0,8.56h54.66a4.28,4.28,0,0,0,0-8.56Z"
|
||||
transform="translate(-161.92 -143.11)"
|
||||
id="path10"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M366.61,182.47a39.37,39.37,0,0,0-72.94-20.55h-108a23.83,23.83,0,0,0-23.8,23.8V326.28a23.83,23.83,0,0,0,23.8,23.8H326.28a23.83,23.83,0,0,0,23.8-23.8V214.52A39.31,39.31,0,0,0,366.61,182.47Zm-45.39,10.44,8.52-22.41a1.89,1.89,0,0,1,2-1.46,1.86,1.86,0,0,1,1.85,1.81,3.62,3.62,0,0,1-.28,1.18l-8.52,22.41a1.94,1.94,0,0,1-3.81-.36A3.57,3.57,0,0,1,321.22,192.91ZM317.88,176a1.86,1.86,0,0,1,2,1.92c0,.82-.18,1.61-1.68,2.25l-11.47,5,11.47,5c1.5.65,1.68,1.43,1.68,2.25a1.86,1.86,0,0,1-2,1.92,4.19,4.19,0,0,1-2-.5l-14.5-6.66a2.22,2.22,0,0,1,0-4.06l14.5-6.66A4.19,4.19,0,0,1,317.88,176Zm-147.4,9.7a15.26,15.26,0,0,1,15.24-15.24h104A39.48,39.48,0,0,0,292.5,201h-122Zm171,140.56a15.26,15.26,0,0,1-15.24,15.24H185.72a15.26,15.26,0,0,1-15.24-15.24V209.52H298.67a39.33,39.33,0,0,0,42.85,9.63Zm11.56-139-14.5,6.66a4.21,4.21,0,0,1-2,.5,1.86,1.86,0,0,1-2-1.92c0-.82.18-1.6,1.67-2.25l11.47-5-11.47-5c-1.49-.64-1.67-1.43-1.67-2.25a1.86,1.86,0,0,1,2-1.92,4.21,4.21,0,0,1,2,.5l14.5,6.66a2.23,2.23,0,0,1,0,4.06Z"
|
||||
transform="translate(-161.92 -143.11)"
|
||||
id="path12"
|
||||
style="fill:#ba6600;fill-opacity:1" />
|
||||
<metadata
|
||||
id="metadata923">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title>shell environment v2</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -430,6 +430,7 @@ goodMorning=Good morning
|
|||
goodAfternoon=Good afternoon
|
||||
goodEvening=Good evening
|
||||
addVisual=Visual ...
|
||||
addDesktop=Desktop ...
|
||||
ssh=SSH
|
||||
sshConfiguration=SSH Configuration
|
||||
size=Size
|
||||
|
|
|
@ -106,6 +106,25 @@ openInTerminal=Open in terminal
|
|||
file=File
|
||||
directory=Directory
|
||||
symbolicLink=Symbolic link
|
||||
|
||||
desktopEnvironment.displayName=Desktop environment
|
||||
desktopEnvironment.displayDescription=Create a reusable desktop environment configuration
|
||||
desktopHost=Desktop host
|
||||
desktopHostDescription=The desktop connection to use as a base
|
||||
desktopShellDialect=Shell dialect
|
||||
desktopShellDialectDescription=The shell dialect to use to run scripts and applications
|
||||
desktopSnippets=Script snippets
|
||||
desktopSnippetsDescription=List of reusable script snippets to run first
|
||||
desktopInitScript=Init script
|
||||
desktopInitScriptDescription=Init commands specific to this environment
|
||||
desktopTerminal=Terminal application
|
||||
desktopTerminalDescription=The terminal to use on the desktop to start scripts in
|
||||
desktopApplication.displayName=Desktop application
|
||||
desktopApplication.displayDescription=Run an application in a desktop environment
|
||||
desktopEnvironmentBase=Desktop environment
|
||||
desktopEnvironmentBaseDescription=The desktop environment to run this application on
|
||||
desktopApplicationPath=Application path
|
||||
desktopApplicationPathDescription=The path of the executable to run
|
||||
desktopApplicationArguments=Arguments
|
||||
desktopApplicationArgumentsDescription=The optional arguments to pass to the application
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue