mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ability to create custom compound node decorator or tree structure provider
This commit is contained in:
+29
-12
@@ -4,51 +4,68 @@ package com.intellij.ide.projectView.impl;
|
||||
import com.intellij.ide.projectView.PresentationData;
|
||||
import com.intellij.ide.projectView.ProjectViewNode;
|
||||
import com.intellij.ide.projectView.ProjectViewNodeDecorator;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.packageDependencies.ui.PackageDependenciesNode;
|
||||
import com.intellij.ui.ColoredTreeCellRenderer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* This class is intended to combine all decorators for batch usages.
|
||||
*
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
public final class CompoundProjectViewNodeDecorator implements ProjectViewNodeDecorator {
|
||||
private static final ProjectViewNodeDecorator EMPTY = new CompoundProjectViewNodeDecorator();
|
||||
private static final Key<ProjectViewNodeDecorator> KEY = Key.create("ProjectViewNodeDecorator");
|
||||
private final Project project;
|
||||
private static final Logger LOG = Logger.getInstance(CompoundProjectViewNodeDecorator.class);
|
||||
private final ProjectViewNodeDecorator[] decorators;
|
||||
|
||||
/**
|
||||
* @return a shared instance for the specified project
|
||||
*/
|
||||
@NotNull
|
||||
public static ProjectViewNodeDecorator get(@NotNull Project project) {
|
||||
if (project.isDisposed()) return EMPTY;
|
||||
ProjectViewNodeDecorator provider = project.getUserData(KEY);
|
||||
if (provider != null) return provider;
|
||||
provider = new CompoundProjectViewNodeDecorator(project);
|
||||
provider = new CompoundProjectViewNodeDecorator(EP_NAME.getExtensions(project));
|
||||
project.putUserData(KEY, provider);
|
||||
return provider;
|
||||
}
|
||||
|
||||
private CompoundProjectViewNodeDecorator(@NotNull Project project) {
|
||||
this.project = project;
|
||||
public CompoundProjectViewNodeDecorator(@NotNull ProjectViewNodeDecorator... decorators) {
|
||||
this.decorators = decorators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decorate(ProjectViewNode node, PresentationData data) {
|
||||
if (!project.isDisposed()) {
|
||||
for (ProjectViewNodeDecorator decorator : EP_NAME.getExtensions(project)) {
|
||||
decorator.decorate(node, data);
|
||||
}
|
||||
}
|
||||
forEach(decorator -> decorator.decorate(node, data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decorate(PackageDependenciesNode node, ColoredTreeCellRenderer cellRenderer) {
|
||||
if (!project.isDisposed()) {
|
||||
for (ProjectViewNodeDecorator decorator : EP_NAME.getExtensions(project)) {
|
||||
decorator.decorate(node, cellRenderer);
|
||||
forEach(decorator -> decorator.decorate(node, cellRenderer));
|
||||
}
|
||||
|
||||
private void forEach(@NotNull Consumer<ProjectViewNodeDecorator> consumer) {
|
||||
for (ProjectViewNodeDecorator decorator : decorators) {
|
||||
try {
|
||||
consumer.accept(decorator);
|
||||
}
|
||||
catch (IndexNotReadyException exception) {
|
||||
throw new ProcessCanceledException(exception);
|
||||
}
|
||||
catch (ProcessCanceledException exception) {
|
||||
throw exception;
|
||||
}
|
||||
catch (Exception exception) {
|
||||
LOG.warn("unexpected error in " + decorator, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-39
@@ -6,7 +6,6 @@ import com.intellij.ide.projectView.ViewSettings;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
@@ -23,24 +22,26 @@ import java.util.Objects;
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
public final class CompoundTreeStructureProvider implements TreeStructureProvider {
|
||||
private static final TreeStructureProvider EMPTY = new CompoundTreeStructureProvider();
|
||||
private static final Key<TreeStructureProvider> KEY = Key.create("TreeStructureProvider");
|
||||
private static final Logger LOG = Logger.getInstance(CompoundTreeStructureProvider.class);
|
||||
private final Project project;
|
||||
private final TreeStructureProvider[] providers;
|
||||
|
||||
/**
|
||||
* @return a shared instance for the specified project
|
||||
*/
|
||||
@NotNull
|
||||
public static TreeStructureProvider get(@NotNull Project project) {
|
||||
if (project.isDisposed()) return EMPTY;
|
||||
TreeStructureProvider provider = project.getUserData(KEY);
|
||||
if (provider != null) return provider;
|
||||
provider = new CompoundTreeStructureProvider(project);
|
||||
provider = new CompoundTreeStructureProvider(EP_NAME.getExtensions(project));
|
||||
project.putUserData(KEY, provider);
|
||||
return provider;
|
||||
}
|
||||
|
||||
private CompoundTreeStructureProvider(@NotNull Project project) {
|
||||
this.project = project;
|
||||
public CompoundTreeStructureProvider(@NotNull TreeStructureProvider... providers) {
|
||||
this.providers = providers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -48,30 +49,25 @@ public final class CompoundTreeStructureProvider implements TreeStructureProvide
|
||||
public Collection<AbstractTreeNode> modify(@NotNull AbstractTreeNode parent,
|
||||
@NotNull Collection<AbstractTreeNode> children,
|
||||
ViewSettings settings) {
|
||||
if (!children.isEmpty()) {
|
||||
TreeStructureProvider[] providers = getProviders();
|
||||
if (providers != null && providers.length != 0) {
|
||||
for (TreeStructureProvider provider : providers) {
|
||||
try {
|
||||
children = provider.modify(parent, children, settings);
|
||||
if (children.stream().anyMatch(Objects::isNull)) {
|
||||
LOG.warn("null child provided by " + provider);
|
||||
children = StreamEx.of(children).nonNull().toImmutableList();
|
||||
}
|
||||
}
|
||||
catch (IndexNotReadyException exception) {
|
||||
throw new ProcessCanceledException(exception);
|
||||
}
|
||||
catch (ProcessCanceledException exception) {
|
||||
throw exception;
|
||||
}
|
||||
catch (Exception exception) {
|
||||
LOG.warn("unexpected error in " + provider, exception);
|
||||
}
|
||||
for (TreeStructureProvider provider : providers) {
|
||||
try {
|
||||
children = provider.modify(parent, children, settings);
|
||||
if (children.stream().anyMatch(Objects::isNull)) {
|
||||
LOG.warn("null child provided by " + provider);
|
||||
children = StreamEx.of(children).nonNull().toImmutableList();
|
||||
}
|
||||
}
|
||||
children.forEach(node -> node.setParent(parent));
|
||||
catch (IndexNotReadyException exception) {
|
||||
throw new ProcessCanceledException(exception);
|
||||
}
|
||||
catch (ProcessCanceledException exception) {
|
||||
throw exception;
|
||||
}
|
||||
catch (Exception exception) {
|
||||
LOG.warn("unexpected error in " + provider, exception);
|
||||
}
|
||||
}
|
||||
children.forEach(node -> node.setParent(parent));
|
||||
return children;
|
||||
}
|
||||
|
||||
@@ -79,24 +75,20 @@ public final class CompoundTreeStructureProvider implements TreeStructureProvide
|
||||
@Override
|
||||
public Object getData(Collection<AbstractTreeNode> selection, String id) {
|
||||
if (id != null && selection != null && !selection.isEmpty()) {
|
||||
TreeStructureProvider[] providers = getProviders();
|
||||
if (providers != null && providers.length != 0) {
|
||||
for (TreeStructureProvider provider : providers) {
|
||||
if (isDumbMode(provider)) continue;
|
||||
for (TreeStructureProvider provider : providers) {
|
||||
try {
|
||||
Object data = provider.getData(selection, id);
|
||||
if (data != null) return data;
|
||||
}
|
||||
catch (IndexNotReadyException ignore) {
|
||||
}
|
||||
catch (ProcessCanceledException ignore) {
|
||||
}
|
||||
catch (Exception exception) {
|
||||
LOG.warn("unexpected error in " + provider, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TreeStructureProvider[] getProviders() {
|
||||
return project.isDisposed() ? null : EP_NAME.getExtensions(project);
|
||||
}
|
||||
|
||||
private boolean isDumbMode(TreeStructureProvider provider) {
|
||||
return project.isDisposed() || DumbService.isDumb(project) && !DumbService.isDumbAware(provider);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user