mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-6949: Add proper hierarchical sorting to TreeColumn in GTreeTable
This commit is contained in:
@@ -51,6 +51,11 @@ public class GTreeTableModel<T extends GTreeTableNode> extends ThreadedTableMode
|
|||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
return rowObject;
|
return rowObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Comparator<GTreeTableNode> getComparator() {
|
||||||
|
return Comparator.comparingInt(GTreeTableNode::getIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GTreeTableNode rootNode;
|
private GTreeTableNode rootNode;
|
||||||
@@ -68,7 +73,7 @@ public class GTreeTableModel<T extends GTreeTableNode> extends ThreadedTableMode
|
|||||||
@Override
|
@Override
|
||||||
protected TableColumnDescriptor<T> createTableColumnDescriptor() {
|
protected TableColumnDescriptor<T> createTableColumnDescriptor() {
|
||||||
final TableColumnDescriptor<T> descriptor = new TableColumnDescriptor<>();
|
final TableColumnDescriptor<T> descriptor = new TableColumnDescriptor<>();
|
||||||
descriptor.addVisibleColumn(new TreeColumn(treeColumnName()));
|
descriptor.addVisibleColumn(new TreeColumn(treeColumnName()), 0, true);
|
||||||
|
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
@@ -122,6 +127,7 @@ public class GTreeTableModel<T extends GTreeTableNode> extends ThreadedTableMode
|
|||||||
protected void doLoad(Accumulator<T> accumulator, TaskMonitor monitor)
|
protected void doLoad(Accumulator<T> accumulator, TaskMonitor monitor)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
if (rootNode != null) {
|
if (rootNode != null) {
|
||||||
|
rootNode.reindex();
|
||||||
for (final GTreeTableNode c : rootNode.expandedDescendants()) {
|
for (final GTreeTableNode c : rootNode.expandedDescendants()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
if (c.isVisible()) {
|
if (c.isVisible()) {
|
||||||
|
|||||||
@@ -15,13 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package docking.widgets.gtreetable;
|
package docking.widgets.gtreetable;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import javax.swing.Icon;
|
|
||||||
|
|
||||||
public class GTreeTableNode implements Serializable {
|
public class GTreeTableNode implements Serializable {
|
||||||
private class EachAncestorIterator implements Iterator<GTreeTableNode> {
|
private class EachAncestorIterator implements Iterator<GTreeTableNode> {
|
||||||
GTreeTableNode curNode = getParent();
|
GTreeTableNode curNode = getParent();
|
||||||
@@ -53,7 +52,22 @@ public class GTreeTableNode implements Serializable {
|
|||||||
nodes.addAll(curNode.getChildren());
|
nodes.addAll(curNode.getChildren());
|
||||||
return curNode;
|
return curNode;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EachDecendantDFSIterator implements Iterator<GTreeTableNode> {
|
||||||
|
final List<GTreeTableNode> nodes = new ArrayList<>(children);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return !nodes.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GTreeTableNode next() {
|
||||||
|
final GTreeTableNode curNode = nodes.removeFirst();
|
||||||
|
nodes.addAll(0, curNode.getChildren());
|
||||||
|
return curNode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EachExpandedIterator implements Iterator<GTreeTableNode> {
|
private class EachExpandedIterator implements Iterator<GTreeTableNode> {
|
||||||
@@ -68,11 +82,10 @@ public class GTreeTableNode implements Serializable {
|
|||||||
public GTreeTableNode next() {
|
public GTreeTableNode next() {
|
||||||
final GTreeTableNode curNode = nodes.removeFirst();
|
final GTreeTableNode curNode = nodes.removeFirst();
|
||||||
if (curNode.isExpanded()) {
|
if (curNode.isExpanded()) {
|
||||||
nodes.addAll((curNode.getChildren()));
|
nodes.addAll(curNode.getChildren());
|
||||||
}
|
}
|
||||||
return curNode;
|
return curNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
@@ -85,6 +98,8 @@ public class GTreeTableNode implements Serializable {
|
|||||||
|
|
||||||
protected boolean visible;
|
protected boolean visible;
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
|
||||||
public GTreeTableNode(final String name) {
|
public GTreeTableNode(final String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
expanded = false;
|
expanded = false;
|
||||||
@@ -92,6 +107,16 @@ public class GTreeTableNode implements Serializable {
|
|||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reindex the tree for sorting
|
||||||
|
*/
|
||||||
|
void reindex() {
|
||||||
|
int i = 0;
|
||||||
|
for (GTreeTableNode node : getRoot().descendantsDFS()) {
|
||||||
|
node.index = i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new child to this node's children
|
* Add new child to this node's children
|
||||||
*
|
*
|
||||||
@@ -146,6 +171,15 @@ public class GTreeTableNode implements Serializable {
|
|||||||
return EachDecendantIterator::new;
|
return EachDecendantIterator::new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an iterable of all the descendants of this node in DFS order
|
||||||
|
*
|
||||||
|
* @return An iterable of descendants
|
||||||
|
*/
|
||||||
|
public Iterable<GTreeTableNode> descendantsDFS() {
|
||||||
|
return EachDecendantDFSIterator::new;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an iterable of all the expanded descendants of this node
|
* Get an iterable of all the expanded descendants of this node
|
||||||
*
|
*
|
||||||
@@ -209,6 +243,21 @@ public class GTreeTableNode implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an action on each descendant of this node in DFS order
|
||||||
|
*
|
||||||
|
* @param action To perform on each descendant
|
||||||
|
*/
|
||||||
|
public void forEachDescendantDFS(final Consumer<GTreeTableNode> action) {
|
||||||
|
final List<GTreeTableNode> nodes = new ArrayList<>(children);
|
||||||
|
|
||||||
|
while (!nodes.isEmpty()) {
|
||||||
|
final GTreeTableNode curNode = nodes.removeFirst();
|
||||||
|
action.accept(curNode);
|
||||||
|
nodes.addAll(0, curNode.getChildren());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform an action on each expanded descendant of this node
|
* Perform an action on each expanded descendant of this node
|
||||||
*
|
*
|
||||||
@@ -454,6 +503,15 @@ public class GTreeTableNode implements Serializable {
|
|||||||
child.setParent(null);
|
child.setParent(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get this node's index in the tree, for sorting purposes
|
||||||
|
*
|
||||||
|
* @return Index in tree
|
||||||
|
*/
|
||||||
|
int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change node expanded state
|
* Change node expanded state
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user