1 /*******************************************************************************
2 * Copyright (c) 2007, 2012 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.browsing.ui.swt.widgets;
14 import java.util.List;
15 import java.util.concurrent.CopyOnWriteArrayList;
17 import org.eclipse.swt.events.ModifyListener;
18 import org.eclipse.swt.widgets.Composite;
19 import org.eclipse.swt.widgets.Control;
20 import org.eclipse.swt.widgets.Display;
21 import org.simantics.Simantics;
22 import org.simantics.browsing.ui.swt.widgets.impl.Widget;
23 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
24 import org.simantics.db.ReadGraph;
25 import org.simantics.db.common.request.ParametrizedRead;
26 import org.simantics.db.common.request.UniqueRead;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.management.ISessionContext;
29 import org.simantics.db.procedure.Listener;
30 import org.simantics.utils.datastructures.Pair;
32 public class Combo2 extends WidgetImpl {
34 private WidgetSupport support;
35 private final CopyOnWriteArrayList<ModifyListener> modifyListeners = new CopyOnWriteArrayList<ModifyListener>();
36 private List<Pair<String, Object>> itemList;
38 final private Display display;
39 final private org.eclipse.swt.widgets.Combo combo;
41 public Combo2(Composite parent, WidgetSupport support, int style) {
43 this.display = parent.getDisplay();
44 combo = new org.eclipse.swt.widgets.Combo(parent, style);
45 combo.setData("org.simantics.browsing.ui.widgets.Combo", this);
46 support.register(this);
49 public void setAvailable(List<Pair<String, Object>> items) {
52 for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
54 combo.clearSelection();
57 } catch (Throwable t) {
62 for(Pair<String, Object> key : items) {
64 combo.setData(key.first, index++);
66 String selectionKey = (String)combo.getData("_SelectionKey");
67 if(selectionKey != null) {
68 Integer selectionIndex = (Integer)combo.getData(selectionKey);
69 if(selectionIndex != null) combo.select(selectionIndex);
72 for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
76 public <T> void setAvailable(final ParametrizedRead<T, List<Pair<String, Object>>> read) {
78 Simantics.getSession().async(new UniqueRead<List<Pair<String, Object>>>() {
81 public List<Pair<String, Object>> perform(ReadGraph graph) throws DatabaseException {
82 T input = support.getInput(graph);
83 return graph.syncRequest(read.get(input));
86 }, new Listener<List<Pair<String, Object>>>() {
89 public void exception(Throwable t) {
94 public void execute(final List<Pair<String, Object>> items) {
95 if(isDisposed()) return;
96 display.asyncExec(new Runnable() {
100 if(isDisposed()) return;
102 for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
103 combo.setData(items);
104 combo.clearSelection();
107 } catch (Throwable t) {
112 for(Pair<String, Object> key : items) {
113 combo.add(key.first);
114 combo.setData(key.first, index++);
116 String selectionKey = (String)combo.getData("_SelectionKey");
117 if(selectionKey != null) {
118 Integer selectionIndex = (Integer)combo.getData(selectionKey);
119 if(selectionIndex != null) combo.select(selectionIndex);
122 for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
129 public boolean isDisposed() {
130 return combo.isDisposed();
137 public void setSelection(String selectionKey) {
139 if(selectionKey == null) return;
140 for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
141 combo.setData("_SelectionKey", selectionKey);
142 Integer selectionIndex = (Integer)combo.getData(selectionKey);
143 if(selectionIndex != null) combo.select(selectionIndex);
144 for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
148 public <T> void setSelection(final ParametrizedRead<T, String> read) {
150 Simantics.getSession().async(new UniqueRead<String>() {
153 public String perform(ReadGraph graph) throws DatabaseException {
154 T input = support.getInput(graph);
155 return graph.syncRequest(read.get(input));
158 }, new Listener<String>() {
161 public void exception(Throwable t) {
166 public void execute(final String selectionKey) {
167 if(isDisposed()) return;
168 display.asyncExec(new Runnable() {
172 if(isDisposed()) return;
173 if(selectionKey == null) return;
174 for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
175 combo.setData("_SelectionKey", selectionKey);
176 Integer selectionIndex = (Integer)combo.getData(selectionKey);
177 if(selectionIndex != null) combo.select(selectionIndex);
178 for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
185 public boolean isDisposed() {
186 return combo.isDisposed();
193 public org.eclipse.swt.widgets.Combo getWidget() {
198 public Control getControl() {
202 // private AtomicBoolean inputDisposed;
205 public void setInput(ISessionContext context, Object input) {
207 // if (this.inputDisposed != null)
208 // this.inputDisposed.set(true);
209 // final AtomicBoolean inputDisposed = this.inputDisposed = new AtomicBoolean(false);
211 if (modifyListeners != null) {
212 for (ModifyListener listener : modifyListeners) {
213 if(listener instanceof Widget) {
214 ((Widget) listener).setInput(context, input);
219 // if(itemFactory != null) {
220 // itemFactory.listen(context, input, new Listener<Map<String, Object>>() {
223 // public void exception(Throwable t) {
224 // t.printStackTrace();
228 // public void execute(final Map<String, Object> items) {
229 // if(isDisposed()) return;
230 // display.asyncExec(new Runnable() {
233 // public void run() {
234 // if(isDisposed()) return;
235 //// System.out.println("Combo received new items: " + items.size());
236 // for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
237 // combo.setData(items);
238 // combo.clearSelection();
240 // combo.removeAll();
241 // } catch (Throwable t) {
242 // t.printStackTrace();
245 // for(String key : items.keySet()) {
246 //// System.out.println("-" + key);
248 // combo.setData(key, index++);
250 // String selectionKey = (String)combo.getData("_SelectionKey");
251 // if(selectionKey != null) {
252 // Integer selectionIndex = (Integer)combo.getData(selectionKey);
253 // if(selectionIndex != null) combo.select(selectionIndex);
255 // for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
256 // //label.setSize(200, 20);
257 //// label.getParent().layout();
258 //// label.getParent().getParent().layout();
265 // public boolean isDisposed() {
266 // return combo.isDisposed() || inputDisposed.get();
272 // if(itemFactory2 != null) {
273 // itemFactory2.listen(context, input, new Listener<List<Pair<String, Object>>>() {
276 // public void exception(Throwable t) {
277 // t.printStackTrace();
281 // public void execute(final List<Pair<String, Object>> items) {
282 // if(isDisposed()) return;
283 // display.asyncExec(new Runnable() {
286 // public void run() {
287 // if(isDisposed()) return;
288 //// System.out.println("Combo received new items: " + items.size());
290 // for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
291 // combo.setData(items);
292 // combo.clearSelection();
294 // combo.removeAll();
295 // } catch (Throwable t) {
296 // t.printStackTrace();
298 // if (items != null) {
300 // for(Pair<String, Object> key : items) {
301 //// System.out.println("-" + key);
302 // combo.add(key.first);
303 // combo.setData(key.first, index++);
305 // String selectionKey = (String)combo.getData("_SelectionKey");
306 // if(selectionKey != null) {
307 // Integer selectionIndex = (Integer)combo.getData(selectionKey);
308 // if(selectionIndex != null) combo.select(selectionIndex);
311 // for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
312 // //label.setSize(200, 20);
313 //// label.getParent().layout();
314 //// label.getParent().getParent().layout();
321 // public boolean isDisposed() {
322 // return combo.isDisposed() || inputDisposed.get();
328 // if(selectionFactory != null) {
329 // selectionFactory.listen(context, input, new Listener<String>() {
332 // public void exception(Throwable t) {
333 // t.printStackTrace();
337 // public void execute(final String selectionKey) {
338 // if(isDisposed()) return;
339 // display.asyncExec(new Runnable() {
342 // public void run() {
343 // if(isDisposed()) return;
344 // if(selectionKey == null) return;
345 //// System.out.println("Combo received new selection key: " + selectionKey);
346 // for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
347 // combo.setData("_SelectionKey", selectionKey);
348 // Integer selectionIndex = (Integer)combo.getData(selectionKey);
349 // if(selectionIndex != null) combo.select(selectionIndex);
350 // for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
357 // public boolean isDisposed() {
358 // return combo.isDisposed() || inputDisposed.get();
366 public synchronized void addModifyListener(ModifyListener listener) {
367 modifyListeners.add(listener);
368 combo.addModifyListener(listener);
374 * @throws IndexOutOfBoundsException if index is outside widget bounds
376 @SuppressWarnings("unchecked")
377 public <T> Pair<String, T> getData(int index) {
378 // if (itemFactory != null)
379 // new IllegalStateException("this method is only useful when used with Combo.setItemFactory2").printStackTrace();
382 return (Pair<String, T>) itemList.get(index);
386 * @return selected combo list item or <code>null</code> if no item is
389 public <T> Pair<String, T> getSelectedData() {
390 return getData(combo.getSelectionIndex());