This commit is contained in:
crschnick 2024-11-07 19:40:29 +00:00
parent bcdf8e098b
commit 3211ef39ce
163 changed files with 668 additions and 584 deletions

View file

@ -8,8 +8,6 @@ import io.xpipe.beacon.api.ConnectionTerminalExchange;
import com.sun.net.httpserver.HttpExchange;
import java.util.UUID;
public class ConnectionTerminalExchangeImpl extends ConnectionTerminalExchange {
@Override

View file

@ -1,7 +1,7 @@
package io.xpipe.app.beacon.impl;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.core.launcher.LauncherInput;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.util.PlatformState;
import io.xpipe.beacon.BeaconServerException;
import io.xpipe.beacon.api.DaemonOpenExchange;

View file

@ -5,19 +5,19 @@ import io.xpipe.app.browser.file.BrowserConnectionListFilterComp;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.file.BrowserFileSystemTabComp;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.DialogComp;
import io.xpipe.app.comp.base.LeftSplitPaneComp;
import io.xpipe.app.comp.base.StackComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.ext.ShellStore;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.StackComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.FileReference;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.FileSystemStore;

View file

@ -2,9 +2,9 @@ package io.xpipe.app.browser;
import io.xpipe.app.browser.file.BrowserEntry;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.FileReference;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.FileNames;

View file

@ -3,17 +3,17 @@ package io.xpipe.app.browser;
import io.xpipe.app.browser.file.BrowserConnectionListComp;
import io.xpipe.app.browser.file.BrowserConnectionListFilterComp;
import io.xpipe.app.browser.file.BrowserTransferComp;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.comp.base.LeftSplitPaneComp;
import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.ext.ShellStore;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.AnchorComp;
import io.xpipe.app.comp.base.LeftSplitPaneComp;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.comp.base.StackComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.ext.ShellStore;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ThreadHelper;
@ -80,10 +80,10 @@ public class BrowserFullSessionComp extends SimpleComp {
leftSplit.set(d);
});
splitPane.apply(struc -> {
struc.getLeft().setMinWidth(200);
struc.getLeft().setMaxWidth(500);
struc.get().setPickOnBounds(false);
});
struc.getLeft().setMinWidth(200);
struc.getLeft().setMaxWidth(500);
struc.get().setPickOnBounds(false);
});
splitPane.apply(struc -> {
struc.get().skinProperty().subscribe(newValue -> {
@ -173,7 +173,7 @@ public class BrowserFullSessionComp extends SimpleComp {
var cache = new HashMap<BrowserSessionTab, Region>();
var pinnedStack = new StackComp(List.of());
pinnedStack.apply(struc -> {
model.getEffectiveRightTab().subscribe( (newValue) -> {
model.getEffectiveRightTab().subscribe((newValue) -> {
PlatformThread.runLaterIfNeeded(() -> {
var all = model.getAllTabs();
cache.keySet().removeIf(browserSessionTab -> !all.contains(browserSessionTab));
@ -204,6 +204,7 @@ public class BrowserFullSessionComp extends SimpleComp {
tabs.getHeaderHeight().subscribe(number -> {
AnchorPane.setTopAnchor(struc.get(), number.doubleValue());
});
}); return pinnedStack;
});
return pinnedStack;
}
}

View file

@ -1,10 +1,10 @@
package io.xpipe.app.browser;
import io.xpipe.app.browser.file.BrowserHistoryTabModel;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.browser.file.BrowserHistorySavedState;
import io.xpipe.app.browser.file.BrowserHistorySavedStateImpl;
import io.xpipe.app.browser.file.BrowserHistoryTabModel;
import io.xpipe.app.browser.file.BrowserTransferModel;
import io.xpipe.app.browser.file.BrowserFileSystemTabModel;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.BooleanScope;
@ -12,6 +12,7 @@ import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.FileNames;
import io.xpipe.core.store.FileSystemStore;
import io.xpipe.core.util.FailableFunction;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property;
@ -21,6 +22,7 @@ import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableMap;
import lombok.Getter;
import java.util.*;
@ -41,28 +43,32 @@ public class BrowserFullSessionModel extends BrowserAbstractSessionModel<Browser
private final ObservableValue<BrowserSessionTab> effectiveRightTab = createEffectiveRightTab();
private ObservableValue<BrowserSessionTab> createEffectiveRightTab() {
return Bindings.createObjectBinding(() -> {
var current = selectedEntry.getValue();
if (!current.isCloseable()) {
return null;
}
return Bindings.createObjectBinding(
() -> {
var current = selectedEntry.getValue();
if (!current.isCloseable()) {
return null;
}
var split = splits.get(current);
if (split != null) {
return split;
}
var split = splits.get(current);
if (split != null) {
return split;
}
var global = globalPinnedTab.getValue();
if (global == null) {
return null;
}
var global = globalPinnedTab.getValue();
if (global == null) {
return null;
}
if (global == selectedEntry.getValue()) {
return null;
}
if (global == selectedEntry.getValue()) {
return null;
}
return global;
}, globalPinnedTab, selectedEntry, splits);
return global;
},
globalPinnedTab,
selectedEntry,
splits);
}
public BrowserFullSessionModel() {

View file

@ -6,8 +6,8 @@ import io.xpipe.app.storage.DataColor;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import lombok.Getter;
@Getter

View file

@ -1,14 +1,14 @@
package io.xpipe.app.browser;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.ContextMenuHelper;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.PlatformThread;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
@ -45,7 +45,8 @@ public class BrowserSessionTabsComp extends SimpleComp {
@Getter
private final DoubleProperty headerHeight;
public BrowserSessionTabsComp(BrowserFullSessionModel model, ObservableDoubleValue leftPadding, DoubleProperty rightPadding) {
public BrowserSessionTabsComp(
BrowserFullSessionModel model, ObservableDoubleValue leftPadding, DoubleProperty rightPadding) {
this.model = model;
this.leftPadding = leftPadding;
this.rightPadding = rightPadding;
@ -263,9 +264,13 @@ public class BrowserSessionTabsComp extends SimpleComp {
if (tabModel.isCloseable()) {
var unsplit = ContextMenuHelper.item(LabelGraphic.none(), AppI18n.get("unpinTab"));
unsplit.visibleProperty().bind(PlatformThread.sync(Bindings.createBooleanBinding(() -> {
return model.getGlobalPinnedTab().getValue() != null && model.getGlobalPinnedTab().getValue().equals(tabModel);
}, model.getGlobalPinnedTab())));
unsplit.visibleProperty()
.bind(PlatformThread.sync(Bindings.createBooleanBinding(
() -> {
return model.getGlobalPinnedTab().getValue() != null
&& model.getGlobalPinnedTab().getValue().equals(tabModel);
},
model.getGlobalPinnedTab())));
unsplit.setOnAction(event -> {
model.unpinTab(tabModel);
event.consume();
@ -396,9 +401,14 @@ public class BrowserSessionTabsComp extends SimpleComp {
if (tabModel.getBrowserModel() instanceof BrowserFullSessionModel sessionModel) {
var global = PlatformThread.sync(sessionModel.getGlobalPinnedTab());
tab.textProperty().bind(Bindings.createStringBinding(() -> {
return tabModel.getName() + (global.getValue() == tabModel ? " (" + AppI18n.get("pinned") + ")" : "");
}, global, AppPrefs.get().language()));
tab.textProperty()
.bind(Bindings.createStringBinding(
() -> {
return tabModel.getName()
+ (global.getValue() == tabModel ? " (" + AppI18n.get("pinned") + ")" : "");
},
global,
AppPrefs.get().language()));
} else {
tab.setText(tabModel.getName());
}

View file

@ -14,9 +14,7 @@ public abstract class BrowserStoreSessionTab<T extends DataStore> extends Browse
protected final DataStoreEntryRef<? extends T> entry;
public BrowserStoreSessionTab(BrowserAbstractSessionModel<?> browserModel, DataStoreEntryRef<? extends T> entry) {
super(
browserModel,
DataStorage.get().getStoreEntryDisplayName(entry.get()));
super(browserModel, DataStorage.get().getStoreEntryDisplayName(entry.get()));
this.entry = entry;
}

View file

@ -1,11 +1,11 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.comp.store.*;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.comp.store.*;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.PlatformThread;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.comp.store.StoreCategoryWrapper;
import io.xpipe.app.comp.store.StoreViewState;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.FilterComp;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.comp.store.StoreCategoryWrapper;
import io.xpipe.app.comp.store.StoreViewState;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.util.DataStoreCategoryChoiceComp;
import javafx.beans.property.Property;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.*;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;
import io.xpipe.core.store.FileEntry;
import io.xpipe.core.store.FileInfo;
@ -72,7 +72,8 @@ public final class BrowserFileListComp extends SimpleComp {
: null));
filenameCol.setComparator(Comparator.comparing(String::toLowerCase));
filenameCol.setSortType(ASCENDING);
filenameCol.setCellFactory(col -> new BrowserFileListNameCell(fileList, typedSelection, fileList.getEditing(), col.getTableView()));
filenameCol.setCellFactory(col ->
new BrowserFileListNameCell(fileList, typedSelection, fileList.getEditing(), col.getTableView()));
filenameCol.setReorderable(false);
filenameCol.setResizable(false);
@ -153,7 +154,10 @@ public final class BrowserFileListComp extends SimpleComp {
});
}
private void prepareColumnVisibility(TableView<BrowserEntry> table, TableColumn<BrowserEntry, String> ownerCol, TableColumn<BrowserEntry, String> filenameCol) {
private void prepareColumnVisibility(
TableView<BrowserEntry> table,
TableColumn<BrowserEntry, String> ownerCol,
TableColumn<BrowserEntry, String> filenameCol) {
var os = fileList.getFileSystemModel()
.getFileSystem()
.getShell()
@ -628,5 +632,4 @@ public final class BrowserFileListComp extends SimpleComp {
}
}
}
}

View file

@ -39,7 +39,8 @@ public final class BrowserFileListModel {
private final Property<Boolean> draggedOverEmpty = new SimpleBooleanProperty();
private final Property<BrowserEntry> editing = new SimpleObjectProperty<>();
public BrowserFileListModel(BrowserFileSystemTabModel.SelectionMode selectionMode, BrowserFileSystemTabModel fileSystemModel) {
public BrowserFileListModel(
BrowserFileSystemTabModel.SelectionMode selectionMode, BrowserFileSystemTabModel fileSystemModel) {
this.selectionMode = selectionMode;
this.fileSystemModel = fileSystemModel;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.browser.file;
import atlantafx.base.controls.Spacer;
import io.xpipe.app.comp.base.LazyTextFieldComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.ContextMenuHelper;
import io.xpipe.app.util.InputHelper;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.FileKind;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
@ -28,6 +28,8 @@ import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import atlantafx.base.controls.Spacer;
class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
private final BrowserFileListModel fileList;
@ -37,16 +39,26 @@ class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
private final BooleanProperty updating = new SimpleBooleanProperty();
public BrowserFileListNameCell(BrowserFileListModel fileList, ObservableStringValue typedSelection, Property<BrowserEntry> editing, TableView<BrowserEntry> tableView) {
public BrowserFileListNameCell(
BrowserFileListModel fileList,
ObservableStringValue typedSelection,
Property<BrowserEntry> editing,
TableView<BrowserEntry> tableView) {
this.fileList = fileList;
this.typedSelection = typedSelection;
accessibleTextProperty().bind(Bindings.createStringBinding(() -> {
return getItem() != null ? getItem() : null;
}, itemProperty()));
accessibleTextProperty()
.bind(Bindings.createStringBinding(
() -> {
return getItem() != null ? getItem() : null;
},
itemProperty()));
setAccessibleRole(AccessibleRole.TEXT);
var textField = new LazyTextFieldComp(text).minWidth(USE_PREF_SIZE).createStructure().get();
var textField = new LazyTextFieldComp(text)
.minWidth(USE_PREF_SIZE)
.createStructure()
.get();
var quickAccess = createQuickAccessButton();
setupShortcuts(tableView, (ButtonBase) quickAccess);
setupRename(fileList, textField, editing);
@ -62,16 +74,22 @@ class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
}
private Region createQuickAccessButton() {
var quickAccess = new BrowserQuickAccessButtonComp(() -> getTableRow().getItem(), fileList.getFileSystemModel()).hide(Bindings.createBooleanBinding(() -> {
if (getTableRow() == null) {
return true;
}
var quickAccess = new BrowserQuickAccessButtonComp(() -> getTableRow().getItem(), fileList.getFileSystemModel())
.hide(Bindings.createBooleanBinding(
() -> {
if (getTableRow() == null) {
return true;
}
var item = getTableRow().getItem();
var notDir = item.getRawFileEntry().resolved().getKind() != FileKind.DIRECTORY;
var isParentLink = item.getRawFileEntry().equals(fileList.getFileSystemModel().getCurrentParentDirectory());
return notDir || isParentLink;
}, itemProperty())).focusTraversable(false).createRegion();
var item = getTableRow().getItem();
var notDir = item.getRawFileEntry().resolved().getKind() != FileKind.DIRECTORY;
var isParentLink = item.getRawFileEntry()
.equals(fileList.getFileSystemModel().getCurrentParentDirectory());
return notDir || isParentLink;
},
itemProperty()))
.focusTraversable(false)
.createRegion();
return quickAccess;
}
@ -85,7 +103,10 @@ class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
});
InputHelper.onExactKeyCode(tableView, KeyCode.SPACE, true, event -> {
var selection = typedSelection.get() + " ";
var found = fileList.getShown().getValue().stream().filter(browserEntry -> browserEntry.getFileName().toLowerCase().startsWith(selection)).findFirst();
var found = fileList.getShown().getValue().stream()
.filter(browserEntry ->
browserEntry.getFileName().toLowerCase().startsWith(selection))
.findFirst();
// Ugly fix to prevent space from showing the menu when there is a file matching
// Due to the table view input map, these events always get sent and consumed, not allowing us to
// differentiate between these cases
@ -96,7 +117,8 @@ class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
var selected = fileList.getSelection();
// Only show one menu across all selected entries
if (selected.size() > 0 && selected.getLast() == getTableRow().getItem()) {
var cm = new BrowserContextMenu(fileList.getFileSystemModel(), getTableRow().getItem(), false);
var cm = new BrowserContextMenu(
fileList.getFileSystemModel(), getTableRow().getItem(), false);
ContextMenuHelper.toggleShow(cm, this, Side.RIGHT);
event.consume();
}
@ -159,11 +181,17 @@ class BrowserFileListNameCell extends TableCell<BrowserEntry, String> {
var isDirectory = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY;
pseudoClassStateChanged(PseudoClass.getPseudoClass("folder"), isDirectory);
var normalName = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.LINK ?
getTableRow().getItem().getFileName() + " -> " + getTableRow().getItem().getRawFileEntry().resolved().getPath() :
getTableRow().getItem().getFileName();
var normalName = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.LINK
? getTableRow().getItem().getFileName() + " -> "
+ getTableRow()
.getItem()
.getRawFileEntry()
.resolved()
.getPath()
: getTableRow().getItem().getFileName();
var fileName = normalName;
var hidden = getTableRow().getItem().getRawFileEntry().getInfo().explicitlyHidden() || fileName.startsWith(".");
var hidden = getTableRow().getItem().getRawFileEntry().getInfo().explicitlyHidden()
|| fileName.startsWith(".");
getTableRow().pseudoClassStateChanged(PseudoClass.getPseudoClass("hidden"), hidden);
text.set(fileName);
// Visibility seems to be bugged, so use opacity

View file

@ -1,12 +1,12 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.browser.icon.BrowserIcons;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.VBoxViewComp;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.VBoxViewComp;
import io.xpipe.core.store.FileEntry;
import javafx.collections.ObservableList;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.core.AppStyle;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.core.AppStyle;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.PlatformThread;

View file

@ -1,15 +1,15 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.comp.base.ModalOverlayComp;
import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.comp.augment.ContextMenuAugment;
import io.xpipe.app.comp.base.ModalOverlayComp;
import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.comp.base.TooltipAugment;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.util.InputHelper;
import javafx.geometry.Pos;

View file

@ -1,17 +1,17 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.browser.BrowserAbstractSessionModel;
import io.xpipe.app.browser.BrowserStoreSessionTab;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.ModalOverlayComp;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.ext.ShellStore;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.terminal.TerminalLauncher;
import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.ShellControl;
@ -23,9 +23,9 @@ import io.xpipe.core.util.FailableRunnable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import lombok.Getter;
import lombok.SneakyThrows;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;

View file

@ -1,20 +1,20 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.browser.BrowserFullSessionModel;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.comp.base.LabelComp;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.comp.base.PrettySvgComp;
import io.xpipe.app.comp.base.TileButtonComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.comp.base.LabelComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.comp.base.PrettySvgComp;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.ThreadHelper;
import javafx.beans.binding.Bindings;

View file

@ -3,8 +3,8 @@ package io.xpipe.app.browser.file;
import io.xpipe.app.browser.BrowserAbstractSessionModel;
import io.xpipe.app.browser.BrowserFullSessionModel;
import io.xpipe.app.browser.BrowserSessionTab;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.storage.DataColor;
public final class BrowserHistoryTabModel extends BrowserSessionTab {

View file

@ -123,9 +123,8 @@ public class BrowserNavBarComp extends Comp<BrowserNavBarComp.Structure> {
});
});
});
var pathBar = new TextFieldComp(path, true)
.styleClass(Styles.CENTER_PILL)
.styleClass("path-text");
var pathBar =
new TextFieldComp(path, true).styleClass(Styles.CENTER_PILL).styleClass("path-text");
pathBar.apply(struc -> {
struc.get().focusedProperty().subscribe(val -> {
struc.get()

View file

@ -1,12 +1,12 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.SimpleTitledPaneComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.process.ShellControl;
import io.xpipe.core.store.FileEntry;

View file

@ -141,7 +141,8 @@ public class BrowserQuickAccessContextMenu extends ContextMenu {
this.menu = new Menu(
// Use original name, not the link target
browserEntry.getRawFileEntry().getName(),
PrettyImageHelper.ofFixedSize(BrowserIconManager.getFileIcon(browserEntry.getRawFileEntry()), 24, 24)
PrettyImageHelper.ofFixedSize(
BrowserIconManager.getFileIcon(browserEntry.getRawFileEntry()), 24, 24)
.createRegion());
createMenu();
addInputListeners();

View file

@ -1,12 +1,12 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.comp.augment.ContextMenuAugment;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.comp.base.LabelComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.HumanReadableFormat;

View file

@ -3,14 +3,15 @@ package io.xpipe.app.browser.file;
import io.xpipe.app.browser.BrowserAbstractSessionModel;
import io.xpipe.app.browser.BrowserFullSessionModel;
import io.xpipe.app.browser.BrowserSessionTab;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.storage.DataColor;
import io.xpipe.app.terminal.TerminalDockComp;
import io.xpipe.app.terminal.TerminalDockModel;
import io.xpipe.app.terminal.TerminalView;
import io.xpipe.app.terminal.TerminalViewInstance;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableBooleanValue;
@ -27,7 +28,10 @@ public final class BrowserTerminalDockTabModel extends BrowserSessionTab {
private TerminalView.Listener listener;
private ObservableBooleanValue viewActive;
public BrowserTerminalDockTabModel(BrowserAbstractSessionModel<?> browserModel, BrowserSessionTab origin, ObservableList<UUID> terminalRequests) {
public BrowserTerminalDockTabModel(
BrowserAbstractSessionModel<?> browserModel,
BrowserSessionTab origin,
ObservableList<UUID> terminalRequests) {
super(browserModel, AppI18n.get("terminal"));
this.origin = origin;
this.terminalRequests = terminalRequests;
@ -55,7 +59,10 @@ public final class BrowserTerminalDockTabModel extends BrowserSessionTab {
}
sessions.add(session);
var tv = terminals.stream().filter(instance -> sessions.stream().anyMatch(s -> instance.getTerminalProcess().equals(s.getTerminal()))).toList();
var tv = terminals.stream()
.filter(instance -> sessions.stream()
.anyMatch(s -> instance.getTerminalProcess().equals(s.getTerminal())))
.toList();
if (tv.isEmpty()) {
return;
}
@ -88,9 +95,18 @@ public final class BrowserTerminalDockTabModel extends BrowserSessionTab {
};
TerminalView.get().addListener(listener);
viewActive = Bindings.createBooleanBinding(() -> {
return this.browserModel.getSelectedEntry().getValue() == origin && AppLayoutModel.get().getEntries().indexOf(AppLayoutModel.get().getSelected().getValue()) == 1;
}, this.browserModel.getSelectedEntry(), AppLayoutModel.get().getSelected());
viewActive = Bindings.createBooleanBinding(
() -> {
return this.browserModel.getSelectedEntry().getValue() == origin
&& AppLayoutModel.get()
.getEntries()
.indexOf(AppLayoutModel.get()
.getSelected()
.getValue())
== 1;
},
this.browserModel.getSelectedEntry(),
AppLayoutModel.get().getSelected());
viewActive.subscribe(aBoolean -> {
Platform.runLater(() -> {
dockModel.toggleView(aBoolean);

View file

@ -1,10 +1,10 @@
package io.xpipe.app.browser.file;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.ThreadHelper;
@ -104,88 +104,84 @@ public class BrowserTransferComp extends SimpleComp {
.padding(new Insets(10, 10, 5, 10))
.apply(struc -> struc.get().setMinHeight(200))
.apply(struc -> struc.get().setMaxHeight(200));
var stack = new StackComp(List.of(backgroundStack, listBox))
.apply(struc -> {
struc.get().addEventFilter(DragEvent.DRAG_ENTERED, event -> {
struc.get().pseudoClassStateChanged(PseudoClass.getPseudoClass("drag-over"), true);
});
struc.get().addEventFilter(DragEvent.DRAG_EXITED, event -> struc.get()
.pseudoClassStateChanged(PseudoClass.getPseudoClass("drag-over"), false));
struc.get().setOnDragOver(event -> {
// Accept drops from inside the app window
if (event.getGestureSource() != null && event.getGestureSource() != struc.get()) {
event.acceptTransferModes(TransferMode.ANY);
event.consume();
}
});
struc.get().setOnDragDropped(event -> {
// Accept drops from inside the app window
if (event.getGestureSource() != null) {
var drag = BrowserClipboard.retrieveDrag(event.getDragboard());
if (drag == null) {
return;
var stack = new StackComp(List.of(backgroundStack, listBox)).apply(struc -> {
struc.get().addEventFilter(DragEvent.DRAG_ENTERED, event -> {
struc.get().pseudoClassStateChanged(PseudoClass.getPseudoClass("drag-over"), true);
});
struc.get().addEventFilter(DragEvent.DRAG_EXITED, event -> struc.get()
.pseudoClassStateChanged(PseudoClass.getPseudoClass("drag-over"), false));
struc.get().setOnDragOver(event -> {
// Accept drops from inside the app window
if (event.getGestureSource() != null && event.getGestureSource() != struc.get()) {
event.acceptTransferModes(TransferMode.ANY);
event.consume();
}
});
struc.get().setOnDragDropped(event -> {
// Accept drops from inside the app window
if (event.getGestureSource() != null) {
var drag = BrowserClipboard.retrieveDrag(event.getDragboard());
if (drag == null) {
return;
}
if (!(model.getBrowserSessionModel().getSelectedEntry().getValue()
instanceof BrowserFileSystemTabModel fileSystemModel)) {
return;
}
var files = drag.getEntries();
model.drop(fileSystemModel, files);
event.setDropCompleted(true);
event.consume();
}
});
struc.get().setOnDragDetected(event -> {
var items = model.getCurrentItems();
var selected =
items.stream().map(item -> item.getBrowserEntry()).toList();
var files = items.stream()
.filter(item -> item.downloadFinished().get())
.map(item -> {
try {
var file = item.getLocalFile();
if (!Files.exists(file)) {
return Optional.<File>empty();
}
return Optional.of(file.toRealPath().toFile());
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.flatMap(Optional::stream)
.toList();
if (files.isEmpty()) {
return;
}
if (!(model.getBrowserSessionModel()
.getSelectedEntry()
.getValue()
instanceof BrowserFileSystemTabModel fileSystemModel)) {
return;
}
var cc = new ClipboardContent();
cc.putFiles(files);
Dragboard db = struc.get().startDragAndDrop(TransferMode.COPY);
db.setContent(cc);
var files = drag.getEntries();
model.drop(fileSystemModel, files);
event.setDropCompleted(true);
event.consume();
}
});
struc.get().setOnDragDetected(event -> {
var items = model.getCurrentItems();
var selected = items.stream()
.map(item -> item.getBrowserEntry())
.toList();
var files = items.stream()
.filter(item -> item.downloadFinished().get())
.map(item -> {
try {
var file = item.getLocalFile();
if (!Files.exists(file)) {
return Optional.<File>empty();
}
Image image = BrowserFileSelectionListComp.snapshot(FXCollections.observableList(selected));
db.setDragView(image, -20, 15);
return Optional.of(file.toRealPath().toFile());
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.flatMap(Optional::stream)
.toList();
if (files.isEmpty()) {
return;
}
event.setDragDetect(true);
event.consume();
});
struc.get().setOnDragDone(event -> {
if (!event.isAccepted()) {
return;
}
var cc = new ClipboardContent();
cc.putFiles(files);
Dragboard db = struc.get().startDragAndDrop(TransferMode.COPY);
db.setContent(cc);
Image image = BrowserFileSelectionListComp.snapshot(FXCollections.observableList(selected));
db.setDragView(image, -20, 15);
event.setDragDetect(true);
event.consume();
});
struc.get().setOnDragDone(event -> {
if (!event.isAccepted()) {
return;
}
// The files might not have been transferred yet
// We can't listen to this, so just don't delete them
model.clear(false);
event.consume();
});
});
// The files might not have been transferred yet
// We can't listen to this, so just don't delete them
model.clear(false);
event.consume();
});
});
stack.apply(struc -> {
model.getBrowserSessionModel().getDraggingFiles().addListener((observable, oldValue, newValue) -> {

View file

@ -191,7 +191,8 @@ public class BrowserTransferModel {
Path localFile;
Property<BrowserTransferProgress> progress;
public Item(BrowserFileSystemTabModel openFileSystemModel, String name, BrowserEntry browserEntry, Path localFile) {
public Item(
BrowserFileSystemTabModel openFileSystemModel, String name, BrowserEntry browserEntry, Path localFile) {
this.openFileSystemModel = openFileSystemModel;
this.name = name;
this.browserEntry = browserEntry;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.augment.Augment;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.comp.base.TooltipAugment;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.PlatformThread;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.Translatable;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.browser.BrowserFileChooserSessionComp;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.ContextualFileReference;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.window.AppWindowHelper;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppActionLinkDetector;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.core.AppActionLinkDetector;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.PlatformThread;
import javafx.beans.binding.Bindings;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.AppI18n;
import javafx.beans.property.ListProperty;
import javafx.geometry.Orientation;

View file

@ -3,8 +3,8 @@ package io.xpipe.app.comp.base;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ThreadHelper;
import javafx.application.Platform;

View file

@ -1,15 +1,15 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.resources.AppResources;
import io.xpipe.app.util.Hyperlinks;
import io.xpipe.app.util.MarkdownHelper;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ShellTemp;
import javafx.application.Platform;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.PlatformThread;
import javafx.application.Platform;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.util.PlatformThread;
import javafx.beans.Observable;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.AppFont;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Button;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.resources.AppImages;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.store.FileNames;
import javafx.beans.binding.Bindings;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.App;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.core.App;
import io.xpipe.app.resources.AppImages;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.core.store.FileNames;
import javafx.beans.binding.Bindings;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.resources.AppImages;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.store.FileNames;
import javafx.beans.binding.Bindings;

View file

@ -2,8 +2,8 @@ package io.xpipe.app.comp.base;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ClipboardHelper;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.util.InPlaceSecretValue;
import javafx.beans.property.Property;

View file

@ -1,13 +1,13 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.update.UpdateAvailableAlert;
import io.xpipe.app.update.XPipeDistributionType;
import io.xpipe.app.util.PlatformThread;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.PlatformThread;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleIntegerProperty;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.PlatformThread;
import javafx.beans.binding.Bindings;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.base;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.augment.Augment;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.PlatformThread;
import javafx.beans.binding.Bindings;

View file

@ -3,8 +3,8 @@ package io.xpipe.app.comp.store;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.comp.base.StackComp;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.resources.AppResources;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.core.process.OsNameState;
import io.xpipe.core.store.FileNames;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.core.AppFont;
import io.xpipe.core.process.OsType;
import javafx.geometry.HPos;

View file

@ -1,17 +1,17 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.augment.ContextMenuAugment;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.storage.DataColor;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreCategory;
import io.xpipe.app.util.ContextMenuHelper;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.LabelGraphic;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.ScrollComp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ScrollComp;
import javafx.beans.binding.Bindings;
import javafx.scene.layout.Region;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataColor;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreCategory;
import io.xpipe.app.util.PlatformThread;
import javafx.beans.property.*;
import javafx.collections.FXCollections;

View file

@ -1,5 +1,7 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.FilterComp;
import io.xpipe.app.comp.base.HorizontalComp;
@ -8,8 +10,6 @@ import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.LocalStore;
import io.xpipe.app.ext.ShellStore;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.DataStoreEntryRef;

View file

@ -1,5 +1,7 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.DialogComp;
import io.xpipe.app.comp.base.ErrorOverlayComp;
@ -9,9 +11,6 @@ import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.ext.DataStoreCreationCategory;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.ExceptionConverter;
import io.xpipe.app.issue.TrackEvent;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.DataStoreCreationCategory;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.util.ScanAlert;
import javafx.scene.control.Menu;

View file

@ -1,8 +1,5 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.core.*;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.SimpleCompStructure;
@ -10,10 +7,13 @@ import io.xpipe.app.comp.augment.ContextMenuAugment;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.comp.base.LabelComp;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.comp.base.TooltipAugment;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.core.App;
import io.xpipe.app.core.AppActionLinkDetector;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.resources.AppResources;
import io.xpipe.app.storage.DataColor;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;

View file

@ -1,12 +1,12 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.CountComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.CountComp;
import io.xpipe.app.comp.base.FilterComp;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.ThreadHelper;

View file

@ -1,13 +1,13 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataColor;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreCategory;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.SingletonSessionStore;

View file

@ -1,13 +1,13 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.DialogComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.DialogComp;
import io.xpipe.app.comp.base.FilterComp;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.resources.SystemIcon;
import io.xpipe.app.resources.SystemIcons;
import io.xpipe.app.storage.DataStoreEntry;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.PrettySvgComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.ScanAlert;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.LeftSplitPaneComp;
import io.xpipe.app.core.AppActionLinkDetector;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.InputHelper;
import javafx.scene.input.KeyCode;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.core.store.DataStore;

View file

@ -1,15 +1,15 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.DialogComp;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.comp.base.MarkdownEditorComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.BindingsHelper;
import javafx.application.Platform;
import javafx.beans.property.Property;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.SimpleCompStructure;
import io.xpipe.app.ext.DataStoreProvider;
import io.xpipe.app.ext.DataStoreProviders;
import io.xpipe.app.util.JfxHelper;
import javafx.beans.property.Property;

View file

@ -4,8 +4,8 @@ import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.ContextMenuHelper;
import io.xpipe.app.util.LabelGraphic;
import javafx.geometry.Side;
import javafx.scene.control.Button;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.core.process.OsType;
import javafx.beans.property.BooleanProperty;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.DerivedObservableList;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.storage.DataColor;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.ThreadHelper;
import javafx.beans.binding.Bindings;

View file

@ -1,15 +1,10 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.CompStructure;
import io.xpipe.app.comp.base.HorizontalComp;
import io.xpipe.app.comp.base.IconButtonComp;
import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.comp.base.*;
import io.xpipe.app.storage.DataColor;
import io.xpipe.app.util.LabelGraphic;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ToggleSwitchComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.DataStore;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.comp.store;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreCategory;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.StorageListener;
import io.xpipe.app.util.DerivedObservableList;
import io.xpipe.app.util.PlatformThread;
import javafx.application.Platform;
import javafx.beans.property.*;

View file

@ -2,11 +2,11 @@ package io.xpipe.app.core;
import io.xpipe.app.comp.base.AppLayoutComp;
import io.xpipe.app.core.window.AppMainWindow;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.update.XPipeDistributionType;
import io.xpipe.app.util.LicenseProvider;
import io.xpipe.app.util.PlatformThread;
import javafx.application.Application;
import javafx.beans.binding.Bindings;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.core;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.core.launcher.LauncherInput;
import io.xpipe.app.core.window.AppWindowHelper;
import javafx.scene.control.Alert;
import javafx.scene.input.Clipboard;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.core;
import io.xpipe.app.Main;
import io.xpipe.app.core.launcher.LauncherInput;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.core.launcher.LauncherInput;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.PlatformState;
import io.xpipe.app.util.ThreadHelper;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.core;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.MarkdownComp;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.resources.AppResources;
import javafx.beans.property.SimpleBooleanProperty;

View file

@ -1,9 +1,9 @@
package io.xpipe.app.core;
import io.xpipe.app.comp.base.ModalOverlayComp;
import io.xpipe.app.comp.base.TooltipAugment;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.ext.PrefsChoiceValue;
import io.xpipe.app.comp.base.TooltipAugment;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;

View file

@ -3,14 +3,14 @@ package io.xpipe.app.core;
import io.xpipe.app.beacon.AppBeaconServer;
import io.xpipe.app.browser.BrowserFullSessionComp;
import io.xpipe.app.browser.BrowserFullSessionModel;
import io.xpipe.app.comp.store.StoreLayoutComp;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.comp.store.StoreLayoutComp;
import io.xpipe.app.prefs.AppPrefsComp;
import io.xpipe.app.terminal.TerminalView;
import io.xpipe.app.util.Hyperlinks;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.LicenseProvider;
import io.xpipe.app.terminal.TerminalView;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
@ -99,12 +99,12 @@ public class AppLayoutModel {
new BrowserFullSessionComp(BrowserFullSessionModel.DEFAULT),
null,
new KeyCodeCombination(KeyCode.DIGIT2, KeyCombination.SHORTCUT_DOWN)),
// new Entry(
// AppI18n.observable("terminal"),
// new LabelGraphic.IconGraphic("mdi2m-monitor-screenshot"),
// new TerminalDockComp(),
// null,
// new KeyCodeCombination(KeyCode.DIGIT3, KeyCombination.SHORTCUT_DOWN)),
// new Entry(
// AppI18n.observable("terminal"),
// new LabelGraphic.IconGraphic("mdi2m-monitor-screenshot"),
// new TerminalDockComp(),
// null,
// new KeyCodeCombination(KeyCode.DIGIT3, KeyCombination.SHORTCUT_DOWN)),
new Entry(
AppI18n.observable("settings"),
new LabelGraphic.IconGraphic("mdsmz-miscellaneous_services"),

View file

@ -50,6 +50,7 @@ public class AppProperties {
* Unique identifier that resets on every XPipe restart.
*/
UUID sessionId;
boolean newBuildSession;
public AppProperties() {
@ -121,15 +122,15 @@ public class AppProperties {
.map(Boolean::parseBoolean)
.orElse(false);
AppCache.setBasePath(dataDir.resolve("cache"));
UUID id = AppCache.getNonNull("uuid", UUID.class, null);
if (id == null) {
uuid = UUID.randomUUID();
AppCache.update("uuid", uuid);
} else {
uuid = id;
}
UUID id = AppCache.getNonNull("uuid", UUID.class, null);
if (id == null) {
uuid = UUID.randomUUID();
AppCache.update("uuid", uuid);
} else {
uuid = id;
}
initialLaunch = AppCache.getNonNull("lastBuildId", String.class, () -> null) == null;
sessionId = UUID.randomUUID();
sessionId = UUID.randomUUID();
var cachedBuildId = AppCache.getNonNull("lastBuildId", String.class, () -> null);
newBuildSession = !buildUuid.toString().equals(cachedBuildId);
AppCache.update("lastBuildId", buildUuid);

View file

@ -2,11 +2,11 @@ package io.xpipe.app.core;
import io.xpipe.app.core.window.AppMainWindow;
import io.xpipe.app.ext.PrefsChoiceValue;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.resources.AppResources;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;
import javafx.animation.Interpolator;
@ -214,10 +214,7 @@ public class AppTheme {
AppResources.with("atlantafx.base", theme.getUserAgentStylesheet().substring(1), path -> {
var baseStyleContent = Files.readString(path);
builder.append("\n")
.append(baseStyleContent
.lines()
.skip(skipLines)
.collect(Collectors.joining("\n")));
.append(baseStyleContent.lines().skip(skipLines).collect(Collectors.joining("\n")));
});
Application.setUserAgentStylesheet(Styles.toDataURI(builder.toString()));

View file

@ -1,16 +1,10 @@
package io.xpipe.app.core.check;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.LocalShell;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ProcessOutputException;
import io.xpipe.core.util.XPipeInstallation;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
public class AppTestCommandCheck {
public static void check() throws Exception {
@ -20,10 +14,16 @@ public class AppTestCommandCheck {
try (var sc = LocalShell.getShell().start()) {
try {
sc.getShellDialect().directoryExists(sc, XPipeInstallation.getCurrentInstallationBasePath().toString()).execute();
sc.getShellDialect()
.directoryExists(
sc,
XPipeInstallation.getCurrentInstallationBasePath()
.toString())
.execute();
} catch (ProcessOutputException ex) {
throw ProcessOutputException.withPrefix(
"Installation self test failed. Is your \"test\" shell command working as expected and is the XPipe installation directory accessible?", ex);
"Installation self test failed. Is your \"test\" shell command working as expected and is the XPipe installation directory accessible?",
ex);
}
}
}

View file

@ -7,11 +7,11 @@ import io.xpipe.app.core.AppGreetings;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.core.check.AppPtbCheck;
import io.xpipe.app.core.window.AppMainWindow;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.update.UpdateChangelogAlert;
import io.xpipe.app.util.NativeBridge;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.util.ThreadHelper;
import javafx.stage.Stage;

View file

@ -5,9 +5,9 @@ import io.xpipe.app.core.*;
import io.xpipe.app.core.check.AppDebugModeCheck;
import io.xpipe.app.core.check.AppTempCheck;
import io.xpipe.app.core.check.AppUserDirectoryCheck;
import io.xpipe.app.core.launcher.LauncherCommand;
import io.xpipe.app.core.window.ModifiedStage;
import io.xpipe.app.issue.*;
import io.xpipe.app.core.launcher.LauncherCommand;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.LocalShell;
import io.xpipe.app.util.PlatformState;

View file

@ -56,7 +56,8 @@ public abstract class PlatformMode extends OperationMode {
// If we downloaded an update, and decided to no longer automatically update, don't remind us!
// You can still update manually in the about tab
if (AppPrefs.get().automaticallyUpdate().get() || AppPrefs.get().checkForSecurityUpdates().get()) {
if (AppPrefs.get().automaticallyUpdate().get()
|| AppPrefs.get().checkForSecurityUpdates().get()) {
UpdateAvailableAlert.showIfNeeded();
}

View file

@ -1,8 +1,8 @@
package io.xpipe.app.core.mode;
import io.xpipe.app.core.AppTray;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.*;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;
import java.awt.*;

View file

@ -1,10 +1,10 @@
package io.xpipe.app.core.window;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.core.AppTheme;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.core.window;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.core.*;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.resources.AppImages;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.core.window;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;
import javafx.animation.PauseTransition;

View file

@ -1,8 +1,7 @@
package io.xpipe.app.core.window;
import com.sun.jna.ptr.IntByReference;
import io.sentry.protocol.User;
import io.xpipe.app.util.Rect;
import javafx.stage.Window;
import com.sun.jna.Library;
@ -12,6 +11,7 @@ import com.sun.jna.PointerType;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.ptr.IntByReference;
import lombok.Getter;
import lombok.SneakyThrows;
@ -24,21 +24,23 @@ public class NativeWinWindowControl {
public static Optional<NativeWinWindowControl> byPid(long pid) {
var ref = new AtomicReference<NativeWinWindowControl>();
User32.INSTANCE.EnumWindows((hWnd, data) -> {
var visible = User32.INSTANCE.IsWindowVisible(hWnd);
if (!visible) {
return true;
}
User32.INSTANCE.EnumWindows(
(hWnd, data) -> {
var visible = User32.INSTANCE.IsWindowVisible(hWnd);
if (!visible) {
return true;
}
var wpid = new IntByReference();
User32.INSTANCE.GetWindowThreadProcessId(hWnd, wpid);
if (wpid.getValue() == pid) {
ref.set(new NativeWinWindowControl(hWnd));
return false;
} else {
return true;
}
}, null);
var wpid = new IntByReference();
User32.INSTANCE.GetWindowThreadProcessId(hWnd, wpid);
if (wpid.getValue() == pid) {
ref.set(new NativeWinWindowControl(hWnd));
return false;
} else {
return true;
}
},
null);
return Optional.ofNullable(ref.get());
}
@ -68,23 +70,24 @@ public class NativeWinWindowControl {
public void removeBorders() {
var style = User32.INSTANCE.GetWindowLong(windowHandle, User32.GWL_STYLE);
var mod = style & ~(User32.WS_CAPTION | User32.WS_THICKFRAME | User32.WS_MAXIMIZEBOX);
User32.INSTANCE.SetWindowLong(windowHandle,User32.GWL_STYLE,mod);
User32.INSTANCE.SetWindowLong(windowHandle, User32.GWL_STYLE, mod);
}
public boolean isIconified() {
return (User32.INSTANCE.GetWindowLong(windowHandle,User32.GWL_STYLE) & User32.WS_MINIMIZE) != 0;
return (User32.INSTANCE.GetWindowLong(windowHandle, User32.GWL_STYLE) & User32.WS_MINIMIZE) != 0;
}
public void alwaysInFront() {
orderRelative(new WinDef.HWND(new Pointer( 0xFFFFFFFFFFFFFFFFL)));
orderRelative(new WinDef.HWND(new Pointer(0xFFFFFFFFFFFFFFFFL)));
}
public void defaultOrder() {
orderRelative(new WinDef.HWND(new Pointer( -2)));
orderRelative(new WinDef.HWND(new Pointer(-2)));
}
public void orderRelative(WinDef.HWND predecessor) {
User32.INSTANCE.SetWindowPos(windowHandle, predecessor, 0, 0, 0, 0, User32.SWP_NOACTIVATE | User32.SWP_NOMOVE | User32.SWP_NOSIZE);
User32.INSTANCE.SetWindowPos(
windowHandle, predecessor, 0, 0, 0, 0, User32.SWP_NOACTIVATE | User32.SWP_NOMOVE | User32.SWP_NOSIZE);
}
public void show() {
@ -96,11 +99,12 @@ public class NativeWinWindowControl {
}
public void minimize() {
User32.INSTANCE.ShowWindow(windowHandle,User32.SW_MINIMIZE);
User32.INSTANCE.ShowWindow(windowHandle, User32.SW_MINIMIZE);
}
public void move(Rect bounds) {
User32.INSTANCE.SetWindowPos(windowHandle, null, bounds.getX(), bounds.getY(), bounds.getW(), bounds.getH(), User32.SWP_NOACTIVATE);
User32.INSTANCE.SetWindowPos(
windowHandle, null, bounds.getX(), bounds.getY(), bounds.getW(), bounds.getH(), User32.SWP_NOACTIVATE);
}
public Rect getBounds() {

View file

@ -1,13 +1,13 @@
package io.xpipe.app.ext;
import io.xpipe.app.browser.BrowserFullSessionModel;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.MarkdownComp;
import io.xpipe.app.comp.store.StoreEntryComp;
import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.comp.store.StoreSection;
import io.xpipe.app.comp.store.StoreSectionComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.resources.AppImages;
import io.xpipe.app.storage.DataStoreEntry;

View file

@ -1,12 +1,12 @@
package io.xpipe.app.ext;
import io.xpipe.app.comp.store.StoreToggleComp;
import io.xpipe.app.comp.store.StoreEntryComp;
import io.xpipe.app.comp.store.StoreSection;
import io.xpipe.app.comp.store.StoreToggleComp;
import io.xpipe.app.comp.store.StoreViewState;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.BindingsHelper;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.EnabledStoreState;
import io.xpipe.core.store.StatefulDataStore;

View file

@ -1,11 +1,7 @@
package io.xpipe.app.ext;
import io.xpipe.app.comp.store.StoreToggleComp;
import io.xpipe.app.comp.store.SystemStateComp;
import io.xpipe.app.comp.store.StoreEntryComp;
import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.comp.store.StoreSection;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.store.*;
import io.xpipe.app.util.LabelGraphic;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.SingletonSessionStore;

View file

@ -1,8 +1,8 @@
package io.xpipe.app.issue;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.core.util.Deobfuscator;
import javafx.geometry.Insets;

View file

@ -1,14 +1,14 @@
package io.xpipe.app.issue;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.TitledPaneComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.augment.GrowAugment;
import io.xpipe.app.util.LicenseRequiredException;
import io.xpipe.app.util.PlatformState;

View file

@ -74,7 +74,10 @@ public class TerminalErrorHandler extends GuiErrorHandlerBase implements ErrorHa
}
try {
var rel = XPipeDistributionType.get().getUpdateHandler().refreshUpdateCheck(false, !AppPrefs.get().automaticallyUpdate().get());
var rel = XPipeDistributionType.get()
.getUpdateHandler()
.refreshUpdateCheck(
false, !AppPrefs.get().automaticallyUpdate().get());
if (rel != null && rel.isUpdate()) {
var update = AppWindowHelper.showBlockingAlert(alert -> {
alert.setAlertType(Alert.AlertType.INFORMATION);

View file

@ -1,13 +1,13 @@
package io.xpipe.app.issue;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.ListSelectorComp;
import io.xpipe.app.comp.base.MarkdownComp;
import io.xpipe.app.comp.base.TitledPaneComp;
import io.xpipe.app.core.*;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.resources.AppResources;
import javafx.beans.property.ListProperty;

View file

@ -1,12 +1,12 @@
package io.xpipe.app.prefs;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.LabelComp;
import io.xpipe.app.comp.base.TileButtonComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.core.window.AppWindowHelper;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.base.LabelComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.util.Hyperlinks;
import io.xpipe.app.util.JfxHelper;
import io.xpipe.app.util.OptionsBuilder;

View file

@ -1,17 +1,17 @@
package io.xpipe.app.prefs;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.core.*;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.ext.PrefsHandler;
import io.xpipe.app.ext.PrefsProvider;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.terminal.ExternalTerminalType;
import io.xpipe.app.terminal.TerminalView;
import io.xpipe.app.update.XPipeDistributionType;
import io.xpipe.app.util.PasswordLockSecretValue;
import io.xpipe.app.util.PlatformThread;
import io.xpipe.core.process.OsType;
import io.xpipe.core.util.InPlaceSecretValue;
import io.xpipe.core.util.ModuleHelper;
@ -52,12 +52,14 @@ public class AppPrefs {
mapVaultShared(new SimpleBooleanProperty(false), "dontAutomaticallyStartVmSshServer", Boolean.class, false);
final BooleanProperty dontAcceptNewHostKeys =
mapVaultShared(new SimpleBooleanProperty(false), "dontAcceptNewHostKeys", Boolean.class, false);
public final BooleanProperty performanceMode = mapLocal(new SimpleBooleanProperty(), "performanceMode", Boolean.class, false);
public final BooleanProperty performanceMode =
mapLocal(new SimpleBooleanProperty(), "performanceMode", Boolean.class, false);
public final BooleanProperty useBundledTools =
mapLocal(new SimpleBooleanProperty(false), "useBundledTools", Boolean.class, true);
public final ObjectProperty<AppTheme.Theme> theme =
mapLocal(new SimpleObjectProperty<>(), "theme", AppTheme.Theme.class, false);
final BooleanProperty useSystemFont = mapLocal(new SimpleBooleanProperty(true), "useSystemFont", Boolean.class, false);
final BooleanProperty useSystemFont =
mapLocal(new SimpleBooleanProperty(true), "useSystemFont", Boolean.class, false);
final Property<Integer> uiScale = mapLocal(new SimpleObjectProperty<>(null), "uiScale", Integer.class, true);
final BooleanProperty saveWindowLocation =
mapLocal(new SimpleBooleanProperty(true), "saveWindowLocation", Boolean.class, false);
@ -88,22 +90,28 @@ public class AppPrefs {
mapVaultShared(new SimpleObjectProperty<>(), "passwordManager", ExternalPasswordManager.class, false);
final StringProperty passwordManagerCommand =
mapLocal(new SimpleStringProperty(""), "passwordManagerCommand", String.class, false);
final ObjectProperty<StartupBehaviour> startupBehaviour =
mapLocal(new SimpleObjectProperty<>(StartupBehaviour.GUI), "startupBehaviour", StartupBehaviour.class, true);
final ObjectProperty<StartupBehaviour> startupBehaviour = mapLocal(
new SimpleObjectProperty<>(StartupBehaviour.GUI), "startupBehaviour", StartupBehaviour.class, true);
public final BooleanProperty enableGitStorage =
mapLocal(new SimpleBooleanProperty(false), "enableGitStorage", Boolean.class, true);
final StringProperty storageGitRemote = mapLocal(new SimpleStringProperty(""), "storageGitRemote", String.class, true);
final StringProperty storageGitRemote =
mapLocal(new SimpleStringProperty(""), "storageGitRemote", String.class, true);
final ObjectProperty<CloseBehaviour> closeBehaviour =
mapLocal(new SimpleObjectProperty<>(CloseBehaviour.QUIT), "closeBehaviour", CloseBehaviour.class, false);
final ObjectProperty<ExternalEditorType> externalEditor =
mapLocal(new SimpleObjectProperty<>(), "externalEditor", ExternalEditorType.class, false);
final StringProperty customEditorCommand = mapLocal(new SimpleStringProperty(""), "customEditorCommand", String.class, false);
final StringProperty customEditorCommand =
mapLocal(new SimpleStringProperty(""), "customEditorCommand", String.class, false);
final BooleanProperty automaticallyCheckForUpdates =
mapLocal(new SimpleBooleanProperty(true), "automaticallyCheckForUpdates", Boolean.class, false);
final BooleanProperty encryptAllVaultData =
mapVaultShared(new SimpleBooleanProperty(false), "encryptAllVaultData", Boolean.class, true);
final BooleanProperty enableTerminalLogging = map(Mapping.builder()
.property(new SimpleBooleanProperty(false)).key("enableTerminalLogging").valueClass(Boolean.class).licenseFeatureId("logging").build());
.property(new SimpleBooleanProperty(false))
.key("enableTerminalLogging")
.valueClass(Boolean.class)
.licenseFeatureId("logging")
.build());
final BooleanProperty enforceWindowModality =
mapLocal(new SimpleBooleanProperty(false), "enforceWindowModality", Boolean.class, false);
final BooleanProperty checkForSecurityUpdates =
@ -114,13 +122,14 @@ public class AppPrefs {
mapLocal(new SimpleBooleanProperty(true), "showChildrenConnectionsInParentCategory", Boolean.class, false);
final BooleanProperty lockVaultOnHibernation =
mapLocal(new SimpleBooleanProperty(false), "lockVaultOnHibernation", Boolean.class, false);
final BooleanProperty openConnectionSearchWindowOnConnectionCreation =
mapLocal(new SimpleBooleanProperty(true), "openConnectionSearchWindowOnConnectionCreation", Boolean.class, false);
final BooleanProperty openConnectionSearchWindowOnConnectionCreation = mapLocal(
new SimpleBooleanProperty(true), "openConnectionSearchWindowOnConnectionCreation", Boolean.class, false);
final ObjectProperty<Path> storageDirectory =
mapLocal(new SimpleObjectProperty<>(DEFAULT_STORAGE_DIR), "storageDirectory", Path.class, true);
final BooleanProperty confirmAllDeletions =
mapLocal(new SimpleBooleanProperty(false), "confirmAllDeletions", Boolean.class, false);
final BooleanProperty developerMode = mapLocal(new SimpleBooleanProperty(false), "developerMode", Boolean.class, true);
final BooleanProperty developerMode =
mapLocal(new SimpleBooleanProperty(false), "developerMode", Boolean.class, true);
final BooleanProperty developerDisableUpdateVersionCheck =
mapLocal(new SimpleBooleanProperty(false), "developerDisableUpdateVersionCheck", Boolean.class, false);
private final ObservableBooleanValue developerDisableUpdateVersionCheckEffective =
@ -132,8 +141,8 @@ public class AppPrefs {
final BooleanProperty developerForceSshTty =
mapLocal(new SimpleBooleanProperty(false), "developerForceSshTty", Boolean.class, false);
final ObjectProperty<SupportedLocale> language =
mapLocal(new SimpleObjectProperty<>(SupportedLocale.getEnglish()), "language", SupportedLocale.class, false);
final ObjectProperty<SupportedLocale> language = mapLocal(
new SimpleObjectProperty<>(SupportedLocale.getEnglish()), "language", SupportedLocale.class, false);
final BooleanProperty requireDoubleClickForConnections =
mapLocal(new SimpleBooleanProperty(false), "requireDoubleClickForConnections", Boolean.class, false);
@ -157,7 +166,7 @@ public class AppPrefs {
mapVaultShared(new SimpleStringProperty(), "workspaceLock", String.class, true);
final StringProperty apiKey =
mapVaultShared(new SimpleStringProperty(UUID.randomUUID().toString()), "apiKey", String.class ,true);
mapVaultShared(new SimpleStringProperty(UUID.randomUUID().toString()), "apiKey", String.class, true);
final BooleanProperty disableApiAuthentication =
mapLocal(new SimpleBooleanProperty(false), "disableApiAuthentication", Boolean.class, false);
@ -595,8 +604,7 @@ public class AppPrefs {
T def = (T) value.getProperty().getValue();
Property<T> property = (Property<T>) value.getProperty();
Class<T> clazz = (Class<T>) value.getValueClass();
var val = handler.loadObject(
value.getKey(), clazz, def);
var val = handler.loadObject(value.getKey(), clazz, def);
property.setValue(val);
return val;
}
@ -656,7 +664,8 @@ public class AppPrefs {
boolean requiresRestart;
String licenseFeatureId;
public Mapping(String key, Property<?> property, Class<?> valueClass, boolean vaultSpecific, boolean requiresRestart) {
public Mapping(
String key, Property<?> property, Class<?> valueClass, boolean vaultSpecific, boolean requiresRestart) {
this.key = key;
this.property = property;
this.valueClass = valueClass;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.prefs;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.util.PlatformThread;
import javafx.geometry.Insets;

View file

@ -1,11 +1,11 @@
package io.xpipe.app.prefs;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.comp.Comp;
import io.xpipe.app.comp.SimpleComp;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.util.PlatformThread;
import javafx.css.PseudoClass;
@ -14,6 +14,7 @@ import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.layout.Region;
import javafx.scene.text.TextAlignment;
import org.kordamp.ikonli.javafx.FontIcon;
import java.util.ArrayList;

Some files were not shown because too many files have changed in this diff Show more