mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-93476 Built-in code arrangement does not support alphabetization
This commit is contained in:
+42
-1
@@ -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) {
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
+20
@@ -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).
|
||||
*
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
+141
-111
@@ -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) {
|
||||
|
||||
+8
-4
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+104
@@ -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;
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user