mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Polish various features
This commit is contained in:
parent
b16a547996
commit
480b8d37ff
9 changed files with 107 additions and 58 deletions
|
@ -25,19 +25,15 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
|||
}
|
||||
|
||||
public static ObservableList<StoreEntrySection> createTopLevels() {
|
||||
var topLevel = BindingsHelper.mappedContentBinding(
|
||||
StoreViewState.get()
|
||||
.getAllEntries()
|
||||
.filtered(storeEntryWrapper ->
|
||||
!storeEntryWrapper.getEntry().getState().isUsable()
|
||||
|| storeEntryWrapper
|
||||
.getEntry()
|
||||
.getProvider()
|
||||
.getParent(storeEntryWrapper
|
||||
.getEntry()
|
||||
.getStore())
|
||||
== null),
|
||||
storeEntryWrapper -> create(storeEntryWrapper));
|
||||
var filtered = BindingsHelper.filteredContentBinding(
|
||||
StoreViewState.get().getAllEntries(),
|
||||
storeEntryWrapper -> !storeEntryWrapper.getEntry().getState().isUsable()
|
||||
|| storeEntryWrapper
|
||||
.getEntry()
|
||||
.getProvider()
|
||||
.getParent(storeEntryWrapper.getEntry().getStore())
|
||||
== null);
|
||||
var topLevel = BindingsHelper.mappedContentBinding(filtered, storeEntryWrapper -> create(storeEntryWrapper));
|
||||
var ordered = BindingsHelper.orderedContentBinding(
|
||||
topLevel,
|
||||
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
||||
|
@ -51,16 +47,15 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
|||
return new StoreEntrySection(e, FXCollections.observableArrayList());
|
||||
}
|
||||
|
||||
var children = BindingsHelper.mappedContentBinding(
|
||||
StoreViewState.get()
|
||||
.getAllEntries()
|
||||
.filtered(other -> other.getEntry().getState().isUsable()
|
||||
&& e.getEntry()
|
||||
.getStore()
|
||||
.equals(other.getEntry()
|
||||
.getProvider()
|
||||
.getParent(other.getEntry().getStore()))),
|
||||
entry1 -> create(entry1));
|
||||
var filtered = BindingsHelper.filteredContentBinding(
|
||||
StoreViewState.get().getAllEntries(),
|
||||
other -> other.getEntry().getState().isUsable()
|
||||
&& e.getEntry()
|
||||
.getStore()
|
||||
.equals(other.getEntry()
|
||||
.getProvider()
|
||||
.getParent(other.getEntry().getStore())));
|
||||
var children = BindingsHelper.mappedContentBinding(filtered, entry1 -> create(entry1));
|
||||
var ordered = BindingsHelper.orderedContentBinding(
|
||||
children,
|
||||
Comparator.<StoreEntrySection, Instant>comparing(storeEntrySection ->
|
||||
|
@ -94,7 +89,9 @@ public class StoreEntrySection implements StorageFilter.Filterable {
|
|||
storeEntrySection.entry.lastAccessProperty().getValue()));
|
||||
var shown = BindingsHelper.filteredContentBinding(
|
||||
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) -> {
|
||||
return e.comp(false).apply(GrowAugment.create(true, false));
|
||||
})
|
||||
|
|
|
@ -80,12 +80,12 @@ public class App extends Application {
|
|||
appWindow.show();
|
||||
|
||||
// For demo purposes
|
||||
if (true) {
|
||||
stage.setX(310);
|
||||
stage.setY(178);
|
||||
stage.setWidth(1300);
|
||||
stage.setHeight(730);
|
||||
}
|
||||
// if (true) {
|
||||
// stage.setX(310);
|
||||
// stage.setY(178);
|
||||
// stage.setWidth(1300);
|
||||
// stage.setHeight(730);
|
||||
// }
|
||||
}
|
||||
|
||||
public void focus() {
|
||||
|
|
|
@ -90,6 +90,7 @@ public class AppGreetings {
|
|||
label.setGraphic(cb);
|
||||
AppFont.medium(label);
|
||||
label.setPadding(new Insets(40, 0, 10, 0));
|
||||
label.setOnMouseClicked(event -> accepted.set(!accepted.get()));
|
||||
return label;
|
||||
})
|
||||
.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);
|
||||
this.command = command;
|
||||
this.executable = executable;
|
||||
}
|
||||
|
||||
public boolean isAvailable() {
|
||||
try (ShellProcessControl pc = ShellStore.local().create().start()) {
|
||||
return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(command));
|
||||
return pc.executeBooleanSimpleCommand(pc.getShellType().getWhichCommand(executable));
|
||||
} catch (Exception e) {
|
||||
ErrorEvent.fromThrowable(e).omit().handle();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return OsType.getLocal().equals(OsType.LINUX);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class WindowsFullPathType extends ExternalApplicationType {
|
||||
|
|
|
@ -109,7 +109,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
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) {
|
||||
super(id, command);
|
||||
|
@ -117,9 +117,14 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelectable() {
|
||||
return OsType.getLocal().equals(OsType.LINUX);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class WindowsFullPathType extends ExternalApplicationType.WindowsFullPathType implements ExternalEditorType {
|
||||
|
@ -174,7 +179,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
|
|||
var env = System.getenv("VISUAL");
|
||||
if (env != null) {
|
||||
var found = LINUX_EDITORS.stream()
|
||||
.filter(externalEditorType -> externalEditorType.command.equalsIgnoreCase(env))
|
||||
.filter(externalEditorType -> externalEditorType.executable.equalsIgnoreCase(env))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (found == null) {
|
||||
|
|
|
@ -69,6 +69,14 @@ recentlyUsed=Recently used
|
|||
programmingLanguages=Programming languages
|
||||
applications=Applications
|
||||
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
|
||||
unknown=Unknown
|
||||
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
|
||||
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
|
||||
computer without providing any further notice or receiving any additional consent. This feature may not be disabled.
|
||||
If you do not want to receive automatic updates, you must uninstall the Software.
|
||||
computer without providing any further notice or receiving any additional consent. This feature may be disabled.
|
||||
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
|
||||
not be disabled. If you do not want to send error reports to its server, you must uninstall the Software.
|
||||
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.
|
||||
be disabled.
|
||||
|
||||
### Open-Source Notices
|
||||
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
## Welcome to X-Pipe!
|
||||
|
||||
X-Pipe (short for eXtended Pipe) is a tool that enables a fast and an efficient data transfer/exchange between
|
||||
all types of producers and consumers of data, e.g. different file types,
|
||||
applications, programming languages, databases, technologies, and more.
|
||||
Thank you for trying out the X-Pipe Alpha.
|
||||
You can overview the development status, report issues, and more at the following places:
|
||||
|
||||
It is currently in early development and this build is an alpha version.
|
||||
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)
|
||||
#### [GitHub Repository](https://github.com/xpipe-io/xpipe/)
|
||||
|
||||
#### [Discord Server](https://discord.gg/8y89vS8cRb)
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package io.xpipe.extension.fxcomps.util;
|
||||
|
||||
import io.xpipe.extension.util.ThreadHelper;
|
||||
import javafx.beans.binding.Binding;
|
||||
import javafx.beans.binding.ListBinding;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import lombok.Value;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
|
@ -14,6 +18,37 @@ import java.util.function.Predicate;
|
|||
|
||||
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?
|
||||
*/
|
||||
|
@ -30,6 +65,17 @@ public class BindingsHelper {
|
|||
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) {
|
||||
setContent(l1, l2);
|
||||
l2.addListener((ListChangeListener<? super T>) c -> {
|
||||
|
@ -56,6 +102,7 @@ public class BindingsHelper {
|
|||
l2.addListener((ListChangeListener<? super V>) c -> {
|
||||
runnable.run();
|
||||
});
|
||||
linkPersistently(l2, l1);
|
||||
return l1;
|
||||
}
|
||||
|
||||
|
@ -68,9 +115,14 @@ public class BindingsHelper {
|
|||
l2.addListener((ListChangeListener<? super V>) c -> {
|
||||
runnable.run();
|
||||
});
|
||||
linkPersistently(l2, 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) {
|
||||
ObservableList<V> l1 = FXCollections.observableList(new ArrayList<>());
|
||||
Runnable runnable = () -> {
|
||||
|
@ -83,6 +135,7 @@ public class BindingsHelper {
|
|||
predicate.addListener((c,o,n) -> {
|
||||
runnable.run();
|
||||
});
|
||||
linkPersistently(l2, l1);
|
||||
return l1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue