From 616c8af5c682cdf64971a5e77a47157415a5e99e Mon Sep 17 00:00:00 2001 From: "andrey.zaytsev" Date: Mon, 28 May 2012 05:08:53 +0400 Subject: [PATCH] breakpoints ui. tree nodes grouping. --- .../debugger/ui/JavaDebuggerSupport.java | 4 +- .../debugger/ui/XBreakpointClassGroup.java | 58 ++++ .../ui/XBreakpointGroupingByCategoryRule.java | 12 +- .../ui/XBreakpointGroupingByClassRule.java | 53 ++++ .../ui/XBreakpointGroupingByPackageRule.java | 54 ++++ .../debugger/ui/XBreakpointPackageGroup.java | 51 ++++ .../ui/breakpoints/BreakpointTree.java | 2 +- .../actionSystem/ex/CheckboxAction.java | 1 + .../breakpoints/ui/XBreakpointGroup.java | 5 - .../ui/XBreakpointGroupingByTypeRule.java | 5 + .../ui/XBreakpointGroupingRule.java | 4 + .../breakpoints/XBreakpointPanelProvider.java | 2 +- .../breakpoints/ui/BreakpointItemsTree.java | 45 +-- .../BreakpointMasterDetailPopupBuilder.java | 269 ++++++++++++++++++ .../ui/BreakpointPanelProvider.java | 2 +- .../BreakpointsMasterDetailPopupFactory.java | 172 +---------- 16 files changed, 539 insertions(+), 200 deletions(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java create mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java create mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java create mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java create mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointMasterDetailPopupBuilder.java diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index 675ba7211a7a..2dda3d70feb4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -214,8 +214,10 @@ public class JavaDebuggerSupport extends DebuggerSupport { } @Override - public void provideBreakpointsGroupingRules(Collection rules) { + public void createBreakpointsGroupingRules(Collection rules) { rules.add(new XBreakpointGroupingByCategoryRule()); + rules.add(new XBreakpointGroupingByPackageRule()); + rules.add(new XBreakpointGroupingByClassRule()); } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java new file mode 100644 index 000000000000..5a81258caaa4 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointClassGroup.java @@ -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; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java index 477417f54ee7..7b8fe5d4b767 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByCategoryRule.java @@ -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 extends XBreakpointGroupingRule { XBreakpointGroupingByCategoryRule() { super("XBreakpointGroupingByCategoryRule", "Type"); } + @Override + public boolean isAlwaysEnabled() { + return true; + } + @Override public XBreakpointCategoryGroup getGroup(@NotNull B b, @NotNull Collection groups) { if (b instanceof Breakpoint) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java new file mode 100644 index 000000000000..aa28158221ae --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java @@ -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 extends XBreakpointGroupingRule { + XBreakpointGroupingByClassRule() { + super("XBreakpointGroupingByClassRule", "Group by Class"); + } + + @Override + public boolean isAlwaysEnabled() { + return false; + } + + @Override + public XBreakpointClassGroup getGroup(@NotNull B b, @NotNull Collection 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; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java new file mode 100644 index 000000000000..a9f43cc444ee --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java @@ -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 extends XBreakpointGroupingRule { + + protected XBreakpointGroupingByPackageRule() { + super("XBreakpointGroupingByPackageRule", "Group by package"); + } + + @Override + public XBreakpointPackageGroup getGroup(@NotNull B breakpoint, @NotNull Collection 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); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java new file mode 100644 index 000000000000..0d193a20255b --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointPackageGroup.java @@ -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; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointTree.java index d99efc55bbb2..2d39fe03ead5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointTree.java @@ -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) { diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java index 90f095f062ee..0af1dca66998 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ex/CheckboxAction.java @@ -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()); diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroup.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroup.java index ffa9c892f209..03d32f3fd8db 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroup.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroup.java @@ -36,11 +36,6 @@ public abstract class XBreakpointGroup implements Comparable { 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(); diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java index ec64306ea25a..d843b375833c 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingByTypeRule.java @@ -33,6 +33,11 @@ public class XBreakpointGroupingByTypeRule extends XBreakpointGroupingRule groups) { if (b instanceof XBreakpoint) { diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java index b152b869d3e7..477dc9ce697c 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/ui/XBreakpointGroupingRule.java @@ -29,6 +29,10 @@ public abstract class XBreakpointGroupingRule { 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; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java index 5529ba0af3d4..02ca25d275f0 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointPanelProvider.java @@ -50,7 +50,7 @@ public class XBreakpointPanelProvider extends BreakpointPanelProvider myListeners = new CopyOnWriteArrayList(); @Override - public void provideBreakpointsGroupingRules(Collection rules) { + public void createBreakpointsGroupingRules(Collection rules) { rules.add(new XBreakpointGroupingByTypeRule()); rules.add(new XBreakpointFileGroupingRule()); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItemsTree.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItemsTree.java index 7392d9e24881..a06d9c859f09 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItemsTree.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointItemsTree.java @@ -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 groups = myGroups.get(groupingRule); + if (groups == null) { + groups = Collections.emptyList(); + } + + + Collection filtered = new ArrayList(); + 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 BreakpointsGroupNode 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 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 groupingRules) { + public void setGroupingRules(Collection groupingRules) { List selectedBreakpoints = getSelectedBreakpoints(); List allBreakpoints = new ArrayList(myNodes.keySet()); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointMasterDetailPopupBuilder.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointMasterDetailPopupBuilder.java new file mode 100644 index 000000000000..1900c8c81c58 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointMasterDetailPopupBuilder.java @@ -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 myBreakpointsPanelProviders; + private BreakpointItemsTree myTree; + private final List myRulesAvailable = new ArrayList(); + + private final Set myRulesEnabled = new HashSet(); + + @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 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 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 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 collectItems() { + ArrayList items = new ArrayList(); + for (BreakpointPanelProvider panelProvider : myBreakpointsPanelProviders) { + panelProvider.provideBreakpointItems(myProject, items); + } + return items; + } + + public void setBreakpointsPanelProviders(Collection 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 getEnabledRulesList() { + List result = new ArrayList(); + for (XBreakpointGroupingRule rule : myRulesAvailable) { + if (myRulesEnabled.contains(rule)) { + result.add(rule); + } + } + return result; + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java index 954a4ddcb564..fc6fdd750d69 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointPanelProvider.java @@ -32,7 +32,7 @@ import java.util.Collection; */ public abstract class BreakpointPanelProvider { - public abstract void provideBreakpointsGroupingRules(Collection rules); + public abstract void createBreakpointsGroupingRules(Collection rules); public interface BreakpointsListener { void breakpointsChanged(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java index e8ddf05d8e57..963bdcc01f19 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/BreakpointsMasterDetailPopupFactory.java @@ -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 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 rules = new ArrayList(); - - for (BreakpointPanelProvider provider : myBreakpointPanelProviders) { - provider.provideBreakpointsGroupingRules(rules); - } - - final BreakpointItemsTree tree = BreakpointItemsTree.createTree(rules); - - final ArrayList 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 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 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 collectItems() { - ArrayList items = new ArrayList(); - for (BreakpointPanelProvider panelProvider : myBreakpointPanelProviders) { - panelProvider.provideBreakpointItems(myProject, items); - } - return items; + BreakpointMasterDetailPopupBuilder builder = new BreakpointMasterDetailPopupBuilder(myProject); + builder.setInitialBreakpoint(initialBreakpoint); + builder.setBreakpointsPanelProviders(myBreakpointPanelProviders); + return builder.createPopup(); } }