]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/Combo.java
Optimized EntityInstances and ModelingUtils.search*Shallow queries
[simantics/platform.git] / bundles / org.simantics.browsing.ui.swt / src / org / simantics / browsing / ui / swt / widgets / Combo.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2012 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.browsing.ui.swt.widgets;
13
14 import java.util.List;
15 import java.util.Map;
16 import java.util.concurrent.CopyOnWriteArrayList;
17 import java.util.concurrent.atomic.AtomicBoolean;
18
19 import org.eclipse.swt.events.ModifyListener;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Display;
23 import org.simantics.browsing.ui.swt.widgets.impl.ReadFactory;
24 import org.simantics.browsing.ui.swt.widgets.impl.Widget;
25 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;
26 import org.simantics.db.management.ISessionContext;
27 import org.simantics.db.procedure.Listener;
28 import org.simantics.utils.datastructures.Pair;
29
30 public class Combo extends WidgetImpl {
31
32     private ReadFactory<?, Map<String, Object>> itemFactory;
33     private ReadFactory<?, List<Pair<String, Object>>> itemFactory2;
34     private ReadFactory<?, String> selectionFactory;
35     private final CopyOnWriteArrayList<ModifyListener> modifyListeners = new CopyOnWriteArrayList<ModifyListener>();
36     private List<Pair<String, Object>> itemList;
37
38     final private Display display;
39     final private org.eclipse.swt.widgets.Combo combo;
40
41     public Combo(Composite parent, WidgetSupport support, int style) {
42         super(support);
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);
47     }
48
49     public void setItemFactory(ReadFactory<?, Map<String, Object>> itemFactory) {
50         if (this.itemFactory2 != null)
51             throw new IllegalStateException("Cannot use both itemFactory and itemFactory2");
52         this.itemFactory = itemFactory;
53     }
54
55     public void setItemFactory2(ReadFactory<?, List<Pair<String, Object>>> itemFactory) {
56         if (this.itemFactory != null)
57             throw new IllegalStateException("Cannot use both itemFactory and itemFactory2");
58         this.itemFactory2 = itemFactory;
59     }
60
61     public void setSelectionFactory(ReadFactory<?, String> selectionFactory) {
62         this.selectionFactory = selectionFactory;
63     }
64
65     public org.eclipse.swt.widgets.Combo getWidget() {
66         return combo;
67     }
68
69     @Override
70     public Control getControl() {
71         return combo;
72     }
73
74     private AtomicBoolean inputDisposed;
75
76     @Override
77     public void setInput(ISessionContext context, Object input) {
78
79         if (this.inputDisposed != null)
80             this.inputDisposed.set(true);
81         final AtomicBoolean inputDisposed = this.inputDisposed = new AtomicBoolean(false);
82
83         if (modifyListeners != null) {
84             for (ModifyListener listener : modifyListeners) {
85                 if(listener instanceof Widget) {
86                     ((Widget) listener).setInput(context, input);
87                 }
88             }
89         }
90
91         if(itemFactory != null) {
92             itemFactory.listen(context, input, new Listener<Map<String, Object>>() {
93
94                 @Override
95                 public void exception(Throwable t) {
96                     t.printStackTrace();
97                 }
98
99                 @Override
100                 public void execute(final Map<String, Object> items) {
101                     if(isDisposed()) return;
102                     display.asyncExec(new Runnable() {
103
104                         @Override
105                         public void run() {
106                             if(isDisposed()) return;
107 //                            System.out.println("Combo received new items: " + items.size());
108                             for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
109                             combo.setData(items);
110                             combo.clearSelection();
111                             try {
112                                 combo.removeAll();
113                             } catch (Throwable t) {
114                                 t.printStackTrace();
115                             }
116                             int index = 0;
117                             for(String key : items.keySet()) {
118 //                                System.out.println("-" + key);
119                                 combo.add(key);
120                                 combo.setData(key, index++);
121                             }
122                             String selectionKey = (String)combo.getData("_SelectionKey");
123                             if(selectionKey != null) {
124                                 Integer selectionIndex = (Integer)combo.getData(selectionKey);
125                                 if(selectionIndex != null) combo.select(selectionIndex);
126                             }
127                             for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
128                             //label.setSize(200, 20);
129 //                            label.getParent().layout();
130 //                            label.getParent().getParent().layout();
131                         }
132
133                     });
134                 }
135
136                 @Override
137                 public boolean isDisposed() {
138                     return combo.isDisposed() || inputDisposed.get();
139                 }
140
141             });
142         }
143
144         if(itemFactory2 != null) {
145             itemFactory2.listen(context, input, new Listener<List<Pair<String, Object>>>() {
146
147                 @Override
148                 public void exception(Throwable t) {
149                     t.printStackTrace();
150                 }
151
152                 @Override
153                 public void execute(final List<Pair<String, Object>> items) {
154                     if(isDisposed()) return;
155                     display.asyncExec(new Runnable() {
156
157                         @Override
158                         public void run() {
159                             if(isDisposed()) return;
160 //                            System.out.println("Combo received new items: " + items.size());
161                             itemList = items;
162                             for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
163                             combo.setData(items);
164                             combo.clearSelection();
165                             try {
166                                 combo.removeAll();
167                             } catch (Throwable t) {
168                                 t.printStackTrace();
169                             }
170                             if (items != null) {
171                                 int index = 0;
172                                 for(Pair<String, Object> key : items) {
173 //                                    System.out.println("-" + key);
174                                     combo.add(key.first);
175                                     combo.setData(key.first, index++);
176                                 }
177                                 String selectionKey = (String)combo.getData("_SelectionKey");
178                                 if(selectionKey != null) {
179                                     Integer selectionIndex = (Integer)combo.getData(selectionKey);
180                                     if(selectionIndex != null) combo.select(selectionIndex);
181                                 }
182                             }
183                             for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
184                             //label.setSize(200, 20);
185 //                                                      label.getParent().layout();
186 //                                                      label.getParent().getParent().layout();
187                         }
188
189                     });
190                 }
191
192                 @Override
193                 public boolean isDisposed() {
194                     return combo.isDisposed() || inputDisposed.get();
195                 }
196
197             });
198         }
199
200         if(selectionFactory != null) {
201             selectionFactory.listen(context, input, new Listener<String>() {
202
203                 @Override
204                 public void exception(Throwable t) {
205                     t.printStackTrace();
206                 }
207
208                 @Override
209                 public void execute(final String selectionKey) {
210                     if(isDisposed()) return;
211                     display.asyncExec(new Runnable() {
212
213                         @Override
214                         public void run() {
215                             if(isDisposed()) return;
216                             if(selectionKey == null) return;
217 //                            System.out.println("Combo received new selection key: " + selectionKey);
218                             for(ModifyListener listener : modifyListeners) combo.removeModifyListener(listener);
219                             combo.setData("_SelectionKey", selectionKey);
220                             Integer selectionIndex = (Integer)combo.getData(selectionKey);
221                             if(selectionIndex != null) combo.select(selectionIndex);
222                             for(ModifyListener listener : modifyListeners) combo.addModifyListener(listener);
223                         }
224
225                     });
226                 }
227
228                 @Override
229                 public boolean isDisposed() {
230                     return combo.isDisposed() || inputDisposed.get();
231                 }
232
233             });
234         }
235
236     }
237
238     public synchronized void addModifyListener(ModifyListener listener) {
239         modifyListeners.add(listener);
240         combo.addModifyListener(listener);
241     }
242
243     /**
244      * @param index
245      * @return
246      * @throws IndexOutOfBoundsException if index is outside widget bounds
247      */
248     @SuppressWarnings("unchecked")
249     public <T> Pair<String, T> getData(int index) {
250         if (itemFactory != null)
251             new IllegalStateException("this method is only useful when used with Combo.setItemFactory2").printStackTrace();
252         if (index == -1)
253             return null;
254         return (Pair<String, T>) itemList.get(index);
255     }
256
257     /**
258      * @return selected combo list item or <code>null</code> if no item is
259      *         selected
260      */
261     public <T> Pair<String, T> getSelectedData() {
262         return getData(combo.getSelectionIndex());
263     }
264
265 }