IDEA-93476 Built-in code arrangement does not support alphabetization

This commit is contained in:
Denis.Zhdanov
2012-11-15 16:19:39 +04:00
parent c95c4aa5cf
commit 7a6be157f7
10 changed files with 330 additions and 121 deletions
@@ -15,10 +15,14 @@
*/
package com.intellij.psi.codeStyle.arrangement;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
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.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,11 +34,13 @@ import java.util.Set;
* @author Denis Zhdanov
* @since 10/31/12 12:30 PM
*/
public class ArrangementConditionInfo {
public class ArrangementRuleInfo {
@NotNull private final Set<ArrangementAtomMatchCondition> myAtomConditions = ContainerUtilRt.newHashSet();
@NotNull private final Set<Object> myConditions = ContainerUtilRt.newHashSet();
@NotNull private ArrangementEntryOrderType myOrderType = ArrangementMatchRule.DEFAULT_ORDER_TYPE;
@Nullable private String myNamePattern;
@Nullable
@@ -46,6 +52,15 @@ public class ArrangementConditionInfo {
myNamePattern = namePattern;
}
@NotNull
public ArrangementEntryOrderType getOrderType() {
return myOrderType;
}
public void setOrderType(@NotNull ArrangementEntryOrderType orderType) {
myOrderType = orderType;
}
public void addAtomCondition(@NotNull ArrangementAtomMatchCondition condition) {
switch (condition.getType()) {
case NAME: myNamePattern = condition.getValue().toString(); break;
@@ -72,6 +87,32 @@ public class ArrangementConditionInfo {
}
}
public void copyConditionsFrom(@NotNull ArrangementRuleInfo info) {
clearConditions();
myConditions.addAll(info.myConditions);
myAtomConditions.addAll(info.myAtomConditions);
}
public void clear() {
clearConditions();
myOrderType = ArrangementMatchRule.DEFAULT_ORDER_TYPE;
myNamePattern = null;
}
public void clearConditions() {
myConditions.clear();
myAtomConditions.clear();
}
@Nullable
public StdArrangementMatchRule buildRule() {
ArrangementMatchCondition condition = buildCondition();
if (condition == null) {
return null;
}
return new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), myOrderType);
}
@Nullable
public ArrangementMatchCondition buildCondition() {
if (myAtomConditions.isEmpty()) {
@@ -164,8 +164,8 @@ public class ArrangementUtil {
}
@NotNull
public static ArrangementConditionInfo extractConditions(@NotNull ArrangementMatchCondition condition) {
final ArrangementConditionInfo result = new ArrangementConditionInfo();
public static ArrangementRuleInfo extractConditions(@NotNull ArrangementMatchCondition condition) {
final ArrangementRuleInfo result = new ArrangementRuleInfo();
condition.invite(new ArrangementMatchConditionVisitor() {
@Override
public void visit(@NotNull ArrangementAtomMatchCondition condition) {
@@ -20,5 +20,5 @@ package com.intellij.psi.codeStyle.arrangement.model;
* @since 8/6/12 5:02 PM
*/
public enum ArrangementSettingType {
TYPE, MODIFIER, NAME
TYPE, MODIFIER, NAME, ORDER
}
@@ -18,6 +18,7 @@ package com.intellij.application.options.codeStyle.arrangement;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.util.ArrangementConfigUtil;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
@@ -98,6 +99,8 @@ public class ArrangementNodeDisplayManager {
return ApplicationBundle.message("arrangement.text.type");
case MODIFIER:
return ApplicationBundle.message("arrangement.text.modifier");
case NAME:
return ApplicationBundle.message("arrangement.text.name");
}
return type.toString().toLowerCase();
}
@@ -133,6 +136,23 @@ public class ArrangementNodeDisplayManager {
return myMaxWidths.get(type);
}
public int getMaxWidth(@NotNull ArrangementEntryOrderType... orderTypes) {
SimpleColoredComponent renderer = new SimpleColoredComponent();
int result = 0;
for (ArrangementEntryOrderType type : orderTypes) {
renderer.clear();
TextAttributes attributes = myColorsProvider.getTextAttributes(ArrangementSettingType.ORDER, true);
renderer.append(getDisplayValue(type), SimpleTextAttributes.fromTextAttributes(attributes));
result = Math.max(result, renderer.getPreferredSize().width);
renderer.clear();
attributes = myColorsProvider.getTextAttributes(ArrangementSettingType.ORDER, false);
renderer.append(getDisplayValue(type), SimpleTextAttributes.fromTextAttributes(attributes));
result = Math.max(result, renderer.getPreferredSize().width);
}
return result;
}
/**
* Asks current manager to sort in-place given arrangement condition ids ('field', 'class', 'method', 'public', 'static', 'final' etc).
*
@@ -58,7 +58,6 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementMatchC
PredefinedConditionBorderStrategy strategy = new PredefinedConditionBorderStrategy();
BORDER_STRATEGIES.put(ArrangementSettingType.TYPE, strategy);
BORDER_STRATEGIES.put(ArrangementSettingType.MODIFIER, strategy);
assert BORDER_STRATEGIES.size() == ArrangementSettingType.values().length;
}
@NotNull
@@ -22,15 +22,15 @@ import com.intellij.application.options.codeStyle.arrangement.util.ArrangementCo
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.ArrangementConditionInfo;
import com.intellij.psi.codeStyle.arrangement.ArrangementRuleInfo;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
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.ui.IdeBorderFactory;
import com.intellij.ui.components.JBTextField;
@@ -40,20 +40,15 @@ import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.MultiRowFlowPanel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Control for managing {@link ArrangementEntryMatcher matching rule conditions} for a single {@link ArrangementMatchRule}.
@@ -65,19 +60,22 @@ import java.util.Set;
*/
public class ArrangementMatchingRuleEditor extends JPanel {
@NotNull private final Map<Object, ArrangementAtomMatchConditionComponent> myComponents = ContainerUtilRt.newHashMap();
@NotNull private final List<MultiRowFlowPanel> myRows = ContainerUtilRt.newArrayList();
@NotNull private final Map<Object, ArrangementAtomMatchConditionComponent> myConditionComponents = ContainerUtilRt.newHashMap();
@NotNull private final List<MultiRowFlowPanel> myRows = ContainerUtilRt.newArrayList();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private final JBTextField myNameField = new JBTextField(20);
@NotNull private final Map<ArrangementEntryOrderType, ArrangementOrderTypeComponent> myOrderTypeComponents
= new EnumMap<ArrangementEntryOrderType, ArrangementOrderTypeComponent>(ArrangementEntryOrderType.class);
@NotNull private final ArrangementRuleInfo myRuleInfo = new ArrangementRuleInfo();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private final JBTextField myNameField = new JBTextField(20);
@NotNull private final ArrangementMatchingRulesControl myControl;
@NotNull private final ArrangementStandardSettingsAware myFilter;
@NotNull private final ArrangementColorsProvider myColorsProvider;
@Nullable private ArrangementConditionInfo myConditionInfo;
private int myRow = -1;
private int myLabelWidth;
private int myLabelWidth;
private boolean myRequestFocus;
public ArrangementMatchingRuleEditor(@NotNull ArrangementStandardSettingsAware filter,
@@ -110,9 +108,63 @@ public class ArrangementMatchingRuleEditor extends JPanel {
addRowIfPossible(ArrangementSettingType.TYPE, supportedSettings, displayManager);
addRowIfPossible(ArrangementSettingType.MODIFIER, supportedSettings, displayManager);
addNameFilterIfPossible();
addOrderRowIfPossible(displayManager);
applyBackground(UIUtil.getListBackground());
}
private void addRowIfPossible(@NotNull ArrangementSettingType key,
@NotNull Map<ArrangementSettingType, Set<?>> supportedSettings,
@NotNull ArrangementNodeDisplayManager manager)
{
Set<?> values = supportedSettings.get(key);
if (values == null || values.isEmpty()) {
return;
}
MultiRowFlowPanel valuesPanel = newRow(manager.getDisplayLabel(key));
for (Object value : manager.sort(values)) {
ArrangementAtomMatchConditionComponent component =
new ArrangementAtomMatchConditionComponent(manager, myColorsProvider, new ArrangementAtomMatchCondition(key, value), null);
myConditionComponents.put(value, component);
valuesPanel.add(component.getUiComponent());
}
}
private void addNameFilterIfPossible() {
if (!myFilter.isNameFilterSupported()) {
return;
}
MultiRowFlowPanel panel = newRow(ApplicationBundle.message("arrangement.text.name"));
panel.add(myNameField);
}
private void addOrderRowIfPossible(@NotNull ArrangementNodeDisplayManager displayManager) {
if (!myFilter.isNameFilterSupported()) {
return;
}
MultiRowFlowPanel panel = newRow(ApplicationBundle.message("arrangement.order.name"));
ArrangementEntryOrderType[] orderTypes = { ArrangementEntryOrderType.KEEP, ArrangementEntryOrderType.BY_NAME };
int maxWidth = displayManager.getMaxWidth(orderTypes);
for (ArrangementEntryOrderType type : orderTypes) {
ArrangementOrderTypeComponent component = new ArrangementOrderTypeComponent(type, displayManager, myColorsProvider, maxWidth);
panel.add(component);
myOrderTypeComponents.put(type, component);
}
}
private MultiRowFlowPanel newRow(@NotNull String rowLabel) {
MultiRowFlowPanel result = new MultiRowFlowPanel(
FlowLayout.LEFT, ArrangementConstants.HORIZONTAL_GAP, ArrangementConstants.VERTICAL_GAP
);
JLabel label = new JLabel(rowLabel + ":");
add(label, new GridBag().anchor(GridBagConstraints.NORTHWEST).insets(ArrangementConstants.VERTICAL_PADDING, 0, 0, 0));
myLabelWidth = Math.max(myLabelWidth, label.getPreferredSize().width);
add(result, new GridBag().anchor(GridBagConstraints.WEST).weightx(1).fillCellHorizontally().coverLine());
myRows.add(result);
return result;
}
private void scheduleNameUpdate() {
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@@ -125,7 +177,7 @@ public class ArrangementMatchingRuleEditor extends JPanel {
private void updateName() {
myAlarm.cancelAllRequests();
if (myRow < 0 || myConditionInfo == null) {
if (myRow < 0) {
return;
}
@@ -133,55 +185,11 @@ public class ArrangementMatchingRuleEditor extends JPanel {
if (StringUtil.isEmpty(namePattern)) {
namePattern = null;
}
if (Comparing.equal(namePattern, myConditionInfo.getNamePattern())) {
if (Comparing.equal(namePattern, myRuleInfo.getNamePattern())) {
return;
}
myConditionInfo.setNamePattern(namePattern);
ArrangementMatchCondition newCondition = myConditionInfo.buildCondition();
Object modelValue = newCondition == null
? new EmptyArrangementRuleComponent(myControl.getRowHeight(myRow))
: new StdArrangementMatchRule(new StdArrangementEntryMatcher(newCondition));
myControl.getModel().set(myRow, modelValue);
myControl.repaintRows(myRow, myRow, true);
}
private void addRowIfPossible(@NotNull ArrangementSettingType key,
@NotNull Map<ArrangementSettingType, Set<?>> supportedSettings,
@NotNull ArrangementNodeDisplayManager manager)
{
Set<?> values = supportedSettings.get(key);
if (values == null || values.isEmpty()) {
return;
}
MultiRowFlowPanel valuesPanel = newRow(manager.getDisplayLabel(key));
for (Object value : manager.sort(values)) {
ArrangementAtomMatchConditionComponent component =
new ArrangementAtomMatchConditionComponent(manager, myColorsProvider, new ArrangementAtomMatchCondition(key, value), null);
myComponents.put(value, component);
valuesPanel.add(component.getUiComponent());
}
}
private void addNameFilterIfPossible() {
if (!myFilter.isNameFilterSupported()) {
return;
}
MultiRowFlowPanel panel = newRow(ApplicationBundle.message("arrangement.text.name"));
panel.add(myNameField);
}
private MultiRowFlowPanel newRow(@NotNull String rowLabel) {
MultiRowFlowPanel result = new MultiRowFlowPanel(
FlowLayout.LEFT, ArrangementConstants.HORIZONTAL_GAP, ArrangementConstants.VERTICAL_GAP
);
JLabel label = new JLabel(rowLabel + ":");
add(label, new GridBag().anchor(GridBagConstraints.NORTHWEST).insets(ArrangementConstants.VERTICAL_PADDING, 0, 0, 0));
myLabelWidth = Math.max(myLabelWidth, label.getPreferredSize().width);
add(result, new GridBag().anchor(GridBagConstraints.WEST).weightx(1).fillCellHorizontally().coverLine());
myRows.add(result);
return result;
myRuleInfo.setNamePattern(namePattern);
updateModelValue();
}
@Override
@@ -211,14 +219,14 @@ public class ArrangementMatchingRuleEditor extends JPanel {
myAlarm.cancelAllRequests();
if (newModel) {
myRow = row;
myConditionInfo = null;
myRuleInfo.clear();
myNameField.setText("");
myAlarm.cancelAllRequests();
myRequestFocus = true;
}
// Reset state.
for (ArrangementAtomMatchConditionComponent component : myComponents.values()) {
for (ArrangementAtomMatchConditionComponent component : myConditionComponents.values()) {
component.setEnabled(false);
component.setSelected(false);
}
@@ -231,44 +239,61 @@ public class ArrangementMatchingRuleEditor extends JPanel {
Object element = model.getElementAt(row);
if (element instanceof EmptyArrangementRuleComponent) {
for (ArrangementAtomMatchConditionComponent component : myComponents.values()) {
for (ArrangementAtomMatchConditionComponent component : myConditionComponents.values()) {
ArrangementAtomMatchCondition condition = component.getMatchCondition();
Map<ArrangementSettingType, Set<?>> map = ArrangementConfigUtil.buildAvailableConditions(myFilter, condition);
component.setEnabled(map.get(condition.getType()).contains(condition.getValue()));
}
myConditionInfo = new ArrangementConditionInfo();
myRuleInfo.clearConditions();
ArrangementOrderTypeComponent orderTypeComponent = myOrderTypeComponents.get(myRuleInfo.getOrderType());
if (orderTypeComponent != null) {
orderTypeComponent.setSelected(true);
}
return;
}
if (!(element instanceof StdArrangementMatchRule)) {
return;
}
ArrangementMatchCondition condition = ((StdArrangementMatchRule)element).getMatcher().getCondition();
myConditionInfo = ArrangementUtil.extractConditions(condition);
myNameField.setText(myConditionInfo.getNamePattern() == null ? "" : myConditionInfo.getNamePattern());
StdArrangementMatchRule rule = (StdArrangementMatchRule)element;
ArrangementMatchCondition condition = rule.getMatcher().getCondition();
ArrangementRuleInfo infoWithConditions = ArrangementUtil.extractConditions(condition);
myRuleInfo.copyConditionsFrom(infoWithConditions);
myNameField.setText(myRuleInfo.getNamePattern() == null ? "" : myRuleInfo.getNamePattern());
Map<ArrangementSettingType, Set<?>> available = ArrangementConfigUtil.buildAvailableConditions(myFilter, condition);
for (Collection<?> ids : available.values()) {
for (Object id : ids) {
ArrangementAtomMatchConditionComponent component = myComponents.get(id);
ArrangementAtomMatchConditionComponent component = myConditionComponents.get(id);
if (component != null) {
component.setEnabled(true);
component.setSelected(myConditionInfo.hasCondition(id));
component.setSelected(myRuleInfo.hasCondition(id));
}
}
}
for (ArrangementOrderTypeComponent component : myOrderTypeComponents.values()) {
component.setSelected(false);
}
ArrangementOrderTypeComponent orderTypeComponent = myOrderTypeComponents.get(rule.getOrderType());
if (orderTypeComponent != null) {
orderTypeComponent.setSelected(true);
}
repaint();
}
private void updateState() {
assert myConditionInfo != null;
ArrangementMatchCondition newCondition = myConditionInfo.buildCondition();
Object modelValue = newCondition == null
? new EmptyArrangementRuleComponent(myControl.getRowHeight(myRow))
: new StdArrangementMatchRule(new StdArrangementEntryMatcher(newCondition));
updateModelValue();
updateState(myRow, false);
}
private void updateModelValue() {
Object modelValue = myRuleInfo.buildRule();
if (modelValue == null) {
modelValue = new EmptyArrangementRuleComponent(myControl.getRowHeight(myRow));
}
myControl.getModel().set(myRow, modelValue);
myControl.repaintRows(myRow, myRow, true);
updateState(myRow, false);
}
public void applyAvailableWidth(int width) {
@@ -286,22 +311,41 @@ public class ArrangementMatchingRuleEditor extends JPanel {
}
private void onMouseClicked(@NotNull MouseEvent e) {
if (myRow < 0 || myConditionInfo == null) {
if (myRow < 0) {
return;
}
ArrangementAtomMatchConditionComponent clickedComponent = getNodeComponentAt(e.getLocationOnScreen());
if (clickedComponent != null && clickedComponent.isEnabled()) {
onComponentSelected(clickedComponent);
Point locationOnScreen = e.getLocationOnScreen();
for (ArrangementAtomMatchConditionComponent component : myConditionComponents.values()) {
Rectangle screenBounds = component.getScreenBounds();
if (screenBounds == null || !screenBounds.contains(locationOnScreen)) {
continue;
}
if (component.isEnabled()) {
onComponentSelected(component);
}
return;
}
for (ArrangementOrderTypeComponent component : myOrderTypeComponents.values()) {
Rectangle bounds = component.getScreenBounds();
if (bounds == null || !bounds.contains(locationOnScreen)) {
continue;
}
if (component.getOrderType() != myRuleInfo.getOrderType()) {
myRuleInfo.setOrderType(component.getOrderType());
updateState();
}
return;
}
}
private void onComponentSelected(@NotNull ArrangementAtomMatchConditionComponent component) {
ArrangementAtomMatchCondition chosenCondition = component.getMatchCondition();
boolean remove = myConditionInfo.hasCondition(chosenCondition.getValue());
boolean remove = myRuleInfo.hasCondition(chosenCondition.getValue());
component.setSelected(!remove);
repaintComponent(component);
if (remove) {
myConditionInfo.removeCondition(chosenCondition.getValue());
myRuleInfo.removeCondition(chosenCondition.getValue());
ensureConsistency();
updateState();
return;
@@ -313,16 +357,16 @@ public class ArrangementMatchingRuleEditor extends JPanel {
continue;
}
for (Object key : mutex) {
if (myConditionInfo.hasCondition(key)) {
ArrangementAtomMatchConditionComponent componentToDeselect = myComponents.get(key);
myConditionInfo.removeCondition(componentToDeselect.getMatchCondition().getValue());
myConditionInfo.addAtomCondition(chosenCondition);
ArrangementMatchCondition newCondition = myConditionInfo.buildCondition();
for (ArrangementAtomMatchConditionComponent componentToCheck : myComponents.values()) {
if (myRuleInfo.hasCondition(key)) {
ArrangementAtomMatchConditionComponent componentToDeselect = myConditionComponents.get(key);
myRuleInfo.removeCondition(componentToDeselect.getMatchCondition().getValue());
myRuleInfo.addAtomCondition(chosenCondition);
ArrangementMatchCondition newCondition = myRuleInfo.buildCondition();
for (ArrangementAtomMatchConditionComponent componentToCheck : myConditionComponents.values()) {
Object value = componentToCheck.getMatchCondition().getValue();
if (myConditionInfo.hasCondition(value) && !ArrangementConfigUtil.isEnabled(value, myFilter, newCondition)) {
myConditionInfo.removeCondition(componentToCheck.getMatchCondition().getValue());
newCondition = myConditionInfo.buildCondition();
if (myRuleInfo.hasCondition(value) && !ArrangementConfigUtil.isEnabled(value, myFilter, newCondition)) {
myRuleInfo.removeCondition(componentToCheck.getMatchCondition().getValue());
newCondition = myRuleInfo.buildCondition();
}
}
@@ -333,19 +377,16 @@ public class ArrangementMatchingRuleEditor extends JPanel {
}
}
}
myConditionInfo.addAtomCondition(chosenCondition);
myRuleInfo.addAtomCondition(chosenCondition);
updateState();
}
private void ensureConsistency() {
if (myConditionInfo == null) {
return;
}
ArrangementMatchCondition condition = myConditionInfo.buildCondition();
ArrangementMatchCondition condition = myRuleInfo.buildCondition();
Map<ArrangementSettingType, Set<?>> map = ArrangementConfigUtil.buildAvailableConditions(myFilter, condition);
for (ArrangementAtomMatchConditionComponent c : myComponents.values()) {
for (ArrangementAtomMatchConditionComponent c : myConditionComponents.values()) {
Object v = c.getMatchCondition().getValue();
if (!myConditionInfo.hasCondition(v)) {
if (!myRuleInfo.hasCondition(v)) {
continue;
}
boolean remain = false;
@@ -356,24 +397,13 @@ public class ArrangementMatchingRuleEditor extends JPanel {
}
}
if (!remain) {
myConditionInfo.removeCondition(v);
myRuleInfo.removeCondition(v);
ensureConsistency();
return;
}
}
}
@Nullable
private ArrangementAtomMatchConditionComponent getNodeComponentAt(@NotNull Point screenPoint) {
for (ArrangementAtomMatchConditionComponent component : myComponents.values()) {
Rectangle screenBounds = component.getScreenBounds();
if (screenBounds != null && screenBounds.contains(screenPoint)) {
return component;
}
}
return null;
}
private void repaintComponent(@NotNull ArrangementMatchConditionComponent component) {
Rectangle bounds = component.getScreenBounds();
if (bounds != null) {
@@ -24,6 +24,7 @@ import com.intellij.application.options.codeStyle.arrangement.util.IntObjectMap;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.AbstractTableCellEditor;
@@ -423,12 +424,14 @@ public class ArrangementMatchingRulesControl extends JBTable {
if (value instanceof ArrangementRepresentationAware) {
return ((ArrangementRepresentationAware)value).getComponent();
}
if (!(value instanceof StdArrangementMatchRule)) {
return EMPTY_RENDERER;
}
StdArrangementMatchRule rule = (StdArrangementMatchRule)value;
ArrangementListRowDecorator component = myComponents.get(row);
if (component == null) {
if (!(value instanceof StdArrangementMatchRule)) {
return EMPTY_RENDERER;
}
StdArrangementMatchRule rule = (StdArrangementMatchRule)value;
ArrangementMatchConditionComponent ruleComponent = myFactory.getComponent(rule.getMatcher().getCondition(), rule, true);
component = new ArrangementListRowDecorator(ruleComponent, ArrangementMatchingRulesControl.this);
myComponents.set(row, component);
@@ -438,6 +441,7 @@ public class ArrangementMatchingRulesControl extends JBTable {
component.setRowIndex((myEditorRow >= 0 && row > myEditorRow) ? row : row + 1);
component.setSelected(getSelectionModel().isSelectedIndex(row) || (myEditorRow >= 0 && row == myEditorRow - 1));
component.setBeingEdited(myEditorRow >= 0 && myEditorRow == row + 1);
component.setShowSortIcon(rule.getOrderType() == ArrangementEntryOrderType.BY_NAME);
return component.getUiComponent();
}
}
@@ -0,0 +1,104 @@
/*
* 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.match;
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.util.ArrangementConfigUtil;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SideBorder;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.GridBag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
/**
* @author Denis Zhdanov
* @since 11/15/12 1:01 PM
*/
public class ArrangementOrderTypeComponent extends JPanel {
@NotNull
private final SimpleColoredComponent myTextControl = new SimpleColoredComponent() {
@Override public Dimension getMinimumSize() { return getPreferredSize(); }
@Override public Dimension getMaximumSize() { return getPreferredSize(); }
@Override public Dimension getPreferredSize() { return myTextControlSize == null ? super.getPreferredSize() : myTextControlSize; }
@Override public String toString() { return "text component for " + this; }
};
@NotNull private final ArrangementEntryOrderType myOrderType;
@NotNull private final ArrangementColorsProvider myColorsProvider;
@NotNull private final String myText;
@NotNull private final SideBorder myBorder;
@Nullable private final Dimension myTextControlSize;
@Nullable private Rectangle myScreenBounds;
public ArrangementOrderTypeComponent(@NotNull ArrangementEntryOrderType orderType,
@NotNull ArrangementNodeDisplayManager displayManager,
@NotNull ArrangementColorsProvider colorsProvider,
int width)
{
super(new GridBagLayout());
myOrderType = orderType;
myColorsProvider = colorsProvider;
myTextControl.setTextAlign(SwingConstants.CENTER);
myText = displayManager.getDisplayValue(orderType);
TextAttributes attributes = colorsProvider.getTextAttributes(ArrangementSettingType.ORDER, false);
myTextControl.append(myText, SimpleTextAttributes.fromTextAttributes(attributes));
myTextControlSize = new Dimension(width, myTextControl.getPreferredSize().height);
add(myTextControl, new GridBag().anchor(GridBagConstraints.WEST));
setBorder(myBorder = (SideBorder)IdeBorderFactory.createBorder());
}
public void setSelected(boolean selected) {
myTextControl.clear();
TextAttributes attributes = myColorsProvider.getTextAttributes(ArrangementSettingType.ORDER, selected);
myTextControl.append(myText, SimpleTextAttributes.fromTextAttributes(attributes));
myBorder.setLineColor(myColorsProvider.getBorderColor(selected));
Color myBackgroundColor = attributes.getBackgroundColor();
myTextControl.setBackground(myBackgroundColor);
}
@Override
protected void paintComponent(Graphics g) {
Point point = ArrangementConfigUtil.getLocationOnScreen(this);
if (point != null) {
Rectangle bounds = getBounds();
myScreenBounds = new Rectangle(point.x, point.y, bounds.width, bounds.height);
}
super.paintComponent(g);
}
@NotNull
public ArrangementEntryOrderType getOrderType() {
return myOrderType;
}
@Nullable
public Rectangle getScreenBounds() {
return myScreenBounds;
}
}
@@ -18,6 +18,7 @@ package com.intellij.application.options.codeStyle.arrangement.util;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchConditionComponent;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
@@ -41,6 +42,8 @@ import java.awt.event.MouseEvent;
*/
public class ArrangementListRowDecorator extends JPanel implements ArrangementMatchConditionComponent {
@NotNull private final JLabel mySortLabel = new JLabel(AllIcons.Icons.Inspector.SortByName);
@NotNull private final ArrangementRuleIndexControl myRowIndexControl;
@NotNull private final ArrangementMatchConditionComponent myDelegate;
@NotNull private final ArrangementMatchingRulesControl myControl;
@@ -56,7 +59,9 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementMa
{
myDelegate = delegate;
myControl = control;
mySortLabel.setVisible(false);
AnAction action = ActionManager.getInstance().getAction("Arrangement.Rule.Edit");
Presentation presentation = action.getTemplatePresentation().clone();
Icon editIcon = presentation.getIcon();
@@ -82,6 +87,7 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementMa
GridBag constraints = new GridBag().anchor(GridBagConstraints.CENTER)
.insets(0, ArrangementConstants.HORIZONTAL_PADDING, 0, ArrangementConstants.HORIZONTAL_GAP * 2);
add(myRowIndexControl, constraints);
add(new InsetsPanel(mySortLabel), new GridBag().anchor(GridBagConstraints.CENTER).insets(0, 0, 0, ArrangementConstants.HORIZONTAL_GAP));
add(myDelegate.getUiComponent(), new GridBag().weightx(1).anchor(GridBagConstraints.WEST));
add(myEditButton, new GridBag().anchor(GridBagConstraints.EAST));
setBorder(IdeBorderFactory.createEmptyBorder(ArrangementConstants.VERTICAL_GAP));
@@ -154,6 +160,10 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementMa
myDelegate.setSelected(selected);
}
public void setShowSortIcon(boolean show) {
mySortLabel.setVisible(show);
}
@Override
public Rectangle onMouseEntered(@NotNull MouseEvent e) {
setBackground(UIUtil.getDecoratedRowColor());
@@ -558,6 +558,7 @@ arrangement.text.empty.rule=<empty rule>
arrangement.text.type=Type
arrangement.text.modifier=Modifier
arrangement.text.name=Name
arrangement.order.name=Order
arrangement.action.rule.add.text=Add rule
arrangement.action.rule.add.description=Add new arrangement rule
arrangement.action.rule.remove.text=Remove rule(s)