1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2012 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.browsing.ui.swt.contentassist;
\r
14 import java.util.ArrayList;
\r
15 import java.util.List;
\r
17 import org.eclipse.swt.SWT;
\r
18 import org.eclipse.swt.widgets.Composite;
\r
19 import org.eclipse.swt.widgets.Event;
\r
20 import org.eclipse.swt.widgets.Listener;
\r
21 import org.eclipse.swt.widgets.TreeItem;
\r
22 import org.simantics.browsing.ui.NodeContext;
\r
23 import org.simantics.browsing.ui.common.modifiers.EnumeratedValue;
\r
24 import org.simantics.browsing.ui.common.modifiers.Enumeration;
\r
25 import org.simantics.browsing.ui.content.Labeler.CustomModifier;
\r
28 * @author Tuukka Lehtonen
\r
30 abstract public class AbstractContentAssistModifier<T> implements CustomModifier {
\r
32 protected final Enumeration<T> enumeration;
\r
33 protected final T value;
\r
35 protected ContentAssistTextField text;
\r
37 public AbstractContentAssistModifier(Enumeration<T> enumeration, T value) {
\r
38 if (enumeration == null)
\r
39 throw new NullPointerException("null enumeration");
\r
40 if (enumeration.size() == 0)
\r
41 throw new IllegalArgumentException("");
\r
43 this.enumeration = enumeration;
\r
48 public String getValue() {
\r
50 return value.toString();
\r
51 return enumeration.values().get(0).getName();
\r
55 public String isValid(String label) {
\r
56 if (enumeration.findByName(label) == null)
\r
57 return "Value '" + label + "' is not among the enumerated values " + enumeration.values();
\r
62 public void modify(String label) {
\r
63 String error = isValid(label);
\r
65 throw new IllegalArgumentException(error);
\r
66 modifyWithValue(this.value, label);
\r
69 abstract void modifyWithValue(T oldEnumValue, String enumValue);
\r
72 * Override to customize the content assist proposal objects created from
\r
73 * the enumerated values.
\r
78 protected NamedObject<T> createNamedObject(EnumeratedValue<T> value) {
\r
79 return new NamedObject<T>(value.getObject(), value.getName());
\r
82 protected List<NamedObject<T>> toNamedObjects(Enumeration<T> enumeration) {
\r
83 List<NamedObject<T>> namedObjects = new ArrayList<NamedObject<T>>();
\r
84 for (EnumeratedValue<T> v : enumeration.values())
\r
85 namedObjects.add(createNamedObject(v));
\r
86 return namedObjects;
\r
90 public Object createControl(Object parentControl, Object controlItem, final int columnIndex, NodeContext context) {
\r
91 Composite parent = (Composite) parentControl;
\r
92 final TreeItem item = (TreeItem) controlItem;
\r
94 List<NamedObject<T>> possibleValues = toNamedObjects(enumeration);
\r
96 EnumeratedValue<T> enuValue = enumeration.find(value);
\r
98 NamedObject<T> selectedValue = enuValue != null ? createNamedObject(enuValue) : null;
\r
100 text = new ContentAssistTextField(parent, selectedValue, possibleValues, SWT.NONE);
\r
102 Listener textListener = new Listener() {
\r
106 public void handleEvent(final Event e) {
\r
109 String newText = text.getControl().getText();
\r
110 // System.out.println("VALIDATE NEW TEXT: " + newText);
\r
111 error = isValid(newText);
\r
112 if (error != null) {
\r
113 text.getControl().setBackground(text.getDisplay().getSystemColor(SWT.COLOR_RED));
\r
114 // System.out.println("validation error: " + error);
\r
116 text.getControl().setBackground(null);
\r
118 // text.getDisplay().asyncExec(new Runnable() {
\r
120 // public void run() {
\r
121 //if (!text.getControl().isDisposed())
\r
122 //text.getControl().traverse(SWT.TRAVERSE_ARROW_NEXT);
\r
123 //text.getControl().setSelection(text.getControl().getCaretPosition());
\r
129 // Safety check since it seems that this may happen with
\r
131 // if (item.isDisposed())
\r
134 // newText = text.getControl().getText();
\r
135 // String leftText = newText.substring(0, e.start);
\r
136 // String rightText = newText.substring(e.end, newText.length());
\r
137 // GC gc = new GC(text.getControl());
\r
138 // Point size = gc.textExtent(leftText + e.text + rightText);
\r
140 // size = text.getControl().computeSize(size.x, SWT.DEFAULT);
\r
141 // Rectangle itemRect = item.getBounds(columnIndex),
\r
142 // rect = tree.getClientArea();
\r
143 // editor.minimumWidth = Math.max(size.x, itemRect.width) + insetX * 2;
\r
144 // int left = itemRect.x,
\r
145 // right = rect.x + rect.width;
\r
146 // editor.minimumWidth = Math.min(editor.minimumWidth, right - left);
\r
147 // editor.minimumHeight = size.y + insetY * 2;
\r
148 // editor.layout();
\r
150 // case SWT.FocusOut: {
\r
151 // System.out.println("focus out");
\r
152 // String t = text.getControl().getText();
\r
155 // // Item may be disposed if the tree gets reset after a previous editing.
\r
156 // if (!item.isDisposed()) {
\r
157 // item.setText(columnIndex, t);
\r
158 // //queueSelectionRefresh(context);
\r
163 case SWT.Traverse: {
\r
164 //System.out.println(AbstractContentAssistEnumerationModifier.class.getSimpleName() + " TRAVERSE: " + e.detail);
\r
165 switch (e.detail) {
\r
166 case SWT.TRAVERSE_RETURN:
\r
167 //System.out.println("TRAVERSE: RETURN");
\r
168 INamedObject obj = text.getResult();
\r
169 String txt = obj != null ? obj.getName() : text.getControl().getText();
\r
170 if (txt == null || error != null) {
\r
175 if (!item.isDisposed()) {
\r
176 item.setText(columnIndex, txt);
\r
177 //queueSelectionRefresh(context);
\r
180 case SWT.TRAVERSE_ESCAPE:
\r
181 //System.out.println("TRAVERSE: ESCAPE");
\r
186 //System.out.println("unhandled traversal: " + e.detail);
\r
194 text.getControl().addListener(SWT.Modify, textListener);
\r
195 // text.getControl().addListener(SWT.Verify, textListener);
\r
196 // text.getControl().addListener(SWT.FocusOut, textListener);
\r
197 text.getControl().addListener(SWT.Traverse, textListener);
\r
200 text.text.selectAll();
\r
201 text.getDisplay().asyncExec(new Runnable() {
\r
203 public void run() {
\r
204 if (!text.isDisposed())
\r