package jetbrains.mps.baseLanguage.unitTest.execution.tool;
/*Generated by MPS */
import javax.swing.JPanel;
import com.intellij.openapi.Disposable;
import jetbrains.mps.baseLanguage.unitTest.execution.client.TestRunState;
import jetbrains.mps.project.MPSProject;
import java.util.List;
import jetbrains.mps.baseLanguage.closures.runtime._FunctionTypes;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.ArrayList;
import com.intellij.openapi.project.Project;
import com.intellij.execution.ui.ConsoleView;
import jetbrains.mps.ide.project.ProjectHelper;
import javax.swing.JComponent;
import java.awt.Dimension;
import com.intellij.openapi.ui.Splitter;
import java.awt.BorderLayout;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.ActionPlaces;
import javax.swing.JScrollPane;
import com.intellij.ui.ScrollPaneFactory;
import javax.swing.JTable;
import com.intellij.ui.table.JBTable;
import java.awt.GridLayout;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.execution.process.ProcessListener;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import com.intellij.ide.util.PropertiesComponent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import com.intellij.openapi.actionSystem.DataProvider;
import java.awt.LayoutManager;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import jetbrains.mps.workbench.MPSDataKeys;
import jetbrains.mps.ide.ui.tree.MPSTreeNode;
import jetbrains.mps.baseLanguage.unitTest.execution.client.ITestNodeWrapper;
public class UnitTestViewComponent extends JPanel implements Disposable {
private static final String SPLITTER_SIZE_PROPERTY = UnitTestOptions.PREFIX + ".UnitTestViewComponent" + ".splitter";
private final TestRunState myTestState;
private final TestOutputComponent myOutputComponent;
private final TestTree myTreeComponent;
private final ProgressLine myProgressLineComponent;
private final TestToolbarPanel myActionToolComponent;
private final MPSProject myProject;
private final FailedTestOccurrenceNavigator myTestNavigator;
private final List<_FunctionTypes._void_P0_E0> myListeners = ListSequence.fromList(new ArrayList<_FunctionTypes._void_P0_E0>());
public UnitTestViewComponent(Project project, ConsoleView console, TestRunState testRunState, _FunctionTypes._void_P0_E0 closeListener) {
myProject = ProjectHelper.fromIdeaProject(project);
myTestState = testRunState;
StatisticsTableModel statisticsModel = new StatisticsTableModel(myTestState);
myTreeComponent = new TestTree(myTestState, myProject, this);
myTestNavigator = new FailedTestOccurrenceNavigator(myTreeComponent);
myActionToolComponent = new TestToolbarPanel(myTreeComponent, myTestNavigator);
JComponent leftPanel = createTreeComponent(myActionToolComponent, myTreeComponent);
myProgressLineComponent = new ProgressLine(myTestState);
myProgressLineComponent.setMinimumSize(new Dimension(0, myProgressLineComponent.getMinimumSize().height));
myOutputComponent = new TestOutputComponent(console, myTestState);
myTreeComponent.addTreeSelectionListener(new TestTreeSelectionListener(myTreeComponent, statisticsModel, myOutputComponent));
myTreeComponent.addMouseListener(new TestTreeRootMouseListener(myTreeComponent, statisticsModel, myOutputComponent));
JPanel rightPanel = createOutputComponent(console, myProgressLineComponent, myOutputComponent.getComponent(), statisticsModel);
Splitter splitter = new Splitter(false);
initSplitterProportion(splitter, 0.2f, "tree");
splitter.setFirstComponent(leftPanel);
splitter.setSecondComponent(rightPanel);
setLayout(new BorderLayout());
add(splitter, BorderLayout.CENTER);
myTestState.addView(myTreeComponent);
myTestState.addView(myProgressLineComponent);
myTestState.addView(myOutputComponent);
addCloseListener(closeListener);
}
public JComponent createActionsToolbar(ConsoleView console) {
DefaultActionGroup group = new DefaultActionGroup(console.createConsoleActions());
ActionManager manager = ActionManager.getInstance();
ActionToolbar toolbar = manager.createActionToolbar(ActionPlaces.UNKNOWN, group, false);
toolbar.setLayoutPolicy(ActionToolbar.WRAP_LAYOUT_POLICY);
return toolbar.getComponent();
}
private JComponent createTreeComponent(JComponent toolbar, JComponent tree) {
UnitTestViewComponent.MyTreePanel treePanel = new UnitTestViewComponent.MyTreePanel(new BorderLayout());
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(tree);
treePanel.add(scrollPane, BorderLayout.CENTER);
treePanel.add(toolbar, BorderLayout.NORTH);
return treePanel;
}
private JComponent createStatisticsComponent(StatisticsTableModel testStatisticsModel) {
JTable statisticsTable = new JBTable(testStatisticsModel);
statisticsTable.setDefaultRenderer(TestStatisticsRow.class, new StatisticsRowRenderer());
JPanel tablePanel = new JPanel(new GridLayout(1, 1));
tablePanel.add(new JBScrollPane(statisticsTable));
return tablePanel;
}
public ProcessListener getProcessListener() {
return myProgressLineComponent.getProcessListener();
}
@Override
public void dispose() {
myOutputComponent.dispose();
myTreeComponent.dispose();
invokeCloseListeners();
}
public void addCloseListener(_FunctionTypes._void_P0_E0 listener) {
ListSequence.fromList(myListeners).addElement(listener);
}
public void invokeCloseListeners() {
for (_FunctionTypes._void_P0_E0 listener : ListSequence.fromList(myListeners)) {
listener.invoke();
}
}
private JPanel createOutputComponent(ConsoleView console, JComponent progressLine, JComponent testOutput, StatisticsTableModel statisticsModel) {
JPanel rightPanel = new JPanel(new GridBagLayout());
JComponent stackTraceActions = createActionsToolbar(console);
stackTraceActions.setMaximumSize(new Dimension(rightPanel.getWidth(), stackTraceActions.getMaximumSize().height));
Splitter outputStatisticSplitter = new Splitter(false);
initSplitterProportion(outputStatisticSplitter, 0.5f, "statistic");
outputStatisticSplitter.setFirstComponent(testOutput);
JComponent statistics = createStatisticsComponent(statisticsModel);
outputStatisticSplitter.setSecondComponent(statistics);
GridBagConstraints c = new GridBagConstraints();
rightPanel.setBorder(null);
c.fill = GridBagConstraints.VERTICAL;
c.anchor = GridBagConstraints.LINE_START;
c.gridx = 0;
c.gridy = 1;
c.weighty = 1;
c.weightx = 0;
rightPanel.add(stackTraceActions, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 0;
c.weighty = 0;
c.weightx = 1;
rightPanel.add(progressLine, c);
c.fill = GridBagConstraints.BOTH;
c.gridx = 1;
c.gridy = 1;
c.weighty = 1;
c.weightx = 1;
rightPanel.add(outputStatisticSplitter, c);
return rightPanel;
}
public void initSplitterProportion(final Splitter splitter, float defaultProportion, final String id) {
final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance();
String value = propertiesComponent.getValue(UnitTestViewComponent.SPLITTER_SIZE_PROPERTY + "." + id);
float proportion = defaultProportion;
if ((value != null && value.length() > 0)) {
try {
proportion = Float.parseFloat(value);
} catch (NumberFormatException ignore) {
}
}
splitter.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals(Splitter.PROP_PROPORTION)) {
propertiesComponent.setValue(UnitTestViewComponent.SPLITTER_SIZE_PROPERTY + "." + id, String.valueOf(splitter.getProportion()));
}
}
});
splitter.setProportion(proportion);
}
/*package*/ class MyTreePanel extends JPanel implements DataProvider {
public MyTreePanel(LayoutManager manager) {
super(manager);
}
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (MPSDataKeys.MPS_PROJECT.is(dataId)) {
return myProject;
}
if (MPSDataKeys.NODE.is(dataId)) {
MPSTreeNode currentNode = myTreeComponent.getCurrentNode();
if (currentNode == null) {
return null;
}
ITestNodeWrapper testWrapper = (ITestNodeWrapper) currentNode.getUserObject();
// XXX it's unclear whether we shall assume model read lock here, or obtain it ourselves
// I didn't get the lock here as it's stupid to ask for SNode not inside a lock already.
return testWrapper.getNodePointer().resolve(myProject.getRepository());
}
return null;
}
}
}