fix TransactionDetails handling of attributes
This commit is contained in:
		
							
								
								
									
										1
									
								
								features/com.minres.scviewer.e4.feature/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								features/com.minres.scviewer.e4.feature/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/target/
 | 
			
		||||
@@ -12,9 +12,13 @@ package com.minres.scviewer.e4.application.parts;
 | 
			
		||||
 | 
			
		||||
import java.util.AbstractMap;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.TreeMap;
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
import java.util.regex.PatternSyntaxException;
 | 
			
		||||
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.DoubleClickEvent;
 | 
			
		||||
import org.eclipse.jface.viewers.IDoubleClickListener;
 | 
			
		||||
import org.eclipse.jface.viewers.IElementComparer;
 | 
			
		||||
import org.eclipse.jface.viewers.ISelection;
 | 
			
		||||
import org.eclipse.jface.viewers.IStructuredSelection;
 | 
			
		||||
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.StyledString;
 | 
			
		||||
import org.eclipse.jface.viewers.TreeExpansionEvent;
 | 
			
		||||
import org.eclipse.jface.viewers.TreePath;
 | 
			
		||||
import org.eclipse.jface.viewers.TreeViewer;
 | 
			
		||||
import org.eclipse.jface.viewers.TreeViewerColumn;
 | 
			
		||||
import org.eclipse.jface.viewers.Viewer;
 | 
			
		||||
@@ -146,16 +152,19 @@ public class TransactionDetails {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public void treeCollapsed(TreeExpansionEvent event) {
 | 
			
		||||
				Object o = event.getElement();
 | 
			
		||||
				TreePath[] paths = treeViewer.getExpandedTreePaths();
 | 
			
		||||
				treeViewer.getSelection();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public void treeExpanded(TreeExpansionEvent event) {
 | 
			
		||||
				Object o = event.getElement();
 | 
			
		||||
				TreePath[] paths = treeViewer.getExpandedTreePaths();
 | 
			
		||||
				treeViewer.getSelection();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// Set up the table
 | 
			
		||||
		Tree tree = treeViewer.getTree();
 | 
			
		||||
		tree.setLayoutData(new GridData(GridData.FILL_BOTH));
 | 
			
		||||
@@ -273,77 +282,110 @@ public class TransactionDetails {
 | 
			
		||||
		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) {
 | 
			
		||||
		if(object instanceof ITx){
 | 
			
		||||
			ArrayList<String> names = new ArrayList<>();
 | 
			
		||||
			int indexInParent=getTopItemHier(names);
 | 
			
		||||
			ArrayList<Boolean> states = getExpandedState(treeViewer.getTree().getItems());
 | 
			
		||||
			Object oldInput = treeViewer.getInput();
 | 
			
		||||
			if(oldInput!=null) {
 | 
			
		||||
				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);
 | 
			
		||||
			setExpandedState(treeViewer.getTree().getItems(), states);
 | 
			
		||||
			setTopItemFromHier(names, indexInParent);
 | 
			
		||||
			final Integer newHash = getAttrNameHash(object);
 | 
			
		||||
			final ViewSettings newSettings = settings.get(newHash);
 | 
			
		||||
			if(newSettings!=null) {
 | 
			
		||||
				setExpandedState(newSettings.paths);
 | 
			
		||||
				setTopItemFromHier(newSettings.names, treeViewer.getTree().getItems());
 | 
			
		||||
			} else
 | 
			
		||||
				setExpandedState(null);
 | 
			
		||||
		} else {
 | 
			
		||||
			treeViewer.setInput(null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void setExpandedState(TreeItem[] treeItems, ArrayList<Boolean> states) {
 | 
			
		||||
		for (int i = 0; i < treeItems.length; i++) {
 | 
			
		||||
			treeItems[i].setExpanded(states.size()>i?states.get(i):true);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	int getAttrNameHash(Object o) {
 | 
			
		||||
		if(o instanceof ITx) {
 | 
			
		||||
			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){
 | 
			
		||||
		int indexInParent=-1;
 | 
			
		||||
		TreeItem obj = treeViewer.getTree().getTopItem();
 | 
			
		||||
		if(obj!=null) {
 | 
			
		||||
			names.add(0, obj.getText(0));
 | 
			
		||||
			if(obj.getParentItem()!=null) {
 | 
			
		||||
				TreeItem pobj=obj.getParentItem();
 | 
			
		||||
				names.add(0, pobj.getText(0));
 | 
			
		||||
				TreeItem[] items = pobj.getItems();
 | 
			
		||||
				for (int i = 0; i < items.length; i++) {
 | 
			
		||||
					if(items[i]==obj) {
 | 
			
		||||
						indexInParent=i;
 | 
			
		||||
	
 | 
			
		||||
	private void setExpandedState(TreePath[] paths) {
 | 
			
		||||
		if(paths==null)
 | 
			
		||||
			treeViewer.setAutoExpandLevel(2);
 | 
			
		||||
		else {
 | 
			
		||||
			TransactionTreeContentProvider cp = (TransactionTreeContentProvider) treeViewer.getContentProvider();
 | 
			
		||||
			Object[] elems = cp.getElements(treeViewer.getInput());
 | 
			
		||||
			for(TreePath path: paths) {
 | 
			
		||||
				TreeNode firstSeg = (TreeNode)path.getFirstSegment();
 | 
			
		||||
				for(Object elem : elems) {
 | 
			
		||||
					if(((TreeNode)elem).type == firstSeg.type) {
 | 
			
		||||
						treeViewer.setExpandedState(elem, true);
 | 
			
		||||
						if(firstSeg.type==TransactionDetails.Type.ATTRS && path.getSegmentCount()>1)
 | 
			
		||||
							expandSubNodes(path, 1, (TreeNode)elem);
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return indexInParent;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void setTopItemFromHier(ArrayList<String> names, int indexInParent) {
 | 
			
		||||
		if(indexInParent<0 || names.size()==0 ) return;
 | 
			
		||||
		TreeItem selItem=null;
 | 
			
		||||
		for (TreeItem item : treeViewer.getTree().getItems()) { // find item from category
 | 
			
		||||
			if(item.getText(0).equals(names.get(0))) {
 | 
			
		||||
				if(names.size()>1) { // if we had an attribute as top item
 | 
			
		||||
					TreeItem[] subItems=item.getItems();
 | 
			
		||||
					for(TreeItem it : subItems) { // try to align by name
 | 
			
		||||
						if(it.getText(0).equals(names.get(1))) {
 | 
			
		||||
							selItem=it;
 | 
			
		||||
							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];
 | 
			
		||||
	private void expandSubNodes(TreePath path, int level, TreeNode elem) {
 | 
			
		||||
		if(level==path.getSegmentCount()) return;
 | 
			
		||||
		TransactionTreeContentProvider cp = (TransactionTreeContentProvider) treeViewer.getContentProvider();
 | 
			
		||||
		Object[] childs = cp.getChildren(elem);
 | 
			
		||||
		TreeNode nextSeg = (TreeNode)path.getSegment(level);
 | 
			
		||||
		for(Object child:childs) {
 | 
			
		||||
			if(child instanceof TreeNode) {
 | 
			
		||||
				TreeNode node = (TreeNode) child;
 | 
			
		||||
				if(nextSeg.toString().equals(node.toString())) {
 | 
			
		||||
					treeViewer.setExpandedState(node, true);
 | 
			
		||||
					expandSubNodes(path, level+1, node);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				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.
 | 
			
		||||
	 *
 | 
			
		||||
@@ -513,7 +555,7 @@ public class TransactionDetails {
 | 
			
		||||
	/**
 | 
			
		||||
	 * The Class TreeNode.
 | 
			
		||||
	 */
 | 
			
		||||
	class TreeNode{
 | 
			
		||||
	class TreeNode implements Comparable<TreeNode>{
 | 
			
		||||
 | 
			
		||||
		/** The type. */
 | 
			
		||||
		public Type type;
 | 
			
		||||
@@ -576,6 +618,24 @@ public class TransactionDetails {
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user