package jetbrains.mps.ide.platform.dependencyViewer;
/*Generated by MPS */
import javax.swing.JPanel;
import com.intellij.openapi.project.Project;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import jetbrains.mps.ide.tools.BaseTool;
import jetbrains.mps.project.MPSProject;
import java.awt.BorderLayout;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.openapi.ui.Splitter;
import jetbrains.mps.ide.findusages.view.UsagesView;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.ide.findusages.model.SearchResults;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import jetbrains.mps.progress.ProgressMonitorAdapter;
import jetbrains.mps.internal.collections.runtime.Sequence;
import org.jetbrains.mps.openapi.module.SModule;
import javax.swing.JComponent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import jetbrains.mps.icons.MPSIcons;
public class DependenciesPanel extends JPanel {
private DependencyTree myInitTree;
private TargetsView myTargetsView;
private ReferencesView myReferencesView;
private final Project myProject;
private final jetbrains.mps.project.Project myMPSProject;
private DependencyViewerScope myScope;
private DependencyViewerScope myInitialScope;
private Iterable<SNode> mySourceNodes = ListSequence.fromList(new ArrayList<SNode>());
private BaseTool myTool;
private ReferencesFinder myReferencesFinder = null;
private boolean myIsMeta;
public DependenciesPanel(BaseTool tool, MPSProject project) {
super(new BorderLayout());
myTool = tool;
myIsMeta = false;
// FIXME pass project right into DependencyTree instead of setContent(scope, myMPSProject) later in resetContent(), below.
myInitTree = new DependencyTree(this);
myProject = project.getProject();
myMPSProject = project;
myTargetsView = new TargetsView(myProject, this);
myReferencesView = new ReferencesView(myProject, this);
JBScrollPane leftPane = new JBScrollPane(myInitTree);
Splitter treeSplitter = new Splitter(false);
treeSplitter.setFirstComponent(leftPane);
treeSplitter.setSecondComponent(myTargetsView.getTreeComponent());
Splitter splitter = new Splitter(true);
splitter.setFirstComponent(treeSplitter);
splitter.setSecondComponent(myReferencesView.getComponent());
splitter.setDividerWidth(5);
treeSplitter.setDividerWidth(5);
add(splitter, BorderLayout.CENTER);
add(createToolbar(), BorderLayout.NORTH);
}
public void resetContent(DependencyViewerScope scope, boolean isMeta) {
myIsMeta = isMeta;
myReferencesFinder = new ReferencesFinder();
setVisible(true);
myInitTree.setContent(scope, myMPSProject);
myInitialScope = scope;
updateTargetsView(scope);
repaint();
}
public UsagesView getReferencesViewComponent() {
return myReferencesView;
}
public DependencyViewerScope getCurrentScope() {
return myScope;
}
public void updateTargetsView(final DependencyViewerScope sourceScope) {
myScope = sourceScope;
final Wrappers._T<SearchResults<SNode>> results = new Wrappers._T<SearchResults<SNode>>(new SearchResults<SNode>());
ProgressManager.getInstance().run(new Task.Modal(myProject, "Analyzing dependencies", true) {
@Override
public void run(@NotNull final ProgressIndicator indicator) {
myMPSProject.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
ProgressMonitor monitor = new ProgressMonitorAdapter(indicator);
mySourceNodes = sourceScope.getNodes();
try {
if (myIsMeta) {
monitor.start("computing used languages", Sequence.fromIterable(mySourceNodes).count());
results.value = myReferencesFinder.getUsedConcepts(mySourceNodes, sourceScope, monitor);
} else {
monitor.start("computing references' targets", Sequence.fromIterable(mySourceNodes).count());
results.value = myReferencesFinder.findRefsFromScopeToOuter(mySourceNodes, sourceScope, monitor);
}
} finally {
monitor.done();
}
}
});
}
});
myTargetsView.setContents(results.value);
updateReferencesView(null);
}
public void selectInTargetsView(SModule module) {
myTargetsView.selectModule(module);
}
public SearchResults updateReferencesView(final DependencyViewerScope targetScope) {
final SearchResults[] results = new SearchResults[1];
if (targetScope == null) {
myReferencesView.setContents(new SearchResults());
return results[0];
}
ProgressManager.getInstance().run(new Task.Modal(myProject, "Analyzing dependencies", true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
final ProgressMonitor monitor = new ProgressMonitorAdapter(indicator);
final Wrappers._T<SearchResults> result = new Wrappers._T<SearchResults>();
myMPSProject.getRepository().getModelAccess().runReadAction(new Runnable() {
public void run() {
try {
if (myIsMeta) {
monitor.start("filtering nodes", Sequence.fromIterable(mySourceNodes).count());
result.value = myReferencesFinder.getLanguageUsagesSearchResults(mySourceNodes, myScope, targetScope, monitor);
} else {
monitor.start("filtering references", Sequence.fromIterable(mySourceNodes).count());
result.value = myReferencesFinder.getRefsBetweenScopes(mySourceNodes, myScope, targetScope, monitor);
}
} finally {
monitor.done();
}
}
});
results[0] = result.value;
myReferencesView.setContents(result.value);
}
});
return results[0];
}
public void close() {
myTool.close();
}
private JComponent createToolbar() {
DefaultActionGroup group = new DefaultActionGroup();
group.add(new DependenciesPanel.CloseAction());
group.add(new DependenciesPanel.RerunAction());
group.add(new DependenciesPanel.ToggleUsedLanguages());
return ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true).getComponent();
}
public boolean isMeta() {
return myIsMeta;
}
private class CloseAction extends AnAction {
public CloseAction() {
super("Close", "Close dependencies viewer", AllIcons.Actions.Cancel);
}
@Override
public void actionPerformed(AnActionEvent event) {
myTool.setAvailable(false);
}
}
private class RerunAction extends AnAction {
public RerunAction() {
super("Rerun", "Rerun dependencies viewer", AllIcons.Actions.Refresh);
}
@Override
public void actionPerformed(AnActionEvent event) {
resetContent(myInitialScope, myIsMeta);
}
}
public class ToggleUsedLanguages extends ToggleAction {
public ToggleUsedLanguages() {
super("Show used languages", "Show used languages", MPSIcons.Nodes.Language);
}
@Override
public boolean isSelected(AnActionEvent event) {
return myIsMeta;
}
@Override
public void setSelected(AnActionEvent event, boolean b) {
resetContent(myInitialScope, b);
}
}
}