1 package org.simantics.browsing.ui.nattable;
3 import java.util.Collection;
5 import java.util.regex.Pattern;
7 import org.eclipse.jface.viewers.IStructuredSelection;
8 import org.eclipse.nebula.widgets.nattable.NatTable;
9 import org.eclipse.swt.events.KeyAdapter;
10 import org.eclipse.swt.events.KeyEvent;
11 import org.simantics.browsing.ui.GraphExplorer;
12 import org.simantics.utils.ui.AdaptionUtils;
15 * Selects tree items based on pressed key events.<p>
18 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
21 public class KeyToSelectionAdapter extends KeyAdapter {
23 private static final int KEY_INPUT_DELAY = 500;
25 private final NatTableGraphExplorer explorer;
27 private String matcher = "";
28 private int prevEvent = 0;
29 private int columns = 0;
31 protected Pattern alphaNum;
34 * @param contextProvider
37 public KeyToSelectionAdapter(GraphExplorer explorer) {
38 this(explorer,"\\p{Alnum}");
41 public KeyToSelectionAdapter(GraphExplorer explorer, String pattern) {
42 assert explorer != null;
44 this.explorer = (NatTableGraphExplorer)explorer;
45 this.alphaNum = Pattern.compile(pattern);
48 public boolean acceptKey(char key) {
49 return alphaNum.matcher(Character.toString(key)).matches();
53 public void keyPressed(KeyEvent e) {
54 if (explorer.isDisposed())
57 if (!acceptKey(e.character))
59 // concatenate / replace matcher.
60 if ((e.time - prevEvent) > KEY_INPUT_DELAY )
63 matcher = matcher += Character.toString(e.character);
65 NatTable tree = explorer.getControl();
66 columns = explorer.getColumns().length;
68 IStructuredSelection sel = (IStructuredSelection)explorer.getWidgetSelection();
69 Collection<RowSelectionItem> selected = AdaptionUtils.adaptToCollection(sel, RowSelectionItem.class);
72 TreeNode item = find(tree, selected);
74 if (item == null && matcher.length() > 1) {
75 matcher = matcher.substring(matcher.length()-1);
76 item = find(tree, selected);
81 explorer.select(item);
83 // without this the default handling would take over.
87 private TreeNode previous = null;
88 private boolean foundPrev = false;
90 private TreeNode find(NatTable tree, Collection<RowSelectionItem> selected) {
93 List<TreeNode> items = explorer.getItems();
95 if (selected.size() == 0) {
98 item = findItem(items);
101 previous = selected.iterator().next().item;
103 item = findItem(items);
107 item = findItem(items);
113 private TreeNode findItem(List<TreeNode> items) {
114 for (int i = 0; i < items.size(); i++) {
115 TreeNode item = items.get(i);
116 if (item != previous) {
117 if (foundPrev && matches(item, columns, matcher))
131 * @param depth Depth of the item in the tree.
132 * @param columns Number of columns.
133 * @param string Matching string.
136 protected boolean matches(TreeNode item, int columns, String matcher) {
137 for (int c = 0; c < columns; c++) {
138 if (matchesColumn(item, c, matcher)) {
152 protected boolean matchesColumn(TreeNode item, int column, String matcher) {
153 String text = item.getValueString(column);
156 if (text.toLowerCase().startsWith(matcher)) {