diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java index 75d9a81edc62..a989065def91 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java @@ -18,6 +18,7 @@ package com.intellij.debugger.settings; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.ui.JavaDebuggerSupport; import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.OptionsBundle; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.project.Project; import com.intellij.ui.classFilter.ClassFilterEditor; @@ -75,7 +76,7 @@ public class DebuggerSteppingConfigurable implements SearchableConfigurable, Con } public String getDisplayName() { - return DebuggerBundle.message("debugger.stepping.configurable.display.name"); + return OptionsBundle.message("options.java.display.name"); } @NotNull 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 32d024f07de1..0e5a9230fe72 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -350,7 +350,6 @@ public class JavaDebuggerSupport extends DebuggerSupport { @Override public Collection getConfigurables() { final ArrayList configurables = new ArrayList(); - configurables.add(new DebuggerSteppingConfigurable()); configurables.add(new UserRenderersConfigurable(null)); configurables.add(new DebuggerHotswapConfigurable()); return configurables; @@ -367,16 +366,16 @@ public class JavaDebuggerSupport extends DebuggerSupport { switch (category) { case DATA_VIEWS: return Collections.singletonList(new DebuggerDataViewsConfigurable(null)); + case STEPPING: + return Collections.singletonList(new DebuggerSteppingConfigurable()); } return Collections.emptyList(); } @Override public void applied(@NotNull XDebuggerSettings.Category category) { - switch (category) { - case DATA_VIEWS: - NodeRendererSettings.getInstance().fireRenderersChanged(); - break; + if (category == XDebuggerSettings.Category.DATA_VIEWS) { + NodeRendererSettings.getInstance().fireRenderersChanged(); } } } diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties index 7c0ea2b59628..dd88b8304e0a 100644 --- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties +++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties @@ -2,6 +2,7 @@ xdebugger.colors.page.name=Debugger debugger.configurable.display.name=Debugger debugger.dataViews.display.name=Data Views +debugger.stepping.display.name=Stepping xdebugger.default.content.title=Debug xdebugger.debugger.tab.title=Debugger diff --git a/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java b/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java index 884a11711992..43aa9b37b510 100644 --- a/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java +++ b/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java @@ -48,6 +48,10 @@ public class VerticalFlowLayout extends FlowLayout implements Serializable { this(alignment, 5, 5, fillHorizontally, fillVertically); } + public VerticalFlowLayout(int hGap, int vGap) { + this(TOP, hGap, vGap, true, false); + } + public VerticalFlowLayout(@VerticalFlowAlignment int alignment, int hGap, int vGap, boolean fillHorizontally, boolean fillVertically) { setAlignment(alignment); this.hGap = hGap; diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java index 1c0afe84d41c..9546278edf87 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -35,7 +35,17 @@ import org.jetbrains.annotations.Nullable; */ public abstract class XDebuggerSettings implements PersistentStateComponent { public enum Category { - DATA_VIEWS + DATA_VIEWS(true), STEPPING(true); + + private final boolean separatePage; + + Category(boolean separatePage) { + this.separatePage = separatePage; + } + + public boolean isSeparatePage() { + return separatePage; + } } public static final ExtensionPointName EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.settings"); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java index e85f5a0e0778..d140a74f35c8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java @@ -16,138 +16,38 @@ package com.intellij.xdebugger.impl.settings; import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.options.SearchableConfigurable; -import com.intellij.ui.IdeBorderFactory; import com.intellij.xdebugger.XDebuggerBundle; -import com.intellij.xdebugger.impl.DebuggerSupport; import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.awt.*; -import java.util.List; - -class DataViewsConfigurable implements SearchableConfigurable.Parent { - private DataViewsConfigurableUi root; - private Configurable[] children; - - private JComponent component; - - @Override - public boolean hasOwnContent() { - return true; - } - - @Override - public boolean isVisible() { - return true; - } - - @Override - public Configurable[] getConfigurables() { - if (children == null) { - List configurables = DebuggerConfigurableProvider.getConfigurables(XDebuggerSettings.Category.DATA_VIEWS); - children = configurables.toArray(new Configurable[configurables.size()]); - } - return children.length == 1 ? DebuggerConfigurable.EMPTY_CONFIGURABLES : children; - } +class DataViewsConfigurable extends SubCompositeConfigurable implements Configurable.NoScroll { @NotNull @Override public String getId() { return "debugger.dataViews"; } - @Nullable - @Override - public Runnable enableSearch(String option) { - return null; - } - @Nls @Override public String getDisplayName() { return XDebuggerBundle.message("debugger.dataViews.display.name"); } - @Nullable @Override - public String getHelpTopic() { - getConfigurables(); - return children.length == 1 ? children[0].getHelpTopic() : null; + protected DataViewsConfigurableUi createRootUi() { + return new DataViewsConfigurableUi(); } - @Nullable + @NotNull @Override - public JComponent createComponent() { - if (component == null) { - if (root == null) { - root = new DataViewsConfigurableUi(); - } - - getConfigurables(); - if (children.length == 1) { - JPanel panel = new JPanel(new BorderLayout(0, IdeBorderFactory.TITLED_BORDER_BOTTOM_INSET)); - panel.add(root.getComponent(), BorderLayout.NORTH); - Configurable configurable = children[0]; - JComponent configurableComponent = configurable.createComponent(); - assert configurableComponent != null; - configurableComponent.setBorder(IdeBorderFactory.createTitledBorder(configurable.getDisplayName(), false)); - panel.add(configurableComponent, BorderLayout.CENTER); - component = panel; - } - else { - component = root.getComponent(); - } - } - return component; + protected XDebuggerSettings.Category getCategory() { + return XDebuggerSettings.Category.DATA_VIEWS; } + @NotNull @Override - public boolean isModified() { - if (root != null && root.isModified(XDebuggerSettingsManager.getInstanceImpl().getDataViewSettings())) { - return true; - } - else { - return children.length == 1 && children[0].isModified(); - } - } - - @Override - public void apply() throws ConfigurationException { - if (root != null) { - root.apply(XDebuggerSettingsManager.getInstanceImpl().getDataViewSettings()); - for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) { - support.getSettingsPanelProvider().applied(XDebuggerSettings.Category.DATA_VIEWS); - } - } - - if (children.length == 1) { - children[0].apply(); - } - } - - @Override - public void reset() { - if (root != null) { - root.reset(XDebuggerSettingsManager.getInstanceImpl().getDataViewSettings()); - } - if (children.length == 1) { - children[0].reset(); - } - } - - @Override - public void disposeUIResources() { - root = null; - component = null; - - if (children.length == 1) { - children[0].disposeUIResources(); - } - children = null; + protected XDebuggerDataViewSettings getSettings() { + return XDebuggerSettingsManager.getInstanceImpl().getDataViewSettings(); } } \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java index bff0d2236f7f..59d72fd24a3d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java @@ -20,6 +20,7 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.impl.DebuggerSupport; +import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -70,6 +71,11 @@ public class DebuggerConfigurable implements SearchableConfigurable.Parent { List configurables = new ArrayList(); configurables.add(new DataViewsConfigurable()); + List steppingConfigurables = DebuggerConfigurableProvider.getConfigurables(XDebuggerSettings.Category.STEPPING, providers); + if (!steppingConfigurables.isEmpty()) { + configurables.add(new SteppingConfigurable(steppingConfigurables)); + } + Configurable rootConfigurable = null; for (DebuggerSettingsPanelProvider provider : providers) { configurables.addAll(provider.getConfigurables()); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java index 3983e7677e78..f66bd6797be2 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java @@ -23,6 +23,7 @@ import com.intellij.xdebugger.impl.DebuggerSupport; import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jetbrains.annotations.NotNull; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -65,14 +66,21 @@ public class DebuggerConfigurableProvider extends ConfigurableProvider { @NotNull static List getConfigurables(@NotNull XDebuggerSettings.Category category) { List providers = getSortedProviders(); - if (providers.isEmpty()) { - return Collections.emptyList(); - } + return providers.isEmpty() ? Collections.emptyList() : getConfigurables(category, providers); + } - List configurables = new SmartList(); + @NotNull + static List getConfigurables(@NotNull XDebuggerSettings.Category category, @NotNull List providers) { + List configurables = null; for (DebuggerSettingsPanelProvider provider : providers) { - configurables.addAll(provider.getConfigurable(category)); + Collection providerConfigurables = provider.getConfigurable(category); + if (!providerConfigurables.isEmpty()) { + if (configurables == null) { + configurables = new SmartList(); + } + configurables.addAll(providerConfigurables); + } } - return configurables.isEmpty() ? Collections.emptyList() : configurables; + return ContainerUtil.isEmpty(configurables) ? Collections.emptyList() : configurables; } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java new file mode 100644 index 000000000000..eca20339a2d8 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 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.settings; + +import com.intellij.openapi.options.Configurable; +import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.settings.XDebuggerSettings; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +class SteppingConfigurable extends SubCompositeConfigurable implements Configurable.NoScroll { + public SteppingConfigurable(@NotNull List configurables) { + assert !configurables.isEmpty(); + children = configurables.toArray(new Configurable[configurables.size()]); + } + + @NotNull + @Override + public String getId() { + return "debugger.stepping"; + } + + @Nls + @Override + public String getDisplayName() { + return XDebuggerBundle.message("debugger.stepping.display.name"); + } + + @Override + protected DataViewsConfigurableUi createRootUi() { + return null; + } + + @NotNull + @Override + protected XDebuggerSettings.Category getCategory() { + return XDebuggerSettings.Category.STEPPING; + } +} \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java new file mode 100644 index 000000000000..a9c5ec6db4a6 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java @@ -0,0 +1,178 @@ +/* + * Copyright 2000-2014 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.settings; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SearchableConfigurable; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.xdebugger.impl.DebuggerSupport; +import com.intellij.xdebugger.settings.XDebuggerSettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.List; + +abstract class SubCompositeConfigurable implements SearchableConfigurable.Parent { + protected DataViewsConfigurableUi root; + protected Configurable[] children; + protected JComponent rootComponent; + + @Override + public boolean hasOwnContent() { + return getCategory() != XDebuggerSettings.Category.STEPPING; + } + + @Override + public boolean isVisible() { + return true; + } + + @Nullable + @Override + public Runnable enableSearch(String option) { + return null; + } + + @Nullable + @Override + public String getHelpTopic() { + getConfigurables(); + return children != null && children.length == 1 ? children[0].getHelpTopic() : null; + } + + @Override + public final void disposeUIResources() { + root = null; + rootComponent = null; + + if (isChildrenMerged()) { + for (Configurable child : children) { + child.reset(); + } + } + children = null; + } + + protected XDebuggerDataViewSettings getSettings() { + return null; + } + + @Nullable + protected abstract DataViewsConfigurableUi createRootUi(); + + @NotNull + protected abstract XDebuggerSettings.Category getCategory(); + + private boolean isChildrenMerged() { + return children != null && (!getCategory().isSeparatePage() || children.length == 1); + } + + @Override + public final Configurable[] getConfigurables() { + if (children == null) { + List configurables = DebuggerConfigurableProvider.getConfigurables(getCategory()); + children = configurables.toArray(new Configurable[configurables.size()]); + } + return isChildrenMerged() ? DebuggerConfigurable.EMPTY_CONFIGURABLES : children; + } + + @Nullable + @Override + public final JComponent createComponent() { + if (rootComponent == null) { + if (root == null) { + root = createRootUi(); + } + + getConfigurables(); + if (isChildrenMerged()) { + if (children.length == 0) { + rootComponent = root == null ? null : root.getComponent(); + } + else if (root == null && children.length == 1) { + rootComponent = children[0].createComponent(); + } + else { + JPanel panel = new JPanel(new VerticalFlowLayout(0, IdeBorderFactory.TITLED_BORDER_BOTTOM_INSET)); + if (root != null) { + panel.add(root.getComponent()); + } + for (Configurable child : children) { + JComponent component = child.createComponent(); + if (component != null) { + component.setBorder(IdeBorderFactory.createTitledBorder(child.getDisplayName(), false)); + panel.add(component); + } + } + rootComponent = panel; + } + } + else { + rootComponent = root == null ? null : root.getComponent(); + } + } + return rootComponent; + } + + @Override + public final void reset() { + if (root != null) { + root.reset(getSettings()); + } + + if (isChildrenMerged()) { + for (Configurable child : children) { + child.reset(); + } + } + } + + @Override + public final boolean isModified() { + if (root != null && root.isModified(getSettings())) { + return true; + } + else if (isChildrenMerged()) { + for (Configurable child : children) { + if (child.isModified()) { + return true; + } + } + } + return false; + } + + @Override + public final void apply() throws ConfigurationException { + if (root != null) { + root.apply(getSettings()); + for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) { + support.getSettingsPanelProvider().applied(getCategory()); + } + } + + if (isChildrenMerged()) { + for (Configurable child : children) { + if (child.isModified()) { + child.apply(); + } + } + } + } +} \ No newline at end of file diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties index 26d078746bef..0b7069199dcc 100644 --- a/resources-en/src/messages/DebuggerBundle.properties +++ b/resources-en/src/messages/DebuggerBundle.properties @@ -206,7 +206,6 @@ label.compound.renderer.configurable.table.header.name=Name label.compound.renderer.configurable.table.header.expression=Expression debugger.launching.configurable.display.name=Launching debugger.hotswap.configurable.display.name=HotSwap -debugger.stepping.configurable.display.name=Stepping label.debugger.launching.configurable.hide.window=Hide debug &window on process termination label.debugger.focusAppOnBreakpoint=Focus application on breakpoint label.debugger.hotswap.configurable.hotswap.background=Reload classes in &background