breakpoints ui. tree nodes grouping.

This commit is contained in:
andrey.zaytsev
2012-05-28 05:09:40 +04:00
parent 9f0dc8a4a3
commit 616c8af5c6
16 changed files with 539 additions and 200 deletions
@@ -214,8 +214,10 @@ public class JavaDebuggerSupport extends DebuggerSupport {
}
@Override
public void provideBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules) {
public void createBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules) {
rules.add(new XBreakpointGroupingByCategoryRule());
rules.add(new XBreakpointGroupingByPackageRule());
rules.add(new XBreakpointGroupingByClassRule());
}
@Override
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.debugger.ui;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class XBreakpointClassGroup extends XBreakpointGroup {
private static final String DEFAULT_PACKAGE_NAME = DebuggerBundle.message("default.package.name");
private String myPackageName;
private String myClassName;
public XBreakpointClassGroup(@Nullable String packageName, String className) {
myPackageName = packageName != null ? packageName : DEFAULT_PACKAGE_NAME;
myClassName = className;
}
@Override
public Icon getIcon(boolean isOpen) {
return PlatformIcons.CLASS_ICON;
}
@NotNull
@Override
public String getName() {
return getClassName();
}
@NotNull
public String getPackageName() {
return myPackageName;
}
@NotNull
public String getClassName() {
return myClassName;
}
}
@@ -22,18 +22,16 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* Created with IntelliJ IDEA.
* User: zajac
* Date: 23.05.12
* Time: 16:24
* To change this template use File | Settings | File Templates.
*/
class XBreakpointGroupingByCategoryRule<B> extends XBreakpointGroupingRule<B, XBreakpointCategoryGroup> {
XBreakpointGroupingByCategoryRule() {
super("XBreakpointGroupingByCategoryRule", "Type");
}
@Override
public boolean isAlwaysEnabled() {
return true;
}
@Override
public XBreakpointCategoryGroup getGroup(@NotNull B b, @NotNull Collection<XBreakpointCategoryGroup> groups) {
if (b instanceof Breakpoint) {
@@ -0,0 +1,53 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.debugger.ui;
import com.intellij.debugger.ui.breakpoints.Breakpoint;
import com.intellij.debugger.ui.breakpoints.BreakpointFactory;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
class XBreakpointGroupingByClassRule<B> extends XBreakpointGroupingRule<B, XBreakpointClassGroup> {
XBreakpointGroupingByClassRule() {
super("XBreakpointGroupingByClassRule", "Group by Class");
}
@Override
public boolean isAlwaysEnabled() {
return false;
}
@Override
public XBreakpointClassGroup getGroup(@NotNull B b, @NotNull Collection<XBreakpointClassGroup> groups) {
if (b instanceof Breakpoint) {
final Breakpoint breakpoint = (Breakpoint)b;
String className = breakpoint.getShortClassName();
String packageName = breakpoint.getPackageName();
if (className == null) {
return null;
}
for (XBreakpointClassGroup group : groups) {
if (group.getClassName().equals(className) && group.getPackageName().equals(packageName)) {
return group;
}
}
return new XBreakpointClassGroup(packageName, className);
}
return null;
}
}
@@ -0,0 +1,54 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.debugger.ui;
import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter;
import com.intellij.debugger.ui.breakpoints.ExceptionBreakpoint;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class XBreakpointGroupingByPackageRule<B> extends XBreakpointGroupingRule<B, XBreakpointPackageGroup> {
protected XBreakpointGroupingByPackageRule() {
super("XBreakpointGroupingByPackageRule", "Group by package");
}
@Override
public XBreakpointPackageGroup getGroup(@NotNull B breakpoint, @NotNull Collection<XBreakpointPackageGroup> groups) {
String packageName = null;
if (breakpoint instanceof BreakpointWithHighlighter) {
packageName = ((BreakpointWithHighlighter)breakpoint).getPackageName();
}
else if (breakpoint instanceof ExceptionBreakpoint) {
packageName = ((ExceptionBreakpoint)breakpoint).getPackageName();
}
if (packageName == null) {
return null;
}
for (XBreakpointPackageGroup group : groups) {
if (StringUtil.equals(group.getPackageName(), packageName)) {
return group;
}
}
return new XBreakpointPackageGroup(packageName);
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.debugger.ui;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroup;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class XBreakpointPackageGroup extends XBreakpointGroup {
private static final String DEFAULT_PACKAGE_NAME = DebuggerBundle.message("default.package.name");
private String myPackageName;
public XBreakpointPackageGroup(String packageName) {
myPackageName = packageName;
}
@Override
public Icon getIcon(boolean isOpen) {
return PlatformIcons.PACKAGE_ICON;
}
@NotNull
@Override
public String getName() {
String packageName = getPackageName();
return StringUtil.isEmpty(packageName) ? DEFAULT_PACKAGE_NAME : packageName;
}
@NotNull
public String getPackageName() {
return myPackageName;
}
}
@@ -679,7 +679,7 @@ public class BreakpointTree extends CheckboxTree {
if (!(descriptor instanceof BreakpointDescriptor)) {
return node;
}
final Breakpoint breakpoint = ((BreakpointDescriptor)descriptor).getBreakpoint();
final String packageName;
if (breakpoint instanceof ExceptionBreakpoint) {
@@ -45,6 +45,7 @@ public abstract class CheckboxAction extends ToggleAction implements CustomCompo
public JComponent createCustomComponent(Presentation presentation) {
myCheckBox = new JCheckBox(presentation.getText());
myCheckBox.setOpaque(false);
myCheckBox.setToolTipText(presentation.getDescription());
myCheckBox.setMnemonic(presentation.getMnemonic());
myCheckBox.setDisplayedMnemonicIndex(presentation.getDisplayedMnemonicIndex());
@@ -36,11 +36,6 @@ public abstract class XBreakpointGroup implements Comparable<XBreakpointGroup> {
return getName().compareTo(o.getName());
}
@Override
public boolean equals(Object obj) {
return obj instanceof XBreakpointGroup && compareTo((XBreakpointGroup)obj) == 0;
}
@Override
public int hashCode() {
return getName().hashCode();
@@ -33,6 +33,11 @@ public class XBreakpointGroupingByTypeRule<B> extends XBreakpointGroupingRule<B,
super("XBreakpointGroupingByTypeRule", "Type");
}
@Override
public boolean isAlwaysEnabled() {
return true;
}
@Override
public XBreakpointTypeGroup getGroup(@NotNull B b, @NotNull Collection<XBreakpointTypeGroup> groups) {
if (b instanceof XBreakpoint) {
@@ -29,6 +29,10 @@ public abstract class XBreakpointGroupingRule<B, G extends XBreakpointGroup> {
private final String myId;
private final String myPresentableName;
public boolean isAlwaysEnabled() {
return false;
}
protected XBreakpointGroupingRule(final @NotNull @NonNls String id, final @NonNls @Nls String presentableName) {
myId = id;
myPresentableName = presentableName;
@@ -50,7 +50,7 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider<XBreakpoin
private List<MyXBreakpointListener> myListeners = new CopyOnWriteArrayList<MyXBreakpointListener>();
@Override
public void provideBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules) {
public void createBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules) {
rules.add(new XBreakpointGroupingByTypeRule());
rules.add(new XBreakpointFileGroupingRule());
}
@@ -95,15 +95,42 @@ public class BreakpointItemsTree extends CheckboxTree {
@NotNull
private CheckedTreeNode getParentNode(final BreakpointItem breakpoint) {
CheckedTreeNode parent = myRoot;
XBreakpointGroup parentGroup = null;
for (int i = 0; i < myGroupingRules.size(); i++) {
XBreakpointGroup group = getGroup(breakpoint.getBreakpoint(), myGroupingRules.get(i));
XBreakpointGroup group = getGroup(parentGroup, breakpoint, myGroupingRules.get(i));
if (group != null) {
parent = getOrCreateGroupNode(parent, group, i);
parentGroup = group;
}
}
return parent;
}
@Nullable
private XBreakpointGroup getGroup(XBreakpointGroup parentGroup, final BreakpointItem breakpoint, final XBreakpointGroupingRule groupingRule) {
//noinspection unchecked
Collection<XBreakpointGroup> groups = myGroups.get(groupingRule);
if (groups == null) {
groups = Collections.emptyList();
}
Collection<XBreakpointGroup> filtered = new ArrayList<XBreakpointGroup>();
for (XBreakpointGroup group : groups) {
TreeNode parent = myGroupNodes.get(group).getParent();
if ((parentGroup == null && parent == myRoot) || ((BreakpointsGroupNode)parent).getGroup() == parentGroup) {
filtered.add(group);
}
}
XBreakpointGroup group = groupingRule.getGroup(breakpoint.getBreakpoint(), filtered);
if (group != null) {
myGroups.put(groupingRule, group);
}
return group;
}
private <G extends XBreakpointGroup> BreakpointsGroupNode<G> getOrCreateGroupNode(CheckedTreeNode parent, final G group,
final int level) {
//noinspection unchecked
@@ -123,20 +150,6 @@ public class BreakpointItemsTree extends CheckboxTree {
}
}
@Nullable
private XBreakpointGroup getGroup(final Object breakpoint, final XBreakpointGroupingRule groupingRule) {
//noinspection unchecked
Collection<XBreakpointGroup> groups = myGroups.get(groupingRule);
if (groups == null) {
groups = Collections.emptyList();
}
XBreakpointGroup group = groupingRule.getGroup(breakpoint, groups);
if (group != null) {
myGroups.put(groupingRule, group);
}
return group;
}
@Override
protected void onNodeStateChanged(final CheckedTreeNode node) {
if (node instanceof BreakpointItemNode) {
@@ -144,7 +157,7 @@ public class BreakpointItemsTree extends CheckboxTree {
}
}
public void setGroupingRules(List<XBreakpointGroupingRule> groupingRules) {
public void setGroupingRules(Collection<XBreakpointGroupingRule> groupingRules) {
List<BreakpointItem> selectedBreakpoints = getSelectedBreakpoints();
List<BreakpointItem> allBreakpoints = new ArrayList<BreakpointItem>(myNodes.keySet());
@@ -0,0 +1,269 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.ToggleAction;
import com.intellij.openapi.actionSystem.ex.CheckboxAction;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ListUtil;
import com.intellij.ui.popup.util.MasterDetailPopupBuilder;
import com.intellij.util.IconUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.HashSet;
import com.intellij.xdebugger.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import com.intellij.xdebugger.ui.DebuggerColors;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class BreakpointMasterDetailPopupBuilder {
private Project myProject;
private MasterDetailPopupBuilder myPopupBuilder;
private Collection<BreakpointPanelProvider> myBreakpointsPanelProviders;
private BreakpointItemsTree myTree;
private final List<XBreakpointGroupingRule> myRulesAvailable = new ArrayList<XBreakpointGroupingRule>();
private final Set<XBreakpointGroupingRule> myRulesEnabled = new HashSet<XBreakpointGroupingRule>();
@Nullable private Object myInitialBreakpoint;
public void setInitialBreakpoint(@Nullable Object initialBreakpoint) {
myInitialBreakpoint = initialBreakpoint;
}
public BreakpointMasterDetailPopupBuilder(Project project) {
myProject = project;
}
public JBPopup createPopup() {
myPopupBuilder = new MasterDetailPopupBuilder(myProject);
for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
provider.createBreakpointsGroupingRules(myRulesAvailable);
}
for (XBreakpointGroupingRule rule : myRulesAvailable) {
if (rule.isAlwaysEnabled()) {
myRulesEnabled.add(rule);
}
}
DefaultActionGroup actions = createActions();
myTree = BreakpointItemsTree.createTree(getEnabledRulesList());
final ArrayList<BreakpointItem> breakpoints = collectItems();
myTree.buildTree(breakpoints);
final BreakpointPanelProvider.BreakpointsListener listener = new BreakpointPanelProvider.BreakpointsListener() {
@Override
public void breakpointsChanged() {
myTree.buildTree(collectItems());
}
};
for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
provider.addListener(listener, myProject);
}
final JBPopup popup = myPopupBuilder.
setActionsGroup(actions).
setTree(myTree).
setDelegate(new MasterDetailPopupBuilder.Delegate() {
@Override
public String getTitle() {
return "Breakpoints";
}
@Override
public void handleMnemonic(KeyEvent e, Project project, JBPopup popup) {
//To change body of implemented methods use File | Settings | File Templates.
}
public JComponent createAccessoryView(Project project) {
return new JCheckBox();
}
@Override
public Object[] getSelectedItemsInTree() {
final List<BreakpointItem> res = myTree.getSelectedBreakpoints();
return res.toArray(new Object[res.size()]);
}
}).setCloseOnEnter(false).createMasterDetailPopup();
myTree.setBorder(IdeBorderFactory.createBorder());
myPopupBuilder.getDetailView().setScheme(createScheme());
myTree.setDelegate(new BreakpointItemsTree.BreakpointItemsTreeDelegate() {
@Override
public void execute(BreakpointItem item) {
item.execute(myProject, popup);
}
});
initSelection(breakpoints);
popup.addListener(new JBPopupListener() {
@Override
public void beforeShown(LightweightWindowEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void onClosed(LightweightWindowEvent event) {
for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
provider.removeListener(listener);
}
}
});
return popup;
}
void initSelection(ArrayList<BreakpointItem> breakpoints) {
boolean found = false;
for (BreakpointItem breakpoint : breakpoints) {
if (breakpoint.getBreakpoint() == myInitialBreakpoint) {
myTree.selectBreakpointItem(breakpoint);
found = true;
break;
}
}
if (!found && !breakpoints.isEmpty()) {
myTree.selectBreakpointItem(breakpoints.get(0));
}
}
EditorColorsScheme createScheme() {
final EditorColorsScheme scheme =
new EditorColorsSchemeImpl(EditorColorsManager.getInstance().getGlobalScheme(), DefaultColorSchemesManager.getInstance());
scheme.setName("abc");
scheme
.setAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES, new TextAttributes(Color.black, Color.CYAN, null, EffectType.BOXED, Font.BOLD));
return scheme;
}
DefaultActionGroup createActions() {
DefaultActionGroup actions = new DefaultActionGroup();
final DefaultActionGroup breakpointTypes = new DefaultActionGroup();
for (BreakpointPanelProvider provider : myBreakpointsPanelProviders) {
breakpointTypes.addAll(provider.getAddBreakpointActions(myProject));
}
actions.add(new AnAction("Add Breakpoint", null, IconUtil.getAddIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
JBPopupFactory.getInstance()
.createActionGroupPopup(null, breakpointTypes, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, false)
.showUnderneathOf(myPopupBuilder.getActionToolbar().getComponent());
}
});
actions.add(new AnAction("Remove Breakpoint", null, PlatformIcons.DELETE_ICON) {
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(MasterDetailPopupBuilder.allowedToRemoveItems(myPopupBuilder.getSelectedItems()));
}
@Override
public void actionPerformed(AnActionEvent e) {
myPopupBuilder.removeSelectedItems(myProject);
}
});
for (XBreakpointGroupingRule rule : myRulesAvailable) {
if (!rule.isAlwaysEnabled()) {
actions.add(new ToggleBreakpointGroupingRuleEnabledAction(rule));
}
}
return actions;
}
ArrayList<BreakpointItem> collectItems() {
ArrayList<BreakpointItem> items = new ArrayList<BreakpointItem>();
for (BreakpointPanelProvider panelProvider : myBreakpointsPanelProviders) {
panelProvider.provideBreakpointItems(myProject, items);
}
return items;
}
public void setBreakpointsPanelProviders(Collection<BreakpointPanelProvider> breakpointsPanelProviders) {
myBreakpointsPanelProviders = breakpointsPanelProviders;
}
private class ToggleBreakpointGroupingRuleEnabledAction extends CheckboxAction {
private XBreakpointGroupingRule myRule;
public ToggleBreakpointGroupingRuleEnabledAction(XBreakpointGroupingRule rule) {
super(rule.getPresentableName());
myRule = rule;
getTemplatePresentation().setText(rule.getPresentableName());
}
@Override
public boolean isSelected(AnActionEvent e) {
return myRulesEnabled.contains(myRule);
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
if (state) {
myRulesEnabled.add(myRule);
}
else {
myRulesEnabled.remove(myRule);
}
myTree.setGroupingRules(getEnabledRulesList());
}
}
private List<XBreakpointGroupingRule> getEnabledRulesList() {
List<XBreakpointGroupingRule> result = new ArrayList<XBreakpointGroupingRule>();
for (XBreakpointGroupingRule rule : myRulesAvailable) {
if (myRulesEnabled.contains(rule)) {
result.add(rule);
}
}
return result;
}
}
@@ -32,7 +32,7 @@ import java.util.Collection;
*/
public abstract class BreakpointPanelProvider<B> {
public abstract void provideBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules);
public abstract void createBreakpointsGroupingRules(Collection<XBreakpointGroupingRule> rules);
public interface BreakpointsListener {
void breakpointsChanged();
@@ -15,44 +15,19 @@
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.ex.DefaultColorSchemesManager;
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.popup.util.MasterDetailPopupBuilder;
import com.intellij.util.IconUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.xdebugger.breakpoints.ui.BreakpointItem;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule;
import com.intellij.xdebugger.impl.DebuggerSupport;
import com.intellij.xdebugger.ui.DebuggerColors;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.*;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: zajac
* Date: 5/9/12
* Time: 3:11 AM
* To change this template use File | Settings | File Templates.
*/
public class BreakpointsMasterDetailPopupFactory {
private final List<BreakpointPanelProvider> myBreakpointPanelProviders;
@@ -77,148 +52,9 @@ public class BreakpointsMasterDetailPopupFactory {
}
public JBPopup createPopup(@Nullable Object initialBreakpoint) {
MasterDetailPopupBuilder popupBuilder = new MasterDetailPopupBuilder(myProject);
DefaultActionGroup actions = getActions(popupBuilder);
final Collection<XBreakpointGroupingRule> rules = new ArrayList<XBreakpointGroupingRule>();
for (BreakpointPanelProvider provider : myBreakpointPanelProviders) {
provider.provideBreakpointsGroupingRules(rules);
}
final BreakpointItemsTree tree = BreakpointItemsTree.createTree(rules);
final ArrayList<BreakpointItem> breakpoints = collectItems();
tree.buildTree(breakpoints);
final BreakpointPanelProvider.BreakpointsListener listener = new BreakpointPanelProvider.BreakpointsListener() {
@Override
public void breakpointsChanged() {
tree.buildTree(collectItems());
}
};
for (BreakpointPanelProvider provider : myBreakpointPanelProviders) {
provider.addListener(listener, myProject);
}
final JBPopup popup = popupBuilder.
setActionsGroup(actions).
setTree(tree).
setDelegate(new MasterDetailPopupBuilder.Delegate() {
@Override
public String getTitle() {
return "Breakpoints";
}
@Override
public void handleMnemonic(KeyEvent e, Project project, JBPopup popup) {
//To change body of implemented methods use File | Settings | File Templates.
}
public JComponent createAccessoryView(Project project) {
return new JCheckBox();
}
@Override
public Object[] getSelectedItemsInTree() {
final List<BreakpointItem> res = tree.getSelectedBreakpoints();
return res.toArray(new Object[res.size()]);
}
}).setCloseOnEnter(false).createMasterDetailPopup();
tree.setBorder(IdeBorderFactory.createBorder());
popupBuilder.getDetailView().setScheme(createScheme());
tree.setDelegate(new BreakpointItemsTree.BreakpointItemsTreeDelegate() {
@Override
public void execute(BreakpointItem item) {
item.execute(myProject, popup);
}
});
initSelection(initialBreakpoint, tree, breakpoints);
popup.addListener(new JBPopupListener() {
@Override
public void beforeShown(LightweightWindowEvent event) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void onClosed(LightweightWindowEvent event) {
for (BreakpointPanelProvider provider : myBreakpointPanelProviders) {
provider.removeListener(listener);
}
}
});
return popup;
}
private void initSelection(Object initialBreakpoint, BreakpointItemsTree tree, ArrayList<BreakpointItem> breakpoints) {
boolean found = false;
for (BreakpointItem breakpoint : breakpoints) {
if (breakpoint.getBreakpoint() == initialBreakpoint) {
tree.selectBreakpointItem(breakpoint);
found = true;
break;
}
}
if (!found && !breakpoints.isEmpty()) {
tree.selectBreakpointItem(breakpoints.get(0));
}
}
private EditorColorsScheme createScheme() {
final EditorColorsScheme scheme =
new EditorColorsSchemeImpl(EditorColorsManager.getInstance().getGlobalScheme(), DefaultColorSchemesManager.getInstance());
scheme.setName("abc");
scheme.setAttributes(DebuggerColors.BREAKPOINT_ATTRIBUTES, new TextAttributes(Color.black, Color.CYAN, null, EffectType.BOXED, Font.BOLD));
return scheme;
}
private DefaultActionGroup getActions(final MasterDetailPopupBuilder builder) {
DefaultActionGroup actions = new DefaultActionGroup();
final DefaultActionGroup breakpointTypes = new DefaultActionGroup();
for (BreakpointPanelProvider provider : myBreakpointPanelProviders) {
breakpointTypes.addAll(provider.getAddBreakpointActions(myProject));
}
actions.add(new AnAction("Add Breakpoint", null, IconUtil.getAddIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
JBPopupFactory.getInstance()
.createActionGroupPopup(null, breakpointTypes, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, false)
.showUnderneathOf(builder.getActionToolbar().getComponent());
}
});
actions.add(new AnAction("Remove Breakpoint", null, PlatformIcons.DELETE_ICON) {
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabled(MasterDetailPopupBuilder.allowedToRemoveItems(builder.getSelectedItems()));
}
@Override
public void actionPerformed(AnActionEvent e) {
builder.removeSelectedItems(myProject);
}
});
return actions;
}
private ArrayList<BreakpointItem> collectItems() {
ArrayList<BreakpointItem> items = new ArrayList<BreakpointItem>();
for (BreakpointPanelProvider panelProvider : myBreakpointPanelProviders) {
panelProvider.provideBreakpointItems(myProject, items);
}
return items;
BreakpointMasterDetailPopupBuilder builder = new BreakpointMasterDetailPopupBuilder(myProject);
builder.setInitialBreakpoint(initialBreakpoint);
builder.setBreakpointsPanelProviders(myBreakpointPanelProviders);
return builder.createPopup();
}
}