fix TransactionDetails handling of attributes

This commit is contained in:
Eyck Jentzsch 2020-06-11 10:51:59 +02:00
parent 688a6abd99
commit 35ccc71f10
2 changed files with 112 additions and 51 deletions

View File

@ -0,0 +1 @@
/target/

View File

@ -12,9 +12,13 @@ package com.minres.scviewer.e4.application.parts;
import java.util.AbstractMap; import java.util.AbstractMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.Vector; import java.util.Vector;
import java.util.function.Function;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -34,6 +38,7 @@ import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IElementComparer;
import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeContentProvider;
@ -42,6 +47,7 @@ import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledString; import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.Viewer;
@ -146,16 +152,19 @@ public class TransactionDetails {
@Override @Override
public void treeCollapsed(TreeExpansionEvent event) { public void treeCollapsed(TreeExpansionEvent event) {
Object o = event.getElement();
TreePath[] paths = treeViewer.getExpandedTreePaths();
treeViewer.getSelection(); treeViewer.getSelection();
} }
@Override @Override
public void treeExpanded(TreeExpansionEvent event) { public void treeExpanded(TreeExpansionEvent event) {
Object o = event.getElement();
TreePath[] paths = treeViewer.getExpandedTreePaths();
treeViewer.getSelection(); treeViewer.getSelection();
} }
}); });
// Set up the table // Set up the table
Tree tree = treeViewer.getTree(); Tree tree = treeViewer.getTree();
tree.setLayoutData(new GridData(GridData.FILL_BOTH)); tree.setLayoutData(new GridData(GridData.FILL_BOTH));
@ -273,77 +282,110 @@ public class TransactionDetails {
this.waveformViewerPart=part; this.waveformViewerPart=part;
} }
class ViewSettings {
public ViewSettings(List<String> names, TreePath[] paths) {
super();
this.names = names;
this.paths = paths;
}
public List<String> names;
public TreePath[] paths;
}
HashMap<Integer, ViewSettings> settings = new HashMap<>();
public void setInput(Object object) { public void setInput(Object object) {
if(object instanceof ITx){ if(object instanceof ITx){
ArrayList<String> names = new ArrayList<>(); Object oldInput = treeViewer.getInput();
int indexInParent=getTopItemHier(names); if(oldInput!=null) {
ArrayList<Boolean> states = getExpandedState(treeViewer.getTree().getItems()); final Integer hash = getAttrNameHash(oldInput);
final List<String> names = getTopItemHier(treeViewer.getTree().getTopItem());
final TreePath[] paths = treeViewer.getInput()!=null?treeViewer.getExpandedTreePaths():null;
settings.put(hash, new ViewSettings(names, paths));
}
treeViewer.setInput(object); treeViewer.setInput(object);
setExpandedState(treeViewer.getTree().getItems(), states); final Integer newHash = getAttrNameHash(object);
setTopItemFromHier(names, indexInParent); final ViewSettings newSettings = settings.get(newHash);
if(newSettings!=null) {
setExpandedState(newSettings.paths);
setTopItemFromHier(newSettings.names, treeViewer.getTree().getItems());
} else
setExpandedState(null);
} else { } else {
treeViewer.setInput(null); treeViewer.setInput(null);
} }
} }
private void setExpandedState(TreeItem[] treeItems, ArrayList<Boolean> states) { int getAttrNameHash(Object o) {
for (int i = 0; i < treeItems.length; i++) { if(o instanceof ITx) {
treeItems[i].setExpanded(states.size()>i?states.get(i):true); ITx tx = (ITx) o;
} List<String> attr_names = tx.getAttributes().stream().map(a -> a.getName()).collect(Collectors.toList());
} return Objects.hash(attr_names);
} else
return o.hashCode();
private ArrayList<Boolean> getExpandedState(TreeItem[] items){
ArrayList<Boolean> ret = new ArrayList<>();
for (TreeItem treeItem : items)
ret.add(treeItem.getItemCount()>0?treeItem.getExpanded():true);
return ret;
} }
private int getTopItemHier(ArrayList<String> names){ private void setExpandedState(TreePath[] paths) {
int indexInParent=-1; if(paths==null)
TreeItem obj = treeViewer.getTree().getTopItem(); treeViewer.setAutoExpandLevel(2);
if(obj!=null) { else {
names.add(0, obj.getText(0)); TransactionTreeContentProvider cp = (TransactionTreeContentProvider) treeViewer.getContentProvider();
if(obj.getParentItem()!=null) { Object[] elems = cp.getElements(treeViewer.getInput());
TreeItem pobj=obj.getParentItem(); for(TreePath path: paths) {
names.add(0, pobj.getText(0)); TreeNode firstSeg = (TreeNode)path.getFirstSegment();
TreeItem[] items = pobj.getItems(); for(Object elem : elems) {
for (int i = 0; i < items.length; i++) { if(((TreeNode)elem).type == firstSeg.type) {
if(items[i]==obj) { treeViewer.setExpandedState(elem, true);
indexInParent=i; if(firstSeg.type==TransactionDetails.Type.ATTRS && path.getSegmentCount()>1)
expandSubNodes(path, 1, (TreeNode)elem);
break; break;
} }
} }
} }
} }
return indexInParent;
} }
private void setTopItemFromHier(ArrayList<String> names, int indexInParent) { private void expandSubNodes(TreePath path, int level, TreeNode elem) {
if(indexInParent<0 || names.size()==0 ) return; if(level==path.getSegmentCount()) return;
TreeItem selItem=null; TransactionTreeContentProvider cp = (TransactionTreeContentProvider) treeViewer.getContentProvider();
for (TreeItem item : treeViewer.getTree().getItems()) { // find item from category Object[] childs = cp.getChildren(elem);
if(item.getText(0).equals(names.get(0))) { TreeNode nextSeg = (TreeNode)path.getSegment(level);
if(names.size()>1) { // if we had an attribute as top item for(Object child:childs) {
TreeItem[] subItems=item.getItems(); if(child instanceof TreeNode) {
for(TreeItem it : subItems) { // try to align by name TreeNode node = (TreeNode) child;
if(it.getText(0).equals(names.get(1))) { if(nextSeg.toString().equals(node.toString())) {
selItem=it; treeViewer.setExpandedState(node, true);
break; expandSubNodes(path, level+1, node);
} break;
}
if(selItem==null && indexInParent>=0 && subItems.length>0) // name based match failed so try to use position
selItem=subItems[subItems.length>indexInParent?indexInParent:subItems.length-1];
} }
if(selItem==null) // no match in attributes so set the category as top item
selItem=item;
break;
} }
} }
if(selItem!=null)
treeViewer.getTree().setTopItem(selItem);
} }
List<String> getTopItemHier(TreeItem node){
if(node == null) {
return new ArrayList<String>();
} else {
List<String> elems = getTopItemHier(node.getParentItem());
elems.add(node.getText(0));
return elems;
}
}
private void setTopItemFromHier(List<String> names, TreeItem [] items) {
for (TreeItem item : items) { // find item from category
if(item.getText(0).equals(names.get(0))) {
if(names.size()==1 || item.getItemCount()==0) {
treeViewer.getTree().setTopItem(item);
} else {
setTopItemFromHier(names.subList(1, names.size()), item.getItems());
}
return;
}
}
}
/** /**
* Sets the selection. * Sets the selection.
* *
@ -513,7 +555,7 @@ public class TransactionDetails {
/** /**
* The Class TreeNode. * The Class TreeNode.
*/ */
class TreeNode{ class TreeNode implements Comparable<TreeNode>{
/** The type. */ /** The type. */
public Type type; public Type type;
@ -576,6 +618,24 @@ public class TransactionDetails {
} }
private Object[] childs=null; private Object[] childs=null;
@Override
public boolean equals(Object o) {
if(o instanceof TreeNode) {
TreeNode t = (TreeNode) o;
return type==t.type && hier_path.equals(t.hier_path);
}
return false;
}
@Override
public int compareTo(TreeNode o) {
int res1 = type.compareTo(o.type);
if(res1==0) {
return hier_path.compareTo(o.hier_path);
} else
return res1;
}
} }
/** /**