Implement retained target sessions, runtime sizing and Component navigation
This commit is contained in:
+11
-8
@@ -36,14 +36,17 @@ public final class DesignerFileEditor extends UserDataHolderBase implements File
|
||||
try {
|
||||
ToolkitGate.check(project, file);
|
||||
Path settings =
|
||||
Path.of(
|
||||
System.getProperty(
|
||||
"neitzel.designer.launch",
|
||||
Path.of(
|
||||
project.getBasePath(),
|
||||
".neitzel-fx-designer",
|
||||
"host.properties")
|
||||
.toString()));
|
||||
Path.of(project.getBasePath(), ".neitzel-fx-designer", "host.properties");
|
||||
String explicit = System.getProperty("neitzel.designer.launch");
|
||||
if (explicit != null) {
|
||||
var configured = HostLaunch.load(Path.of(explicit));
|
||||
if (configured
|
||||
.configuration()
|
||||
.getParent()
|
||||
.toRealPath()
|
||||
.equals(Path.of(project.getBasePath()).toRealPath()))
|
||||
settings = Path.of(explicit);
|
||||
}
|
||||
var launch = HostLaunch.load(settings);
|
||||
SwingUtilities.invokeLater(
|
||||
() -> {
|
||||
|
||||
@@ -26,6 +26,14 @@ public final class IntellijDocuments implements HostServices.Documents, AutoClos
|
||||
private final java.util.concurrent.CopyOnWriteArrayList<java.util.function.Consumer<URI>>
|
||||
changes = new java.util.concurrent.CopyOnWriteArrayList<>();
|
||||
|
||||
private final java.util.List<java.util.function.Consumer<URI>> saves =
|
||||
new java.util.concurrent.CopyOnWriteArrayList<>();
|
||||
|
||||
public AutoCloseable onSave(java.util.function.Consumer<URI> listener) {
|
||||
saves.add(listener);
|
||||
return () -> saves.remove(listener);
|
||||
}
|
||||
|
||||
public AutoCloseable onChange(java.util.function.Consumer<URI> listener) {
|
||||
changes.add(listener);
|
||||
return () -> changes.remove(listener);
|
||||
@@ -48,6 +56,18 @@ public final class IntellijDocuments implements HostServices.Documents, AutoClos
|
||||
this.project = Objects.requireNonNull(project);
|
||||
lifetime = this::disposeResources;
|
||||
Disposer.register(project, lifetime);
|
||||
ApplicationManager.getApplication()
|
||||
.getMessageBus()
|
||||
.connect(lifetime)
|
||||
.subscribe(
|
||||
com.intellij.openapi.fileEditor.FileDocumentManagerListener.TOPIC,
|
||||
new com.intellij.openapi.fileEditor.FileDocumentManagerListener() {
|
||||
public void afterDocumentSaved(Document document) {
|
||||
var file = FileDocumentManager.getInstance().getFile(document);
|
||||
if (file != null && file.isInLocalFileSystem())
|
||||
saves.forEach(listener -> listener.accept(canonicalUri(file)));
|
||||
}
|
||||
});
|
||||
EditorFactory.getInstance()
|
||||
.getEventMulticaster()
|
||||
.addDocumentListener(
|
||||
|
||||
@@ -27,31 +27,85 @@ public final class IntellijHost implements AutoCloseable {
|
||||
docs,
|
||||
(request, output) -> scope.own(builds.start(request, output)),
|
||||
runtimes,
|
||||
location -> {
|
||||
var result = new CompletableFuture<Void>();
|
||||
ApplicationManager.getApplication()
|
||||
.invokeLater(
|
||||
() ->
|
||||
WriteIntentReadAction.run(
|
||||
() -> {
|
||||
try {
|
||||
if (project.isDisposed())
|
||||
throw new IllegalStateException("Project disposed");
|
||||
var file =
|
||||
LocalFileSystem.getInstance()
|
||||
.refreshAndFindFileByNioFile(
|
||||
Path.of(location.document()));
|
||||
if (file == null)
|
||||
throw new IllegalArgumentException(
|
||||
"Navigation file unavailable");
|
||||
new OpenFileDescriptor(project, file, location.offset())
|
||||
.navigate(true);
|
||||
result.complete(null);
|
||||
} catch (Throwable e) {
|
||||
result.completeExceptionally(e);
|
||||
}
|
||||
}));
|
||||
return result;
|
||||
new HostServices.Navigation() {
|
||||
public CompletionStage<java.util.List<HostServices.Location>> componentSources(
|
||||
String type) {
|
||||
if (!type.matches("[A-Za-z_$][A-Za-z0-9_$]*(\\.[A-Za-z_$][A-Za-z0-9_$]*)*"))
|
||||
return CompletableFuture.failedFuture(
|
||||
new IllegalArgumentException("Invalid type"));
|
||||
return CompletableFuture.supplyAsync(
|
||||
() ->
|
||||
com.intellij.openapi.application.ReadAction.compute(
|
||||
() -> {
|
||||
var result = new java.util.ArrayList<HostServices.Location>();
|
||||
String path = type.replace('.', '/');
|
||||
for (var owner :
|
||||
com.intellij.openapi.project.ProjectManager.getInstance()
|
||||
.getOpenProjects()) {
|
||||
var roots =
|
||||
com.intellij.openapi.roots.ProjectRootManager.getInstance(owner)
|
||||
.getContentSourceRoots();
|
||||
boolean declared =
|
||||
java.util.Arrays.stream(roots)
|
||||
.anyMatch(
|
||||
r -> r.findFileByRelativePath(path + ".java") != null);
|
||||
if (declared)
|
||||
for (var root : roots) {
|
||||
var file = root.findFileByRelativePath(path + ".fxml");
|
||||
if (file != null && file.isInLocalFileSystem())
|
||||
result.add(
|
||||
new HostServices.Location(
|
||||
Path.of(file.getPath()).toUri(), 0));
|
||||
}
|
||||
}
|
||||
return java.util.List.copyOf(result);
|
||||
}));
|
||||
}
|
||||
|
||||
public CompletionStage<Void> open(HostServices.Location location) {
|
||||
var result = new CompletableFuture<Void>();
|
||||
ApplicationManager.getApplication()
|
||||
.invokeLater(
|
||||
() ->
|
||||
WriteIntentReadAction.run(
|
||||
() -> {
|
||||
try {
|
||||
if (project.isDisposed())
|
||||
throw new IllegalStateException("Project disposed");
|
||||
var file =
|
||||
LocalFileSystem.getInstance()
|
||||
.refreshAndFindFileByNioFile(
|
||||
Path.of(location.document()));
|
||||
if (file == null)
|
||||
throw new IllegalArgumentException(
|
||||
"Navigation file unavailable");
|
||||
Project owner = project;
|
||||
for (var candidate :
|
||||
com.intellij.openapi.project.ProjectManager.getInstance()
|
||||
.getOpenProjects())
|
||||
if (!candidate.isDisposed()
|
||||
&& com.intellij.openapi.roots.ProjectFileIndex
|
||||
.getInstance(candidate)
|
||||
.isInSourceContent(file)) {
|
||||
owner = candidate;
|
||||
break;
|
||||
}
|
||||
if ("fxml".equalsIgnoreCase(file.getExtension())) {
|
||||
var manager =
|
||||
com.intellij.openapi.fileEditor.FileEditorManager
|
||||
.getInstance(owner);
|
||||
manager.openFile(file, true);
|
||||
manager.setSelectedEditor(file, "neitzel-fx-designer");
|
||||
} else
|
||||
new OpenFileDescriptor(owner, file, location.offset())
|
||||
.navigate(true);
|
||||
result.complete(null);
|
||||
} catch (Throwable e) {
|
||||
result.completeExceptionally(e);
|
||||
}
|
||||
}));
|
||||
return result;
|
||||
}
|
||||
},
|
||||
diagnostics,
|
||||
scope);
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public final class ConnectedWorkflowTest extends BasePlatformTestCase {
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
Thread.sleep(10);
|
||||
}
|
||||
assertEquals(32, (int) future.get(1, TimeUnit.SECONDS));
|
||||
assertEquals(50, (int) future.get(1, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user