package jetbrains.mps.debugger.api.ui.breakpoints;
/*Generated by MPS */
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.actionSystem.DataProvider;
import javax.swing.JPanel;
import javax.swing.JComponent;
import jetbrains.mps.project.Project;
import jetbrains.mps.debug.api.BreakpointManagerComponent;
import jetbrains.mps.debug.api.breakpoints.BreakpointProvidersManager;
import javax.swing.JScrollPane;
import java.util.Map;
import jetbrains.mps.debug.api.breakpoints.IBreakpointKind;
import jetbrains.mps.debug.api.breakpoints.IBreakpointPropertiesUi;
import java.util.HashMap;
import jetbrains.mps.debug.api.breakpoints.IBreakpoint;
import jetbrains.mps.ide.project.ProjectHelper;
import java.awt.BorderLayout;
import com.intellij.ui.ScrollPaneFactory;
import javax.swing.UIManager;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import java.awt.Dimension;
import jetbrains.mps.debug.api.breakpoints.IBreakpointsProvider;
import org.jetbrains.annotations.Nullable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import jetbrains.mps.workbench.action.BaseAction;
import com.intellij.openapi.actionSystem.Separator;
import com.intellij.openapi.actionSystem.ToggleAction;
import jetbrains.mps.debugger.api.ui.icons.Icons;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.AnAction;
import javax.swing.AbstractAction;
import java.awt.event.ActionEvent;
import javax.swing.KeyStroke;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import com.intellij.ide.DataManager;
import jetbrains.mps.debug.api.breakpoints.ILocationBreakpoint;
import jetbrains.mps.openapi.navigation.EditorNavigator;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.Action;
public class BreakpointsBrowserDialog extends DialogWrapper implements DataProvider {
private static final String COMMAND_SHOW_NODE = "COMMAND_SHOW_NODE";
private final JPanel myMainPanel;
private JComponent myPropertiesEditorPanel;
private final Project myProject;
private final BreakpointManagerComponent myBreakpointsManager;
private final BreakpointProvidersManager myProvidersManager;
private final BreakpointsUiComponent myBreakpointsUi;
private final JScrollPane myBreakpointsScrollPane;
private final BreakpointsView[] myViews;
private int myCurrentViewIndex;
private final Map<IBreakpointKind, IBreakpointPropertiesUi> myKindToUi = new HashMap<IBreakpointKind, IBreakpointPropertiesUi>();
private final BreakpointManagerComponent.BreakpointManagerListener myBreakpointManagerListener = new BreakpointManagerComponent.BreakpointManagerListener() {
@Override
public void breakpointsChanged() {
IBreakpoint bp = myViews[myCurrentViewIndex].getSelectedBreakpoint();
breakpointSelected(bp);
}
};
public BreakpointsBrowserDialog(Project mpsProject) {
super(ProjectHelper.toIdeaProject(mpsProject));
setTitle("Breakpoints");
setModal(false);
this.setOKButtonText("Close");
myProject = mpsProject;
myBreakpointsManager = BreakpointManagerComponent.getInstance(ProjectHelper.toIdeaProject(mpsProject));
myBreakpointsUi = BreakpointsUiComponent.getInstance(ProjectHelper.toIdeaProject(mpsProject));
myProvidersManager = BreakpointProvidersManager.getInstance();
myCurrentViewIndex = BreakpointViewSettingsComponent.getInstance(mpsProject).getViewIndex();
myViews = new BreakpointsView[]{new BreakpointsTable(mpsProject, myBreakpointsManager), new BreakpointsTree(mpsProject, myBreakpointsManager)};
myMainPanel = new JPanel(new BorderLayout());
myBreakpointsScrollPane = ScrollPaneFactory.createScrollPane(myViews[myCurrentViewIndex].getMainComponent());
myBreakpointsScrollPane.getViewport().setBackground(UIManager.getColor("Table.background"));
myMainPanel.add(myBreakpointsScrollPane, BorderLayout.CENTER);
ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, createActionGroup(), true);
myMainPanel.add(actionToolbar.getComponent(), BorderLayout.NORTH);
myMainPanel.setMinimumSize(new Dimension(500, 500));
// register keyboard/mouse actions on all views
registerActionsOnViews();
initPropertiesUi();
init();
}
private void saveState() {
if (myProject.isDisposed()) {
return;
}
for (BreakpointsView view : myViews) {
view.saveState();
}
}
private void initPropertiesUi() {
for (IBreakpointKind kind : myProvidersManager.getAllKinds()) {
IBreakpointsProvider provider = myProvidersManager.getProvider(kind);
if (provider == null) {
continue;
}
IBreakpointPropertiesUi editor = provider.createPropertiesEditor(kind);
if (editor == null) {
continue;
}
myKindToUi.put(kind, editor);
}
for (BreakpointsView view : myViews) {
view.addBreakpointSelectionListener(new BreakpointsView.BreakpointSelectionListener() {
@Override
public void breakpointSelected(@Nullable IBreakpoint breakpoint) {
BreakpointsBrowserDialog.this.breakpointSelected(breakpoint);
}
});
}
myBreakpointsManager.addChangeListener(myBreakpointManagerListener);
IBreakpoint selectedBreakpoint = myViews[myCurrentViewIndex].getSelectedBreakpoint();
if (selectedBreakpoint != null) {
breakpointSelected(selectedBreakpoint);
}
}
public void selectBreakpoint(@Nullable IBreakpoint breakpoint) {
myViews[myCurrentViewIndex].selectBreakpoint(breakpoint);
}
private void breakpointSelected(IBreakpoint breakpoint) {
if (myPropertiesEditorPanel != null) {
myMainPanel.remove(myPropertiesEditorPanel);
}
if (breakpoint != null) {
IBreakpointPropertiesUi ui = myKindToUi.get(breakpoint.getKind());
if (ui != null) {
ui.setBreakpoint(breakpoint);
myPropertiesEditorPanel = ui.getMainComponent();
myMainPanel.add(myPropertiesEditorPanel, BorderLayout.SOUTH);
}
}
myMainPanel.updateUI();
}
private ActionGroup createActionGroup() {
// create actions
DefaultActionGroup group = new DefaultActionGroup();
group.add(((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.debugger.api.ui.actions.GoToBreakpointSourceAction_Action")));
group.add(((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.debugger.api.ui.actions.ViewBreakpointSourceAction_Action")));
group.add(createAddActionGroup());
group.add(((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.debugger.api.ui.actions.DeleteBreakpointAction_Action")));
group.add(new Separator());
group.add(new ToggleAction("Tree View", "Toggle Tree/List View", Icons.BREAKPOINTS_DIALOG_TREE_VIEW) {
@Override
public boolean isSelected(AnActionEvent e) {
return isTreeView();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
switchView();
e.getPresentation().setText(myViews[1 - myCurrentViewIndex].getTitle());
}
});
group.add(new ToggleAction("Group By Module", "Group By Module", Icons.BREAKPOINTS_DIALOG_GROUP_BY_MODULE) {
@Override
public void update(AnActionEvent e) {
super.update(e);
e.getPresentation().setEnabled(isTreeView());
}
@Override
public boolean isSelected(AnActionEvent e) {
if (!(isTreeView())) {
return false;
}
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
return tree.isModuleGroupVisible();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
tree.toggleModuleGroup(state);
tree.update();
}
});
group.add(new ToggleAction("Group By Model", "Group By Model", Icons.BREAKPOINTS_DIALOG_GROUP_BY_MODEL) {
@Override
public void update(AnActionEvent e) {
super.update(e);
e.getPresentation().setEnabled(isTreeView());
}
@Override
public boolean isSelected(AnActionEvent e) {
if (!(isTreeView())) {
return false;
}
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
return tree.isModelGroupVisible();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
tree.toggleModelGroup(state);
tree.update();
}
});
group.add(new ToggleAction("Group By Root", "Group By Root", Icons.BREAKPOINTS_DIALOG_GROUP_BY_ROOT) {
@Override
public void update(AnActionEvent e) {
super.update(e);
e.getPresentation().setEnabled(isTreeView());
}
@Override
public boolean isSelected(AnActionEvent e) {
if (!(isTreeView())) {
return false;
}
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
return tree.isRootGroupVisible();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
tree.toggleRootGroup(state);
tree.update();
}
});
group.add(new AnAction("Expand All", "Expand All", jetbrains.mps.ide.findusages.view.icons.Icons.EXPAND_ICON) {
@Override
public void update(AnActionEvent e) {
// todo refactor actions: each view should provide their own actions
e.getPresentation().setEnabled(isTreeView());
}
@Override
public void actionPerformed(AnActionEvent e) {
if (!(isTreeView())) {
return;
}
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
tree.expandAll();
}
});
group.add(new AnAction("Collapse All", "Collapse All", jetbrains.mps.ide.findusages.view.icons.Icons.COLLAPSE_ICON) {
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(isTreeView());
}
@Override
public void actionPerformed(AnActionEvent e) {
if (!(isTreeView())) {
return;
}
BreakpointsTree tree = (BreakpointsTree) myViews[myCurrentViewIndex];
tree.collapseAll();
}
});
return group;
}
private DefaultActionGroup createAddActionGroup() {
DefaultActionGroup addActionGroup = new DefaultActionGroup("Add Breakpoint", true) {
@Override
public void update(AnActionEvent e) {
super.update(e);
e.getPresentation().setIcon(Icons.BREAKPOINTS_DIALOG_ADD);
}
};
for (final IBreakpointKind kind : myProvidersManager.getAllKinds()) {
IBreakpointsProvider provider = myProvidersManager.getProvider(kind);
if (provider != null && provider.canCreateFromUi(kind)) {
// TODO can't we ask this from kind??
AnAction addBreakpoointAction = new AnAction(kind.getPresentation(), "Create " + kind.getPresentation(), null) {
@Override
public void actionPerformed(AnActionEvent e) {
myBreakpointsUi.createFromUi(kind);
}
};
addActionGroup.add(addBreakpoointAction);
}
}
return addActionGroup;
}
private IBreakpoint getBreakpoint(AnActionEvent e) {
return BreakpointsUtil.MPS_BREAKPOINT.getData(e.getDataContext());
}
private boolean isTreeView() {
return myViews[myCurrentViewIndex] instanceof BreakpointsTree;
}
private void switchView() {
myCurrentViewIndex = 1 - myCurrentViewIndex;
BreakpointViewSettingsComponent.getInstance(myProject).setViewIndex(myCurrentViewIndex);
myBreakpointsScrollPane.setViewportView(myViews[myCurrentViewIndex].getMainComponent());
}
protected AbstractAction createWrapper(final AnAction action) {
return new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
action.actionPerformed(createEvent(action));
}
};
}
private void registerActionsOnViews() {
for (BreakpointsView myView : myViews) {
// show on enter
myView.getMainComponent().getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), COMMAND_SHOW_NODE);
myView.getMainComponent().getActionMap().put(COMMAND_SHOW_NODE, createWrapper(((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.debugger.api.ui.actions.ViewBreakpointSourceAction_Action"))));
// open on f4
myView.getMainComponent().registerKeyboardAction(createWrapper(((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.debugger.api.ui.actions.GoToBreakpointSourceAction_Action"))), KeyStroke.getKeyStroke("F4"), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// delete on del
myView.getMainComponent().registerKeyboardAction(createWrapper(((BaseAction) ActionManager.getInstance().getAction("jetbrains.mps.debugger.api.ui.actions.DeleteBreakpointAction_Action"))), KeyStroke.getKeyStroke("DELETE"), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
// open on double click
myView.getMainComponent().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
IBreakpoint breakpoint = BreakpointsUtil.MPS_BREAKPOINT.getData(myViews[myCurrentViewIndex]);
if (breakpoint == null) {
return;
}
dispose();
openNode(breakpoint, true, true);
}
}
});
}
}
private AnActionEvent createEvent(AnAction action) {
return new AnActionEvent(null, DataManager.getInstance().getDataContext(this.getContentPane()), ActionPlaces.UNKNOWN, action.getTemplatePresentation(), ActionManager.getInstance(), 0);
}
private void openNode(IBreakpoint breakpoint, boolean focus, boolean select) {
if (!((breakpoint instanceof ILocationBreakpoint))) {
return;
}
new EditorNavigator(myProject).shallFocus(focus).shallSelect(select).open(((ILocationBreakpoint) breakpoint).getLocation().getNodePointer());
}
@Nullable
@Override
protected JComponent createCenterPanel() {
this.getWindow().addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
saveState();
}
});
return myMainPanel;
}
@Nullable
@NonNls
@Override
protected String getDimensionServiceKey() {
return BreakpointsBrowserDialog.class.getName();
}
@Override
@NotNull
protected Action[] createActions() {
return new Action[]{getOKAction()};
}
@Override
@Nullable
public Object getData(@NonNls String dataId) {
if (BreakpointsUtil.MPS_BREAKPOINTS_BROWSER_DIALOG.is(dataId)) {
return this;
}
return myViews[myCurrentViewIndex].getData(dataId);
}
@Override
public void dispose() {
for (BreakpointsView view : myViews) {
view.dispose();
}
myBreakpointsManager.removeChangeListener(myBreakpointManagerListener);
super.dispose();
}
}