IDEA-19061 Integrate the Rearranger-plugin into core-IDE

Grouping rules UI
This commit is contained in:
Denis.Zhdanov
2012-09-27 22:14:47 +04:00
parent fcc87ab35f
commit 2529cf996c
21 changed files with 468 additions and 127 deletions
@@ -95,12 +95,22 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
));
}
private static final Map<ArrangementGroupingType, Set<ArrangementEntryOrderType>> GROUPING_RULES = ContainerUtilRt.newHashMap();
static {
GROUPING_RULES.put(ArrangementGroupingType.GETTERS_AND_SETTERS, EnumSet.noneOf(ArrangementEntryOrderType.class));
GROUPING_RULES.put(ArrangementGroupingType.OVERRIDDEN_METHODS,
EnumSet.of(ArrangementEntryOrderType.BY_NAME, ArrangementEntryOrderType.KEEP));
GROUPING_RULES.put(ArrangementGroupingType.DEPENDENT_METHODS,
EnumSet.of(ArrangementEntryOrderType.BREADTH_FIRST, ArrangementEntryOrderType.DEPTH_FIRST));
}
private static final List<ArrangementGroupingRule> DEFAULT_GROUPING_RULES = new ArrayList<ArrangementGroupingRule>();
static {
DEFAULT_GROUPING_RULES.add(new ArrangementGroupingRule(ArrangementGroupingType.GETTERS_AND_SETTERS));
}
private static final List<StdArrangementMatchRule> DEFAULT_MATCH_RULES = new ArrayList<StdArrangementMatchRule>();
static {
ArrangementModifier[] visibility = {PUBLIC, PROTECTED, PACKAGE_PRIVATE, PRIVATE};
for (ArrangementModifier modifier : visibility) {
@@ -169,7 +179,7 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
}
return Pair.create(newEntryInfo.getEntries().get(0), existingEntriesInfo.getEntries());
}
@NotNull
@Override
public List<JavaElementArrangementEntry> parse(@NotNull PsiElement root,
@@ -183,9 +193,14 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
if (settings != null) {
for (ArrangementGroupingRule rule : settings.getGroupings()) {
switch (rule.getRule()) {
case GETTERS_AND_SETTERS: setupGettersAndSetters(parseInfo); break;
case UTILITY_METHODS: setupUtilityMethods(parseInfo, rule.getOrderType()); break;
case OVERRIDDEN_METHODS: setupOverriddenMethods(parseInfo);
case GETTERS_AND_SETTERS:
setupGettersAndSetters(parseInfo);
break;
case DEPENDENT_METHODS:
setupUtilityMethods(parseInfo, rule.getOrderType());
break;
case OVERRIDDEN_METHODS:
setupOverriddenMethods(parseInfo);
}
}
}
@@ -341,12 +356,22 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
@NotNull
@Override
public List<Set<ArrangementMatchCondition>> getGroupingConditions() {
return UI_GROUPING_RULES;
return Collections.emptyList();
//return UI_GROUPING_RULES;
}
@Nullable
@Override
public StdArrangementSettings getDefaultSettings() {
return DEFAULT_SETTINGS;
}
@Override
public boolean isEnabled(@NotNull ArrangementGroupingType groupingType, @Nullable ArrangementEntryOrderType orderType) {
Set<ArrangementEntryOrderType> orderTypes = GROUPING_RULES.get(groupingType);
if (orderTypes == null) {
return false;
}
return orderType == null || orderTypes.contains(orderType);
}
}
@@ -19,7 +19,7 @@ import org.junit.Test
import static com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType.GETTERS_AND_SETTERS
import static com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType.OVERRIDDEN_METHODS
import static com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType.UTILITY_METHODS
import static com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType.DEPENDENT_METHODS
import static com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier.PUBLIC
import static com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType.BREADTH_FIRST
import static com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType.DEPTH_FIRST
@@ -65,7 +65,7 @@ class Test {
void util11() {}
void service2() { util2(); }
}''',
groups: [group(UTILITY_METHODS, DEPTH_FIRST)],
groups: [group(DEPENDENT_METHODS, DEPTH_FIRST)],
expected: '''\
class Test {
void service1() { util1(); }
@@ -87,7 +87,7 @@ class Test {
void service2() { util2(); util1(); }
void util3() {}
}''',
groups: [group(UTILITY_METHODS, BREADTH_FIRST)],
groups: [group(DEPENDENT_METHODS, BREADTH_FIRST)],
expected: '''\
class Test {
void service1() { util1(); util2(); }
@@ -143,7 +143,7 @@ class Base {
void test4() {}
void test1() { test2(); }</range>
}''',
groups: [group(UTILITY_METHODS, DEPTH_FIRST), group(OVERRIDDEN_METHODS)],
groups: [group(DEPENDENT_METHODS, DEPTH_FIRST), group(OVERRIDDEN_METHODS)],
expected: '''\
class Base {
void base1() {}
@@ -26,6 +26,6 @@ public enum ArrangementGroupingType {
GETTERS_AND_SETTERS,
OVERRIDDEN_METHODS,
UTILITY_METHODS
DEPENDENT_METHODS
}
@@ -16,9 +16,11 @@
package com.intellij.psi.codeStyle.arrangement.settings;
import com.intellij.psi.codeStyle.arrangement.StdArrangementSettings;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -61,6 +63,19 @@ public interface ArrangementStandardSettingsAware {
*/
boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementMatchCondition current);
/**
* Allows to answer if given grouping type (optionally with the given order type) can be used.
*
* @param groupingType target grouping type to check
* @param orderType target order type to check whether it can be used with the given grouping type;
* <code>null</code> to indicate that we want to know if given grouping type can be used in general
* for the languages-specific realisation of this interface
* @return <code>true</code> if given arguments are eligible for the languages-specific realisation of this interface;
* <code>false</code> otherwise
*/
boolean isEnabled(@NotNull ArrangementGroupingType groupingType, @Nullable ArrangementEntryOrderType orderType);
/**
* @return collections of mutual exclusion settings. E.g. not more than one visibility modifier can be used for a single
* java language rule
@@ -16,8 +16,10 @@
package com.intellij.psi.codeStyle.arrangement.settings;
import com.intellij.psi.codeStyle.arrangement.Rearranger;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -48,6 +50,20 @@ public interface ArrangementStandardSettingsRepresentationAware {
@NotNull
String getDisplayValue(@NotNull ArrangementModifier modifier);
/**
* @param groupingType target grouping type
* @return text to show end-user for the given grouping type
*/
@NotNull
String getDisplayValue(@NotNull ArrangementGroupingType groupingType);
/**
* @param orderType target order type
* @return text to show end-user for the given order type
*/
@NotNull
String getDisplayValue(@NotNull ArrangementEntryOrderType orderType);
/**
* Allows to sort given arrangement condition ids ('field', 'class', 'method', 'public', 'static', 'final' etc) before showing
* them to an end-user.
@@ -15,8 +15,12 @@
*/
package com.intellij.psi.codeStyle.arrangement.settings;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
@@ -60,7 +64,8 @@ public class DefaultArrangementSettingsRepresentationManager implements Arrangem
}
}
@NotNull private static final Comparator<Object> COMPARATOR = new Comparator<Object>() {
@NotNull
private static final Comparator<Object> COMPARATOR = new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
if (WEIGHTS.containsKey(o1) && WEIGHTS.containsKey(o2)) {
@@ -78,6 +83,26 @@ public class DefaultArrangementSettingsRepresentationManager implements Arrangem
}
};
private static final Map<ArrangementGroupingType, String> GROUPING_TYPES = ContainerUtil.newHashMap();
static {
GROUPING_TYPES.put(ArrangementGroupingType.GETTERS_AND_SETTERS,
ApplicationBundle.message("arrangement.settings.groups.getters.and.setters.together"));
GROUPING_TYPES.put(ArrangementGroupingType.OVERRIDDEN_METHODS,
ApplicationBundle.message("arrangement.settings.groups.overridden.methods"));
GROUPING_TYPES.put(ArrangementGroupingType.DEPENDENT_METHODS,
ApplicationBundle.message("arrangement.settings.groups.dependent.methods"));
assert GROUPING_TYPES.size() == ArrangementGroupingType.values().length;
}
private static final Map<ArrangementEntryOrderType, String> ORDER_TYPES = ContainerUtil.newHashMap();
static {
ORDER_TYPES.put(ArrangementEntryOrderType.KEEP, ApplicationBundle.message("arrangement.settings.order.type.keep"));
ORDER_TYPES.put(ArrangementEntryOrderType.BY_NAME, ApplicationBundle.message("arrangement.settings.order.type.by.name"));
ORDER_TYPES.put(ArrangementEntryOrderType.DEPTH_FIRST, ApplicationBundle.message("arrangement.settings.order.type.depth.first"));
ORDER_TYPES.put(ArrangementEntryOrderType.BREADTH_FIRST, ApplicationBundle.message("arrangement.settings.order.type.breadth.first"));
assert ORDER_TYPES.size() == ArrangementEntryOrderType.values().length;
}
@NotNull
@Override
public String getDisplayValue(@NotNull ArrangementEntryType type) {
@@ -95,6 +120,18 @@ public class DefaultArrangementSettingsRepresentationManager implements Arrangem
return s.toLowerCase().replace("_", " ");
}
@NotNull
@Override
public String getDisplayValue(@NotNull ArrangementGroupingType groupingType) {
return GROUPING_TYPES.get(groupingType);
}
@NotNull
@Override
public String getDisplayValue(@NotNull ArrangementEntryOrderType orderType) {
return ORDER_TYPES.get(orderType);
}
@NotNull
@Override
public <T> List<T> sort(@NotNull Collection<T> ids) {
@@ -0,0 +1,71 @@
/*
* 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.application.options.codeStyle.arrangement;
import com.intellij.application.options.codeStyle.arrangement.node.ArrangementCheckBoxNode;
import com.intellij.application.options.codeStyle.arrangement.node.ArrangementSectionNode;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* This class is responsible for representing {@link ArrangementGroupingRule grouping rules} at tree structure.
* <p/>
* Thread-safe.
*
* @author Denis Zhdanov
* @since 9/27/12 2:36 PM
*/
public class ArrangementGroupingRulesManager {
@NotNull public static final ArrangementGroupingRulesManager INSTANCE = new ArrangementGroupingRulesManager();
@SuppressWarnings("MethodMayBeStatic")
@Nullable
public MutableTreeNode buildAvailableRules(@NotNull ArrangementStandardSettingsAware settingsFilter,
@NotNull ArrangementNodeDisplayManager displayManager)
{
ArrangementSectionNode result = new ArrangementSectionNode(ApplicationBundle.message("arrangement.settings.section.groups"));
for (ArrangementGroupingType groupingType : ArrangementGroupingType.values()) {
if (!settingsFilter.isEnabled(groupingType, null)) {
continue;
}
ArrangementCheckBoxNode groupingCheckNode = new ArrangementCheckBoxNode(displayManager.getDisplayValue(groupingType));
result.add(groupingCheckNode);
}
return result;
}
public void applyRules(@NotNull List<ArrangementGroupingRule> rules, @NotNull TreeNode groupsRoot) {
// TODO den implement
}
@NotNull
public List<ArrangementGroupingRule> buildRules(@NotNull TreeNode groupsRoot) {
List<ArrangementGroupingRule> result = new ArrayList<ArrangementGroupingRule>();
// TODO den implement
return result;
}
}
@@ -17,11 +17,13 @@ package com.intellij.application.options.codeStyle.arrangement;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsRepresentationAware;
import gnu.trove.TObjectIntHashMap;
@@ -94,6 +96,12 @@ public class ArrangementNodeDisplayManager {
else if (value instanceof ArrangementModifier) {
return myRepresentationManager.getDisplayValue((ArrangementModifier)value);
}
else if (value instanceof ArrangementGroupingType) {
return myRepresentationManager.getDisplayValue((ArrangementGroupingType)value);
}
else if (value instanceof ArrangementEntryOrderType) {
return myRepresentationManager.getDisplayValue((ArrangementEntryOrderType)value);
}
else {
return value.toString();
}
@@ -96,7 +96,7 @@ public class ArrangementRuleEditingModelBuilder {
Pair<ArrangementTreeNode, Integer> pair = ArrangementConfigUtil.map(null, grouped, null);
ArrangementTreeNode topMostNode = ArrangementConfigUtil.getRoot(pair.first);
ArrangementConfigUtil.markRows(root, tree.isRootVisible());
ArrangementConfigUtil.markRows(root, true);
ArrangementTreeNode bottomHierarchy = null;
if (anchor != null) {
bottomHierarchy = ArrangementConfigUtil.cutSubHierarchy(root, treeModel, anchor);
@@ -106,7 +106,7 @@ public class ArrangementRuleEditingModelBuilder {
ArrangementConfigUtil.insert(root, root.getChildCount(), bottomHierarchy, treeModel);
}
TIntIntHashMap rowChanges = ArrangementConfigUtil.collectRowChangesAndUnmark(root, tree.isRootVisible());
TIntIntHashMap rowChanges = ArrangementConfigUtil.collectRowChangesAndUnmark(root, true);
topMostNode = ArrangementConfigUtil.getLastBefore(pair.first, root);
int row = ArrangementConfigUtil.getRow(pair.first, tree.isRootVisible());
ArrangementRuleEditingModelImpl model = new ArrangementRuleEditingModelImpl(
@@ -15,6 +15,8 @@
*/
package com.intellij.application.options.codeStyle.arrangement;
import com.intellij.application.options.codeStyle.arrangement.node.match.ArrangementAtomMatchNodeComponent;
import com.intellij.application.options.codeStyle.arrangement.node.match.ArrangementMatchNodeComponent;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
@@ -42,9 +44,9 @@ import java.util.List;
*/
public class ArrangementRuleEditor extends JPanel {
@NotNull private final List<JComponent> myColoredComponents = new ArrayList<JComponent>();
@NotNull private final Map<Object, ArrangementAtomNodeComponent> myComponents =
new HashMap<Object, ArrangementAtomNodeComponent>();
@NotNull private final List<JComponent> myColoredComponents = new ArrayList<JComponent>();
@NotNull private final Map<Object, ArrangementAtomMatchNodeComponent> myComponents =
new HashMap<Object, ArrangementAtomMatchNodeComponent>();
@NotNull private final ArrangementStandardSettingsAware myFilter;
@Nullable private ArrangementRuleEditingModel myModel;
@@ -79,12 +81,13 @@ public class ArrangementRuleEditor extends JPanel {
JPanel valuesPanel = new MultiRowFlowPanel(FlowLayout.LEFT, 8, 5);
for (Object value : manager.sort(values)) {
ArrangementAtomNodeComponent component = new ArrangementAtomNodeComponent(manager, new ArrangementAtomMatchCondition(key, value), null);
ArrangementAtomMatchNodeComponent component =
new ArrangementAtomMatchNodeComponent(manager, new ArrangementAtomMatchCondition(key, value), null);
myComponents.put(value, component);
valuesPanel.add(component.getUiComponent());
}
int top = ArrangementAtomNodeComponent.VERTICAL_PADDING;
int top = ArrangementAtomMatchNodeComponent.VERTICAL_PADDING;
add(new JLabel(manager.getDisplayLabel(key) + ":"), new GridBag().anchor(GridBagConstraints.NORTHWEST).insets(top, 0, 0, 0));
add(valuesPanel, new GridBag().anchor(GridBagConstraints.WEST).weightx(1).fillCellHorizontally().coverLine());
myColoredComponents.add(valuesPanel);
@@ -100,7 +103,7 @@ public class ArrangementRuleEditor extends JPanel {
myModel = model;
// Reset state.
for (ArrangementAtomNodeComponent component : myComponents.values()) {
for (ArrangementAtomMatchNodeComponent component : myComponents.values()) {
component.setEnabled(false);
component.setSelected(false);
}
@@ -114,7 +117,7 @@ public class ArrangementRuleEditor extends JPanel {
);
for (Collection<?> ids : available.values()) {
for (Object id : ids) {
ArrangementAtomNodeComponent component = myComponents.get(id);
ArrangementAtomMatchNodeComponent component = myComponents.get(id);
if (component != null) {
component.setEnabled(true);
component.setSelected(model.hasCondition(id));
@@ -135,7 +138,7 @@ public class ArrangementRuleEditor extends JPanel {
if (myModel == null) {
return;
}
ArrangementAtomNodeComponent clickedComponent = getNodeComponentAt(e.getLocationOnScreen());
ArrangementAtomMatchNodeComponent clickedComponent = getNodeComponentAt(e.getLocationOnScreen());
if (clickedComponent == null || !clickedComponent.isEnabled()) {
return;
}
@@ -155,9 +158,9 @@ public class ArrangementRuleEditor extends JPanel {
}
for (Object key : mutex) {
if (myModel.hasCondition(key)) {
ArrangementAtomNodeComponent componentToDeselect = myComponents.get(key);
ArrangementAtomMatchNodeComponent componentToDeselect = myComponents.get(key);
myModel.replaceCondition(componentToDeselect.getMatchCondition(), chosenCondition);
for (ArrangementAtomNodeComponent componentToCheck : myComponents.values()) {
for (ArrangementAtomMatchNodeComponent componentToCheck : myComponents.values()) {
Object value = componentToCheck.getMatchCondition().getValue();
if (myModel.hasCondition(value) && !ArrangementConfigUtil.isEnabled(value, myFilter, myModel.getCondition())) {
myModel.removeAndCondition(componentToCheck.getMatchCondition());
@@ -176,8 +179,8 @@ public class ArrangementRuleEditor extends JPanel {
}
@Nullable
private ArrangementAtomNodeComponent getNodeComponentAt(@NotNull Point screenPoint) {
for (ArrangementAtomNodeComponent component : myComponents.values()) {
private ArrangementAtomMatchNodeComponent getNodeComponentAt(@NotNull Point screenPoint) {
for (ArrangementAtomMatchNodeComponent component : myComponents.values()) {
Rectangle screenBounds = component.getScreenBounds();
if (screenBounds != null && screenBounds.contains(screenPoint)) {
return component;
@@ -186,7 +189,7 @@ public class ArrangementRuleEditor extends JPanel {
return null;
}
private void repaintComponent(@NotNull ArrangementNodeComponent component) {
private void repaintComponent(@NotNull ArrangementMatchNodeComponent component) {
Rectangle bounds = component.getScreenBounds();
if (bounds != null) {
Point location = bounds.getLocation();
@@ -15,15 +15,20 @@
*/
package com.intellij.application.options.codeStyle.arrangement;
import com.intellij.application.options.codeStyle.arrangement.node.ArrangementRepresentationAwareNode;
import com.intellij.application.options.codeStyle.arrangement.node.ArrangementSectionNode;
import com.intellij.application.options.codeStyle.arrangement.node.match.ArrangementMatchNodeComponent;
import com.intellij.application.options.codeStyle.arrangement.node.match.ArrangementMatchNodeComponentFactory;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.StdArrangementSettings;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Alarm;
import com.intellij.util.containers.ContainerUtil;
@@ -57,44 +62,53 @@ public class ArrangementRuleTree {
private static final int EMPTY_RULE_REMOVE_DELAY_MILLIS = 300;
@NotNull private final List<ArrangementRuleSelectionListener> myListeners = new ArrayList<ArrangementRuleSelectionListener>();
@NotNull private final TreeSelectionModel mySelectionModel = new MySelectionModel();
@NotNull private final MyModelChangeListener myModelChangeListener = new MyModelChangeListener();
@NotNull private final MyModelNodesRefresher myModelNodesRefresher = new MyModelNodesRefresher();
@NotNull private final ArrangementRuleEditingModelBuilder myModelBuilder = new ArrangementRuleEditingModelBuilder();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private final RemoveInactiveNewModelRequest myRequest = new RemoveInactiveNewModelRequest();
@NotNull private final List<ArrangementRuleSelectionListener> myListeners = new ArrayList<ArrangementRuleSelectionListener>();
@NotNull private final TreeSelectionModel mySelectionModel = new MySelectionModel();
@NotNull private final MyModelChangeListener myModelChangeListener = new MyModelChangeListener();
@NotNull private final MyModelNodesRefresher myModelNodesRefresher = new MyModelNodesRefresher();
@NotNull private final ArrangementRuleEditingModelBuilder myModelBuilder = new ArrangementRuleEditingModelBuilder();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private final RemoveInactiveNewModelRequest myRequest = new RemoveInactiveNewModelRequest();
@NotNull private final ArrangementGroupingRulesManager myGroupingRulesManager = ArrangementGroupingRulesManager.INSTANCE;
@NotNull private final TIntObjectHashMap<ArrangementNodeComponent> myRenderers =
new TIntObjectHashMap<ArrangementNodeComponent>();
@NotNull private final TIntObjectHashMap<ArrangementMatchNodeComponent> myRenderers =
new TIntObjectHashMap<ArrangementMatchNodeComponent>();
@NotNull private final TIntObjectHashMap<ArrangementRuleEditingModelImpl> myModels =
new TIntObjectHashMap<ArrangementRuleEditingModelImpl>();
@NotNull private final ArrangementTreeNode myRoot;
@NotNull private final ArrangementTreeNode myMatchRulesRoot;
@NotNull private final DefaultTreeModel myTreeModel;
@NotNull private final Tree myTree;
@NotNull private final ArrangementNodeComponentFactory myFactory;
@NotNull private final ArrangementMatchNodeComponentFactory myFactory;
@NotNull private final List<Set<ArrangementMatchCondition>> myUiGroupingRules;
@Nullable private List<ArrangementGroupingRule> myGroupings;
private int myCanvasWidth;
private boolean myExplicitSelectionChange;
private boolean mySkipSelectionChange;
@Nullable private final MutableTreeNode myGroupingsRoot;
private int myCanvasWidth;
private boolean myExplicitSelectionChange;
private boolean mySkipSelectionChange;
public ArrangementRuleTree(@Nullable StdArrangementSettings settings,
@NotNull List<Set<ArrangementMatchCondition>> uiGroupingRules,
@NotNull ArrangementNodeDisplayManager displayManager)
@NotNull ArrangementNodeDisplayManager displayManager,
@NotNull ArrangementStandardSettingsAware settingsFilter)
{
myUiGroupingRules = uiGroupingRules;
myFactory = new ArrangementNodeComponentFactory(displayManager, new Runnable() {
myFactory = new ArrangementMatchNodeComponentFactory(displayManager, new Runnable() {
@Override
public void run() {
notifySelectionListeners();
}
}, uiGroupingRules);
myRoot = new ArrangementTreeNode(null);
myTreeModel = new DefaultTreeModel(myRoot);
myGroupingsRoot = myGroupingRulesManager.buildAvailableRules(settingsFilter, displayManager);
ArrangementTreeNode root = new ArrangementTreeNode(null);
if (myGroupingsRoot != null) {
root.add(myGroupingsRoot);
}
myMatchRulesRoot = new ArrangementSectionNode(ApplicationBundle.message("arrangement.settings.section.match"));
root.add(myMatchRulesRoot);
myTreeModel = new DefaultTreeModel(root);
final Condition<Integer> wideSelectionCondition = new Condition<Integer>() {
@Override
public boolean value(Integer row) {
@@ -218,7 +232,7 @@ public class ArrangementRuleTree {
if (myCanvasWidth <= 0) {
return;
}
ArrangementNodeComponent component = myRenderers.get(row);
ArrangementMatchNodeComponent component = myRenderers.get(row);
if (component == null) {
return;
}
@@ -259,8 +273,8 @@ public class ArrangementRuleTree {
private void selectNextRule() {
ArrangementTreeNode currentSelectionBottom = getCurrentSelectionBottom();
if (currentSelectionBottom == null) {
if (myRoot.getChildCount() > 0) {
mySelectionModel.setSelectionPath(new TreePath(myRoot.getFirstChild().getPath()));
if (myMatchRulesRoot.getChildCount() > 0) {
mySelectionModel.setSelectionPath(new TreePath(myMatchRulesRoot.getFirstChild().getPath()));
}
return;
}
@@ -301,9 +315,9 @@ public class ArrangementRuleTree {
private void doClearSelection() {
mySelectionModel.clearSelection();
myRenderers.forEachValue(new TObjectProcedure<ArrangementNodeComponent>() {
myRenderers.forEachValue(new TObjectProcedure<ArrangementMatchNodeComponent>() {
@Override
public boolean execute(ArrangementNodeComponent node) {
public boolean execute(ArrangementMatchNodeComponent node) {
node.setSelected(false);
return true;
}
@@ -312,7 +326,7 @@ public class ArrangementRuleTree {
}
/**
* Updates renderer {@link ArrangementNodeComponent#setSelected(boolean) 'selected'} state on tree node selection change.
* Updates renderer {@link ArrangementMatchNodeComponent#setSelected(boolean) 'selected'} state on tree node selection change.
*
* @param path changed selection path
* @param selected <code>true</code> if given path is selected now; <code>false</code> if given path was selected anymore
@@ -331,7 +345,7 @@ public class ArrangementRuleTree {
if (row < 0) {
return;
}
ArrangementNodeComponent component = myRenderers.get(row);
ArrangementMatchNodeComponent component = myRenderers.get(row);
if (component != null) {
component.setSelected(selected);
myTreeModel.nodeChanged(node);
@@ -357,7 +371,8 @@ public class ArrangementRuleTree {
private void map(@NotNull List<StdArrangementMatchRule> rules) {
for (StdArrangementMatchRule rule : rules) {
Pair<ArrangementRuleEditingModelImpl, TIntIntHashMap> pair = myModelBuilder.build(rule, myTree, myRoot, null, myUiGroupingRules);
Pair<ArrangementRuleEditingModelImpl, TIntIntHashMap> pair
= myModelBuilder.build(rule, myTree, myMatchRulesRoot, null, myUiGroupingRules);
if (pair != null) {
myModels.put(pair.first.getRow(), pair.first);
pair.first.addListener(myModelChangeListener);
@@ -421,7 +436,7 @@ public class ArrangementRuleTree {
implicitGroupConditions.add(prevGroup);
prevGroup = null;
}
if (!myRoot.equals(topMost) && !topMost.equals(model.getBottomMost()) && !implicitGroupConditions.contains(currentGroup)) {
if (!myMatchRulesRoot.equals(topMost) && !topMost.equals(model.getBottomMost()) && !implicitGroupConditions.contains(currentGroup)) {
prevGroup = currentGroup;
}
rules.add(model.getRule());
@@ -431,28 +446,30 @@ public class ArrangementRuleTree {
rules.add(new StdArrangementMatchRule(new StdArrangementEntryMatcher(prevGroup)));
}
if (myGroupings == null) {
if (myGroupingsRoot == null) {
return new StdArrangementSettings(rules);
}
else {
return new StdArrangementSettings(myGroupings, rules);
return new StdArrangementSettings(myGroupingRulesManager.buildRules(myGroupingsRoot), rules);
}
}
public void setSettings(@Nullable StdArrangementSettings settings) {
myRenderers.clear();
myModels.clear();
while (myRoot.getChildCount() > 0)
myTreeModel.removeNodeFromParent(myRoot.getFirstChild());
while (myMatchRulesRoot.getChildCount() > 0)
myTreeModel.removeNodeFromParent(myMatchRulesRoot.getFirstChild());
if (settings == null) {
return;
}
myGroupings = settings.getGroupings();
if (myGroupingsRoot != null) {
myGroupingRulesManager.applyRules(settings.getGroupings(), myGroupingsRoot);
}
List<StdArrangementMatchRule> rules = settings.getRules();
map(rules);
expandAll(myTree, new TreePath(myRoot));
expandAll(myTree, new TreePath(myTreeModel.getRoot()));
if (ArrangementConstants.LOG_RULE_MODIFICATION) {
LOG.info("Arrangement tree is refreshed. Given rules:");
@@ -469,13 +486,13 @@ public class ArrangementRuleTree {
});
}
}
@NotNull
private ArrangementNodeComponent getNodeComponentAt(int row,
private ArrangementMatchNodeComponent getNodeComponentAt(int row,
@NotNull ArrangementMatchCondition condition,
@Nullable ArrangementRuleEditingModelImpl model)
{
ArrangementNodeComponent result = myRenderers.get(row);
ArrangementMatchNodeComponent result = myRenderers.get(row);
if (result == null || !result.getMatchCondition().equals(condition)) {
myRenderers.put(row, result = myFactory.getComponent(condition, model));
doUpdateCanvasWidth(row);
@@ -484,7 +501,7 @@ public class ArrangementRuleTree {
}
private void onMouseMoved(@NotNull MouseEvent e) {
ArrangementNodeComponent component = getNodeComponentAt(e.getX(), e.getY());
ArrangementMatchNodeComponent component = getNodeComponentAt(e.getX(), e.getY());
if (component == null) {
return;
}
@@ -495,7 +512,7 @@ public class ArrangementRuleTree {
}
private void onMouseClicked(@NotNull MouseEvent e) {
ArrangementNodeComponent component = getNodeComponentAt(e.getX(), e.getY());
ArrangementMatchNodeComponent component = getNodeComponentAt(e.getX(), e.getY());
if (component != null) {
component.handleMouseClick(e);
return;
@@ -511,12 +528,12 @@ public class ArrangementRuleTree {
}
@Nullable
private ArrangementNodeComponent getNodeComponentAt(int x, int y) {
private ArrangementMatchNodeComponent getNodeComponentAt(int x, int y) {
int row = myTree.getRowForLocation(x, y);
return myRenderers.get(row);
}
private void repaintComponent(@NotNull ArrangementNodeComponent component) {
private void repaintComponent(@NotNull ArrangementMatchNodeComponent component) {
Rectangle bounds = component.getScreenBounds();
if (bounds != null) {
repaintScreenBounds(bounds);
@@ -632,7 +649,7 @@ public class ArrangementRuleTree {
final ArrangementTreeNode anchor = activeModels.size() != 1 ? null : activeModels.get(0).getBottomMost();
doClearSelection();
Pair<ArrangementRuleEditingModelImpl,TIntIntHashMap> pair = myModelBuilder.build(
ArrangementRuleEditingModel.EMPTY_RULE, myTree, myRoot, anchor, myUiGroupingRules
ArrangementRuleEditingModel.EMPTY_RULE, myTree, myMatchRulesRoot, anchor, myUiGroupingRules
);
assert pair != null;
processRowChanges(pair.second);
@@ -661,8 +678,11 @@ public class ArrangementRuleTree {
boolean expanded,
boolean leaf,
int row,
boolean hasFocus)
{
boolean hasFocus) {
if (value instanceof ArrangementRepresentationAwareNode) {
return ((ArrangementRepresentationAwareNode)value).getRenderer();
}
ArrangementMatchCondition node = ((ArrangementTreeNode)value).getBackingCondition();
if (node == null) {
return EMPTY_RENDERER;
@@ -670,13 +690,13 @@ public class ArrangementRuleTree {
if (isEmptyCondition(node)) {
return NEW_CONDITION_RENDERER;
}
if (row < 0) {
ArrangementNodeComponent component = myFactory.getComponent(node, null);
ArrangementMatchNodeComponent component = myFactory.getComponent(node, null);
doUpdateCanvasWidth(row);
return component.getUiComponent();
}
ArrangementNodeComponent component = getNodeComponentAt(row, node, myModels.get(row));
ArrangementMatchNodeComponent component = getNodeComponentAt(row, node, myModels.get(row));
component.setSelected(selected);
return component.getUiComponent();
}
@@ -752,7 +772,7 @@ public class ArrangementRuleTree {
}
TreePath path = myTree.getPathForRow(mySelectedRowToRestore);
if (path == null) {
ArrangementTreeNode lastLeaf = myRoot.getLastLeaf();
ArrangementTreeNode lastLeaf = myMatchRulesRoot.getLastLeaf();
if (lastLeaf == null) {
return;
}
@@ -99,7 +99,7 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel {
toolbarControl.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT | SideBorder.TOP | SideBorder.RIGHT));
myContent.add(toolbarControl, new GridBag().weightx(1).fillCellHorizontally().coverLine());
myRuleTree = new ArrangementRuleTree(getSettings(settings), groupingRules, displayManager);
myRuleTree = new ArrangementRuleTree(getSettings(settings), groupingRules, displayManager, mySettingsAware);
final Tree treeComponent = myRuleTree.getTreeComponent();
actionToolbar.setTargetComponent(treeComponent);
JBScrollPane scrollPane = new JBScrollPane(treeComponent);
@@ -0,0 +1,49 @@
/*
* 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.application.options.codeStyle.arrangement.node;
import com.intellij.application.options.codeStyle.arrangement.ArrangementTreeNode;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
/**
* @author Denis Zhdanov
* @since 9/27/12 3:10 PM
*/
public class ArrangementCheckBoxNode extends ArrangementTreeNode implements ArrangementRepresentationAwareNode {
@NotNull private final JPanel myRenderer = new JPanel(new GridBagLayout());
public ArrangementCheckBoxNode(@NotNull String text) {
super(null);
JBCheckBox checkBox = new JBCheckBox(text);
checkBox.setBackground(UIUtil.getTreeBackground());
myRenderer.add(checkBox, new GridBag().anchor(GridBagConstraints.WEST));
}
@NotNull
@Override
public JComponent getRenderer() {
return myRenderer;
}
}
@@ -0,0 +1,31 @@
/*
* 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.application.options.codeStyle.arrangement.node;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.TreeNode;
/**
* @author Denis Zhdanov
* @since 9/27/12 2:48 PM
*/
public interface ArrangementRepresentationAwareNode extends TreeNode {
@NotNull
JComponent getRenderer();
}
@@ -0,0 +1,47 @@
/*
* 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.application.options.codeStyle.arrangement.node;
import com.intellij.application.options.codeStyle.arrangement.ArrangementTreeNode;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author Denis Zhdanov
* @since 9/27/12 2:24 PM
*/
public class ArrangementSectionNode extends ArrangementTreeNode implements ArrangementRepresentationAwareNode {
@NotNull private final JPanel myRenderer = new JPanel();
@NotNull private final JLabel myTextLabel = new JLabel();
public ArrangementSectionNode(@NotNull String text) {
super(null);
myTextLabel.setText(text);
myRenderer.add(myTextLabel);
}
@NotNull
public JComponent getRenderer() {
return myRenderer;
}
@Override
public String toString() {
return String.format("section '%s'", myTextLabel.getText());
}
}
@@ -13,8 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.application.options.codeStyle.arrangement;
package com.intellij.application.options.codeStyle.arrangement.node.match;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConfigUtil;
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
import com.intellij.application.options.codeStyle.arrangement.ArrangementRuleEditingModel;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
@@ -33,26 +36,26 @@ import java.util.List;
import java.util.Map;
/**
* {@link ArrangementNodeComponent Component} for showing {@link ArrangementCompositeMatchCondition composite nodes}.
* {@link ArrangementMatchNodeComponent Component} for showing {@link ArrangementCompositeMatchCondition composite nodes}.
* <p/>
* Not thread-safe.
*
* @author Denis Zhdanov
* @since 8/8/12 10:51 AM
*/
public class ArrangementAndNodeComponent extends JPanel implements ArrangementNodeComponent {
public class ArrangementAndMatchNodeComponent extends JPanel implements ArrangementMatchNodeComponent {
private static final int BUBBLE_CONNECTOR_LENGTH = 10;
@NotNull private final List<ArrangementNodeComponent> myComponents = new ArrayList<ArrangementNodeComponent>();
@NotNull private final List<ArrangementMatchNodeComponent> myComponents = new ArrayList<ArrangementMatchNodeComponent>();
@NotNull private final ArrangementCompositeMatchCondition mySetting;
@Nullable private Rectangle myScreenBounds;
@NotNull private final ArrangementCompositeMatchCondition mySetting;
@Nullable private Rectangle myScreenBounds;
public ArrangementAndNodeComponent(@NotNull ArrangementCompositeMatchCondition setting,
@NotNull ArrangementNodeComponentFactory factory,
@NotNull ArrangementNodeDisplayManager manager,
@Nullable ArrangementRuleEditingModel model)
public ArrangementAndMatchNodeComponent(@NotNull ArrangementCompositeMatchCondition setting,
@NotNull ArrangementMatchNodeComponentFactory factory,
@NotNull ArrangementNodeDisplayManager manager,
@Nullable ArrangementRuleEditingModel model)
{
mySetting = setting;
setLayout(null);
@@ -77,7 +80,7 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
for (Object key : ordered) {
ArrangementMatchCondition operand = operands.get(key);
assert operand != null;
ArrangementNodeComponent component = factory.getComponent(operand, model);
ArrangementMatchNodeComponent component = factory.getComponent(operand, model);
myComponents.add(component);
JComponent uiComponent = component.getUiComponent();
Dimension size = uiComponent.getPreferredSize();
@@ -117,13 +120,13 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
@Override
public void setSelected(boolean selected) {
for (ArrangementNodeComponent component : myComponents) {
for (ArrangementMatchNodeComponent component : myComponents) {
component.setSelected(selected);
}
}
@Override
public ArrangementNodeComponent getNodeComponentAt(@NotNull RelativePoint point) {
public ArrangementMatchNodeComponent getNodeComponentAt(@NotNull RelativePoint point) {
if (myScreenBounds == null) {
return null;
}
@@ -132,7 +135,7 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
return null;
}
for (ArrangementNodeComponent component : myComponents) {
for (ArrangementMatchNodeComponent component : myComponents) {
Rectangle screenBounds = component.getScreenBounds();
if (screenBounds != null && screenBounds.contains(screenPoint)) {
return component;
@@ -204,7 +207,7 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
@Override
public Rectangle handleMouseMove(@NotNull MouseEvent event) {
Point location = event.getLocationOnScreen();
for (ArrangementNodeComponent component : myComponents) {
for (ArrangementMatchNodeComponent component : myComponents) {
Rectangle bounds = component.getScreenBounds();
if (bounds != null && bounds.contains(location)) {
return component.handleMouseMove(event);
@@ -216,7 +219,7 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
@Override
public void handleMouseClick(@NotNull MouseEvent event) {
Point location = event.getLocationOnScreen();
for (ArrangementNodeComponent component : myComponents) {
for (ArrangementMatchNodeComponent component : myComponents) {
Rectangle bounds = component.getScreenBounds();
if (bounds != null && bounds.contains(location)) {
component.handleMouseClick(event);
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.application.options.codeStyle.arrangement;
package com.intellij.application.options.codeStyle.arrangement.node.match;
import com.intellij.application.options.codeStyle.arrangement.*;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
@@ -30,14 +31,14 @@ import java.awt.*;
import java.awt.event.MouseEvent;
/**
* {@link ArrangementNodeComponent} for {@link ArrangementAtomMatchCondition} representation.
* {@link ArrangementMatchNodeComponent} for {@link ArrangementAtomMatchCondition} representation.
* <p/>
* Not thread-safe.
*
* @author Denis Zhdanov
* @since 8/8/12 10:06 AM
*/
public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
public class ArrangementAtomMatchNodeComponent implements ArrangementMatchNodeComponent {
public static final int VERTICAL_PADDING = 2;
public static final int HORIZONTAL_PADDING = 8;
@@ -86,14 +87,14 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
@Nullable private Dimension myLabelSize;
@Nullable private Rectangle myScreenBounds;
private boolean myEnabled = true;
private boolean myInverted;
private boolean myCloseButtonHovered;
public ArrangementAtomNodeComponent(@NotNull ArrangementNodeDisplayManager manager,
@NotNull ArrangementAtomMatchCondition condition,
@Nullable Runnable closeCallback)
public ArrangementAtomMatchNodeComponent(@NotNull ArrangementNodeDisplayManager manager,
@NotNull ArrangementAtomMatchCondition condition,
@Nullable Runnable closeCallback)
{
myCondition = condition;
myCloseCallback = closeCallback;
@@ -175,7 +176,7 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
}
@Override
public ArrangementNodeComponent getNodeComponentAt(@NotNull RelativePoint point) {
public ArrangementMatchNodeComponent getNodeComponentAt(@NotNull RelativePoint point) {
return (myScreenBounds != null && myScreenBounds.contains(point.getScreenPoint())) ? this : null;
}
@@ -13,8 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.application.options.codeStyle.arrangement;
package com.intellij.application.options.codeStyle.arrangement.node.match;
import com.intellij.application.options.codeStyle.arrangement.ArrangementColorsService;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConfigUtil;
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
@@ -33,10 +36,10 @@ import java.awt.event.MouseEvent;
* @author Denis Zhdanov
* @since 9/12/12 5:39 PM
*/
public class ArrangementGroupingNodeComponent extends JPanel implements ArrangementNodeComponent {
public class ArrangementGroupingMatchNodeComponent extends JPanel implements ArrangementMatchNodeComponent {
private static final int TOP_INSET = 3;
@NotNull private final ArrangementColorsService myColorsService = ServiceManager.getService(ArrangementColorsService.class);
@NotNull private final ArrangementAtomMatchCondition myCondition;
@@ -44,8 +47,8 @@ public class ArrangementGroupingNodeComponent extends JPanel implements Arrangem
@NotNull private Dimension myPreferredSize;
private boolean mySelected;
public ArrangementGroupingNodeComponent(@NotNull ArrangementNodeDisplayManager manager,
@NotNull ArrangementAtomMatchCondition condition)
public ArrangementGroupingMatchNodeComponent(@NotNull ArrangementNodeDisplayManager manager,
@NotNull ArrangementAtomMatchCondition condition)
{
myCondition = condition;
String text = StringUtil.capitalize(StringUtil.pluralize(manager.getDisplayValue(myCondition.getValue())));
@@ -69,7 +72,7 @@ public class ArrangementGroupingNodeComponent extends JPanel implements Arrangem
@Nullable
@Override
public ArrangementNodeComponent getNodeComponentAt(@NotNull RelativePoint point) {
public ArrangementMatchNodeComponent getNodeComponentAt(@NotNull RelativePoint point) {
return (myScreenBounds != null && myScreenBounds.contains(point.getScreenPoint())) ? this : null;
}
@@ -81,7 +84,7 @@ public class ArrangementGroupingNodeComponent extends JPanel implements Arrangem
@Override
public void setScreenBounds(@Nullable Rectangle bounds) {
myScreenBounds = bounds;
myScreenBounds = bounds;
}
@Override
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.application.options.codeStyle.arrangement;
package com.intellij.application.options.codeStyle.arrangement.node.match;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.ui.awt.RelativePoint;
@@ -30,7 +30,7 @@ import java.awt.event.MouseEvent;
* @author Denis Zhdanov
* @since 8/10/12 11:22 AM
*/
public interface ArrangementNodeComponent {
public interface ArrangementMatchNodeComponent {
@NotNull
ArrangementMatchCondition getMatchCondition();
@@ -41,7 +41,7 @@ public interface ArrangementNodeComponent {
// TODO den add doc
@Nullable
ArrangementNodeComponent getNodeComponentAt(@NotNull RelativePoint point);
ArrangementMatchNodeComponent getNodeComponentAt(@NotNull RelativePoint point);
// TODO den add doc
@Nullable
@@ -13,8 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.application.options.codeStyle.arrangement;
package com.intellij.application.options.codeStyle.arrangement.node.match;
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
import com.intellij.application.options.codeStyle.arrangement.ArrangementRuleEditingModel;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
@@ -31,15 +33,15 @@ import java.util.Set;
* @author Denis Zhdanov
* @since 8/10/12 2:53 PM
*/
public class ArrangementNodeComponentFactory {
public class ArrangementMatchNodeComponentFactory {
@NotNull private final Set<ArrangementMatchCondition> myGroupingConditions = ContainerUtilRt.newHashSet();
@NotNull private final ArrangementNodeDisplayManager myDisplayManager;
@NotNull private final Runnable myRemoveConditionCallback;
public ArrangementNodeComponentFactory(@NotNull ArrangementNodeDisplayManager manager,
@NotNull Runnable removeConditionCallback,
@NotNull List<Set<ArrangementMatchCondition>> groupingRules)
public ArrangementMatchNodeComponentFactory(@NotNull ArrangementNodeDisplayManager manager,
@NotNull Runnable removeConditionCallback,
@NotNull List<Set<ArrangementMatchCondition>> groupingRules)
{
myDisplayManager = manager;
myRemoveConditionCallback = removeConditionCallback;
@@ -49,19 +51,19 @@ public class ArrangementNodeComponentFactory {
}
@NotNull
public ArrangementNodeComponent getComponent(@NotNull final ArrangementMatchCondition node,
@Nullable final ArrangementRuleEditingModel model)
public ArrangementMatchNodeComponent getComponent(@NotNull final ArrangementMatchCondition node,
@Nullable final ArrangementRuleEditingModel model)
{
final Ref<ArrangementNodeComponent> ref = new Ref<ArrangementNodeComponent>();
final Ref<ArrangementMatchNodeComponent> ref = new Ref<ArrangementMatchNodeComponent>();
node.invite(new ArrangementMatchConditionVisitor() {
@Override
public void visit(@NotNull ArrangementAtomMatchCondition condition) {
ArrangementNodeComponent component;
ArrangementMatchNodeComponent component;
if (myGroupingConditions.contains(condition)) {
component = new ArrangementGroupingNodeComponent(myDisplayManager, condition);
component = new ArrangementGroupingMatchNodeComponent(myDisplayManager, condition);
}
else {
component = new ArrangementAtomNodeComponent(myDisplayManager, condition, prepareRemoveCallback(condition, model));
component = new ArrangementAtomMatchNodeComponent(myDisplayManager, condition, prepareRemoveCallback(condition, model));
}
ref.set(component);
}
@@ -70,7 +72,7 @@ public class ArrangementNodeComponentFactory {
public void visit(@NotNull ArrangementCompositeMatchCondition condition) {
switch (condition.getOperator()) {
case AND:
ref.set(new ArrangementAndNodeComponent(condition, ArrangementNodeComponentFactory.this, myDisplayManager, model));
ref.set(new ArrangementAndMatchNodeComponent(condition, ArrangementMatchNodeComponentFactory.this, myDisplayManager, model));
break;
case OR: // TODO den implement
}
@@ -560,5 +560,15 @@ arrangement.action.rule.add.text=Add rule
arrangement.action.rule.add.description=Add new arrangement rule
arrangement.action.rule.remove.text=Remove rule
arrangement.action.rule.remove.description=Remove selected arrangement rule
arrangement.settings.section.groups=Grouping rules
arrangement.settings.section.match=Matching rules
arrangement.settings.groups.dependent.methods=Keep dependent methods together
arrangement.settings.groups.overridden.methods=Keep overridden methods together
arrangement.settings.groups.getters.and.setters.together=Keep getters and setters together
arrangement.settings.order.type.keep=Keep
arrangement.settings.order.type.by.name=By name
arrangement.settings.order.type.depth.first=Depth-first
arrangement.settings.order.type.breadth.first=Breadth-first
checkbox.spaces.around.lambda.arrow=Lambda arrow
checkbox.spaces.around.method.ref.dbl.colon.arrow=Method reference double colon