mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-19061 Integrate the Rearranger-plugin into core-IDE
Added ability to remove match rules
This commit is contained in:
+61
-7
@@ -51,7 +51,7 @@ four = '4'()
|
||||
'1' {
|
||||
'4'()
|
||||
}
|
||||
def rowMappings = doReplace(initial, one, four, replacement)
|
||||
def rowMappings = doReplace(one, four, replacement)
|
||||
|
||||
// Check
|
||||
def expected = new TreeNodeBuilder().
|
||||
@@ -88,7 +88,7 @@ to = '5'()
|
||||
'1' {
|
||||
'5'()
|
||||
}
|
||||
def rowMappings = doReplace(initial, from, to, replacement)
|
||||
def rowMappings = doReplace(from, to, replacement)
|
||||
|
||||
// Check.
|
||||
def expected = new TreeNodeBuilder().
|
||||
@@ -123,7 +123,7 @@ node = '4'()
|
||||
'1' {
|
||||
'4'()
|
||||
}
|
||||
def rowMappings = doReplace(initial, node, node, replacement)
|
||||
def rowMappings = doReplace(node, node, replacement)
|
||||
|
||||
// Check.
|
||||
def expected = new TreeNodeBuilder().
|
||||
@@ -158,7 +158,7 @@ to = '3'()}
|
||||
'4' {
|
||||
'3'()
|
||||
}
|
||||
def rowMappings = doReplace(initial, from, to, replacement)
|
||||
def rowMappings = doReplace(from, to, replacement)
|
||||
|
||||
// Check.
|
||||
def expected = new TreeNodeBuilder().
|
||||
@@ -194,7 +194,7 @@ to = '2'()}
|
||||
'3' {
|
||||
'2'()
|
||||
}
|
||||
def rowMappings = doReplace(initial, from, to, replacement)
|
||||
def rowMappings = doReplace(from, to, replacement)
|
||||
|
||||
// Check.
|
||||
def expected = new TreeNodeBuilder().
|
||||
@@ -361,15 +361,69 @@ to = '2'()}
|
||||
doInsert(initial, 3, toAdd)
|
||||
assertNodesEqual(expected, initial)
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeFirst() {
|
||||
def from;
|
||||
def to;
|
||||
def initial = new TreeNodeBuilder().
|
||||
'0' {
|
||||
from = '1' {
|
||||
to = '2'()
|
||||
'3'()}
|
||||
'4'()
|
||||
}
|
||||
|
||||
def expected = new TreeNodeBuilder().
|
||||
'0' {
|
||||
'1' {
|
||||
'3'()}
|
||||
'4'()
|
||||
}
|
||||
|
||||
def rowMappings = doRemove(from, to)
|
||||
assertNodesEqual(expected, initial)
|
||||
checkRowMappings([ 3 : 2, 4 : 3 ], rowMappings)
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeWithMerge() {
|
||||
def from;
|
||||
def to;
|
||||
def initial = new TreeNodeBuilder().
|
||||
'0' {
|
||||
'1' {
|
||||
'2'()}
|
||||
from = '3'() {
|
||||
to = '4'()}
|
||||
'1' {
|
||||
'5'()}
|
||||
}
|
||||
|
||||
def expected = new TreeNodeBuilder().
|
||||
'0' {
|
||||
'1' {
|
||||
'2'()
|
||||
'5'()}
|
||||
}
|
||||
|
||||
def rowMappings = doRemove(from, to)
|
||||
assertNodesEqual(expected, initial)
|
||||
checkRowMappings([ 6 : 3 ], rowMappings)
|
||||
}
|
||||
|
||||
private static def doReplace(initial, from, to, replacement) {
|
||||
ArrangementConfigUtil.replace(from, to, replacement, new DefaultTreeModel(initial), true)
|
||||
private static def doReplace(from, to, replacement) {
|
||||
ArrangementConfigUtil.replace(from, to, replacement, new DefaultTreeModel(ArrangementConfigUtil.getRoot(from)), true)
|
||||
}
|
||||
|
||||
private static def doInsert(parent, i, child) {
|
||||
ArrangementConfigUtil.insert(parent, i, child, new DefaultTreeModel(ArrangementConfigUtil.getRoot(parent)))
|
||||
}
|
||||
|
||||
private static def doRemove(from, to) {
|
||||
ArrangementConfigUtil.remove(from, to, new DefaultTreeModel(ArrangementConfigUtil.getRoot(from)), true)
|
||||
}
|
||||
|
||||
private static void assertNodesEqual(@NotNull ArrangementTreeNode expected, @NotNull ArrangementTreeNode actual) {
|
||||
assertEquals(expected.userObject, actual.userObject)
|
||||
assertEquals(expected.childCount, actual.childCount)
|
||||
|
||||
+11
-1
@@ -16,6 +16,7 @@
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.intellij.psi.codeStyle.arrangement.ArrangementUtil.and;
|
||||
@@ -90,7 +91,7 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
@Test
|
||||
public void removeAndKeepAllLevels() {
|
||||
configure(and(atom(FIELD), atom(PUBLIC), atom(STATIC)));
|
||||
ArrangementRuleEditingModel model = myRowMappings.get(2);
|
||||
ArrangementRuleEditingModelImpl model = myRowMappings.get(2);
|
||||
assertNotNull(model);
|
||||
assertEquals(1, myRowMappings.size());
|
||||
|
||||
@@ -107,6 +108,8 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
ArrangementTreeNode modifiersNode = fieldNode.getFirstChild();
|
||||
assertNotNull(modifiersNode);
|
||||
assertEquals(atom(STATIC), modifiersNode.getBackingCondition());
|
||||
|
||||
checkModelTreeNodesConsistency(model);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -194,4 +197,11 @@ public class ArrangementRuleEditingModelImplTest extends AbstractArrangementRule
|
||||
assertNotNull(atomFieldNode);
|
||||
assertEquals(atom(FIELD), atomFieldNode.getBackingCondition());
|
||||
}
|
||||
|
||||
private void checkModelTreeNodesConsistency(@NotNull ArrangementRuleEditingModelImpl model) {
|
||||
model.refreshTreeNodes();
|
||||
ArrangementTreeNode root = ArrangementConfigUtil.getRoot(model.getBottomMost());
|
||||
assertSame(myRoot, root);
|
||||
assertSame(root, ArrangementConfigUtil.getRoot(model.getTopMost()));
|
||||
}
|
||||
}
|
||||
|
||||
+43
-7
@@ -217,7 +217,7 @@ public class ArrangementConfigUtil {
|
||||
/**
|
||||
* Utility method which helps to replace node sub-hierarchy identified by the given start and end nodes (inclusive) by
|
||||
* a sub-hierarchy which is denoted by the given root.
|
||||
*
|
||||
*
|
||||
* @param from indicates start of the node sub-hierarchy (top-most node) to be replaced (inclusive)
|
||||
* @param to indicates end of the node sub-hierarchy (bottom-most node) to be replaced (inclusive)
|
||||
* @param replacement root of the node sub-hierarchy which should replace the one identified by the given 'start' and 'end' nodes
|
||||
@@ -225,20 +225,34 @@ public class ArrangementConfigUtil {
|
||||
* @param rootVisible determines if the root should be count during rows calculations
|
||||
* @return collection of row changes at the form {@code 'old row -> new row'}
|
||||
*/
|
||||
@SuppressWarnings("AssignmentToForLoopParameter")
|
||||
@NotNull
|
||||
public static TIntIntHashMap replace(@NotNull ArrangementTreeNode from,
|
||||
@NotNull ArrangementTreeNode to,
|
||||
@NotNull ArrangementTreeNode replacement,
|
||||
@NotNull DefaultTreeModel treeModel,
|
||||
boolean rootVisible)
|
||||
{
|
||||
return doReplace(from, to, replacement, treeModel, rootVisible);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("AssignmentToForLoopParameter")
|
||||
@NotNull
|
||||
private static TIntIntHashMap doReplace(@NotNull ArrangementTreeNode from,
|
||||
@NotNull ArrangementTreeNode to,
|
||||
@Nullable ArrangementTreeNode replacement,
|
||||
@NotNull DefaultTreeModel treeModel,
|
||||
boolean rootVisible)
|
||||
{
|
||||
markRows(from, rootVisible);
|
||||
if (from == to) {
|
||||
ArrangementTreeNode parent = from.getParent();
|
||||
assert parent != null;
|
||||
int index = parent.getIndex(from);
|
||||
treeModel.removeNodeFromParent(from);
|
||||
insert(parent, index, replacement, treeModel);
|
||||
if (replacement != null) {
|
||||
insert(parent, index, replacement, treeModel);
|
||||
}
|
||||
return collectRowChangesAndUnmark(parent, rootVisible);
|
||||
}
|
||||
|
||||
@@ -298,11 +312,13 @@ public class ArrangementConfigUtil {
|
||||
// Note: we need to have a notion of 'equal nodes' for node re-usage. It's provided by comparing node user objects.
|
||||
|
||||
final ArrangementTreeNode root = from.getParent();
|
||||
assert root != null;
|
||||
|
||||
//region Cut bottom sub-hierarchy
|
||||
ArrangementTreeNode cutHierarchy = null;
|
||||
for (ArrangementTreeNode current = to; current != root; current = current.getParent()) {
|
||||
ArrangementTreeNode parent = current.getParent();
|
||||
assert parent != null;
|
||||
int i = parent.getIndex(current);
|
||||
int childCount = parent.getChildCount();
|
||||
if (i >= childCount - 1) {
|
||||
@@ -331,7 +347,7 @@ public class ArrangementConfigUtil {
|
||||
ArrangementTreeNode parent = current.getParent();
|
||||
treeModel.removeNodeFromParent(current);
|
||||
current = parent;
|
||||
if (parent.getChildCount() > 0) {
|
||||
if (parent == null || parent.getChildCount() > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -339,7 +355,9 @@ public class ArrangementConfigUtil {
|
||||
|
||||
//region Insert nodes.
|
||||
int insertionIndex = root.getChildCount() < childCountBefore ? childCountBefore - 1 : childCountBefore;
|
||||
insert(root, insertionIndex, replacement, treeModel);
|
||||
if (replacement != null) {
|
||||
insert(root, insertionIndex, replacement, treeModel);
|
||||
}
|
||||
if (cutHierarchy != null) {
|
||||
List<ArrangementTreeNode> toInsert = new ArrayList<ArrangementTreeNode>();
|
||||
if (hasEqualSetting(root, cutHierarchy)) {
|
||||
@@ -380,7 +398,7 @@ public class ArrangementConfigUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ArrangementTreeNode getRoot(ArrangementTreeNode node) {
|
||||
public static ArrangementTreeNode getRoot(@NotNull ArrangementTreeNode node) {
|
||||
ArrangementTreeNode root = node;
|
||||
for (ArrangementTreeNode n = root; n != null; n = n.getParent()) {
|
||||
root = n;
|
||||
@@ -536,4 +554,22 @@ public class ArrangementConfigUtil {
|
||||
return matchCondition1.equals(matchCondition2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes target sub-hierarchy from the tree.
|
||||
*
|
||||
* @param from indicates start of the node sub-hierarchy (top-most node) to be replaced (inclusive)
|
||||
* @param to indicates end of the node sub-hierarchy (bottom-most node) to be replaced (inclusive)
|
||||
* @param treeModel model which should hold ui nodes
|
||||
* @param rootVisible determines if the root should be count during rows calculations
|
||||
* @return collection of row changes at the form {@code 'old row -> new row'}
|
||||
*/
|
||||
@NotNull
|
||||
public static TIntIntHashMap remove(@NotNull final ArrangementTreeNode from,
|
||||
@NotNull final ArrangementTreeNode to,
|
||||
@NotNull DefaultTreeModel model,
|
||||
boolean rootVisible)
|
||||
{
|
||||
return doReplace(from, to, null, model, rootVisible);
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -35,6 +35,13 @@ public interface ArrangementRuleEditingModel {
|
||||
@NotNull
|
||||
ArrangementMatchCondition getMatchCondition();
|
||||
|
||||
/**
|
||||
* Asks current model to destroy itself.
|
||||
* <p/>
|
||||
* The key concern here is to perform necessary tree modification.
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
/**
|
||||
* Allows to answer if current model has a registered condition for the given key. A key is expected to be one of the standard
|
||||
* keys, e.g. {@link ArrangementEntryType type}, {@link ArrangementModifier modifier} etc.
|
||||
|
||||
+37
-43
@@ -144,11 +144,12 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
|
||||
@Override
|
||||
public void removeAndCondition(@NotNull ArrangementMatchCondition condition) {
|
||||
if (!(myMatchCondition instanceof ArrangementCompositeMatchCondition)) {
|
||||
// TODO den implement
|
||||
if (myMatchCondition.equals(condition)) {
|
||||
destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
assert myMatchCondition instanceof ArrangementCompositeMatchCondition;
|
||||
ArrangementMatchCondition newCondition = myMatchCondition.clone();
|
||||
ArrangementCompositeMatchCondition composite = (ArrangementCompositeMatchCondition)newCondition;
|
||||
composite.getOperands().remove(condition);
|
||||
@@ -166,49 +167,46 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
ArrangementTreeNode newTop = ArrangementConfigUtil.getRoot(newBottom);
|
||||
final TIntIntHashMap rowChanges = ArrangementConfigUtil.replace(myTopMost, myBottomMost, newTop, myTreeModel, myRootVisible);
|
||||
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);
|
||||
refreshTreeNodes();
|
||||
int newRow = ArrangementConfigUtil.getRow(myBottomMost, myRootVisible);
|
||||
rowChanges.put(myRow, newRow);
|
||||
myRow = newRow;
|
||||
if (myRow != newRow) {
|
||||
rowChanges.put(myRow, newRow);
|
||||
myRow = newRow;
|
||||
}
|
||||
refreshConditions();
|
||||
notifyListeners(rowChanges);
|
||||
for (Listener listener : myListeners) {
|
||||
listener.onChanged(this, 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));
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
for (Listener listener : myListeners) {
|
||||
listener.beforeModelDestroy(this);
|
||||
}
|
||||
TIntIntHashMap rowChanges = ArrangementConfigUtil.remove(myTopMost, myBottomMost, myTreeModel, myRootVisible);
|
||||
for (Listener listener : myListeners) {
|
||||
listener.afterModelDestroy(rowChanges);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,12 +214,6 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
private void notifyListeners(@NotNull TIntIntHashMap rowChanges) {
|
||||
for (Listener listener : myListeners) {
|
||||
listener.onChanged(this, rowChanges);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "model for " + myMatchCondition;
|
||||
@@ -246,5 +238,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
|
||||
|
||||
public interface Listener {
|
||||
void onChanged(@NotNull ArrangementRuleEditingModelImpl model, @NotNull TIntIntHashMap rowChanges);
|
||||
void beforeModelDestroy(@NotNull ArrangementRuleEditingModelImpl model);
|
||||
void afterModelDestroy(@NotNull TIntIntHashMap rowChanges);
|
||||
}
|
||||
}
|
||||
|
||||
+66
-52
@@ -341,10 +341,10 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ArrangementNodeComponent getNodeComponentAt(int row, @NotNull ArrangementMatchCondition node) {
|
||||
private ArrangementNodeComponent getNodeComponentAt(int row, @NotNull ArrangementMatchCondition condition) {
|
||||
ArrangementNodeComponent result = myRenderers.get(row);
|
||||
if (result == null) {
|
||||
myRenderers.put(row, result = myFactory.getComponent(node));
|
||||
if (result == null || !result.getMatchCondition().equals(condition)) {
|
||||
myRenderers.put(row, result = myFactory.getComponent(condition));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -434,55 +434,7 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
|
||||
private void onModelChange(@NotNull ArrangementRuleEditingModelImpl model, @NotNull final TIntIntHashMap rowChanges) {
|
||||
expandAll(myTree, new TreePath(myTreeModel.getRoot()));
|
||||
|
||||
// Refresh models.
|
||||
myModels.forEachValue(myModelNodesRefresher);
|
||||
|
||||
// Shift row-based caches.
|
||||
final TIntObjectHashMap<ArrangementRuleEditingModelImpl> changedModelMappings =
|
||||
new TIntObjectHashMap<ArrangementRuleEditingModelImpl>();
|
||||
final TIntObjectHashMap<ArrangementNodeComponent> changedRendererMappings = new TIntObjectHashMap<ArrangementNodeComponent>();
|
||||
rowChanges.forEachEntry(new TIntIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int oldRow, int newRow) {
|
||||
ArrangementRuleEditingModelImpl m = myModels.remove(oldRow);
|
||||
if (m != null) {
|
||||
changedModelMappings.put(newRow, m);
|
||||
}
|
||||
|
||||
ArrangementNodeComponent renderer = myRenderers.remove(oldRow);
|
||||
if (renderer != null) {
|
||||
changedRendererMappings.put(newRow, renderer);
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
processRowChanges(rowChanges);
|
||||
|
||||
// Perform necessary actions for the changed model.
|
||||
ArrangementTreeNode topMost = model.getTopMost();
|
||||
@@ -511,6 +463,51 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
}
|
||||
|
||||
private void processRowChanges(TIntIntHashMap rowChanges) {
|
||||
expandAll(myTree, new TreePath(myTreeModel.getRoot()));
|
||||
|
||||
// Refresh models.
|
||||
myModels.forEachValue(myModelNodesRefresher);
|
||||
|
||||
// Shift row-based caches.
|
||||
final TIntObjectHashMap<ArrangementRuleEditingModelImpl> changedModelMappings =
|
||||
new TIntObjectHashMap<ArrangementRuleEditingModelImpl>();
|
||||
rowChanges.forEachEntry(new TIntIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int oldRow, int newRow) {
|
||||
ArrangementRuleEditingModelImpl m = myModels.remove(oldRow);
|
||||
if (m != null) {
|
||||
changedModelMappings.put(newRow, m);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
putAll(changedModelMappings, myModels);
|
||||
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> void putAll(@NotNull TIntObjectHashMap<T> from, @NotNull final TIntObjectHashMap<T> to) {
|
||||
from.forEachEntry(new TIntObjectProcedure<T>() {
|
||||
@Override
|
||||
@@ -590,6 +587,23 @@ public class ArrangementRuleTree {
|
||||
public void onChanged(@NotNull ArrangementRuleEditingModelImpl model, @NotNull TIntIntHashMap rowChanges) {
|
||||
onModelChange(model, rowChanges);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeModelDestroy(@NotNull ArrangementRuleEditingModelImpl model) {
|
||||
for (ArrangementTreeNode node = model.getBottomMost(); node != null; node = node.getParent()) {
|
||||
int row = myTree.getRowForPath(new TreePath(node.getPath()));
|
||||
myRenderers.remove(row);
|
||||
myModels.remove(row);
|
||||
if (node == model.getTopMost()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterModelDestroy(@NotNull TIntIntHashMap rowChanges) {
|
||||
processRowChanges(rowChanges);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyModelNodesRefresher implements TObjectProcedure<ArrangementRuleEditingModelImpl> {
|
||||
|
||||
Reference in New Issue
Block a user