package jetbrains.mps.debugger.api.ui.tool;
/*Generated by MPS */
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.debug.api.AbstractDebugSession;
import jetbrains.mps.debug.api.AbstractUiState;
import jetbrains.mps.debugger.api.ui.tree.VariablesTree;
import javax.swing.JList;
import com.intellij.openapi.project.Project;
import com.intellij.execution.ui.RunnerLayoutUi;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import com.intellij.ui.content.Content;
import jetbrains.mps.debugger.api.ui.icons.Icons;
import com.intellij.execution.ui.layout.PlaceInGrid;
import javax.swing.JComponent;
import jetbrains.mps.debug.api.evaluation.IEvaluationProvider;
import com.intellij.openapi.actionSystem.DataProvider;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NonNls;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import java.awt.LayoutManager;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.ListCellRendererWrapper;
import jetbrains.mps.debug.api.programState.IThread;
import com.intellij.ui.components.JBList;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.ListSelectionModel;
import javax.swing.DefaultListCellRenderer;
import java.awt.Component;
import jetbrains.mps.debug.api.programState.IStackFrame;
import jetbrains.mps.debug.api.programState.ILocation;
import jetbrains.mps.debug.api.programState.NullLocation;
import java.awt.Color;
import com.intellij.openapi.application.ApplicationManager;
import jetbrains.mps.debug.api.SessionChangeAdapter;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import java.util.List;
public class DebuggerToolPanel {
@NotNull
private final AbstractDebugSession myDebugSession;
@NotNull
private AbstractUiState myUiState;
private DebuggerToolPanel.ThreadsComboBoxModel myThreadsComboBoxModel;
private DebuggerToolPanel.StackFramesListModel myStackFramesListModel;
private VariablesTree myVariablesTree;
private JList myFramesList;
public DebuggerToolPanel(@NotNull Project project, @NotNull AbstractDebugSession session, @NotNull RunnerLayoutUi ui) {
myDebugSession = session;
myUiState = myDebugSession.getUiState();
myDebugSession.addChangeListener(new DebuggerToolPanel.MySessionChangeListener());
ui.getDefaults().initTabDefaults(0, "Debugger", null);
JPanel framesPanel = new DebuggerToolPanel.DebuggerPanel(new BorderLayout());
framesPanel.add(createThreadsComponent(), BorderLayout.NORTH);
framesPanel.add(createStackFrameComponent(), BorderLayout.CENTER);
Content framesContent = ui.createContent(DebuggerToolContent.FRAMES, framesPanel, "Frames", Icons.FRAMES, null);
framesContent.setCloseable(false);
ui.addContent(framesContent, 0, PlaceInGrid.left, false);
JComponent variablesPanel = createVariablesPanel(project);
Content variablesContent = ui.createContent(DebuggerToolContent.VARIABLES, variablesPanel, "Variables", Icons.VARIABLES, null);
variablesContent.setCloseable(false);
ui.addContent(variablesContent, 0, PlaceInGrid.center, false);
IEvaluationProvider evaluationProvider = myDebugSession.getEvaluationProvider();
if (evaluationProvider != null) {
JComponent watches = evaluationProvider.createWatchesPanel();
if (watches != null) {
Content watchesContent = ui.createContent(DebuggerToolContent.WATCHES, watches, "Watches", Icons.WATCHES, null);
watchesContent.setCloseable(false);
ui.addContent(watchesContent, 0, PlaceInGrid.right, true);
}
}
}
public class DebuggerPanel extends JPanel implements DataProvider {
@Nullable
public Object getData(@NonNls String id) {
if (PlatformDataKeys.HELP_ID.is(id)) {
return "ideaInterface.debuggerView";
}
return null;
}
public DebuggerPanel(LayoutManager p0) {
super(p0);
}
}
private JComponent createVariablesPanel(Project project) {
myVariablesTree = new VariablesTree(project, myDebugSession.getUiState());
return new JBScrollPane(myVariablesTree);
}
private JComponent createThreadsComponent() {
myThreadsComboBoxModel = new DebuggerToolPanel.ThreadsComboBoxModel();
ComboBox threadsComboBox = new ComboBox(myThreadsComboBoxModel);
threadsComboBox.setRenderer(new ListCellRendererWrapper<IThread>() {
@Override
public void customize(JList list, IThread value, int index, boolean selected, boolean hasFocus) {
if (value != null) {
setText(value.getPresentation());
setIcon(value.getPresentationIcon());
}
}
});
return threadsComboBox;
}
private JComponent createStackFrameComponent() {
myStackFramesListModel = new DebuggerToolPanel.StackFramesListModel();
myFramesList = new JBList(myStackFramesListModel);
myFramesList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!(e.getValueIsAdjusting())) {
myStackFramesListModel.selected(myFramesList.getSelectedIndex());
}
}
});
myFramesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myFramesList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component defaultComponent = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null) {
IStackFrame frame = (IStackFrame) value;
ILocation location = frame.getLocation();
String framePresentation;
if (location instanceof NullLocation) {
framePresentation = "null";
} else {
String typename = location.getUnitName();
int lastDot = typename.lastIndexOf(".");
String className = typename.substring(lastDot + 1);
String pckgName = (lastDot > 0 ? typename.substring(0, lastDot) : "");
framePresentation = location.getRoutineName() + "():" + location.getLineNumber() + " " + className + "(" + pckgName + ")";
}
setText(framePresentation);
if (!(myDebugSession.getDebuggableFramesSelector().isDebuggableFrame(frame))) {
setForeground(Color.gray);
}
}
return defaultComponent;
}
});
return new JBScrollPane(myFramesList);
}
private void updateUi() {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
myUiState = myDebugSession.getUiState();
myThreadsComboBoxModel.updateThreads();
myStackFramesListModel.updateFrames();
myFramesList.setSelectedValue(myUiState.getStackFrame(), true);
// TODO not good
myVariablesTree.setUiState(myUiState);
myVariablesTree.rebuildNow();
}
});
}
private class MySessionChangeListener extends SessionChangeAdapter {
private MySessionChangeListener() {
}
@Override
public void stateChanged(AbstractDebugSession session) {
if (myDebugSession != session) {
return;
}
updateUi();
}
@Override
public void paused(AbstractDebugSession session) {
if (myDebugSession != session) {
return;
}
updateUi();
}
@Override
public void resumed(AbstractDebugSession session) {
if (myDebugSession != session) {
return;
}
updateUi();
}
}
private class ThreadsComboBoxModel extends AbstractListModel implements ComboBoxModel {
private ThreadsComboBoxModel() {
}
@Override
public void setSelectedItem(Object anItem) {
myUiState.selectThread((IThread) anItem);
}
@Override
public Object getSelectedItem() {
return myUiState.getThread();
}
@Override
public int getSize() {
return getThreads().size();
}
@Override
public Object getElementAt(int index) {
List<? extends IThread> threads = getThreads();
if (index >= threads.size()) {
return null;
}
return threads.get(index);
}
public void updateThreads() {
fireContentsChanged(DebuggerToolPanel.this, -1, getSize());
}
private List<? extends IThread> getThreads() {
return myUiState.getThreads();
}
}
private class StackFramesListModel extends AbstractListModel {
private StackFramesListModel() {
}
@Override
public int getSize() {
return myUiState.getStackFramesCount();
}
@Override
public Object getElementAt(int index) {
if (index >= myUiState.getStackFramesCount()) {
return null;
}
return myUiState.getStackFrame(index);
}
public void updateFrames() {
fireContentsChanged(DebuggerToolPanel.this, -1, getSize());
}
public void selected(int selectedIndex) {
myUiState.selectFrame(selectedIndex);
}
}
}