diff --git a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy index d8b6216d5edc..ba96018c4730 100644 --- a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy +++ b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtilTest.groovy @@ -141,7 +141,7 @@ node = '4'() @Test void replaceWithTwoLevelMergeToNodeBelow() { - // Init. + // Init. def from; def to; def initial = new TreeNodeBuilder(). @@ -172,6 +172,43 @@ to = '3'()} assertNodesEqual(expected, initial) checkRowMappings([:], rowMappings) } + + @Test + void replaceFirstChildWithMergeBelow() { + // Init. + def from; + def to; + def initial = new TreeNodeBuilder(). + '0' { +from = '1'() { +to = '2'()} + '3'() { + '4'() } + '1' { + '5'() + '6'()} + } + + // Modify. + def replacement = new TreeNodeBuilder(). + '3' { + '2'() + } + def rowMappings = doReplace(initial, from, to, replacement) + + // Check. + def expected = new TreeNodeBuilder(). + '0' { + '3' { + '2'() + '4'()} + '1' { + '5'() + '6'()} + } + assertNodesEqual(expected, initial) + checkRowMappings([ 4 : 3, 5 : 4, 6 : 5, 7 : 6 ], rowMappings) + } @Test void addWithoutMergeAbove() { diff --git a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java index f1e338be484a..be4ea08d840e 100644 --- a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java +++ b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelBuilderTest.java @@ -39,7 +39,7 @@ public class ArrangementRuleEditingModelBuilderTest extends AbstractArrangementR assertTrue(model.hasCondition(STATIC)); assertFalse(model.hasCondition(PRIVATE)); assertEquals(1, myRoot.getChildCount()); - assertEquals(matchCondition, myRoot.getFirstChild().getBackingSetting()); + assertEquals(matchCondition, myRoot.getFirstChild().getBackingCondition()); } @Test @@ -51,11 +51,11 @@ public class ArrangementRuleEditingModelBuilderTest extends AbstractArrangementR ArrangementTreeNode fieldUiNode = myRoot.getFirstChild(); assertNotNull(fieldUiNode); - assertEquals(atom(FIELD), fieldUiNode.getBackingSetting()); + assertEquals(atom(FIELD), fieldUiNode.getBackingCondition()); ArrangementTreeNode modifiersUiNode = fieldUiNode.getFirstChild(); assertNotNull(modifiersUiNode); - assertEquals(and(atom(PUBLIC), atom(STATIC)), modifiersUiNode.getBackingSetting()); + assertEquals(and(atom(PUBLIC), atom(STATIC)), modifiersUiNode.getBackingCondition()); } @Test @@ -67,14 +67,14 @@ public class ArrangementRuleEditingModelBuilderTest extends AbstractArrangementR ArrangementTreeNode fieldUiNode = myRoot.getFirstChild(); assertNotNull(fieldUiNode); - assertEquals(atom(FIELD), fieldUiNode.getBackingSetting()); + assertEquals(atom(FIELD), fieldUiNode.getBackingCondition()); ArrangementTreeNode publicStaticUiNode = fieldUiNode.getFirstChild(); assertNotNull(publicStaticUiNode); - assertEquals(and(atom(PUBLIC), atom(STATIC)), publicStaticUiNode.getBackingSetting()); + assertEquals(and(atom(PUBLIC), atom(STATIC)), publicStaticUiNode.getBackingCondition()); ArrangementTreeNode privateUiNode = fieldUiNode.getLastChild(); assertNotNull(privateUiNode); - assertEquals(atom(PRIVATE), privateUiNode.getBackingSetting()); + assertEquals(atom(PRIVATE), privateUiNode.getBackingCondition()); } } diff --git a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java index ad21cf70d1b3..6ad43d9a2071 100644 --- a/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java +++ b/java/java-tests/testSrc/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImplTest.java @@ -40,7 +40,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode child = myRoot.getFirstChild(); assertNotNull(child); ArrangementMatchCondition expectedMatchCondition = and(atom(PUBLIC), atom(STATIC)); - assertEquals(expectedMatchCondition, child.getBackingSetting()); + assertEquals(expectedMatchCondition, child.getBackingCondition()); assertEquals(expectedMatchCondition, model.getMatchCondition()); } @@ -58,11 +58,11 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); - assertEquals(atom(FIELD), fieldNode.getBackingSetting()); + assertEquals(atom(FIELD), fieldNode.getBackingCondition()); ArrangementTreeNode publicNode = fieldNode.getFirstChild(); assertNotNull(publicNode); - assertEquals(atom(PUBLIC), publicNode.getBackingSetting()); + assertEquals(atom(PUBLIC), publicNode.getBackingCondition()); } @Test @@ -80,11 +80,11 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); - assertEquals(atom(FIELD), fieldNode.getBackingSetting()); + assertEquals(atom(FIELD), fieldNode.getBackingCondition()); ArrangementTreeNode modifiersNode = fieldNode.getFirstChild(); assertNotNull(modifiersNode); - assertEquals(and(atom(PUBLIC), atom(STATIC)), modifiersNode.getBackingSetting()); + assertEquals(and(atom(PUBLIC), atom(STATIC)), modifiersNode.getBackingCondition()); } @Test @@ -102,11 +102,11 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); - assertEquals(atom(FIELD), fieldNode.getBackingSetting()); + assertEquals(atom(FIELD), fieldNode.getBackingCondition()); ArrangementTreeNode modifiersNode = fieldNode.getFirstChild(); assertNotNull(modifiersNode); - assertEquals(atom(STATIC), modifiersNode.getBackingSetting()); + assertEquals(atom(STATIC), modifiersNode.getBackingCondition()); } @Test @@ -123,7 +123,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode fieldNode = myRoot.getFirstChild(); assertNotNull(fieldNode); - assertEquals(atom(FIELD), fieldNode.getBackingSetting()); + assertEquals(atom(FIELD), fieldNode.getBackingCondition()); assertEquals(0, fieldNode.getChildCount()); } @@ -150,15 +150,15 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode atomFieldNode = myRoot.getFirstChild(); assertNotNull(atomFieldNode); - assertEquals(atom(FIELD), atomFieldNode.getBackingSetting()); + assertEquals(atom(FIELD), atomFieldNode.getBackingCondition()); ArrangementTreeNode layeredFieldNode = atomFieldNode.getNextSibling(); assertNotNull(atomFieldNode); - assertEquals(atom(FIELD), atomFieldNode.getBackingSetting()); + assertEquals(atom(FIELD), atomFieldNode.getBackingCondition()); ArrangementTreeNode staticNode = layeredFieldNode.getFirstChild(); assertNotNull(staticNode); - assertEquals(atom(STATIC), staticNode.getBackingSetting()); + assertEquals(atom(STATIC), staticNode.getBackingCondition()); } @Test @@ -184,14 +184,14 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule ArrangementTreeNode compositeFieldNode = myRoot.getFirstChild(); assertNotNull(compositeFieldNode); - assertEquals(atom(FIELD), compositeFieldNode.getBackingSetting()); + assertEquals(atom(FIELD), compositeFieldNode.getBackingCondition()); ArrangementTreeNode publicNode = compositeFieldNode.getFirstChild(); assertNotNull(publicNode); - assertEquals(atom(PUBLIC), publicNode.getBackingSetting()); + assertEquals(atom(PUBLIC), publicNode.getBackingCondition()); ArrangementTreeNode atomFieldNode = compositeFieldNode.getNextSibling(); assertNotNull(atomFieldNode); - assertEquals(atom(FIELD), atomFieldNode.getBackingSetting()); + assertEquals(atom(FIELD), atomFieldNode.getBackingCondition()); } } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementCompositeMatchCondition.java b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementCompositeMatchCondition.java index db001821090f..fa92ddb914ad 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementCompositeMatchCondition.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/arrangement/model/ArrangementCompositeMatchCondition.java @@ -24,7 +24,7 @@ import java.util.Set; /** * Encapsulates composite match condition, e.g. "an entry has type 'field' and modifier 'static'". *

- * Thread-safe. + * Not thread-safe. * * @author Denis Zhdanov * @since 8/8/12 1:18 PM diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java index a13ae0cdad4e..9e87d263148d 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementConfigUtil.java @@ -188,7 +188,7 @@ public class ArrangementConfigUtil { int rowsCreated = 0; if (uiParentNode != null && uiParentNode.getChildCount() > 0) { ArrangementTreeNode child = uiParentNode.getChildAt(uiParentNode.getChildCount() - 1); - if (conditionNode.getCurrent().equals(child.getBackingSetting())) { + if (conditionNode.getCurrent().equals(child.getBackingCondition())) { uiNode = child; } } @@ -316,7 +316,7 @@ public class ArrangementConfigUtil { parentCopy.add(cutHierarchy); } for (int j = i + 1; j < childCount; j++) { - ArrangementTreeNode child = parent.getChildAt(j); + ArrangementTreeNode child = parent.getChildAt(i + 1); treeModel.removeNodeFromParent(child); parentCopy.add(child); } @@ -527,8 +527,8 @@ public class ArrangementConfigUtil { } private static boolean hasEqualSetting(@NotNull ArrangementTreeNode node1, @NotNull ArrangementTreeNode node2) { - ArrangementMatchCondition matchCondition1 = node1.getBackingSetting(); - ArrangementMatchCondition matchCondition2 = node2.getBackingSetting(); + ArrangementMatchCondition matchCondition1 = node1.getBackingCondition(); + ArrangementMatchCondition matchCondition2 = node2.getBackingCondition(); if (matchCondition1 == null) { return matchCondition2 == null; } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatcherRuleEditor.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatchConditionEditor.java similarity index 87% rename from platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatcherRuleEditor.java rename to platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatchConditionEditor.java index 0c58485438e4..f4f78563d208 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatcherRuleEditor.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementMatchConditionEditor.java @@ -39,7 +39,7 @@ import java.util.List; * @author Denis Zhdanov * @since 8/14/12 9:54 AM */ -public class ArrangementMatcherRuleEditor extends JPanel { +public class ArrangementMatchConditionEditor extends JPanel { @NotNull private final List myColoredComponents = new ArrayList(); @NotNull private final Map myComponents = @@ -48,8 +48,8 @@ public class ArrangementMatcherRuleEditor extends JPanel { @NotNull private final ArrangementStandardSettingsAware myFilter; @Nullable private ArrangementRuleEditingModel myModel; - public ArrangementMatcherRuleEditor(@NotNull ArrangementStandardSettingsAware filter, - @NotNull ArrangementNodeDisplayManager displayManager) + public ArrangementMatchConditionEditor(@NotNull ArrangementStandardSettingsAware filter, + @NotNull ArrangementNodeDisplayManager displayManager) { myFilter = filter; init(displayManager); @@ -138,30 +138,33 @@ public class ArrangementMatcherRuleEditor extends JPanel { if (component == null) { return; } - ArrangementAtomMatchCondition setting = component.getMatchCondition(); - boolean remove = myModel.hasCondition(setting.getValue()); + ArrangementAtomMatchCondition chosenCondition = component.getMatchCondition(); + boolean remove = myModel.hasCondition(chosenCondition.getValue()); component.setSelected(!remove); repaintComponent(component); if (remove) { - myModel.removeAndCondition(setting); + myModel.removeAndCondition(chosenCondition); return; } Collection> mutexes = myFilter.getMutexes(); for (Set mutex : mutexes) { - if (!mutex.contains(setting.getValue())) { + if (!mutex.contains(chosenCondition.getValue())) { continue; } for (Object key : mutex) { if (myModel.hasCondition(key)) { ArrangementAtomNodeComponent componentToDeselect = myComponents.get(key); - componentToDeselect.setSelected(false); - myModel.removeAndCondition(componentToDeselect.getMatchCondition()); - repaintComponent(componentToDeselect); + myModel.replaceCondition(componentToDeselect.getMatchCondition(), chosenCondition); + + // There is a possible case that some conditions become unavailable, e.g. changing type from 'field' to 'method' + // makes 'volatile' condition inappropriate. + updateState(myModel); + return; } } } - myModel.addAndCondition(setting); + myModel.addAndCondition(chosenCondition); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java index 4b47856a9349..363c6a4f3e3e 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModel.java @@ -48,4 +48,18 @@ public interface ArrangementRuleEditingModel { void addAndCondition(@NotNull ArrangementAtomMatchCondition condition); void removeAndCondition(@NotNull ArrangementMatchCondition condition); + + /** + * We need to be able to replace one condition by another. Most of the time it can be simulated by + * {@link #removeAndCondition(ArrangementMatchCondition) 'remove old'} and + * {@link #addAndCondition(ArrangementAtomMatchCondition) 'add new'} actions sequence but that doesn't work when + * {@link #getMatchCondition() underlying condition} has the only atom condition. Removing it eliminates the condition at all. + * + * @param from condition which should be replaced + * @param to replacement condition + * @throws IllegalArgumentException when given 'from' condition is not a part of the + * {@link #getMatchCondition() underlying match condition} + */ + void replaceCondition(@NotNull ArrangementAtomMatchCondition from, @NotNull ArrangementAtomMatchCondition to) + throws IllegalArgumentException; } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java index f635804743b0..4fb6f360c76a 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleEditingModelImpl.java @@ -34,8 +34,6 @@ import java.util.Set; */ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingModel { - private static final TIntIntHashMap EMPTY_CHANGES = new TIntIntHashMap(); - @NotNull private static final MyConditionsBuilder CONDITIONS_BUILDER = new MyConditionsBuilder(); @NotNull private final Set myListeners = new HashSet(); @@ -129,8 +127,8 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo // No refresh is necessary. return; } - ArrangementMatchCondition matchCondition = myTopMost.getBackingSetting(); - if (matchCondition != null && matchCondition.equals(node.getBackingSetting())) { + ArrangementMatchCondition matchCondition = myTopMost.getBackingCondition(); + if (matchCondition != null && matchCondition.equals(node.getBackingCondition())) { myTopMost = node; return; } @@ -140,62 +138,78 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo @Override public void addAndCondition(@NotNull ArrangementAtomMatchCondition condition) { - TIntIntHashMap rowChanges = doAddAndCondition(condition); - refreshConditions(); - notifyListeners(rowChanges); + ArrangementMatchCondition newCondition = ArrangementUtil.and(myMatchCondition.clone(), condition); + applyNewCondition(newCondition); } - @NotNull - private TIntIntHashMap doAddAndCondition(@NotNull ArrangementAtomMatchCondition condition) { - ArrangementMatchCondition newNode = ArrangementUtil.and(myMatchCondition.clone(), condition); - return applyNewCondition(newNode); - } - @Override public void removeAndCondition(@NotNull ArrangementMatchCondition condition) { - TIntIntHashMap rowChanges = doRemoveAndCondition(condition); - refreshConditions(); - notifyListeners(rowChanges); + if (!(myMatchCondition instanceof ArrangementCompositeMatchCondition)) { + // TODO den implement + return; + } + + ArrangementMatchCondition newCondition = myMatchCondition.clone(); + ArrangementCompositeMatchCondition composite = (ArrangementCompositeMatchCondition)newCondition; + composite.getOperands().remove(condition); + if (composite.getOperands().size() == 1) { + newCondition = composite.getOperands().iterator().next(); + } + applyNewCondition(newCondition); } - @NotNull - private TIntIntHashMap doRemoveAndCondition(@NotNull ArrangementMatchCondition node) { - if (!(myMatchCondition instanceof ArrangementCompositeMatchCondition)) { - return EMPTY_CHANGES; - } - - ArrangementMatchCondition newNode = myMatchCondition.clone(); - ArrangementCompositeMatchCondition composite = (ArrangementCompositeMatchCondition)newNode; - composite.getOperands().remove(node); - if (composite.getOperands().size() == 1) { - newNode = composite.getOperands().iterator().next(); - } - - return applyNewCondition(newNode); - } - - @NotNull - private TIntIntHashMap applyNewCondition(@NotNull ArrangementMatchCondition newNode) { + private void applyNewCondition(@NotNull ArrangementMatchCondition newNode) { myMatchCondition = newNode; HierarchicalArrangementConditionNode grouped = myGrouper.group(newNode); - int newDepth = ArrangementConfigUtil.getDepth(grouped); - int oldDepth = ArrangementConfigUtil.distance(myTopMost, myBottomMost); - if (oldDepth == newDepth) { - myBottomMost.setSettings(ArrangementConfigUtil.getLast(grouped).getCurrent()); - return EMPTY_CHANGES; - } - Pair replacement = ArrangementConfigUtil.map(null, grouped, null); ArrangementTreeNode newBottom = replacement.first; ArrangementTreeNode newTop = ArrangementConfigUtil.getRoot(newBottom); final TIntIntHashMap rowChanges = ArrangementConfigUtil.replace(myTopMost, myBottomMost, newTop, myTreeModel, myRootVisible); - myTopMost = newTop; myBottomMost = newBottom; + for (ArrangementTreeNode node = myBottomMost.getParent(); node != null; node = node.getParent()) { + // There is a possible case that top condition is merged into existing one, hence, we need to refresh it. + ArrangementMatchCondition condition = node.getBackingCondition(); + if (condition != null && condition.equals(newTop.getBackingCondition())) { + newTop = node; + } + } + myTopMost = newTop; rowChanges.remove(myRow); int newRow = ArrangementConfigUtil.getRow(myBottomMost, myRootVisible); rowChanges.put(myRow, newRow); myRow = newRow; - return rowChanges; + refreshConditions(); + notifyListeners(rowChanges); + } + + @Override + public void replaceCondition(@NotNull ArrangementAtomMatchCondition from, @NotNull ArrangementAtomMatchCondition to) + throws IllegalArgumentException + { + for (ArrangementTreeNode node = myBottomMost; node != null; node = node.getParent()) { + if (from.equals(node.getBackingCondition())) { + ArrangementMatchCondition newCondition; + if (myMatchCondition.equals(from)) { + newCondition = to; + } + else { + assert myMatchCondition instanceof ArrangementCompositeMatchCondition; + ArrangementCompositeMatchCondition composite = (ArrangementCompositeMatchCondition)myMatchCondition; + ArrangementCompositeMatchCondition newComposite = composite.clone(); + newComposite.getOperands().remove(from); + newComposite.getOperands().add(to); + newCondition = newComposite; + } + applyNewCondition(newCondition); + return; + } + if (node == myTopMost) { + throw new IllegalArgumentException(String.format( + "Can't perform arrangement match condition modification ('%s' -> '%s'). Reason: target condition doesn't have " + + "'%s' condition - %s", + from, to, from, myMatchCondition)); + } + } } public void addListener(@NotNull Listener listener) { diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java index bebbc4a502b1..e6a547658d1d 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementRuleTree.java @@ -434,6 +434,8 @@ public class ArrangementRuleTree { } private void onModelChange(@NotNull ArrangementRuleEditingModelImpl model, @NotNull final TIntIntHashMap rowChanges) { + expandAll(myTree, new TreePath(myTreeModel.getRoot())); + // Refresh models. myModels.forEachValue(myModelNodesRefresher); @@ -455,14 +457,36 @@ public class ArrangementRuleTree { } return true; } + + }); putAll(changedModelMappings, myModels); putAll(changedRendererMappings, myRenderers); + + // Drop JTree visual caches. + rowChanges.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int oldRow, int newRow) { + refreshTreeNode(oldRow); + refreshTreeNode(newRow); + return true; + } + private void refreshTreeNode(int row) { + TreePath path = myTree.getPathForRow(row); + if (path == null) { + return; + } + TreeNode node = (TreeNode)path.getLastPathComponent(); + if (node == null) { + return; + } + myTreeModel.nodeStructureChanged(node); + } + }); // Perform necessary actions for the changed model. ArrangementTreeNode topMost = model.getTopMost(); ArrangementTreeNode bottomMost = model.getBottomMost(); - expandAll(myTree, new TreePath(myTreeModel.getRoot())); doClearSelection(); myExplicitSelectionChange = true; try { @@ -470,9 +494,10 @@ public class ArrangementRuleTree { TreePath path = new TreePath(node.getPath()); int row = myTree.getRowForPath(path); myRenderers.remove(row); + mySelectionModel.addSelectionPath(path); myTreeModel.nodeChanged(node); mySelectionModel.addSelectionPath(path); - ArrangementMatchCondition matchCondition = node.getBackingSetting(); + ArrangementMatchCondition matchCondition = node.getBackingCondition(); if (matchCondition != null) { getNodeComponentAt(row, matchCondition).setSelected(true); } @@ -506,7 +531,7 @@ public class ArrangementRuleTree { int row, boolean hasFocus) { - ArrangementMatchCondition node = ((ArrangementTreeNode)value).getBackingSetting(); + ArrangementMatchCondition node = ((ArrangementTreeNode)value).getBackingCondition(); if (node == null) { return EMPTY_RENDERER; } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java index 06b964fd7711..7a53fdba7df6 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementSettingsPanel.java @@ -64,7 +64,7 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel { ); final JXTaskPane editorPane = new JXTaskPane(ApplicationBundle.message("arrangement.title.editor")); - final ArrangementMatcherRuleEditor ruleEditor = new ArrangementMatcherRuleEditor(filter, displayManager); + final ArrangementMatchConditionEditor ruleEditor = new ArrangementMatchConditionEditor(filter, displayManager); ruleEditor.applyBackground(component.getBackground()); editorPane.getContentPane().setBackground(component.getBackground()); editorPane.add(ruleEditor); diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java index 4e07dd18e0dd..165d06901b13 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/ArrangementTreeNode.java @@ -22,7 +22,10 @@ import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultMutableTreeNode; /** - * // TODO den add doc + * JTree node for arrangement rule tree. + *

+ * The general idea is to provide two additional properties - {@link #getBackingCondition() backing condition} and {@link #getRow() row} + * and encapsulate class casts. * * @author Denis Zhdanov * @since 8/20/12 10:53 PM @@ -31,25 +34,21 @@ public class ArrangementTreeNode extends DefaultMutableTreeNode { private static final int NO_ROW = -1; - @Nullable private ArrangementMatchCondition mySettings; - private int myRow; + @Nullable private final ArrangementMatchCondition myCondition; + private int myRow; - public ArrangementTreeNode(@Nullable ArrangementMatchCondition settings) { - this(settings, NO_ROW); + public ArrangementTreeNode(@Nullable ArrangementMatchCondition condition) { + this(condition, NO_ROW); } - public ArrangementTreeNode(@Nullable ArrangementMatchCondition settings, int row) { - mySettings = settings; + public ArrangementTreeNode(@Nullable ArrangementMatchCondition condition, int row) { + myCondition = condition; myRow = row; } @Nullable - public ArrangementMatchCondition getBackingSetting() { - return mySettings; - } - - public void setSettings(@Nullable ArrangementMatchCondition settings) { - mySettings = settings; + public ArrangementMatchCondition getBackingCondition() { + return myCondition; } public boolean isRowSet() { @@ -71,9 +70,10 @@ public class ArrangementTreeNode extends DefaultMutableTreeNode { @NotNull public ArrangementTreeNode copy() { // Settings are copied by-ref intentionally here. - return new ArrangementTreeNode(mySettings, myRow); + return new ArrangementTreeNode(myCondition, myRow); } + @Nullable @Override public ArrangementTreeNode getParent() { return (ArrangementTreeNode)super.getParent(); @@ -111,6 +111,6 @@ public class ArrangementTreeNode extends DefaultMutableTreeNode { @Override public String toString() { - return mySettings == null ? "" : mySettings.toString() + (myRow >= 0 ? ": row=" + myRow : ""); + return myCondition == null ? "" : myCondition.toString() + (myRow >= 0 ? ": row=" + myRow : ""); } }