mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-09-02 18:51:01 +12:00
Polish various features
This commit is contained in:
parent
c5c5cd00df
commit
ce5e4e5ed0
9 changed files with 107 additions and 58 deletions
|
@ -25,19 +25,15 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObservableList<StoreEntrySection> createTopLevels() {
|
public static ObservableList<StoreEntrySection> createTopLevels() {
|
||||||
var topLevel = BindingsHelper.mappedContentBinding(
|
var filtered = BindingsHelper.filteredContentBinding(
|
||||||
StoreViewState.get()
|
StoreViewState.get().getAllEntries(),
|
||||||
.getAllEntries()
|
storeEntryWrapper -> !storeEntryWrapper.getEntry().getState().isUsable()
|
||||||
.filtered(storeEntryWrapper ->
|
|| storeEntryWrapper
|
||||||
!storeEntryWrapper.getEntry().getState().isUsable()
|
.getEntry()
|
||||||
|| storeEntryWrapper
|
.getProvider()
|
||||||
.getEntry()
|
.getParent(storeEntryWrapper.getEntry().getStore())
|
||||||
.getProvider()
|
== null);
|
||||||
.getParent(storeEntryWrapper
|
var topLevel = BindingsHelper.mappedContentBinding(filtered, storeEntryWrapper -> create(storeEntryWrapper));
|
||||||
.getEntry()
|
|
||||||
.getStore())
|
|
||||||
== null),
|
|
||||||
storeEntryWrapper -> create(storeEntryWrapper));
|
|
||||||
var ordered = BindingsHelper.orderedContentBinding(
|
var ordered = BindingsHelper.orderedContentBinding(
|
||||||
topLevel,
|
topLevel,
|
||||||
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
||||||
|
@ -51,16 +47,15 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
||||||
return new StoreEntrySection(e, FXCollections.observableArrayList());
|
return new StoreEntrySection(e, FXCollections.observableArrayList());
|
||||||
}
|
}
|
||||||
|
|
||||||
var children = BindingsHelper.mappedContentBinding(
|
var filtered = BindingsHelper.filteredContentBinding(
|
||||||
StoreViewState.get()
|
StoreViewState.get().getAllEntries(),
|
||||||
.getAllEntries()
|
other -> other.getEntry().getState().isUsable()
|
||||||
.filtered(other -> other.getEntry().getState().isUsable()
|
&& e.getEntry()
|
||||||
&& e.getEntry()
|
.getStore()
|
||||||
.getStore()
|
.equals(other.getEntry()
|
||||||
.equals(other.getEntry()
|
.getProvider()
|
||||||
.getProvider()
|
.getParent(other.getEntry().getStore())));
|
||||||
.getParent(other.getEntry().getStore()))),
|
var children = BindingsHelper.mappedContentBinding(filtered, entry1 -> create(entry1));
|
||||||
entry1 -> create(entry1));
|
|
||||||
var ordered = BindingsHelper.orderedContentBinding(
|
var ordered = BindingsHelper.orderedContentBinding(
|
||||||
children,
|
children,
|
||||||
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
||||||
|
@ -94,7 +89,9 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
||||||
storeEntrySection.entry.lastAccessProperty().getValue()));
|
storeEntrySection.entry.lastAccessProperty().getValue()));
|
||||||
var shown = BindingsHelper.filteredContentBinding(
|
var shown = BindingsHelper.filteredContentBinding(
|
||||||
all,
|
all,
|
||||||
StoreViewState.get().getFilterString().map(s -> (storeEntrySection -> storeEntrySection.shouldShow(s))));
|
StoreViewState.get()
|
||||||
|
.getFilterString()
|
||||||
|
.map(s -> (storeEntrySection -> storeEntrySection.shouldShow(s))));
|
||||||
var content = new ListBoxViewComp<>(shown, all, (StoreEntrySection e) -> {
|
var content = new ListBoxViewComp<>(shown, all, (StoreEntrySection e) -> {
|
||||||
return e.comp(false).apply(GrowAugment.create(true, false));
|
return e.comp(false).apply(GrowAugment.create(true, false));
|
||||||
})
|
})
|
||||||
|
|
|
@ -80,12 +80,12 @@ public class App extends Application {
|
||||||
appWindow.show();
|
appWindow.show();
|
||||||
|
|
||||||
// For demo purposes
|
// For demo purposes
|
||||||
if (true) {
|
// if (true) {
|
||||||
stage.setX(310);
|
// stage.setX(310);
|
||||||
stage.setY(178);
|
// stage.setY(178);
|
||||||
stage.setWidth(1300);
|
// stage.setWidth(1300);
|
||||||
stage.setHeight(730);
|
// stage.setHeight(730);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void focus() {
|
public void focus() {
|
||||||
|
|
|
@ -90,6 +90,7 @@ public class AppGreetings {
|
||||||
label.setGraphic(cb);
|
label.setGraphic(cb);
|
||||||
AppFont.medium(label);
|
AppFont.medium(label);
|
||||||
label.setPadding(new Insets(40, 0, 10, 0));
|
label.setPadding(new Insets(40, 0, 10, 0));
|
||||||
|
label.setOnMouseClicked(event -> accepted.set(!accepted.get()));
|
||||||
return label;
|
return label;
|
||||||
})
|
})
|
||||||
.createRegion();
|
.createRegion();
|
||||||
|
|
|
@ -54,28 +54,23 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LinuxPathApplication extends ExternalApplicationType {
|
public static abstract class PathApplication extends ExternalApplicationType {
|
||||||
|
|
||||||
protected final String command;
|
protected final String executable;
|
||||||
|
|
||||||
public LinuxPathApplication(String id, String command) {
|
public PathApplication(String id, String executable) {
|
||||||
super(id);
|
super(id);
|
||||||
this.command = command;
|
this.executable = executable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
try (ShellProcessControl pc = ShellStore.local().create().start()) {
|
try (ShellProcessControl pc = ShellStore.local().create().start()) {
|
||||||
return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(command));
|
return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(executable));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ErrorEvent.fromThrowable(e).omit().handle();
|
ErrorEvent.fromThrowable(e).omit().handle();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSelectable() {
|
|
||||||
return OsType.getLocal().equals(OsType.LINUX);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract static class WindowsFullPathType extends ExternalApplicationType {
|
public abstract static class WindowsFullPathType extends ExternalApplicationType {
|
||||||
|
|
|
@ -109,7 +109,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||||
public void launch(Path file) throws Exception;
|
public void launch(Path file) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
public static class LinuxPathType extends ExternalApplicationType.LinuxPathApplication implements ExternalEditorType {
|
public static class LinuxPathType extends ExternalApplicationType.PathApplication implements ExternalEditorType {
|
||||||
|
|
||||||
public LinuxPathType(String id, String command) {
|
public LinuxPathType(String id, String command) {
|
||||||
super(id, command);
|
super(id, command);
|
||||||
|
@ -117,9 +117,14 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void launch(Path file) throws IOException {
|
public void launch(Path file) throws IOException {
|
||||||
var list = ShellTypes.getPlatformDefault().executeCommandListWithShell(command + " \"" + file + "\"");
|
var list = ShellTypes.getPlatformDefault().executeCommandListWithShell(executable + " \"" + file + "\"");
|
||||||
new ProcessBuilder(list).start();
|
new ProcessBuilder(list).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelectable() {
|
||||||
|
return OsType.getLocal().equals(OsType.LINUX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType implements ExternalEditorType {
|
public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType implements ExternalEditorType {
|
||||||
|
@ -174,7 +179,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
||||||
var env = System.getenv("VISUAL");
|
var env = System.getenv("VISUAL");
|
||||||
if (env != null) {
|
if (env != null) {
|
||||||
var found = LINUX_EDITORS.stream()
|
var found = LINUX_EDITORS.stream()
|
||||||
.filter(externalEditorType -> externalEditorType.command.equalsIgnoreCase(env))
|
.filter(externalEditorType -> externalEditorType.executable.equalsIgnoreCase(env))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
if (found == null) {
|
if (found == null) {
|
||||||
|
|
|
@ -69,6 +69,14 @@ recentlyUsed=Recently used
|
||||||
programmingLanguages=Programming languages
|
programmingLanguages=Programming languages
|
||||||
applications=Applications
|
applications=Applications
|
||||||
addMore=Add more
|
addMore=Add more
|
||||||
|
vscode=Visual Studio Code
|
||||||
|
kate=Kate
|
||||||
|
gedit=GEdit
|
||||||
|
leafpad=Leafpad
|
||||||
|
mousepad=Mousepad
|
||||||
|
pluma=Pluma
|
||||||
|
textEdit=Text Edit
|
||||||
|
sublime=Sublime Text
|
||||||
newTable=new_table
|
newTable=new_table
|
||||||
unknown=Unknown
|
unknown=Unknown
|
||||||
editRaw=Edit Raw
|
editRaw=Edit Raw
|
||||||
|
|
|
@ -46,15 +46,10 @@ specific information we send, please visit https://xpipe.io/privacy_policy. You
|
||||||
1. **Automatic Software Updates.** The Software communicates with its server (and sends information described at the URL
|
1. **Automatic Software Updates.** The Software communicates with its server (and sends information described at the URL
|
||||||
above) to determine whether there are any patches, bug fixes, updates, upgrades or other modifications to improve the
|
above) to determine whether there are any patches, bug fixes, updates, upgrades or other modifications to improve the
|
||||||
Software. You agree that the Software may automatically install any such improvements to the Software on your
|
Software. You agree that the Software may automatically install any such improvements to the Software on your
|
||||||
computer without providing any further notice or receiving any additional consent. This feature may not be disabled.
|
computer without providing any further notice or receiving any additional consent. This feature may be disabled.
|
||||||
If you do not want to receive automatic updates, you must uninstall the Software.
|
|
||||||
2. **Error Reports.** In order to help us improve the Software, when the Software encounters certain errors, it will
|
2. **Error Reports.** In order to help us improve the Software, when the Software encounters certain errors, it will
|
||||||
automatically send some information to its server about the error (as described at the URL above). This feature may
|
automatically send some information to its server about the error (as described at the URL above). This feature may
|
||||||
not be disabled. If you do not want to send error reports to its server, you must uninstall the Software.
|
be disabled.
|
||||||
3. **Anonymized Usage Data.** X-Pipe collects anonymized data about your usage of the Software to help us make it more
|
|
||||||
awesome. Approximately once a day the Software sends such data (as described in more detail at the URL above) to its
|
|
||||||
server. If you do not want to send anonymized usage data to the server, you may opt out by changing your settings in
|
|
||||||
the Preferences view.
|
|
||||||
|
|
||||||
### Open-Source Notices
|
### Open-Source Notices
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
## Welcome to X-Pipe!
|
## Welcome to X-Pipe!
|
||||||
|
|
||||||
X-Pipe (short for eXtended Pipe) is a tool that enables a fast and an efficient data transfer/exchange between
|
Thank you for trying out the X-Pipe Alpha.
|
||||||
all types of producers and consumers of data, e.g. different file types,
|
You can overview the development status, report issues, and more at the following places:
|
||||||
applications, programming languages, databases, technologies, and more.
|
|
||||||
|
|
||||||
It is currently in early development and this build is an alpha version.
|
#### [GitHub Repository](https://github.com/xpipe-io/xpipe/)
|
||||||
A lot of features are incomplete or bugged.
|
|
||||||
You can overview and contribute to the development here:
|
|
||||||
|
|
||||||
#### [Issue Tracker](https://github.com/xpipe-io/xpipe/issues)
|
|
||||||
|
|
||||||
#### [Discord Server](https://discord.gg/8y89vS8cRb)
|
#### [Discord Server](https://discord.gg/8y89vS8cRb)
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package io.xpipe.extension.fxcomps.util;
|
package io.xpipe.extension.fxcomps.util;
|
||||||
|
|
||||||
|
import io.xpipe.extension.util.ThreadHelper;
|
||||||
import javafx.beans.binding.Binding;
|
import javafx.beans.binding.Binding;
|
||||||
|
import javafx.beans.binding.ListBinding;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -14,6 +18,37 @@ import java.util.function.Predicate;
|
||||||
|
|
||||||
public class BindingsHelper {
|
public class BindingsHelper {
|
||||||
|
|
||||||
|
private static final Set<ReferenceEntry> REFERENCES = Collections.newSetFromMap(new ConcurrentHashMap<ReferenceEntry, Boolean>());
|
||||||
|
|
||||||
|
@Value
|
||||||
|
private static class ReferenceEntry {
|
||||||
|
|
||||||
|
WeakReference<?> source;
|
||||||
|
Object target;
|
||||||
|
|
||||||
|
public boolean canGc() {
|
||||||
|
return source.get() == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
ThreadHelper.create("referenceGC", true, () -> {
|
||||||
|
while (true) {
|
||||||
|
for (ReferenceEntry reference : REFERENCES) {
|
||||||
|
if (reference.canGc()) {
|
||||||
|
REFERENCES.remove(reference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ThreadHelper.sleep(1000);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void linkPersistently(Object source, Object target) {
|
||||||
|
REFERENCES.add(new ReferenceEntry(new WeakReference<>(source), target));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: Proper cleanup. Maybe with a separate thread?
|
TODO: Proper cleanup. Maybe with a separate thread?
|
||||||
*/
|
*/
|
||||||
|
@ -30,6 +65,17 @@ public class BindingsHelper {
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends ListBinding<?>> T persist(T binding) {
|
||||||
|
var dependencies = new HashSet<javafx.beans.Observable>();
|
||||||
|
while (dependencies.addAll(binding.getDependencies().stream()
|
||||||
|
.map(o -> (javafx.beans.Observable) o)
|
||||||
|
.toList())) {
|
||||||
|
}
|
||||||
|
dependencies.add(binding);
|
||||||
|
BINDINGS.put(new WeakReference<>(binding), dependencies);
|
||||||
|
return binding;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> void bindContent(ObservableList<T> l1, ObservableList<? extends T> l2) {
|
public static <T> void bindContent(ObservableList<T> l1, ObservableList<? extends T> l2) {
|
||||||
setContent(l1, l2);
|
setContent(l1, l2);
|
||||||
l2.addListener((ListChangeListener<? super T>) c -> {
|
l2.addListener((ListChangeListener<? super T>) c -> {
|
||||||
|
@ -56,6 +102,7 @@ public class BindingsHelper {
|
||||||
l2.addListener((ListChangeListener<? super V>) c -> {
|
l2.addListener((ListChangeListener<? super V>) c -> {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
});
|
});
|
||||||
|
linkPersistently(l2, l1);
|
||||||
return l1;
|
return l1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,9 +115,14 @@ public class BindingsHelper {
|
||||||
l2.addListener((ListChangeListener<? super V>) c -> {
|
l2.addListener((ListChangeListener<? super V>) c -> {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
});
|
});
|
||||||
|
linkPersistently(l2, l1);
|
||||||
return l1;
|
return l1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <V> ObservableList<V> filteredContentBinding(ObservableList<V> l2,Predicate<V> predicate) {
|
||||||
|
return filteredContentBinding(l2, new SimpleObjectProperty<>(predicate));
|
||||||
|
}
|
||||||
|
|
||||||
public static <V> ObservableList<V> filteredContentBinding(ObservableList<V> l2, ObservableValue<Predicate<V>> predicate) {
|
public static <V> ObservableList<V> filteredContentBinding(ObservableList<V> l2, ObservableValue<Predicate<V>> predicate) {
|
||||||
ObservableList<V> l1 = FXCollections.observableList(new ArrayList<>());
|
ObservableList<V> l1 = FXCollections.observableList(new ArrayList<>());
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
|
@ -83,6 +135,7 @@ public class BindingsHelper {
|
||||||
predicate.addListener((c,o,n) -> {
|
predicate.addListener((c,o,n) -> {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
});
|
});
|
||||||
|
linkPersistently(l2, l1);
|
||||||
return l1;
|
return l1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue