mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Reformat
This commit is contained in:
parent
d6cb3bf2bd
commit
27e6fc10e0
40 changed files with 284 additions and 177 deletions
|
@ -63,9 +63,7 @@ public class BrowserOverviewComp extends SimpleComp {
|
||||||
var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview)
|
var commonPane = new SimpleTitledPaneComp(AppI18n.observable("common"), commonOverview)
|
||||||
.apply(struc -> VBox.setVgrow(struc.get(), Priority.NEVER));
|
.apply(struc -> VBox.setVgrow(struc.get(), Priority.NEVER));
|
||||||
|
|
||||||
var roots = model.getFileSystem()
|
var roots = model.getFileSystem().listRoots().stream()
|
||||||
.listRoots()
|
|
||||||
.stream()
|
|
||||||
.map(s -> FileEntry.ofDirectory(model.getFileSystem(), s))
|
.map(s -> FileEntry.ofDirectory(model.getFileSystem(), s))
|
||||||
.toList();
|
.toList();
|
||||||
var rootsOverview = new BrowserFileOverviewComp(model, FXCollections.observableArrayList(roots), false);
|
var rootsOverview = new BrowserFileOverviewComp(model, FXCollections.observableArrayList(roots), false);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.app.browser.icon.BrowserIconFileType;
|
||||||
import io.xpipe.core.store.FileEntry;
|
import io.xpipe.core.store.FileEntry;
|
||||||
import io.xpipe.core.store.FileKind;
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileNames;
|
import io.xpipe.core.store.FileNames;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package io.xpipe.app.browser.file;
|
package io.xpipe.app.browser.file;
|
||||||
|
|
||||||
import atlantafx.base.controls.Spacer;
|
|
||||||
import atlantafx.base.theme.Styles;
|
|
||||||
import io.xpipe.app.browser.action.BrowserAction;
|
import io.xpipe.app.browser.action.BrowserAction;
|
||||||
import io.xpipe.app.comp.base.LazyTextFieldComp;
|
import io.xpipe.app.comp.base.LazyTextFieldComp;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
|
@ -14,6 +12,7 @@ import io.xpipe.core.store.FileEntry;
|
||||||
import io.xpipe.core.store.FileInfo;
|
import io.xpipe.core.store.FileInfo;
|
||||||
import io.xpipe.core.store.FileKind;
|
import io.xpipe.core.store.FileKind;
|
||||||
import io.xpipe.core.store.FileNames;
|
import io.xpipe.core.store.FileNames;
|
||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
|
@ -34,6 +33,9 @@ import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
|
||||||
|
import atlantafx.base.controls.Spacer;
|
||||||
|
import atlantafx.base.theme.Styles;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
@ -104,7 +106,9 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
var modeCol = new TableColumn<BrowserEntry, String>();
|
var modeCol = new TableColumn<BrowserEntry, String>();
|
||||||
modeCol.textProperty().bind(AppI18n.observable("attributes"));
|
modeCol.textProperty().bind(AppI18n.observable("attributes"));
|
||||||
modeCol.setCellValueFactory(param -> new SimpleObjectProperty<>(
|
modeCol.setCellValueFactory(param -> new SimpleObjectProperty<>(
|
||||||
param.getValue().getRawFileEntry().resolved().getInfo() instanceof FileInfo.Unix u ? u.getPermissions() : null));
|
param.getValue().getRawFileEntry().resolved().getInfo() instanceof FileInfo.Unix u
|
||||||
|
? u.getPermissions()
|
||||||
|
: null));
|
||||||
modeCol.setCellFactory(col -> new FileModeCell());
|
modeCol.setCellFactory(col -> new FileModeCell());
|
||||||
modeCol.setResizable(false);
|
modeCol.setResizable(false);
|
||||||
modeCol.setPrefWidth(120);
|
modeCol.setPrefWidth(120);
|
||||||
|
@ -134,7 +138,11 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
table.setFixedCellSize(32.0);
|
table.setFixedCellSize(32.0);
|
||||||
var os = fileList.getFileSystemModel().getFileSystem().getShell().orElseThrow().getOsType();
|
var os = fileList.getFileSystemModel()
|
||||||
|
.getFileSystem()
|
||||||
|
.getShell()
|
||||||
|
.orElseThrow()
|
||||||
|
.getOsType();
|
||||||
table.widthProperty().subscribe((newValue) -> {
|
table.widthProperty().subscribe((newValue) -> {
|
||||||
if (os != OsType.WINDOWS && os != OsType.MACOS) {
|
if (os != OsType.WINDOWS && os != OsType.MACOS) {
|
||||||
ownerCol.setVisible(newValue.doubleValue() > 1000);
|
ownerCol.setVisible(newValue.doubleValue() > 1000);
|
||||||
|
@ -143,7 +151,10 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
filenameCol.setPrefWidth(width);
|
filenameCol.setPrefWidth(width);
|
||||||
});
|
});
|
||||||
|
|
||||||
table.lookupAll(".scroll-bar").stream().filter(node -> node.getPseudoClassStates().contains(PseudoClass.getPseudoClass("horizontal"))).findFirst().ifPresent(node -> {
|
table.lookupAll(".scroll-bar").stream()
|
||||||
|
.filter(node -> node.getPseudoClassStates().contains(PseudoClass.getPseudoClass("horizontal")))
|
||||||
|
.findFirst()
|
||||||
|
.ifPresent(node -> {
|
||||||
Region region = (Region) node;
|
Region region = (Region) node;
|
||||||
region.setMinHeight(0);
|
region.setMinHeight(0);
|
||||||
region.setPrefHeight(0);
|
region.setPrefHeight(0);
|
||||||
|
@ -160,9 +171,12 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getFilenameWidth(TableView<?> tableView) {
|
private double getFilenameWidth(TableView<?> tableView) {
|
||||||
var sum = tableView.getColumns().stream().filter(tableColumn -> tableColumn.isVisible() &&
|
var sum = tableView.getColumns().stream()
|
||||||
tableView.getColumns().indexOf(tableColumn) != 0)
|
.filter(tableColumn -> tableColumn.isVisible()
|
||||||
.mapToDouble(value -> value.getPrefWidth()).sum() + 7;
|
&& tableView.getColumns().indexOf(tableColumn) != 0)
|
||||||
|
.mapToDouble(value -> value.getPrefWidth())
|
||||||
|
.sum()
|
||||||
|
+ 7;
|
||||||
return tableView.getWidth() - sum;
|
return tableView.getWidth() - sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,10 +187,18 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
var m = fileList.getFileSystemModel();
|
var m = fileList.getFileSystemModel();
|
||||||
var user = unix.getUser() != null ? unix.getUser() : m.getCache().getUsers().get(unix.getUid());
|
var user = unix.getUser() != null
|
||||||
var group = unix.getGroup() != null ? unix.getGroup() : m.getCache().getGroups().get(unix.getGid());
|
? unix.getUser()
|
||||||
var uid = String.valueOf(unix.getUid() != null ? unix.getUid() : m.getCache().getUidForUser(user)).replaceAll("000$", "k");
|
: m.getCache().getUsers().get(unix.getUid());
|
||||||
var gid = String.valueOf(unix.getGid() != null ? unix.getGid() : m.getCache().getGidForGroup(group)).replaceAll("000$", "k");
|
var group = unix.getGroup() != null
|
||||||
|
? unix.getGroup()
|
||||||
|
: m.getCache().getGroups().get(unix.getGid());
|
||||||
|
var uid = String.valueOf(
|
||||||
|
unix.getUid() != null ? unix.getUid() : m.getCache().getUidForUser(user))
|
||||||
|
.replaceAll("000$", "k");
|
||||||
|
var gid = String.valueOf(
|
||||||
|
unix.getGid() != null ? unix.getGid() : m.getCache().getGidForGroup(group))
|
||||||
|
.replaceAll("000$", "k");
|
||||||
if (uid.equals(gid)) {
|
if (uid.equals(gid)) {
|
||||||
return user + " [" + uid + "]";
|
return user + " [" + uid + "]";
|
||||||
}
|
}
|
||||||
|
@ -428,19 +450,27 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
var newItems = new ArrayList<>(fileList.getShown().getValue());
|
var newItems = new ArrayList<>(fileList.getShown().getValue());
|
||||||
table.getItems().clear();
|
table.getItems().clear();
|
||||||
|
|
||||||
var hasModifiedDate = newItems.size() == 0 || newItems.stream().anyMatch(entry -> entry.getRawFileEntry().getDate() != null);
|
var hasModifiedDate = newItems.size() == 0
|
||||||
|
|| newItems.stream()
|
||||||
|
.anyMatch(entry -> entry.getRawFileEntry().getDate() != null);
|
||||||
if (!hasModifiedDate) {
|
if (!hasModifiedDate) {
|
||||||
mtimeCol.setVisible(false);
|
mtimeCol.setVisible(false);
|
||||||
} else {
|
} else {
|
||||||
mtimeCol.setVisible(true);
|
mtimeCol.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ownerWidth.set(fileList.getAll().getValue().stream().map(browserEntry -> formatOwner(browserEntry)).map(
|
ownerWidth.set(fileList.getAll().getValue().stream()
|
||||||
s -> s != null ? s.length() * 9 : 0).max(Comparator.naturalOrder()).orElse(150));
|
.map(browserEntry -> formatOwner(browserEntry))
|
||||||
|
.map(s -> s != null ? s.length() * 9 : 0)
|
||||||
|
.max(Comparator.naturalOrder())
|
||||||
|
.orElse(150));
|
||||||
ownerCol.setPrefWidth(ownerWidth.get());
|
ownerCol.setPrefWidth(ownerWidth.get());
|
||||||
|
|
||||||
if (fileList.getFileSystemModel().getFileSystem() != null) {
|
if (fileList.getFileSystemModel().getFileSystem() != null) {
|
||||||
var shell = fileList.getFileSystemModel().getFileSystem().getShell().orElseThrow();
|
var shell = fileList.getFileSystemModel()
|
||||||
|
.getFileSystem()
|
||||||
|
.getShell()
|
||||||
|
.orElseThrow();
|
||||||
if (OsType.WINDOWS.equals(shell.getOsType()) || OsType.MACOS.equals(shell.getOsType())) {
|
if (OsType.WINDOWS.equals(shell.getOsType()) || OsType.MACOS.equals(shell.getOsType())) {
|
||||||
modeCol.setVisible(false);
|
modeCol.setVisible(false);
|
||||||
ownerCol.setVisible(false);
|
ownerCol.setVisible(false);
|
||||||
|
@ -603,13 +633,9 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
.hide(Bindings.createBooleanBinding(
|
.hide(Bindings.createBooleanBinding(
|
||||||
() -> {
|
() -> {
|
||||||
var item = getTableRow().getItem();
|
var item = getTableRow().getItem();
|
||||||
var notDir = item.getRawFileEntry()
|
var notDir = item.getRawFileEntry().resolved().getKind() != FileKind.DIRECTORY;
|
||||||
.resolved()
|
|
||||||
.getKind()
|
|
||||||
!= FileKind.DIRECTORY;
|
|
||||||
var isParentLink = item.getRawFileEntry()
|
var isParentLink = item.getRawFileEntry()
|
||||||
.equals(fileList.getFileSystemModel()
|
.equals(fileList.getFileSystemModel().getCurrentParentDirectory());
|
||||||
.getCurrentParentDirectory());
|
|
||||||
return notDir || isParentLink;
|
return notDir || isParentLink;
|
||||||
},
|
},
|
||||||
itemProperty()))
|
itemProperty()))
|
||||||
|
@ -719,7 +745,9 @@ public final class BrowserFileListComp extends SimpleComp {
|
||||||
.getPath()
|
.getPath()
|
||||||
: getTableRow().getItem().getFileName();
|
: getTableRow().getItem().getFileName();
|
||||||
var fileName = normalName;
|
var fileName = normalName;
|
||||||
var hidden = getTableRow().getItem().getRawFileEntry().getInfo().explicitlyHidden() || fileName.startsWith(".");
|
var hidden =
|
||||||
|
getTableRow().getItem().getRawFileEntry().getInfo().explicitlyHidden()
|
||||||
|
|| fileName.startsWith(".");
|
||||||
getTableRow().pseudoClassStateChanged(HIDDEN, hidden);
|
getTableRow().pseudoClassStateChanged(HIDDEN, hidden);
|
||||||
text.set(fileName);
|
text.set(fileName);
|
||||||
// Visibility seems to be bugged, so use opacity
|
// Visibility seems to be bugged, so use opacity
|
||||||
|
|
|
@ -99,7 +99,8 @@ public final class BrowserFileListModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public BrowserEntry rename(BrowserEntry old, String newName) {
|
public BrowserEntry rename(BrowserEntry old, String newName) {
|
||||||
if (old == null || newName == null
|
if (old == null
|
||||||
|
|| newName == null
|
||||||
|| fileSystemModel == null
|
|| fileSystemModel == null
|
||||||
|| fileSystemModel.isClosed()
|
|| fileSystemModel.isClosed()
|
||||||
|| fileSystemModel.getCurrentPath().get() == null) {
|
|| fileSystemModel.getCurrentPath().get() == null) {
|
||||||
|
|
|
@ -222,11 +222,7 @@ public class BrowserFileTransferOperation {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transfer(
|
private void transfer(
|
||||||
FileEntry sourceFile,
|
FileEntry sourceFile, String targetFile, AtomicLong transferred, AtomicLong totalSize, Instant start)
|
||||||
String targetFile,
|
|
||||||
AtomicLong transferred,
|
|
||||||
AtomicLong totalSize,
|
|
||||||
Instant start)
|
|
||||||
throws Exception {
|
throws Exception {
|
||||||
InputStream inputStream = null;
|
InputStream inputStream = null;
|
||||||
OutputStream outputStream = null;
|
OutputStream outputStream = null;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import io.xpipe.core.process.CommandBuilder;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
import io.xpipe.core.process.ShellControl;
|
import io.xpipe.core.process.ShellControl;
|
||||||
import io.xpipe.core.process.ShellDialect;
|
import io.xpipe.core.process.ShellDialect;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -31,11 +32,19 @@ public class OpenFileSystemCache extends ShellControlCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getUidForUser(String name) {
|
public int getUidForUser(String name) {
|
||||||
return users.entrySet().stream().filter(e -> e.getValue().equals(name)).findFirst().map(e -> e.getKey()).orElse(0);
|
return users.entrySet().stream()
|
||||||
|
.filter(e -> e.getValue().equals(name))
|
||||||
|
.findFirst()
|
||||||
|
.map(e -> e.getKey())
|
||||||
|
.orElse(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGidForGroup(String name) {
|
public int getGidForGroup(String name) {
|
||||||
return groups.entrySet().stream().filter(e -> e.getValue().equals(name)).findFirst().map(e -> e.getKey()).orElse(0);
|
return groups.entrySet().stream()
|
||||||
|
.filter(e -> e.getValue().equals(name))
|
||||||
|
.findFirst()
|
||||||
|
.map(e -> e.getKey())
|
||||||
|
.orElse(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadUsers() throws Exception {
|
private void loadUsers() throws Exception {
|
||||||
|
@ -44,7 +53,9 @@ public class OpenFileSystemCache extends ShellControlCache {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lines = sc.command(CommandBuilder.of().add("cat").addFile("/etc/passwd")).readStdoutIfPossible().orElse("");
|
var lines = sc.command(CommandBuilder.of().add("cat").addFile("/etc/passwd"))
|
||||||
|
.readStdoutIfPossible()
|
||||||
|
.orElse("");
|
||||||
lines.lines().forEach(s -> {
|
lines.lines().forEach(s -> {
|
||||||
var split = s.split(":");
|
var split = s.split(":");
|
||||||
users.putIfAbsent(Integer.parseInt(split[2]), split[0]);
|
users.putIfAbsent(Integer.parseInt(split[2]), split[0]);
|
||||||
|
@ -61,7 +72,9 @@ public class OpenFileSystemCache extends ShellControlCache {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lines = sc.command(CommandBuilder.of().add("cat").addFile("/etc/group")).readStdoutIfPossible().orElse("");
|
var lines = sc.command(CommandBuilder.of().add("cat").addFile("/etc/group"))
|
||||||
|
.readStdoutIfPossible()
|
||||||
|
.orElse("");
|
||||||
lines.lines().forEach(s -> {
|
lines.lines().forEach(s -> {
|
||||||
var split = s.split(":");
|
var split = s.split(":");
|
||||||
groups.putIfAbsent(Integer.parseInt(split[2]), split[0]);
|
groups.putIfAbsent(Integer.parseInt(split[2]), split[0]);
|
||||||
|
|
|
@ -305,8 +305,7 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
|
||||||
loadFilesSync(path);
|
loadFilesSync(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void withFiles(String dir, FailableConsumer<Stream<FileEntry>, Exception> consumer)
|
public void withFiles(String dir, FailableConsumer<Stream<FileEntry>, Exception> consumer) throws Exception {
|
||||||
throws Exception {
|
|
||||||
BooleanScope.executeExclusive(busy, () -> {
|
BooleanScope.executeExclusive(busy, () -> {
|
||||||
if (dir != null) {
|
if (dir != null) {
|
||||||
startIfNeeded();
|
startIfNeeded();
|
||||||
|
@ -357,8 +356,7 @@ public final class OpenFileSystemModel extends BrowserSessionTab<FileSystemStore
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dropFilesIntoAsync(
|
public void dropFilesIntoAsync(FileEntry target, List<FileEntry> files, BrowserFileTransferMode mode) {
|
||||||
FileEntry target, List<FileEntry> files, BrowserFileTransferMode mode) {
|
|
||||||
// We don't have to do anything in this case
|
// We don't have to do anything in this case
|
||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3,8 +3,8 @@ package io.xpipe.app.browser.icon;
|
||||||
import io.xpipe.app.core.AppResources;
|
import io.xpipe.app.core.AppResources;
|
||||||
import io.xpipe.core.store.FileEntry;
|
import io.xpipe.core.store.FileEntry;
|
||||||
import io.xpipe.core.store.FileKind;
|
import io.xpipe.core.store.FileKind;
|
||||||
|
|
||||||
import io.xpipe.core.store.FileNames;
|
import io.xpipe.core.store.FileNames;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
|
|
@ -3,8 +3,8 @@ package io.xpipe.app.browser.icon;
|
||||||
import io.xpipe.app.core.AppResources;
|
import io.xpipe.app.core.AppResources;
|
||||||
import io.xpipe.core.store.FileEntry;
|
import io.xpipe.core.store.FileEntry;
|
||||||
import io.xpipe.core.store.FileKind;
|
import io.xpipe.core.store.FileKind;
|
||||||
|
|
||||||
import io.xpipe.core.store.FileNames;
|
import io.xpipe.core.store.FileNames;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
@ -86,9 +86,7 @@ public abstract class BrowserIconFileType {
|
||||||
|
|
||||||
var name = FileNames.getFileName(entry.getPath());
|
var name = FileNames.getFileName(entry.getPath());
|
||||||
var ext = FileNames.getExtension(entry.getPath());
|
var ext = FileNames.getExtension(entry.getPath());
|
||||||
return (ext != null
|
return (ext != null && endings.contains("." + ext.toLowerCase(Locale.ROOT))) || endings.contains(name);
|
||||||
&& endings.contains("." + ext.toLowerCase(Locale.ROOT)))
|
|
||||||
|| endings.contains(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -364,7 +364,8 @@ public class BrowserSessionTabsComp extends SimpleComp {
|
||||||
|
|
||||||
StackPane c = (StackPane) tabs.lookup("#" + id + " .tab-container");
|
StackPane c = (StackPane) tabs.lookup("#" + id + " .tab-container");
|
||||||
c.getStyleClass().add("color-box");
|
c.getStyleClass().add("color-box");
|
||||||
var color = DataStorage.get().getEffectiveColor(model.getEntry().get());
|
var color =
|
||||||
|
DataStorage.get().getEffectiveColor(model.getEntry().get());
|
||||||
if (color != null) {
|
if (color != null) {
|
||||||
c.getStyleClass().add(color.getId());
|
c.getStyleClass().add(color.getId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,11 +83,15 @@ public class SideMenuBarComp extends Comp<CompStructure<VBox>> {
|
||||||
b.accessibleText(e.name());
|
b.accessibleText(e.name());
|
||||||
|
|
||||||
var indicator = Comp.empty().styleClass("indicator");
|
var indicator = Comp.empty().styleClass("indicator");
|
||||||
var stack = new StackComp(List.of(indicator, b)).apply(struc -> struc.get().setAlignment(Pos.CENTER_RIGHT));
|
var stack = new StackComp(List.of(indicator, b))
|
||||||
|
.apply(struc -> struc.get().setAlignment(Pos.CENTER_RIGHT));
|
||||||
stack.apply(struc -> {
|
stack.apply(struc -> {
|
||||||
var indicatorRegion = (Region) struc.get().getChildren().getFirst();
|
var indicatorRegion = (Region) struc.get().getChildren().getFirst();
|
||||||
indicatorRegion.setMaxWidth(7);
|
indicatorRegion.setMaxWidth(7);
|
||||||
indicatorRegion.backgroundProperty().bind(Bindings.createObjectBinding(() -> {
|
indicatorRegion
|
||||||
|
.backgroundProperty()
|
||||||
|
.bind(Bindings.createObjectBinding(
|
||||||
|
() -> {
|
||||||
if (value.getValue().equals(e)) {
|
if (value.getValue().equals(e)) {
|
||||||
return selectedBorder.get();
|
return selectedBorder.get();
|
||||||
}
|
}
|
||||||
|
@ -97,7 +101,12 @@ public class SideMenuBarComp extends Comp<CompStructure<VBox>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return noneBorder.get();
|
return noneBorder.get();
|
||||||
}, struc.get().hoverProperty(), value, hoverBorder, selectedBorder, noneBorder));
|
},
|
||||||
|
struc.get().hoverProperty(),
|
||||||
|
value,
|
||||||
|
hoverBorder,
|
||||||
|
selectedBorder,
|
||||||
|
noneBorder));
|
||||||
});
|
});
|
||||||
if (shortcut != null) {
|
if (shortcut != null) {
|
||||||
stack.apply(struc -> struc.get().getProperties().put("shortcut", shortcut));
|
stack.apply(struc -> struc.get().getProperties().put("shortcut", shortcut));
|
||||||
|
|
|
@ -58,12 +58,7 @@ public class StoreToggleComp extends SimpleComp {
|
||||||
ObservableValue<LabelGraphic> g = val.map(aBoolean -> aBoolean
|
ObservableValue<LabelGraphic> g = val.map(aBoolean -> aBoolean
|
||||||
? new LabelGraphic.IconGraphic("mdi2c-circle-slice-8")
|
? new LabelGraphic.IconGraphic("mdi2c-circle-slice-8")
|
||||||
: new LabelGraphic.IconGraphic("mdi2p-power"));
|
: new LabelGraphic.IconGraphic("mdi2p-power"));
|
||||||
var t = new StoreToggleComp(
|
var t = new StoreToggleComp(nameKey, g, section, value, v -> {
|
||||||
nameKey,
|
|
||||||
g,
|
|
||||||
section,
|
|
||||||
value,
|
|
||||||
v -> {
|
|
||||||
setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v);
|
setter.accept(section.getWrapper().getEntry().getStore().asNeeded(), v);
|
||||||
});
|
});
|
||||||
t.tooltipKey("enabled");
|
t.tooltipKey("enabled");
|
||||||
|
|
|
@ -3,10 +3,10 @@ package io.xpipe.app.comp.store;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
|
import io.xpipe.app.storage.DataColor;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.storage.DataStoreCategory;
|
import io.xpipe.app.storage.DataStoreCategory;
|
||||||
|
|
||||||
import io.xpipe.app.storage.DataColor;
|
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
|
|
@ -16,8 +16,8 @@ import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||||
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
import io.xpipe.app.fxcomps.util.DerivedObservableList;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
|
||||||
import io.xpipe.app.storage.DataColor;
|
import io.xpipe.app.storage.DataColor;
|
||||||
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.storage.DataStoreEntry;
|
import io.xpipe.app.storage.DataStoreEntry;
|
||||||
import io.xpipe.app.update.XPipeDistributionType;
|
import io.xpipe.app.update.XPipeDistributionType;
|
||||||
import io.xpipe.app.util.*;
|
import io.xpipe.app.util.*;
|
||||||
|
|
|
@ -4,9 +4,9 @@ import io.xpipe.app.ext.ActionProvider;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
|
import io.xpipe.app.storage.DataColor;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.storage.DataStoreCategory;
|
import io.xpipe.app.storage.DataStoreCategory;
|
||||||
import io.xpipe.app.storage.DataColor;
|
|
||||||
import io.xpipe.app.storage.DataStoreEntry;
|
import io.xpipe.app.storage.DataStoreEntry;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ import io.xpipe.app.util.PlatformState;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.desktop.*;
|
import java.awt.desktop.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
public class AppDesktopIntegration {
|
public class AppDesktopIntegration {
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,10 @@ package io.xpipe.app.core;
|
||||||
|
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.issue.TrackEvent;
|
import io.xpipe.app.issue.TrackEvent;
|
||||||
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.WritableImage;
|
import javafx.scene.image.WritableImage;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import io.xpipe.app.storage.DataStoreEntry;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import io.xpipe.core.store.EnabledStoreState;
|
import io.xpipe.core.store.EnabledStoreState;
|
||||||
import io.xpipe.core.store.StatefulDataStore;
|
import io.xpipe.core.store.StatefulDataStore;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
|
||||||
public interface EnabledParentStoreProvider extends DataStoreProvider {
|
public interface EnabledParentStoreProvider extends DataStoreProvider {
|
||||||
|
@ -32,11 +33,14 @@ public interface EnabledParentStoreProvider extends DataStoreProvider {
|
||||||
var state = s.getState().toBuilder().enabled(aBoolean).build();
|
var state = s.getState().toBuilder().enabled(aBoolean).build();
|
||||||
s.setState(state);
|
s.setState(state);
|
||||||
|
|
||||||
var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
var children =
|
||||||
|
DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
for (DataStoreEntry child : children) {
|
for (DataStoreEntry child : children) {
|
||||||
if (child.getStorePersistentState() instanceof EnabledStoreState enabledStoreState) {
|
if (child.getStorePersistentState() instanceof EnabledStoreState enabledStoreState) {
|
||||||
child.setStorePersistentState(enabledStoreState.toBuilder().enabled(aBoolean).build());
|
child.setStorePersistentState(enabledStoreState.toBuilder()
|
||||||
|
.enabled(aBoolean)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,6 +17,7 @@ import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.storage.DataStoreCategory;
|
import io.xpipe.app.storage.DataStoreCategory;
|
||||||
import io.xpipe.app.util.ContextMenuHelper;
|
import io.xpipe.app.util.ContextMenuHelper;
|
||||||
import io.xpipe.app.util.DataStoreFormatter;
|
import io.xpipe.app.util.DataStoreFormatter;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.css.PseudoClass;
|
import javafx.css.PseudoClass;
|
||||||
|
@ -31,6 +32,7 @@ import javafx.scene.input.KeyCodeCombination;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.input.MouseButton;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
@ -57,10 +59,12 @@ public class StoreCategoryComp extends SimpleComp {
|
||||||
|
|
||||||
var expandIcon = Bindings.createStringBinding(
|
var expandIcon = Bindings.createStringBinding(
|
||||||
() -> {
|
() -> {
|
||||||
var exp = category.getExpanded().get() && category.getChildren().size() > 0;
|
var exp = category.getExpanded().get()
|
||||||
|
&& category.getChildren().size() > 0;
|
||||||
return exp ? "mdal-keyboard_arrow_down" : "mdal-keyboard_arrow_right";
|
return exp ? "mdal-keyboard_arrow_down" : "mdal-keyboard_arrow_right";
|
||||||
},
|
},
|
||||||
category.getExpanded(), category.getChildren());
|
category.getExpanded(),
|
||||||
|
category.getChildren());
|
||||||
var expandButton = new IconButtonComp(expandIcon, () -> {
|
var expandButton = new IconButtonComp(expandIcon, () -> {
|
||||||
category.toggleExpanded();
|
category.toggleExpanded();
|
||||||
})
|
})
|
||||||
|
@ -87,7 +91,8 @@ public class StoreCategoryComp extends SimpleComp {
|
||||||
|
|
||||||
return category.getShare().getValue() ? "mdi2g-git" : "mdi2a-account-cancel";
|
return category.getShare().getValue() ? "mdi2g-git" : "mdi2a-account-cancel";
|
||||||
},
|
},
|
||||||
category.getShare(), hover);
|
category.getShare(),
|
||||||
|
hover);
|
||||||
var statusButton = new IconButtonComp(statusIcon)
|
var statusButton = new IconButtonComp(statusIcon)
|
||||||
.apply(struc -> AppFont.small(struc.get()))
|
.apply(struc -> AppFont.small(struc.get()))
|
||||||
.apply(struc -> {
|
.apply(struc -> {
|
||||||
|
@ -114,7 +119,8 @@ public class StoreCategoryComp extends SimpleComp {
|
||||||
.getList();
|
.getList();
|
||||||
var count = new CountComp<>(shownList, category.getContainedEntries(), string -> "(" + string + ")");
|
var count = new CountComp<>(shownList, category.getContainedEntries(), string -> "(" + string + ")");
|
||||||
|
|
||||||
var showStatus = hover.or(new SimpleBooleanProperty(DataStorage.get().supportsSharing())).or(showing);
|
var showStatus = hover.or(new SimpleBooleanProperty(DataStorage.get().supportsSharing()))
|
||||||
|
.or(showing);
|
||||||
var focus = new SimpleBooleanProperty();
|
var focus = new SimpleBooleanProperty();
|
||||||
var h = new HorizontalComp(List.of(
|
var h = new HorizontalComp(List.of(
|
||||||
expandButton,
|
expandButton,
|
||||||
|
@ -153,9 +159,13 @@ public class StoreCategoryComp extends SimpleComp {
|
||||||
new ListBoxViewComp<>(l, l, storeCategoryWrapper -> new StoreCategoryComp(storeCategoryWrapper), false);
|
new ListBoxViewComp<>(l, l, storeCategoryWrapper -> new StoreCategoryComp(storeCategoryWrapper), false);
|
||||||
children.styleClass("children");
|
children.styleClass("children");
|
||||||
|
|
||||||
var hide = Bindings.createBooleanBinding(() -> {
|
var hide = Bindings.createBooleanBinding(
|
||||||
return !category.getExpanded().get() || category.getChildren().isEmpty();
|
() -> {
|
||||||
}, category.getChildren(), category.getExpanded());
|
return !category.getExpanded().get()
|
||||||
|
|| category.getChildren().isEmpty();
|
||||||
|
},
|
||||||
|
category.getChildren(),
|
||||||
|
category.getExpanded());
|
||||||
var v = new VerticalComp(List.of(categoryButton, children.hide(hide)));
|
var v = new VerticalComp(List.of(categoryButton, children.hide(hide)));
|
||||||
v.styleClass("category");
|
v.styleClass("category");
|
||||||
v.apply(struc -> {
|
v.apply(struc -> {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.fxcomps.CompStructure;
|
import io.xpipe.app.fxcomps.CompStructure;
|
||||||
import io.xpipe.app.fxcomps.augment.Augment;
|
import io.xpipe.app.fxcomps.augment.Augment;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.scene.control.Tooltip;
|
import javafx.scene.control.Tooltip;
|
||||||
|
|
|
@ -46,7 +46,9 @@ public abstract class LabelGraphic {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node createGraphicNode() {
|
public Node createGraphicNode() {
|
||||||
return PrettyImageHelper.ofFixedSizeSquare(file, size).styleClass("graphic").createRegion();
|
return PrettyImageHelper.ofFixedSizeSquare(file, size)
|
||||||
|
.styleClass("graphic")
|
||||||
|
.createRegion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package io.xpipe.app.issue;
|
package io.xpipe.app.issue;
|
||||||
|
|
||||||
import io.sentry.*;
|
|
||||||
import io.sentry.protocol.SentryId;
|
|
||||||
import io.sentry.protocol.User;
|
|
||||||
import io.xpipe.app.core.AppLogs;
|
import io.xpipe.app.core.AppLogs;
|
||||||
import io.xpipe.app.core.AppProperties;
|
import io.xpipe.app.core.AppProperties;
|
||||||
import io.xpipe.app.core.AppState;
|
import io.xpipe.app.core.AppState;
|
||||||
|
@ -10,6 +7,10 @@ import io.xpipe.app.core.mode.OperationMode;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.update.XPipeDistributionType;
|
import io.xpipe.app.update.XPipeDistributionType;
|
||||||
import io.xpipe.app.util.LicenseProvider;
|
import io.xpipe.app.util.LicenseProvider;
|
||||||
|
|
||||||
|
import io.sentry.*;
|
||||||
|
import io.sentry.protocol.SentryId;
|
||||||
|
import io.sentry.protocol.User;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
@ -163,7 +164,9 @@ public class SentryErrorHandler implements ErrorHandler {
|
||||||
s.setTag("licenseRequired", Boolean.toString(ee.isLicenseRequired()));
|
s.setTag("licenseRequired", Boolean.toString(ee.isLicenseRequired()));
|
||||||
|
|
||||||
var exMessage = ee.getThrowable() != null ? ee.getThrowable().getMessage() : null;
|
var exMessage = ee.getThrowable() != null ? ee.getThrowable().getMessage() : null;
|
||||||
if (ee.getDescription() != null && !ee.getDescription().equals(exMessage) && (ee.isShouldSendDiagnostics() || ee.isLicenseRequired())) {
|
if (ee.getDescription() != null
|
||||||
|
&& !ee.getDescription().equals(exMessage)
|
||||||
|
&& (ee.isShouldSendDiagnostics() || ee.isLicenseRequired())) {
|
||||||
s.setTag("message", ee.getDescription().lines().collect(Collectors.joining(" ")));
|
s.setTag("message", ee.getDescription().lines().collect(Collectors.joining(" ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,13 @@ public class WorkspacesCategory extends AppPrefsCategory {
|
||||||
@Override
|
@Override
|
||||||
protected Comp<?> create() {
|
protected Comp<?> create() {
|
||||||
return new OptionsBuilder()
|
return new OptionsBuilder()
|
||||||
.addTitle(AppI18n.observable("manageWorkspaces").map(s -> s + (LicenseProvider.get().getFeature("workspaces").isSupported() ? "" : " (Pro)")))
|
.addTitle(AppI18n.observable("manageWorkspaces")
|
||||||
|
.map(s -> s
|
||||||
|
+ (LicenseProvider.get()
|
||||||
|
.getFeature("workspaces")
|
||||||
|
.isSupported()
|
||||||
|
? ""
|
||||||
|
: " (Pro)")))
|
||||||
.sub(new OptionsBuilder()
|
.sub(new OptionsBuilder()
|
||||||
.nameAndDescription("workspaceAdd")
|
.nameAndDescription("workspaceAdd")
|
||||||
.addComp(new ButtonComp(AppI18n.observable("addWorkspace"), WorkspaceCreationAlert::showAsync)))
|
.addComp(new ButtonComp(AppI18n.observable("addWorkspace"), WorkspaceCreationAlert::showAsync)))
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package io.xpipe.app.storage;
|
package io.xpipe.app.storage;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -45,8 +46,7 @@ public enum DataColor {
|
||||||
public static void applyStyleClasses(DataColor color, Node node) {
|
public static void applyStyleClasses(DataColor color, Node node) {
|
||||||
var newList = new ArrayList<>(node.getStyleClass());
|
var newList = new ArrayList<>(node.getStyleClass());
|
||||||
newList.removeIf(s -> Arrays.stream(DataColor.values())
|
newList.removeIf(s -> Arrays.stream(DataColor.values())
|
||||||
.anyMatch(
|
.anyMatch(dataStoreColor -> dataStoreColor.getId().equals(s)));
|
||||||
dataStoreColor -> dataStoreColor.getId().equals(s)));
|
|
||||||
newList.remove("gray");
|
newList.remove("gray");
|
||||||
if (color != null) {
|
if (color != null) {
|
||||||
newList.add(color.getId());
|
newList.add(color.getId());
|
||||||
|
|
|
@ -700,7 +700,8 @@ public abstract class DataStorage {
|
||||||
return root.getColor();
|
return root.getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
var cats = getCategoryParentHierarchy(getStoreCategoryIfPresent(entry.getCategoryUuid()).orElseThrow());
|
var cats = getCategoryParentHierarchy(
|
||||||
|
getStoreCategoryIfPresent(entry.getCategoryUuid()).orElseThrow());
|
||||||
for (DataStoreCategory cat : cats.reversed()) {
|
for (DataStoreCategory cat : cats.reversed()) {
|
||||||
if (cat.getColor() != null) {
|
if (cat.getColor() != null) {
|
||||||
return cat.getColor();
|
return cat.getColor();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package io.xpipe.app.storage;
|
package io.xpipe.app.storage;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import io.xpipe.app.comp.store.StoreSortMode;
|
import io.xpipe.app.comp.store.StoreSortMode;
|
||||||
import io.xpipe.core.util.JacksonMapper;
|
import io.xpipe.core.util.JacksonMapper;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||||
|
@ -128,8 +128,8 @@ public class DataStoreCategory extends StorageElement {
|
||||||
.map(jsonNode -> jsonNode.booleanValue())
|
.map(jsonNode -> jsonNode.booleanValue())
|
||||||
.orElse(true);
|
.orElse(true);
|
||||||
|
|
||||||
return Optional.of(
|
return Optional.of(new DataStoreCategory(
|
||||||
new DataStoreCategory(dir, uuid, name, lastUsed, lastModified, color, false, parentUuid, sortMode, share, expanded));
|
dir, uuid, name, lastUsed, lastModified, color, false, parentUuid, sortMode, share, expanded));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSortMode(StoreSortMode sortMode) {
|
public void setSortMode(StoreSortMode sortMode) {
|
||||||
|
|
|
@ -228,13 +228,15 @@ public class DataStoreEntry extends StorageElement {
|
||||||
.orElse(true);
|
.orElse(true);
|
||||||
|
|
||||||
if (color == null) {
|
if (color == null) {
|
||||||
color = Optional.ofNullable(stateJson.get("color")).map(node -> {
|
color = Optional.ofNullable(stateJson.get("color"))
|
||||||
|
.map(node -> {
|
||||||
try {
|
try {
|
||||||
return mapper.treeToValue(node, DataColor.class);
|
return mapper.treeToValue(node, DataColor.class);
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).orElse(null);
|
})
|
||||||
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
String notes = null;
|
String notes = null;
|
||||||
|
|
|
@ -43,12 +43,17 @@ public abstract class StorageElement {
|
||||||
@Getter
|
@Getter
|
||||||
protected boolean expanded;
|
protected boolean expanded;
|
||||||
|
|
||||||
protected @NonFinal
|
protected @NonFinal @Getter DataColor color;
|
||||||
@Getter DataColor color;
|
|
||||||
|
|
||||||
|
|
||||||
public StorageElement(
|
public StorageElement(
|
||||||
Path directory, UUID uuid, String name, Instant lastUsed, Instant lastModified, DataColor color, boolean expanded, boolean dirty) {
|
Path directory,
|
||||||
|
UUID uuid,
|
||||||
|
String name,
|
||||||
|
Instant lastUsed,
|
||||||
|
Instant lastModified,
|
||||||
|
DataColor color,
|
||||||
|
boolean expanded,
|
||||||
|
boolean dirty) {
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
|
@ -13,8 +13,8 @@ import io.xpipe.app.util.*;
|
||||||
import io.xpipe.core.process.*;
|
import io.xpipe.core.process.*;
|
||||||
import io.xpipe.core.store.FilePath;
|
import io.xpipe.core.store.FilePath;
|
||||||
import io.xpipe.core.util.FailableFunction;
|
import io.xpipe.core.util.FailableFunction;
|
||||||
|
|
||||||
import io.xpipe.core.util.XPipeInstallation;
|
import io.xpipe.core.util.XPipeInstallation;
|
||||||
|
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.ButtonBar;
|
import javafx.scene.control.ButtonBar;
|
||||||
import javafx.scene.control.ButtonType;
|
import javafx.scene.control.ButtonType;
|
||||||
|
@ -240,12 +240,17 @@ public interface ExternalTerminalType extends PrefsChoiceValue {
|
||||||
@Override
|
@Override
|
||||||
protected void execute(Path file, LaunchConfiguration configuration) throws Exception {
|
protected void execute(Path file, LaunchConfiguration configuration) throws Exception {
|
||||||
try (var sc = LocalShell.getShell()) {
|
try (var sc = LocalShell.getShell()) {
|
||||||
// Since mobaxterm uses its own cygwin environment, we have to provide the beacon auth secret to the tmp there as well
|
// Since mobaxterm uses its own cygwin environment, we have to provide the beacon auth secret to the tmp
|
||||||
|
// there as well
|
||||||
// Otherwise it can't connect
|
// Otherwise it can't connect
|
||||||
var slashTemp = Path.of(System.getenv("APPDATA"), "MobaXterm", "slash", "tmp");
|
var slashTemp = Path.of(System.getenv("APPDATA"), "MobaXterm", "slash", "tmp");
|
||||||
if (Files.exists(slashTemp)) {
|
if (Files.exists(slashTemp)) {
|
||||||
var authFileName = XPipeInstallation.getLocalBeaconAuthFile().getFileName().toString();
|
var authFileName = XPipeInstallation.getLocalBeaconAuthFile()
|
||||||
Files.writeString(Path.of(slashTemp.toString(), authFileName),AppBeaconServer.get().getLocalAuthSecret());
|
.getFileName()
|
||||||
|
.toString();
|
||||||
|
Files.writeString(
|
||||||
|
Path.of(slashTemp.toString(), authFileName),
|
||||||
|
AppBeaconServer.get().getLocalAuthSecret());
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixedFile = configuration
|
var fixedFile = configuration
|
||||||
|
|
|
@ -23,7 +23,8 @@ public class DesktopShortcuts {
|
||||||
$S.Arguments = '%s'
|
$S.Arguments = '%s'
|
||||||
$S.Save()
|
$S.Save()
|
||||||
""",
|
""",
|
||||||
executable, shortcutPath, icon, args).replaceAll("\n", ";");
|
executable, shortcutPath, icon, args)
|
||||||
|
.replaceAll("\n", ";");
|
||||||
LocalShell.getLocalPowershell().executeSimpleCommand(content);
|
LocalShell.getLocalPowershell().executeSimpleCommand(content);
|
||||||
return shortcutPath;
|
return shortcutPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,16 @@ public class FileEntry {
|
||||||
String path;
|
String path;
|
||||||
|
|
||||||
public FileEntry(
|
public FileEntry(
|
||||||
FileSystem fileSystem, @NonNull String path, Instant date, long size, FileInfo info, @NonNull FileKind kind
|
FileSystem fileSystem,
|
||||||
) {
|
@NonNull String path,
|
||||||
|
Instant date,
|
||||||
|
long size,
|
||||||
|
FileInfo info,
|
||||||
|
@NonNull FileKind kind) {
|
||||||
this.fileSystem = fileSystem;
|
this.fileSystem = fileSystem;
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.path = kind == FileKind.DIRECTORY ? new FilePath(path).toDirectory().toString() : path;
|
this.path =
|
||||||
|
kind == FileKind.DIRECTORY ? new FilePath(path).toDirectory().toString() : path;
|
||||||
this.date = date;
|
this.date = date;
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
|
|
@ -66,5 +66,4 @@ public interface FileSystem extends Closeable, AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> listRoots() throws Exception;
|
List<String> listRoots() throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,12 @@ public class LinkFileEntry extends FileEntry {
|
||||||
FileEntry target;
|
FileEntry target;
|
||||||
|
|
||||||
public LinkFileEntry(
|
public LinkFileEntry(
|
||||||
FileSystem fileSystem, @NonNull String path, Instant date, long size, @NonNull FileInfo info,
|
FileSystem fileSystem,
|
||||||
@NonNull FileEntry target
|
@NonNull String path,
|
||||||
) {
|
Instant date,
|
||||||
|
long size,
|
||||||
|
@NonNull FileInfo info,
|
||||||
|
@NonNull FileEntry target) {
|
||||||
super(fileSystem, path, date, size, info, FileKind.LINK);
|
super(fileSystem, path, date, size, info, FileKind.LINK);
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,11 @@ import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.core.process.CommandBuilder;
|
import io.xpipe.core.process.CommandBuilder;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -40,8 +42,13 @@ public class ChgrpAction implements BranchAction {
|
||||||
@Override
|
@Override
|
||||||
public List<LeafAction> getBranchingActions(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public List<LeafAction> getBranchingActions(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return model.getCache().getGroups().entrySet().stream()
|
return model.getCache().getGroups().entrySet().stream()
|
||||||
.filter(e -> !e.getValue().equals("nohome") && !e.getValue().equals("nogroup") && !e.getValue().equals("nobody") && (e.getKey().equals(0) || e.getKey() >= 1000))
|
.filter(e -> !e.getValue().equals("nohome")
|
||||||
.map(e -> e.getValue()).map(s -> (LeafAction) new Chgrp(s)).toList();
|
&& !e.getValue().equals("nogroup")
|
||||||
|
&& !e.getValue().equals("nobody")
|
||||||
|
&& (e.getKey().equals(0) || e.getKey() >= 1000))
|
||||||
|
.map(e -> e.getValue())
|
||||||
|
.map(s -> (LeafAction) new Chgrp(s))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Chgrp implements LeafAction {
|
private static class Chgrp implements LeafAction {
|
||||||
|
|
|
@ -7,9 +7,11 @@ import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.core.process.CommandBuilder;
|
import io.xpipe.core.process.CommandBuilder;
|
||||||
import io.xpipe.core.process.OsType;
|
import io.xpipe.core.process.OsType;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -40,8 +42,12 @@ public class ChownAction implements BranchAction {
|
||||||
@Override
|
@Override
|
||||||
public List<LeafAction> getBranchingActions(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
public List<LeafAction> getBranchingActions(OpenFileSystemModel model, List<BrowserEntry> entries) {
|
||||||
return model.getCache().getUsers().entrySet().stream()
|
return model.getCache().getUsers().entrySet().stream()
|
||||||
.filter(e -> !e.getValue().equals("nohome") && !e.getValue().equals("nobody") && (e.getKey().equals(0) || e.getKey() >= 1000))
|
.filter(e -> !e.getValue().equals("nohome")
|
||||||
.map(e -> e.getValue()).map(s -> (LeafAction) new Chown(s)).toList();
|
&& !e.getValue().equals("nobody")
|
||||||
|
&& (e.getKey().equals(0) || e.getKey() >= 1000))
|
||||||
|
.map(e -> e.getValue())
|
||||||
|
.map(s -> (LeafAction) new Chown(s))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Chown implements LeafAction {
|
private static class Chown implements LeafAction {
|
||||||
|
|
|
@ -4,8 +4,8 @@ import io.xpipe.app.browser.action.BrowserActionFormatter;
|
||||||
import io.xpipe.app.browser.file.BrowserEntry;
|
import io.xpipe.app.browser.file.BrowserEntry;
|
||||||
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
import io.xpipe.app.browser.fs.OpenFileSystemModel;
|
||||||
import io.xpipe.app.browser.icon.BrowserIconFileType;
|
import io.xpipe.app.browser.icon.BrowserIconFileType;
|
||||||
|
|
||||||
import io.xpipe.core.store.FileNames;
|
import io.xpipe.core.store.FileNames;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ public class JavapAction extends ToFileCommandAction implements FileTypeAction,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String createCommand(OpenFileSystemModel model, BrowserEntry entry) {
|
protected String createCommand(OpenFileSystemModel model, BrowserEntry entry) {
|
||||||
return "javap -c -p " + FileNames.quoteIfNecessary(entry.getRawFileEntry().getPath());
|
return "javap -c -p "
|
||||||
|
+ FileNames.quoteIfNecessary(entry.getRawFileEntry().getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,8 @@ public abstract class MultiExecuteSelectionAction implements BranchAction {
|
||||||
long exitCode;
|
long exitCode;
|
||||||
try (var command = pc.command(cmd)
|
try (var command = pc.command(cmd)
|
||||||
.withWorkingDirectory(
|
.withWorkingDirectory(
|
||||||
model.getCurrentDirectory().getPath()).start()) {
|
model.getCurrentDirectory().getPath())
|
||||||
|
.start()) {
|
||||||
var r = command.readStdoutAndStderr();
|
var r = command.readStdoutAndStderr();
|
||||||
out.set(r[0]);
|
out.set(r[0]);
|
||||||
err.set(r[1]);
|
err.set(r[1]);
|
||||||
|
@ -79,7 +80,8 @@ public abstract class MultiExecuteSelectionAction implements BranchAction {
|
||||||
}
|
}
|
||||||
// Only throw actual error output
|
// Only throw actual error output
|
||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
throw ErrorEvent.expected(ProcessOutputException.of(exitCode, out.get(), err.get()));
|
throw ErrorEvent.expected(
|
||||||
|
ProcessOutputException.of(exitCode, out.get(), err.get()));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
|
|
|
@ -10,10 +10,12 @@ import io.xpipe.app.fxcomps.impl.DataStoreChoiceComp;
|
||||||
import io.xpipe.app.storage.DataStoreEntry;
|
import io.xpipe.app.storage.DataStoreEntry;
|
||||||
import io.xpipe.app.util.OptionsBuilder;
|
import io.xpipe.app.util.OptionsBuilder;
|
||||||
import io.xpipe.core.store.DataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
|
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -35,8 +35,10 @@ public abstract class AbstractServiceGroupStoreProvider implements DataStoreProv
|
||||||
}
|
}
|
||||||
|
|
||||||
private StoreToggleComp createToggleComp(StoreSection sec) {
|
private StoreToggleComp createToggleComp(StoreSection sec) {
|
||||||
var t = StoreToggleComp.<AbstractServiceGroupStore<?>>enableToggle(null, sec, new SimpleBooleanProperty(false), (g, aBoolean) -> {
|
var t = StoreToggleComp.<AbstractServiceGroupStore<?>>enableToggle(
|
||||||
var children = DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
null, sec, new SimpleBooleanProperty(false), (g, aBoolean) -> {
|
||||||
|
var children =
|
||||||
|
DataStorage.get().getStoreChildren(sec.getWrapper().getEntry());
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
for (DataStoreEntry child : children) {
|
for (DataStoreEntry child : children) {
|
||||||
if (child.getStore() instanceof AbstractServiceStore serviceStore) {
|
if (child.getStore() instanceof AbstractServiceStore serviceStore) {
|
||||||
|
|
Loading…
Reference in a new issue