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

1. Correct rule editing on multi-row change;
2. Handle a rule tree's root visibility;
This commit is contained in:
Denis.Zhdanov
2012-08-21 23:30:42 +04:00
parent ae6085df76
commit d9511284da
5 changed files with 42 additions and 65 deletions
@@ -228,7 +228,7 @@ four = '4'()
}
private static def doReplace(initial, from, to, replacement) {
ArrangementConfigUtil.replace(from, to, replacement, new DefaultTreeModel(initial))
ArrangementConfigUtil.replace(from, to, replacement, new DefaultTreeModel(initial), true)
}
private static def doInsert(parent, i, child) {
@@ -222,6 +222,7 @@ public class ArrangementConfigUtil {
* @param to indicates end of the node sub-hierarchy 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
* @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'}
*/
@SuppressWarnings("AssignmentToForLoopParameter")
@@ -229,15 +230,16 @@ public class ArrangementConfigUtil {
public static TIntIntHashMap replace(@NotNull ArrangementTreeNode from,
@NotNull ArrangementTreeNode to,
@NotNull ArrangementTreeNode replacement,
@NotNull DefaultTreeModel treeModel)
@NotNull DefaultTreeModel treeModel,
boolean rootVisible)
{
markRows(from);
markRows(from, rootVisible);
if (from == to) {
ArrangementTreeNode parent = from.getParent();
int index = parent.getIndex(from);
treeModel.removeNodeFromParent(from);
treeModel.insertNodeInto(replacement, parent, index);
return collectRowChangesAndUnmark(parent);
return collectRowChangesAndUnmark(parent, rootVisible);
}
// The algorithm looks as follows:
@@ -342,17 +344,18 @@ public class ArrangementConfigUtil {
}
//endregion
return collectRowChangesAndUnmark(root);
return collectRowChangesAndUnmark(root, rootVisible);
}
/**
* Enriches every node at the hierarchy denoted by the given node by information about it's row.
*
* @param node reference to the target hierarchy
* @param node reference to the target hierarchy
* @param rootVisible determines if the root should be count during rows calculations
*/
private static void markRows(@NotNull ArrangementTreeNode node) {
private static void markRows(@NotNull ArrangementTreeNode node, boolean rootVisible) {
ArrangementTreeNode root = getRoot(node);
int row = 0;
int row = rootVisible ? 0 : -1;
Stack<ArrangementTreeNode> nodes = new Stack<ArrangementTreeNode>();
nodes.push(root);
while (!nodes.isEmpty()) {
@@ -375,7 +378,7 @@ public class ArrangementConfigUtil {
/**
* Processes hierarchy denoted by the given node assuming that every node there contains information about its initial row
* (see {@link #markRows(ArrangementTreeNode)}).
* (see {@link #markRows(ArrangementTreeNode, boolean)}).
* <p/>
* Collects all row changes and returns them. All row information is dropped from the nodes during the current method processing.
*
@@ -383,10 +386,10 @@ public class ArrangementConfigUtil {
* @return collection of row changes at the form {@code 'old row -> new row'}
*/
@NotNull
private static TIntIntHashMap collectRowChangesAndUnmark(@NotNull ArrangementTreeNode node) {
private static TIntIntHashMap collectRowChangesAndUnmark(@NotNull ArrangementTreeNode node, boolean rootVisible) {
@NotNull TIntIntHashMap changes = new TIntIntHashMap();
ArrangementTreeNode root = getRoot(node);
int row = 0;
int row = rootVisible ? 0 : -1;
Stack<ArrangementTreeNode> nodes = new Stack<ArrangementTreeNode>();
nodes.push(root);
while (!nodes.isEmpty()) {
@@ -406,12 +409,13 @@ public class ArrangementConfigUtil {
/**
* Allows to map given node to its row at the hierarchy.
*
* @param node target node
* @return given node's row at the nodes hierarchy (0-based)
* @param node target node
* @param rootVisible determines if the root should be count on rows calculation
* @return given node's row at the nodes hierarchy (0-based)
*/
public static int getRow(@NotNull ArrangementTreeNode node) {
public static int getRow(@NotNull ArrangementTreeNode node, boolean rootVisible) {
ArrangementTreeNode root = getRoot(node);
int row = 0;
int row = rootVisible ? 0 : -1;
Stack<ArrangementTreeNode> nodes = new Stack<ArrangementTreeNode>();
nodes.push(root);
while (!nodes.isEmpty()) {
@@ -105,7 +105,7 @@ public class ArrangementRuleEditingModelBuilder {
grouper,
rowMappings,
row,
tree.isRootVisible() ? 0 : -1
tree.isRootVisible()
);
rowMappings.put(row, model);
}
@@ -44,7 +44,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
@NotNull private final DefaultTreeModel myTreeModel;
@NotNull private final TIntObjectHashMap<ArrangementRuleEditingModelImpl> myRowMappings;
@NotNull private final ArrangementSettingsGrouper myGrouper;
private final int myRowShift;
private final boolean myRootVisible;
@NotNull private ArrangementTreeNode myTopMost;
@NotNull private ArrangementTreeNode myBottomMost;
@@ -54,17 +54,17 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
/**
* Creates new <code>ArrangementRuleEditingModelImpl</code> object.
*
* @param model tree model which holds target ui nodes. Basically, we need to perform ui nodes modification via it in order
* to generate corresponding events automatically
* @param node backing settings node
* @param topMost there is a possible case that a single settings node is shown in more than one visual line
* @param model tree model which holds target ui nodes. Basically, we need to perform ui nodes modification via it in order
* to generate corresponding events automatically
* @param node backing settings node
* @param topMost there is a possible case that a single settings node is shown in more than one visual line
* ({@link HierarchicalArrangementSettingsNode}). This argument is the top-most UI node used for the
* settings node representation
* @param bottomMost bottom-most UI node used for the given settings node representation
* @param grouper strategy that encapsulates information on how settings node should be displayed
* @param mappings {@code 'row -> model'} mappings
* @param row row number for which current model is registered at the given model mappings
* @param shift specifies a shift to be applied to the node rows on model modification. Primary intention is to handle
* @param bottomMost bottom-most UI node used for the given settings node representation
* @param grouper strategy that encapsulates information on how settings node should be displayed
* @param mappings {@code 'row -> model'} mappings
* @param row row number for which current model is registered at the given model mappings
* @param rootVisible determines if the root should be count during rows calculations
*/
public ArrangementRuleEditingModelImpl(@NotNull DefaultTreeModel model,
@NotNull ArrangementSettingsNode node,
@@ -73,7 +73,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
@NotNull ArrangementSettingsGrouper grouper,
@NotNull TIntObjectHashMap<ArrangementRuleEditingModelImpl> mappings,
int row,
int shift)
boolean rootVisible)
{
myTreeModel = model;
mySettingsNode = node;
@@ -82,7 +82,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
myGrouper = grouper;
myRowMappings = mappings;
myRow = row;
myRowShift = shift;
myRootVisible = rootVisible;
refreshConditions();
}
@@ -185,7 +185,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
Pair<ArrangementTreeNode, Integer> replacement = ArrangementConfigUtil.map(null, grouped, null);
ArrangementTreeNode newBottom = replacement.first;
ArrangementTreeNode newTop = ArrangementConfigUtil.getRoot(newBottom);
final TIntIntHashMap rowChanges = ArrangementConfigUtil.replace(myTopMost, myBottomMost, newTop, myTreeModel);
final TIntIntHashMap rowChanges = ArrangementConfigUtil.replace(myTopMost, myBottomMost, newTop, myTreeModel, myRootVisible);
myTopMost = newTop;
myBottomMost = newBottom;
@@ -198,8 +198,8 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
if (row == myRow) {
return true;
}
if (rowChanges.containsKey(row - myRowShift)) {
newMappings.put(rowChanges.get(row - myRowShift) + myRowShift, model);
if (rowChanges.containsKey(row)) {
newMappings.put(rowChanges.get(row), model);
}
else {
newMappings.put(row, model);
@@ -208,7 +208,7 @@ public class ArrangementRuleEditingModelImpl implements ArrangementRuleEditingMo
return true;
}
});
myRow = ArrangementConfigUtil.getRow(myBottomMost) + myRowShift;
myRow = ArrangementConfigUtil.getRow(myBottomMost, myRootVisible);
newMappings.put(myRow, this);
myRowMappings.clear();
@@ -30,8 +30,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
@@ -114,7 +112,6 @@ public class ArrangementRuleTree {
onMouseClicked(e);
}
});
myTreeModel.addTreeModelListener(new MyTreeModelListener());
List<ArrangementSettingsNode> rules = new ArrayList<ArrangementSettingsNode>();
rules.add(new ArrangementSettingsCompositeNode(ArrangementSettingsCompositeNode.Operator.AND)
@@ -145,6 +142,9 @@ public class ArrangementRuleTree {
for (TreePath p = path; p != null; p = p.getParentPath()) {
int row = myTree.getRowForPath(p);
if (row < 0) {
row = ((ArrangementTreeNode)p.getLastPathComponent()).getRow();
}
if (row < 0) {
return;
}
@@ -299,7 +299,7 @@ public class ArrangementRuleTree {
private void onModelChange(@NotNull ArrangementTreeNode topMost, @NotNull ArrangementTreeNode bottomMost) {
expandAll(myTree, new TreePath(topMost.getPath()));
mySelectionModel.clearSelection();
mySkipSelectionChange = true;
//mySkipSelectionChange = true;
try {
for (ArrangementTreeNode node = bottomMost; node != null; node = node.getParent()) {
TreePath path = new TreePath(node.getPath());
@@ -329,12 +329,8 @@ public class ArrangementRuleTree {
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
// TODO den remove
if (row > 0) {
myTree.getPathForRow(row);
}
boolean hasFocus)
{
ArrangementSettingsNode node = ((ArrangementTreeNode)value).getBackingSetting();
if (node == null) {
return EMPTY_RENDERER;
@@ -388,27 +384,4 @@ public class ArrangementRuleTree {
onModelChange(topMost, bottomMost);
}
}
private class MyTreeModelListener implements TreeModelListener {
@Override
public void treeNodesChanged(TreeModelEvent e) {
// TODO den implement
}
@Override
public void treeNodesInserted(TreeModelEvent e) {
//expandAll(myTree, e.getTreePath());
}
@Override
public void treeNodesRemoved(TreeModelEvent e) {
// TODO den implement
int i = 1;
}
@Override
public void treeStructureChanged(TreeModelEvent e) {
// TODO den implement
}
}
}