mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-23 16:10:24 +00:00
Reformat
This commit is contained in:
parent
d4ad1d2e82
commit
e894390124
35 changed files with 286 additions and 174 deletions
|
@ -16,7 +16,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
|||
import lombok.SneakyThrows;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Value
|
||||
|
|
|
@ -158,7 +158,8 @@ public class BrowserTransferModel {
|
|||
public void transferToDownloads() throws Exception {
|
||||
List<Item> toMove;
|
||||
synchronized (items) {
|
||||
toMove = items.stream().filter(item -> item.downloadFinished().get()).toList();
|
||||
toMove =
|
||||
items.stream().filter(item -> item.downloadFinished().get()).toList();
|
||||
if (toMove.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,8 @@ public interface BrowserAction {
|
|||
default List<BrowserEntry> resolveFilesIfNeeded(List<BrowserEntry> selected) {
|
||||
return automaticallyResolveLinks()
|
||||
? selected.stream()
|
||||
.map(browserEntry -> new BrowserEntry(browserEntry.getRawFileEntry().resolved(), browserEntry.getModel()))
|
||||
.map(browserEntry ->
|
||||
new BrowserEntry(browserEntry.getRawFileEntry().resolved(), browserEntry.getModel()))
|
||||
.toList()
|
||||
: selected;
|
||||
}
|
||||
|
|
|
@ -42,8 +42,12 @@ public class BrowserAlerts {
|
|||
alert.setHeaderText(AppI18n.get("fileConflictAlertHeader"));
|
||||
alert.setAlertType(Alert.AlertType.CONFIRMATION);
|
||||
alert.getButtonTypes().clear();
|
||||
alert.getDialogPane().setContent(AppWindowHelper.alertContentText(AppI18n.get(
|
||||
multiple ? "fileConflictAlertContentMultiple" : "fileConflictAlertContent", file), w - 50));
|
||||
alert.getDialogPane()
|
||||
.setContent(AppWindowHelper.alertContentText(
|
||||
AppI18n.get(
|
||||
multiple ? "fileConflictAlertContentMultiple" : "fileConflictAlertContent",
|
||||
file),
|
||||
w - 50));
|
||||
alert.getDialogPane().setMinWidth(w);
|
||||
alert.getDialogPane().setPrefWidth(w);
|
||||
alert.getDialogPane().setMaxWidth(w);
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class BrowserFileTransferOperation {
|
||||
|
@ -65,7 +64,8 @@ public class BrowserFileTransferOperation {
|
|||
this.progress.accept(progress);
|
||||
}
|
||||
|
||||
private BrowserAlerts.FileConflictChoice handleChoice(FileSystem fileSystem, String target, boolean multiple) throws Exception {
|
||||
private BrowserAlerts.FileConflictChoice handleChoice(FileSystem fileSystem, String target, boolean multiple)
|
||||
throws Exception {
|
||||
if (lastConflictChoice == BrowserAlerts.FileConflictChoice.CANCEL) {
|
||||
return BrowserAlerts.FileConflictChoice.CANCEL;
|
||||
}
|
||||
|
@ -168,7 +168,8 @@ public class BrowserFileTransferOperation {
|
|||
|
||||
if (checkConflicts) {
|
||||
var fileConflictChoice = handleChoice(target.getFileSystem(), targetFile, files.size() > 1);
|
||||
if (fileConflictChoice == BrowserAlerts.FileConflictChoice.SKIP || fileConflictChoice == BrowserAlerts.FileConflictChoice.CANCEL) {
|
||||
if (fileConflictChoice == BrowserAlerts.FileConflictChoice.SKIP
|
||||
|| fileConflictChoice == BrowserAlerts.FileConflictChoice.CANCEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -204,9 +205,11 @@ public class BrowserFileTransferOperation {
|
|||
if (matcher.matches()) {
|
||||
try {
|
||||
var number = Integer.parseInt(matcher.group(2));
|
||||
var newFile = targetFile.getParent().join(matcher.group(1) + " (" + (number + 1) + ")." + matcher.group(3));
|
||||
var newFile =
|
||||
targetFile.getParent().join(matcher.group(1) + " (" + (number + 1) + ")." + matcher.group(3));
|
||||
return newFile.toString();
|
||||
} catch (NumberFormatException e) {}
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
var noExt = targetFile.getFileName().equals(targetFile.getExtension());
|
||||
|
@ -275,8 +278,10 @@ public class BrowserFileTransferOperation {
|
|||
target.getFileSystem().mkdirs(targetFile);
|
||||
} else if (sourceFile.getKind() == FileKind.FILE) {
|
||||
if (checkConflicts) {
|
||||
var fileConflictChoice = handleChoice(target.getFileSystem(), targetFile, files.size() > 1 || flatFiles.size() > 1);
|
||||
if (fileConflictChoice == BrowserAlerts.FileConflictChoice.SKIP || fileConflictChoice == BrowserAlerts.FileConflictChoice.CANCEL) {
|
||||
var fileConflictChoice =
|
||||
handleChoice(target.getFileSystem(), targetFile, files.size() > 1 || flatFiles.size() > 1);
|
||||
if (fileConflictChoice == BrowserAlerts.FileConflictChoice.SKIP
|
||||
|| fileConflictChoice == BrowserAlerts.FileConflictChoice.CANCEL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.xpipe.app.browser.fs;
|
|||
import io.xpipe.app.browser.BrowserSavedState;
|
||||
import io.xpipe.app.browser.BrowserSavedStateImpl;
|
||||
import io.xpipe.app.browser.BrowserTransferProgress;
|
||||
import io.xpipe.app.browser.action.BranchAction;
|
||||
import io.xpipe.app.browser.action.BrowserAction;
|
||||
import io.xpipe.app.browser.file.BrowserFileListModel;
|
||||
import io.xpipe.app.browser.file.BrowserFileTransferMode;
|
||||
|
@ -26,8 +25,8 @@ import io.xpipe.core.process.ShellDialects;
|
|||
import io.xpipe.core.process.ShellOpenFunction;
|
||||
import io.xpipe.core.store.*;
|
||||
import io.xpipe.core.util.FailableConsumer;
|
||||
|
||||
import io.xpipe.core.util.FailableRunnable;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.*;
|
||||
|
||||
|
@ -451,7 +450,12 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
|
|||
return;
|
||||
}
|
||||
|
||||
fileSystem.getShell().orElseThrow().command(command).withWorkingDirectory(getCurrentDirectory().getPath()).execute();
|
||||
fileSystem
|
||||
.getShell()
|
||||
.orElseThrow()
|
||||
.command(command)
|
||||
.withWorkingDirectory(getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
if (refresh) {
|
||||
refreshSync();
|
||||
}
|
||||
|
@ -459,7 +463,6 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
public void runAsync(FailableRunnable<Exception> r, boolean refresh) {
|
||||
if (name == null || name.isBlank()) {
|
||||
return;
|
||||
|
|
|
@ -13,8 +13,8 @@ import io.xpipe.app.fxcomps.util.LabelGraphic;
|
|||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.update.UpdateAvailableAlert;
|
||||
import io.xpipe.app.update.XPipeDistributionType;
|
||||
|
||||
import io.xpipe.app.util.Hyperlinks;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
|
@ -146,15 +146,16 @@ public class SideMenuBarComp extends Comp<CompStructure<VBox>> {
|
|||
var now = Instant.now();
|
||||
var phStart = ZonedDateTime.of(2024, 10, 22, 0, 1, 0, 0, zone).toInstant();
|
||||
var phEnd = ZonedDateTime.of(2024, 10, 23, 0, 1, 0, 0, zone).toInstant();
|
||||
var clicked = AppCache.get("phClicked",Boolean.class,() -> false);
|
||||
var clicked = AppCache.get("phClicked", Boolean.class, () -> false);
|
||||
var phShow = now.isAfter(phStart) && now.isBefore(phEnd) && !clicked;
|
||||
if (phShow) {
|
||||
var hide = new SimpleBooleanProperty(false);
|
||||
var b = new IconButtonComp(new LabelGraphic.ImageGraphic("app:producthunt-color.png", 24), () -> {
|
||||
AppCache.update("phClicked", true);
|
||||
Hyperlinks.open(Hyperlinks.PRODUCT_HUNT);
|
||||
hide.set(true);
|
||||
}).tooltip(new SimpleStringProperty("Product Hunt"));
|
||||
AppCache.update("phClicked", true);
|
||||
Hyperlinks.open(Hyperlinks.PRODUCT_HUNT);
|
||||
hide.set(true);
|
||||
})
|
||||
.tooltip(new SimpleStringProperty("Product Hunt"));
|
||||
b.apply(struc -> {
|
||||
AppFont.setSize(struc.get(), 1);
|
||||
});
|
||||
|
|
|
@ -56,8 +56,7 @@ public class AppExtensionManager {
|
|||
ErrorEvent.fromThrowable(t).handle();
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
throw ExtensionException.corrupt(
|
||||
"Service provider initialization failed", t);
|
||||
throw ExtensionException.corrupt("Service provider initialization failed", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,8 +205,7 @@ public class AppExtensionManager {
|
|||
var ext = getExtensionFromDir(layer, dir);
|
||||
if (ext.isEmpty()) {
|
||||
if (AppProperties.get().isFullVersion()) {
|
||||
throw ExtensionException.corrupt(
|
||||
"Unable to load extension from directory " + dir);
|
||||
throw ExtensionException.corrupt("Unable to load extension from directory " + dir);
|
||||
}
|
||||
} else {
|
||||
if (loadedExtensions.stream()
|
||||
|
|
|
@ -12,7 +12,6 @@ import io.xpipe.app.util.LicenseProvider;
|
|||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
|
|
|
@ -6,7 +6,7 @@ import io.xpipe.app.issue.ErrorEvent;
|
|||
public class AppJavaOptionsCheck {
|
||||
|
||||
public static void check() {
|
||||
if (AppCache.get("javaOptionsWarningShown", Boolean.class,() -> false)) {
|
||||
if (AppCache.get("javaOptionsWarningShown", Boolean.class, () -> false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,9 @@ public class AppShellCheck {
|
|||
|
||||
// We don't want to fall back on macOS as occasional zsh spawn issues would cause many users to use sh
|
||||
var canFallback = !ProcessControlProvider.get()
|
||||
.getEffectiveLocalDialect()
|
||||
.equals(ProcessControlProvider.get().getFallbackDialect()) &&
|
||||
OsType.getLocal() != OsType.MACOS;
|
||||
.getEffectiveLocalDialect()
|
||||
.equals(ProcessControlProvider.get().getFallbackDialect())
|
||||
&& OsType.getLocal() != OsType.MACOS;
|
||||
if (err.isPresent() && canFallback) {
|
||||
var msg = formatMessage(err.get().getMessage());
|
||||
ErrorEvent.fromThrowable(new IllegalStateException(msg)).handle();
|
||||
|
|
|
@ -25,7 +25,8 @@ public class ExtensionException extends RuntimeException {
|
|||
public static ExtensionException corrupt(String message, Throwable cause) {
|
||||
try {
|
||||
var loc = XPipeInstallation.getCurrentInstallationBasePath();
|
||||
var full = message + ".\n\n" + "Please check whether the XPipe installation data at " + loc + " is corrupted.";
|
||||
var full =
|
||||
message + ".\n\n" + "Please check whether the XPipe installation data at " + loc + " is corrupted.";
|
||||
return new ExtensionException(full, cause);
|
||||
} catch (Throwable t) {
|
||||
var full = message + ".\n\n" + "Please check whether the XPipe installation data is corrupted.";
|
||||
|
|
|
@ -4,12 +4,12 @@ import io.xpipe.app.fxcomps.Comp;
|
|||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.util.Callback;
|
||||
|
||||
|
@ -22,7 +22,10 @@ public class ComboTextFieldComp extends Comp<CompStructure<ComboBox<String>>> {
|
|||
private final List<String> predefinedValues;
|
||||
private final Callback<ListView<String>, ListCell<String>> customCellFactory;
|
||||
|
||||
public ComboTextFieldComp(Property<String> value, List<String> predefinedValues, Callback<ListView<String>, ListCell<String>> customCellFactory) {
|
||||
public ComboTextFieldComp(
|
||||
Property<String> value,
|
||||
List<String> predefinedValues,
|
||||
Callback<ListView<String>, ListCell<String>> customCellFactory) {
|
||||
this.value = value;
|
||||
this.predefinedValues = predefinedValues;
|
||||
this.customCellFactory = customCellFactory;
|
||||
|
@ -40,7 +43,8 @@ public class ComboTextFieldComp extends Comp<CompStructure<ComboBox<String>>> {
|
|||
value.addListener((c, o, n) -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
// Check if control value is the same. Then don't set it as that might cause bugs
|
||||
if (Objects.equals(text.getValue(), n) || (n == null && text.getValue().isEmpty())) {
|
||||
if (Objects.equals(text.getValue(), n)
|
||||
|| (n == null && text.getValue().isEmpty())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,28 +7,22 @@ import io.xpipe.app.core.window.AppWindowHelper;
|
|||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||
import io.xpipe.app.fxcomps.augment.GrowAugment;
|
||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.ContextualFileReference;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.scene.control.Cell;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import javafx.scene.paint.Color;
|
||||
import lombok.Value;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
|
@ -53,9 +47,10 @@ public class ContextualFileReferenceChoiceComp extends Comp<CompStructure<HBox>>
|
|||
private final List<PreviousFileReference> previousFileReferences;
|
||||
|
||||
public <T extends FileSystemStore> ContextualFileReferenceChoiceComp(
|
||||
Property<DataStoreEntryRef<T>> fileSystem, Property<String> filePath, boolean allowSync,
|
||||
List<PreviousFileReference> previousFileReferences
|
||||
) {
|
||||
Property<DataStoreEntryRef<T>> fileSystem,
|
||||
Property<String> filePath,
|
||||
boolean allowSync,
|
||||
List<PreviousFileReference> previousFileReferences) {
|
||||
this.allowSync = allowSync;
|
||||
this.previousFileReferences = previousFileReferences;
|
||||
this.fileSystem = new SimpleObjectProperty<>();
|
||||
|
@ -145,7 +140,9 @@ public class ContextualFileReferenceChoiceComp extends Comp<CompStructure<HBox>>
|
|||
}
|
||||
|
||||
private Comp<?> createComboBox() {
|
||||
var items = previousFileReferences.stream().map(previousFileReference -> previousFileReference.getPath().toString()).toList();
|
||||
var items = previousFileReferences.stream()
|
||||
.map(previousFileReference -> previousFileReference.getPath().toString())
|
||||
.toList();
|
||||
var combo = new ComboTextFieldComp(filePath, items, param -> {
|
||||
return new ListCell<>() {
|
||||
@Override
|
||||
|
|
|
@ -20,10 +20,14 @@ public class StoreCategoryListComp extends SimpleComp {
|
|||
sp.styleClass("store-category-bar");
|
||||
sp.apply(struc -> {
|
||||
Region content = (Region) struc.get().getContent();
|
||||
struc.get().minHeightProperty().bind(Bindings.createDoubleBinding(() -> {
|
||||
var h = content.getHeight();
|
||||
return Math.min(200, h + 2);
|
||||
}, content.heightProperty()));
|
||||
struc.get()
|
||||
.minHeightProperty()
|
||||
.bind(Bindings.createDoubleBinding(
|
||||
() -> {
|
||||
var h = content.getHeight();
|
||||
return Math.min(200, h + 2);
|
||||
},
|
||||
content.heightProperty()));
|
||||
});
|
||||
return sp.createRegion();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import io.xpipe.app.core.AppLogs;
|
|||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppState;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.update.XPipeDistributionType;
|
||||
import io.xpipe.app.util.LicenseProvider;
|
||||
|
@ -164,7 +163,11 @@ public class SentryErrorHandler implements ErrorHandler {
|
|||
|
||||
s.setTag("diagnostics", Boolean.toString(ee.isShouldSendDiagnostics()));
|
||||
s.setTag("licenseRequired", Boolean.toString(ee.isLicenseRequired()));
|
||||
s.setTag("fallbackShell", AppPrefs.get() != null ? String.valueOf(AppPrefs.get().useLocalFallbackShell().get()) : "unknown");
|
||||
s.setTag(
|
||||
"fallbackShell",
|
||||
AppPrefs.get() != null
|
||||
? String.valueOf(AppPrefs.get().useLocalFallbackShell().get())
|
||||
: "unknown");
|
||||
|
||||
var exMessage = ee.getThrowable() != null ? ee.getThrowable().getMessage() : null;
|
||||
if (ee.getDescription() != null
|
||||
|
|
|
@ -75,7 +75,9 @@ public class LauncherCommand implements Callable<Integer> {
|
|||
cmd.execute(args);
|
||||
} catch (Throwable t) {
|
||||
// Fix serialization issues with exception class
|
||||
var converted = t instanceof CommandLine.UnmatchedArgumentException u ? new IllegalArgumentException(u.getMessage()) : t;
|
||||
var converted = t instanceof CommandLine.UnmatchedArgumentException u
|
||||
? new IllegalArgumentException(u.getMessage())
|
||||
: t;
|
||||
var e = ErrorEvent.fromThrowable(converted).term().build();
|
||||
// Print error in case we launched from the command-line
|
||||
new LogErrorHandler().handle(e);
|
||||
|
|
|
@ -528,7 +528,12 @@ public class AppPrefs {
|
|||
}
|
||||
|
||||
// Fix erroneous fallback shell set on macOS
|
||||
if (OsType.getLocal() == OsType.MACOS && AppProperties.get().getCanonicalVersion().map(v -> v.getMajor() == 12 && v.getMinor() == 2).orElse(false) && XPipeSession.get().isNewBuildSession()) {
|
||||
if (OsType.getLocal() == OsType.MACOS
|
||||
&& AppProperties.get()
|
||||
.getCanonicalVersion()
|
||||
.map(v -> v.getMajor() == 12 && v.getMinor() == 2)
|
||||
.orElse(false)
|
||||
&& XPipeSession.get().isNewBuildSession()) {
|
||||
useLocalFallbackShell.setValue(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,13 +22,19 @@ public interface ExternalPasswordManager extends PrefsChoiceValue {
|
|||
return null;
|
||||
}
|
||||
|
||||
try (var cc = ProcessControlProvider.get().createLocalProcessControl(true).command(cmd).start()) {
|
||||
try (var cc = ProcessControlProvider.get()
|
||||
.createLocalProcessControl(true)
|
||||
.command(cmd)
|
||||
.start()) {
|
||||
var out = cc.readStdoutOrThrow();
|
||||
|
||||
// Dashlane fixes
|
||||
var rawCmd = AppPrefs.get().passwordManagerCommand.get();
|
||||
if (rawCmd.contains("dcli")) {
|
||||
out = out.lines().findFirst().map(s -> s.trim().replaceAll("\\s+$", "")).orElse(null);
|
||||
out = out.lines()
|
||||
.findFirst()
|
||||
.map(s -> s.trim().replaceAll("\\s+$", ""))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
|
|
@ -75,7 +75,6 @@ public interface ExternalPasswordManagerTemplate extends PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
ExternalPasswordManagerTemplate KEEPER = new ExternalPasswordManagerTemplate() {
|
||||
@Override
|
||||
public String getTemplate() {
|
||||
|
@ -89,7 +88,8 @@ public interface ExternalPasswordManagerTemplate extends PrefsChoiceValue {
|
|||
}
|
||||
};
|
||||
|
||||
List<ExternalPasswordManagerTemplate> ALL = Stream.of(ONEPASSWORD, BITWARDEN, DASHLANE, LASTPASS, KEEPER, MACOS_KEYCHAIN)
|
||||
List<ExternalPasswordManagerTemplate> ALL = Stream.of(
|
||||
ONEPASSWORD, BITWARDEN, DASHLANE, LASTPASS, KEEPER, MACOS_KEYCHAIN)
|
||||
.filter(externalPasswordManager -> externalPasswordManager.isSelectable())
|
||||
.toList();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.app.core.AppI18n;
|
|||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.util.DesktopHelper;
|
||||
import io.xpipe.app.util.OptionsBuilder;
|
||||
|
||||
|
@ -29,14 +28,15 @@ public class LoggingCategory extends AppPrefsCategory {
|
|||
.addToggle(prefs.enableTerminalLogging)
|
||||
.nameAndDescription("terminalLoggingDirectory")
|
||||
.addComp(new ButtonComp(AppI18n.observable("openSessionLogs"), () -> {
|
||||
var dir = AppProperties.get().getDataDir().resolve("sessions");
|
||||
try {
|
||||
Files.createDirectories(dir);
|
||||
DesktopHelper.browsePathLocal(dir);
|
||||
} catch (IOException e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
}
|
||||
}).disable(prefs.enableTerminalLogging.not())))
|
||||
var dir = AppProperties.get().getDataDir().resolve("sessions");
|
||||
try {
|
||||
Files.createDirectories(dir);
|
||||
DesktopHelper.browsePathLocal(dir);
|
||||
} catch (IOException e) {
|
||||
ErrorEvent.fromThrowable(e).handle();
|
||||
}
|
||||
})
|
||||
.disable(prefs.enableTerminalLogging.not())))
|
||||
.buildComp();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,7 @@ public class SecurityCategory extends AppPrefsCategory {
|
|||
.nameAndDescription("disableTerminalRemotePasswordPreparation")
|
||||
.addToggle(prefs.disableTerminalRemotePasswordPreparation)
|
||||
.nameAndDescription("dontAllowTerminalRestart")
|
||||
.addToggle(prefs.dontAllowTerminalRestart)
|
||||
);
|
||||
.addToggle(prefs.dontAllowTerminalRestart));
|
||||
return builder.buildComp();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package io.xpipe.app.terminal;
|
|||
|
||||
import io.xpipe.app.util.LocalShell;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
|
|
@ -4,7 +4,6 @@ import io.xpipe.app.core.AppLogs;
|
|||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.app.util.LocalShell;
|
||||
|
|
|
@ -110,7 +110,9 @@ public class DesktopHelper {
|
|||
public static void browseFileInDirectory(Path file) {
|
||||
if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE_FILE_DIR)) {
|
||||
if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
|
||||
ErrorEvent.fromMessage("Desktop integration unable to open file " + file).expected().handle();
|
||||
ErrorEvent.fromMessage("Desktop integration unable to open file " + file)
|
||||
.expected()
|
||||
.handle();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.xpipe.app.util;
|
|||
import io.xpipe.beacon.BeaconServerException;
|
||||
import io.xpipe.core.process.*;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import lombok.Setter;
|
||||
import lombok.Value;
|
||||
import lombok.experimental.NonFinal;
|
||||
|
@ -27,7 +28,6 @@ public class TerminalLaunchRequest {
|
|||
@NonFinal
|
||||
boolean setupCompleted;
|
||||
|
||||
|
||||
public Path waitForCompletion() throws BeaconServerException {
|
||||
while (true) {
|
||||
if (getResult() == null) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import io.xpipe.app.core.AppProperties;
|
|||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.resources.FileAutoSystemIcon;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
|
@ -34,8 +33,8 @@ public class TerminalLauncher {
|
|||
|
||||
public static void openDirect(
|
||||
String title, FailableFunction<ShellControl, String, Exception> command, ExternalTerminalType type)
|
||||
throws Exception {
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
throws Exception {
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
var script = ScriptHelper.constructTerminalInitFile(
|
||||
sc.getShellDialect(),
|
||||
sc,
|
||||
|
@ -78,49 +77,61 @@ public class TerminalLauncher {
|
|||
type.launch(config);
|
||||
latch.await();
|
||||
} catch (Exception ex) {
|
||||
var modMsg = ex.getMessage() != null && ex.getMessage().contains("Unable to find application named") ? ex.getMessage() + " in installed /Applications on this system" : ex.getMessage();
|
||||
throw ErrorEvent.expected(new IOException("Unable to launch terminal " + type.toTranslatedString().getValue() + ": " + modMsg, ex));
|
||||
var modMsg = ex.getMessage() != null && ex.getMessage().contains("Unable to find application named")
|
||||
? ex.getMessage() + " in installed /Applications on this system"
|
||||
: ex.getMessage();
|
||||
throw ErrorEvent.expected(new IOException(
|
||||
"Unable to launch terminal " + type.toTranslatedString().getValue() + ": " + modMsg, ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final DateTimeFormatter DATE_FORMATTER =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").withZone(ZoneId.systemDefault());
|
||||
|
||||
private static ExternalTerminalType.LaunchConfiguration createConfig(UUID request, DataStoreEntry entry, String cleanTitle, String adjustedTitle) throws
|
||||
Exception {
|
||||
private static ExternalTerminalType.LaunchConfiguration createConfig(
|
||||
UUID request, DataStoreEntry entry, String cleanTitle, String adjustedTitle) throws Exception {
|
||||
var color = entry != null ? DataStorage.get().getEffectiveColor(entry) : null;
|
||||
var d = ProcessControlProvider.get().getEffectiveLocalDialect();
|
||||
var launcherScript = d.terminalLauncherScript(request, adjustedTitle);
|
||||
var preparationScript = ScriptHelper.createLocalExecScript(launcherScript);
|
||||
|
||||
if (!AppPrefs.get().enableTerminalLogging().get()) {
|
||||
var config = new ExternalTerminalType.LaunchConfiguration(
|
||||
entry != null ? color : null, adjustedTitle, cleanTitle, preparationScript, d);
|
||||
return config;
|
||||
}
|
||||
if (!AppPrefs.get().enableTerminalLogging().get()) {
|
||||
var config = new ExternalTerminalType.LaunchConfiguration(
|
||||
entry != null ? color : null, adjustedTitle, cleanTitle, preparationScript, d);
|
||||
return config;
|
||||
}
|
||||
|
||||
var logDir = AppProperties.get().getDataDir().resolve("sessions");
|
||||
var logDir = AppProperties.get().getDataDir().resolve("sessions");
|
||||
Files.createDirectories(logDir);
|
||||
var logFile = logDir.resolve(new FilePath(DataStorage.get().getStoreEntryDisplayName(entry) + " (" +
|
||||
DATE_FORMATTER.format(Instant.now()) + ").log").fileSystemCompatible(OsType.getLocal()).toString());
|
||||
var logFile = logDir.resolve(new FilePath(DataStorage.get().getStoreEntryDisplayName(entry) + " ("
|
||||
+ DATE_FORMATTER.format(Instant.now()) + ").log")
|
||||
.fileSystemCompatible(OsType.getLocal())
|
||||
.toString());
|
||||
try (var sc = LocalShell.getShell().start()) {
|
||||
if (OsType.getLocal() == OsType.WINDOWS) {
|
||||
var content = """
|
||||
var content =
|
||||
"""
|
||||
echo 'Transcript started, output file is "sessions\\%s"'
|
||||
Start-Transcript -Force -LiteralPath "%s" > $Out-Null
|
||||
& %s
|
||||
Stop-Transcript > $Out-Null
|
||||
echo 'Transcript stopped, output file is "sessions\\%s"'
|
||||
""".formatted(logFile.getFileName().toString(), logFile, preparationScript, logFile.getFileName().toString());
|
||||
var ps = ScriptHelper.createExecScript(ShellDialects.POWERSHELL,sc, content);
|
||||
"""
|
||||
.formatted(
|
||||
logFile.getFileName().toString(),
|
||||
logFile,
|
||||
preparationScript,
|
||||
logFile.getFileName().toString());
|
||||
var ps = ScriptHelper.createExecScript(ShellDialects.POWERSHELL, sc, content);
|
||||
var config = new ExternalTerminalType.LaunchConfiguration(
|
||||
entry != null ? color : null, adjustedTitle, cleanTitle, ps, ShellDialects.POWERSHELL);
|
||||
return config;
|
||||
} else {
|
||||
var content = """
|
||||
var content =
|
||||
"""
|
||||
script -Command "%s" "%s"
|
||||
""".formatted(preparationScript, logFile);
|
||||
"""
|
||||
.formatted(preparationScript, logFile);
|
||||
var ps = ScriptHelper.createExecScript(sc.getShellDialect(), sc, content);
|
||||
var config = new ExternalTerminalType.LaunchConfiguration(
|
||||
entry != null ? color : null, adjustedTitle, cleanTitle, ps, sc.getShellDialect());
|
||||
|
|
|
@ -17,8 +17,8 @@ public class TerminalLauncherManager {
|
|||
private static final SequencedMap<UUID, TerminalLaunchRequest> entries = new LinkedHashMap<>();
|
||||
|
||||
public static CountDownLatch submitAsync(
|
||||
UUID request, ProcessControl processControl, TerminalInitScriptConfig config, String directory) throws
|
||||
BeaconClientException {
|
||||
UUID request, ProcessControl processControl, TerminalInitScriptConfig config, String directory)
|
||||
throws BeaconClientException {
|
||||
synchronized (entries) {
|
||||
var req = entries.get(request);
|
||||
if (req == null) {
|
||||
|
|
|
@ -148,7 +148,8 @@ public class ConnectionFileSystem implements FileSystem {
|
|||
|
||||
@Override
|
||||
public void directoryAccessible(String file) throws Exception {
|
||||
var current = shellControl.executeSimpleStringCommand(shellControl.getShellDialect().getPrintWorkingDirectoryCommand());
|
||||
var current = shellControl.executeSimpleStringCommand(
|
||||
shellControl.getShellDialect().getPrintWorkingDirectoryCommand());
|
||||
shellControl.command(shellControl.getShellDialect().getCdCommand(file));
|
||||
shellControl.command(shellControl.getShellDialect().getCdCommand(current));
|
||||
}
|
||||
|
|
|
@ -14,10 +14,12 @@ import io.xpipe.core.process.OsType;
|
|||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FileKind;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.TextField;
|
||||
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -26,7 +28,9 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
|
||||
private final boolean directory;
|
||||
|
||||
public BaseCompressAction(boolean directory) {this.directory = directory;}
|
||||
public BaseCompressAction(boolean directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(OpenFileSystemModel model) throws Exception {
|
||||
|
@ -38,11 +42,12 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
if (sc.getOsType() == OsType.WINDOWS) {
|
||||
var found = CommandSupport.findProgram(sc, "7z");
|
||||
if (found.isPresent()) {
|
||||
model.getCache().getMultiPurposeCache().put("7zExecutable","7z");
|
||||
model.getCache().getMultiPurposeCache().put("7zExecutable", "7z");
|
||||
return;
|
||||
}
|
||||
|
||||
var pf = sc.command(sc.getShellDialect().getPrintEnvironmentVariableCommand("ProgramFiles")).readStdoutOrThrow();
|
||||
var pf = sc.command(sc.getShellDialect().getPrintEnvironmentVariableCommand("ProgramFiles"))
|
||||
.readStdoutOrThrow();
|
||||
var loc = new FilePath(pf).join("7-Zip", "7z.exe").toWindows();
|
||||
if (model.getFileSystem().fileExists(loc)) {
|
||||
model.getCache().getMultiPurposeCache().put("7zExecutable", loc);
|
||||
|
@ -71,11 +76,15 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
@Override
|
||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
var ext = List.of("zip", "tar", "tar.gz", "tgz", "7z", "rar", "xar");
|
||||
if (entries.stream().anyMatch(browserEntry -> ext.stream().anyMatch(s -> browserEntry.getRawFileEntry().getPath().toLowerCase().endsWith("." + s)))) {
|
||||
if (entries.stream().anyMatch(browserEntry -> ext.stream()
|
||||
.anyMatch(s ->
|
||||
browserEntry.getRawFileEntry().getPath().toLowerCase().endsWith("." + s)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return directory ? entries.size() == 1 && entries.getFirst().getRawFileEntry().getKind() == FileKind.DIRECTORY : entries.size() >= 1;
|
||||
return directory
|
||||
? entries.size() == 1 && entries.getFirst().getRawFileEntry().getKind() == FileKind.DIRECTORY
|
||||
: entries.size() >= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,11 +94,11 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
new WindowsZipAction(),
|
||||
new UnixZipAction(),
|
||||
new TarBasedAction(false) {
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
return "tar";
|
||||
}
|
||||
},
|
||||
@Override
|
||||
protected String getExtension() {
|
||||
return "tar";
|
||||
}
|
||||
},
|
||||
new TarBasedAction(true) {
|
||||
|
||||
@Override
|
||||
|
@ -146,7 +155,10 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
protected void create(String fileName, OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
var base = new FilePath(model.getCurrentDirectory().getPath());
|
||||
var target = base.join(fileName);
|
||||
var command = CommandBuilder.of().add("Compress-Archive", "-Force", "-DestinationPath").addFile(target).add("-Path");
|
||||
var command = CommandBuilder.of()
|
||||
.add("Compress-Archive", "-Force", "-DestinationPath")
|
||||
.addFile(target)
|
||||
.add("-Path");
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
var rel = new FilePath(entries.get(i).getRawFileEntry().getPath()).relativize(base);
|
||||
if (directory) {
|
||||
|
@ -159,16 +171,22 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
}
|
||||
}
|
||||
|
||||
model.runAsync(() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
sc.command(command).withWorkingDirectory(base.toString()).execute();
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
sub.command(command).withWorkingDirectory(base.toString()).execute();
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
model.runAsync(
|
||||
() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(base.toString())
|
||||
.execute();
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
sub.command(command)
|
||||
.withWorkingDirectory(base.toString())
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -190,7 +208,9 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
var target = base.join(fileName);
|
||||
var command = CommandBuilder.of().add("zip", "-r", "-");
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
var rel = new FilePath(entries.get(i).getRawFileEntry().getPath()).relativize(base).toUnix();
|
||||
var rel = new FilePath(entries.get(i).getRawFileEntry().getPath())
|
||||
.relativize(base)
|
||||
.toUnix();
|
||||
if (directory) {
|
||||
command.add(".");
|
||||
} else {
|
||||
|
@ -200,10 +220,15 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
command.add(">").addFile(target);
|
||||
|
||||
if (directory) {
|
||||
model.runAsync(() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
sc.command(command).withWorkingDirectory(entries.getFirst().getRawFileEntry().getPath()).execute();
|
||||
}, true);
|
||||
model.runAsync(
|
||||
() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(
|
||||
entries.getFirst().getRawFileEntry().getPath())
|
||||
.execute();
|
||||
},
|
||||
true);
|
||||
} else {
|
||||
model.runCommandAsync(command, true);
|
||||
}
|
||||
|
@ -231,7 +256,14 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
protected void create(String fileName, OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
var base = new FilePath(model.getCurrentDirectory().getPath());
|
||||
var target = base.join(fileName);
|
||||
var command = CommandBuilder.of().addFile(model.getCache().getMultiPurposeCache().get("7zExecutable").toString()).add("a").add("-r").addFile(target);
|
||||
var command = CommandBuilder.of()
|
||||
.addFile(model.getCache()
|
||||
.getMultiPurposeCache()
|
||||
.get("7zExecutable")
|
||||
.toString())
|
||||
.add("a")
|
||||
.add("-r")
|
||||
.addFile(target);
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
var rel = new FilePath(entries.get(i).getRawFileEntry().getPath()).relativize(base);
|
||||
if (directory) {
|
||||
|
@ -264,18 +296,28 @@ public abstract class BaseCompressAction implements BrowserAction, BranchAction
|
|||
|
||||
private final boolean gz;
|
||||
|
||||
private TarBasedAction(boolean gz) {this.gz = gz;}
|
||||
private TarBasedAction(boolean gz) {
|
||||
this.gz = gz;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void create(String fileName, OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
var tar = CommandBuilder.of().add("tar", "-c").addIf(gz, "-z").add("-f").addFile(fileName);
|
||||
var tar = CommandBuilder.of()
|
||||
.add("tar", "-c")
|
||||
.addIf(gz, "-z")
|
||||
.add("-f")
|
||||
.addFile(fileName);
|
||||
var base = new FilePath(model.getCurrentDirectory().getPath());
|
||||
|
||||
if (directory) {
|
||||
var dir = new FilePath(entries.getFirst().getRawFileEntry().getPath());
|
||||
// Fix for bsd find, remove /
|
||||
var command = CommandBuilder.of().add("find").addFile(dir.removeTrailingSlash().toUnix())
|
||||
.add("|", "sed").addLiteral("s,^" + dir.toDirectory().toUnix() + "*,,").add("|");
|
||||
var command = CommandBuilder.of()
|
||||
.add("find")
|
||||
.addFile(dir.removeTrailingSlash().toUnix())
|
||||
.add("|", "sed")
|
||||
.addLiteral("s,^" + dir.toDirectory().toUnix() + "*,,")
|
||||
.add("|");
|
||||
command.add(tar).add("-C").addFile(dir.toDirectory().toUnix()).add("-T", "-");
|
||||
model.runCommandAsync(command, true);
|
||||
} else {
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.xpipe.app.browser.icon.BrowserIcons;
|
|||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
|
@ -36,22 +37,27 @@ public class BaseUntarAction implements ApplicationPathAction, LeafAction {
|
|||
|
||||
@Override
|
||||
public void execute(OpenFileSystemModel model, List<BrowserEntry> entries) throws Exception {
|
||||
model.runAsync(() -> {
|
||||
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
|
||||
for (BrowserEntry entry : entries) {
|
||||
var target = getTarget(entry.getRawFileEntry().getPath());
|
||||
var c = CommandBuilder.of().add("tar");
|
||||
if (toDirectory) {
|
||||
c.add("-C").addFile(target);
|
||||
}
|
||||
c.add("-x").addIf(gz, "-z").add("-f");
|
||||
c.addFile(entry.getRawFileEntry().getPath());
|
||||
if (toDirectory) {
|
||||
model.getFileSystem().mkdirs(target);
|
||||
}
|
||||
sc.command(c).withWorkingDirectory(model.getCurrentDirectory().getPath()).execute();
|
||||
}
|
||||
}, true);
|
||||
model.runAsync(
|
||||
() -> {
|
||||
ShellControl sc = model.getFileSystem().getShell().orElseThrow();
|
||||
for (BrowserEntry entry : entries) {
|
||||
var target = getTarget(entry.getRawFileEntry().getPath());
|
||||
var c = CommandBuilder.of().add("tar");
|
||||
if (toDirectory) {
|
||||
c.add("-C").addFile(target);
|
||||
}
|
||||
c.add("-x").addIf(gz, "-z").add("-f");
|
||||
c.addFile(entry.getRawFileEntry().getPath());
|
||||
if (toDirectory) {
|
||||
model.getFileSystem().mkdirs(target);
|
||||
}
|
||||
sc.command(c)
|
||||
.withWorkingDirectory(
|
||||
model.getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
}
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -73,9 +79,12 @@ public class BaseUntarAction implements ApplicationPathAction, LeafAction {
|
|||
@Override
|
||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
if (gz) {
|
||||
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".tar.gz") || entry.getRawFileEntry().getPath().endsWith(".tgz"));
|
||||
return entries.stream()
|
||||
.allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".tar.gz")
|
||||
|| entry.getRawFileEntry().getPath().endsWith(".tgz"));
|
||||
}
|
||||
|
||||
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".tar"));
|
||||
return entries.stream()
|
||||
.allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".tar"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,8 @@ import io.xpipe.app.browser.icon.BrowserIcons;
|
|||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.core.process.CommandBuilder;
|
||||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.store.FileNames;
|
||||
|
||||
import io.xpipe.ext.base.browser.ExecuteApplicationAction;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
|
@ -19,7 +18,9 @@ public abstract class BaseUnzipUnixAction extends ExecuteApplicationAction {
|
|||
|
||||
private final boolean toDirectory;
|
||||
|
||||
public BaseUnzipUnixAction(boolean toDirectory) {this.toDirectory = toDirectory;}
|
||||
public BaseUnzipUnixAction(boolean toDirectory) {
|
||||
this.toDirectory = toDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getIcon(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
|
@ -38,7 +39,9 @@ public abstract class BaseUnzipUnixAction extends ExecuteApplicationAction {
|
|||
|
||||
@Override
|
||||
protected CommandBuilder createCommand(OpenFileSystemModel model, BrowserEntry entry) {
|
||||
var command = CommandBuilder.of().add("unzip", "-o").addFile(entry.getRawFileEntry().getPath());
|
||||
var command = CommandBuilder.of()
|
||||
.add("unzip", "-o")
|
||||
.addFile(entry.getRawFileEntry().getPath());
|
||||
if (toDirectory) {
|
||||
command.add("-d").addFile(getTarget(entry.getRawFileEntry().getPath()));
|
||||
}
|
||||
|
@ -63,7 +66,8 @@ public abstract class BaseUnzipUnixAction extends ExecuteApplicationAction {
|
|||
|
||||
@Override
|
||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".zip"))
|
||||
return entries.stream()
|
||||
.allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".zip"))
|
||||
&& !model.getFileSystem().getShell().orElseThrow().getOsType().equals(OsType.WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ import io.xpipe.core.process.CommandBuilder;
|
|||
import io.xpipe.core.process.OsType;
|
||||
import io.xpipe.core.process.ShellControl;
|
||||
import io.xpipe.core.process.ShellDialects;
|
||||
import io.xpipe.core.store.FilePath;
|
||||
import io.xpipe.ext.base.browser.ExecuteApplicationAction;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Node;
|
||||
|
||||
|
@ -21,7 +20,9 @@ public abstract class BaseUnzipWindowsAction implements LeafAction {
|
|||
|
||||
private final boolean toDirectory;
|
||||
|
||||
public BaseUnzipWindowsAction(boolean toDirectory) {this.toDirectory = toDirectory;}
|
||||
public BaseUnzipWindowsAction(boolean toDirectory) {
|
||||
this.toDirectory = toDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getIcon(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
|
@ -30,20 +31,22 @@ public abstract class BaseUnzipWindowsAction implements LeafAction {
|
|||
|
||||
@Override
|
||||
public void execute(OpenFileSystemModel model, List<BrowserEntry> entries) throws Exception {
|
||||
model.runAsync(() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
for (BrowserEntry entry : entries) {
|
||||
runCommand(sc, model, entry);
|
||||
}
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
for (BrowserEntry entry : entries) {
|
||||
runCommand(sub, model, entry);
|
||||
model.runAsync(
|
||||
() -> {
|
||||
var sc = model.getFileSystem().getShell().orElseThrow();
|
||||
if (ShellDialects.isPowershell(sc)) {
|
||||
for (BrowserEntry entry : entries) {
|
||||
runCommand(sc, model, entry);
|
||||
}
|
||||
} else {
|
||||
try (var sub = sc.subShell(ShellDialects.POWERSHELL)) {
|
||||
for (BrowserEntry entry : entries) {
|
||||
runCommand(sub, model, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
private void runCommand(ShellControl sc, OpenFileSystemModel model, BrowserEntry entry) throws Exception {
|
||||
|
@ -53,7 +56,9 @@ public abstract class BaseUnzipWindowsAction implements LeafAction {
|
|||
command.add("-DestinationPath").addFile(target);
|
||||
}
|
||||
command.add("-Path").addFile(entry.getRawFileEntry().getPath());
|
||||
sc.command(command).withWorkingDirectory(model.getCurrentDirectory().getPath()).execute();
|
||||
sc.command(command)
|
||||
.withWorkingDirectory(model.getCurrentDirectory().getPath())
|
||||
.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,7 +79,8 @@ public abstract class BaseUnzipWindowsAction implements LeafAction {
|
|||
|
||||
@Override
|
||||
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".zip"))
|
||||
return entries.stream()
|
||||
.allMatch(entry -> entry.getRawFileEntry().getPath().endsWith(".zip"))
|
||||
&& model.getFileSystem().getShell().orElseThrow().getOsType().equals(OsType.WINDOWS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,8 @@ public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.T
|
|||
if (isCompatible(shellControl)) {
|
||||
var shebang = getCommands().startsWith("#");
|
||||
// Fix new lines and shebang
|
||||
var fixedCommands = getCommands().lines()
|
||||
var fixedCommands = getCommands()
|
||||
.lines()
|
||||
.skip(shebang ? 1 : 0)
|
||||
.collect(Collectors.joining(
|
||||
shellControl.getShellDialect().getNewLine().getNewLineString()));
|
||||
|
@ -91,8 +92,9 @@ public class SimpleScriptStore extends ScriptStore implements ShellInitCommand.T
|
|||
var added = all.add(ref);
|
||||
// Prevent loop
|
||||
if (added) {
|
||||
getEffectiveScripts().stream().filter(scriptStoreDataStoreEntryRef -> !all.contains(scriptStoreDataStoreEntryRef)).forEach(
|
||||
scriptStoreDataStoreEntryRef -> {
|
||||
getEffectiveScripts().stream()
|
||||
.filter(scriptStoreDataStoreEntryRef -> !all.contains(scriptStoreDataStoreEntryRef))
|
||||
.forEach(scriptStoreDataStoreEntryRef -> {
|
||||
scriptStoreDataStoreEntryRef.getStore().queryFlattenedScripts(all);
|
||||
});
|
||||
all.remove(ref);
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.ext.DataStorageExtensionProvider;
|
|||
import io.xpipe.app.ext.DataStoreProvider;
|
||||
import io.xpipe.ext.base.action.*;
|
||||
import io.xpipe.ext.base.browser.*;
|
||||
import io.xpipe.ext.base.browser.compress.*;
|
||||
import io.xpipe.ext.base.desktop.DesktopApplicationStoreProvider;
|
||||
import io.xpipe.ext.base.desktop.DesktopCommandStoreProvider;
|
||||
import io.xpipe.ext.base.desktop.DesktopEnvironmentStoreProvider;
|
||||
|
@ -12,7 +13,6 @@ import io.xpipe.ext.base.service.*;
|
|||
import io.xpipe.ext.base.store.StorePauseAction;
|
||||
import io.xpipe.ext.base.store.StoreStartAction;
|
||||
import io.xpipe.ext.base.store.StoreStopAction;
|
||||
import io.xpipe.ext.base.browser.compress.*;
|
||||
|
||||
open module io.xpipe.ext.base {
|
||||
exports io.xpipe.ext.base;
|
||||
|
@ -55,7 +55,9 @@ open module io.xpipe.ext.base {
|
|||
CopyAction,
|
||||
CopyPathAction,
|
||||
PasteAction,
|
||||
NewItemAction, FileCompressAction, DirectoryCompressAction,
|
||||
NewItemAction,
|
||||
FileCompressAction,
|
||||
DirectoryCompressAction,
|
||||
RenameAction,
|
||||
DeleteAction,
|
||||
DeleteLinkAction,
|
||||
|
@ -63,7 +65,10 @@ open module io.xpipe.ext.base {
|
|||
UnzipDirectoryUnixAction,
|
||||
UnzipHereWindowsAction,
|
||||
UnzipDirectoryWindowsAction,
|
||||
UntarHereAction, UntarGzHereAction, UntarDirectoryAction, UntarGzDirectoryAction,
|
||||
UntarHereAction,
|
||||
UntarGzHereAction,
|
||||
UntarDirectoryAction,
|
||||
UntarGzDirectoryAction,
|
||||
JavapAction,
|
||||
JarAction;
|
||||
provides ActionProvider with
|
||||
|
|
Loading…
Reference in a new issue