Mercurial > projects > dwt-addons
comparison dwtx/jface/viewers/TableViewer.d @ 10:b6c35faf97c8
Viewers
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 31 Mar 2008 00:47:19 +0200 |
parents | |
children | cf7413989c65 |
comparison
equal
deleted
inserted
replaced
9:6c14e54dfc11 | 10:b6c35faf97c8 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Tom Schindl <tom.schindl@bestsolution.at> - concept of ViewerRow, | |
11 * fix for 159597, refactoring (bug 153993), | |
12 * widget-independency (bug 154329), fix for 187826, 191468 | |
13 * Port to the D programming language: | |
14 * Frank Benoit <benoit@tionex.de> | |
15 *******************************************************************************/ | |
16 | |
17 module dwtx.jface.viewers.TableViewer; | |
18 | |
19 import dwtx.jface.viewers.AbstractTableViewer; | |
20 import dwtx.jface.viewers.TableViewerRow; | |
21 import dwtx.jface.viewers.ColumnViewerEditor; | |
22 import dwtx.jface.viewers.ISelection; | |
23 import dwtx.jface.viewers.ViewerRow; | |
24 import dwtx.jface.viewers.TableViewerEditor; | |
25 import dwtx.jface.viewers.ColumnViewerEditorActivationStrategy; | |
26 | |
27 import dwt.DWT; | |
28 import dwt.graphics.Point; | |
29 import dwt.widgets.Composite; | |
30 import dwt.widgets.Control; | |
31 import dwt.widgets.Item; | |
32 import dwt.widgets.Table; | |
33 import dwt.widgets.TableItem; | |
34 import dwt.widgets.Widget; | |
35 import dwtx.core.runtime.Assert; | |
36 | |
37 import dwt.dwthelper.utils; | |
38 import dwt.dwthelper.Runnable; | |
39 | |
40 /** | |
41 * A concrete viewer based on a DWT <code>Table</code> control. | |
42 * <p> | |
43 * This class is not intended to be subclassed outside the viewer framework. It | |
44 * is designed to be instantiated with a pre-existing DWT table control and | |
45 * configured with a domain-specific content provider, table label provider, | |
46 * element filter (optional), and element sorter (optional). | |
47 * </p> | |
48 * <p> | |
49 * Label providers for table viewers must implement either the | |
50 * <code>ITableLabelProvider</code> or the <code>ILabelProvider</code> | |
51 * interface (see <code>TableViewer.setLabelProvider</code> for more details). | |
52 * </p> | |
53 * <p> | |
54 * As of 3.1 the TableViewer now supports the DWT.VIRTUAL flag. If the | |
55 * underlying table is DWT.VIRTUAL, the content provider may implement | |
56 * {@link ILazyContentProvider} instead of {@link IStructuredContentProvider}. | |
57 * Note that in this case, the viewer does not support sorting or filtering. | |
58 * Also note that in this case, the Widget based APIs may return null if the | |
59 * element is not specified or not created yet. | |
60 * </p> | |
61 * <p> | |
62 * Users of DWT.VIRTUAL should also avoid using getItems() from the Table within | |
63 * the TreeViewer as this does not necessarily generate a callback for the | |
64 * TreeViewer to populate the items. It also has the side effect of creating all | |
65 * of the items thereby eliminating the performance improvements of DWT.VIRTUAL. | |
66 * </p> | |
67 * | |
68 * @see DWT#VIRTUAL | |
69 * @see #doFindItem(Object) | |
70 * @see #internalRefresh(Object, bool) | |
71 */ | |
72 public class TableViewer : AbstractTableViewer { | |
73 | |
74 public alias AbstractTableViewer.preservingSelection preservingSelection; | |
75 | |
76 /** | |
77 * This viewer's table control. | |
78 */ | |
79 private Table table; | |
80 | |
81 /** | |
82 * The cached row which is reused all over | |
83 */ | |
84 private TableViewerRow cachedRow; | |
85 | |
86 /** | |
87 * Creates a table viewer on a newly-created table control under the given | |
88 * parent. The table control is created using the DWT style bits | |
89 * <code>MULTI, H_SCROLL, V_SCROLL,</code> and <code>BORDER</code>. The | |
90 * viewer has no input, no content provider, a default label provider, no | |
91 * sorter, and no filters. The table has no columns. | |
92 * | |
93 * @param parent | |
94 * the parent control | |
95 */ | |
96 public this(Composite parent) { | |
97 this(parent, DWT.MULTI | DWT.H_SCROLL | DWT.V_SCROLL | DWT.BORDER); | |
98 } | |
99 | |
100 /** | |
101 * Creates a table viewer on a newly-created table control under the given | |
102 * parent. The table control is created using the given style bits. The | |
103 * viewer has no input, no content provider, a default label provider, no | |
104 * sorter, and no filters. The table has no columns. | |
105 * | |
106 * @param parent | |
107 * the parent control | |
108 * @param style | |
109 * DWT style bits | |
110 */ | |
111 public this(Composite parent, int style) { | |
112 this(new Table(parent, style)); | |
113 } | |
114 | |
115 /** | |
116 * Creates a table viewer on the given table control. The viewer has no | |
117 * input, no content provider, a default label provider, no sorter, and no | |
118 * filters. | |
119 * | |
120 * @param table | |
121 * the table control | |
122 */ | |
123 public this(Table table) { | |
124 this.table = table; | |
125 hookControl(table); | |
126 } | |
127 | |
128 public Control getControl() { | |
129 return table; | |
130 } | |
131 | |
132 /** | |
133 * Returns this table viewer's table control. | |
134 * | |
135 * @return the table control | |
136 */ | |
137 public Table getTable() { | |
138 return table; | |
139 } | |
140 | |
141 protected ColumnViewerEditor createViewerEditor() { | |
142 return new TableViewerEditor(this,null,new ColumnViewerEditorActivationStrategy(this),ColumnViewerEditor.DEFAULT); | |
143 } | |
144 | |
145 /** | |
146 * <p> | |
147 * Sets a new selection for this viewer and optionally makes it visible. The | |
148 * TableViewer implementation of this method is inefficient for the | |
149 * ILazyContentProvider as lookup is done by indices rather than elements | |
150 * and may require population of the entire table in worse case. | |
151 * </p> | |
152 * <p> | |
153 * Use Table#setSelection(int[] indices) and Table#showSelection() if you | |
154 * wish to set selection more efficiently when using a ILazyContentProvider. | |
155 * </p> | |
156 * | |
157 * @param selection | |
158 * the new selection | |
159 * @param reveal | |
160 * <code>true</code> if the selection is to be made visible, | |
161 * and <code>false</code> otherwise | |
162 * @see Table#setSelection(int[]) | |
163 * @see Table#showSelection() | |
164 */ | |
165 public void setSelection(ISelection selection, bool reveal) { | |
166 super.setSelection(selection, reveal); | |
167 } | |
168 | |
169 protected ViewerRow getViewerRowFromItem(Widget item) { | |
170 if( cachedRow is null ) { | |
171 cachedRow = new TableViewerRow(cast(TableItem) item); | |
172 } else { | |
173 cachedRow.setItem(cast(TableItem) item); | |
174 } | |
175 | |
176 return cachedRow; | |
177 } | |
178 | |
179 /** | |
180 * Create a new row with style at index | |
181 * | |
182 * @param style | |
183 * @param rowIndex | |
184 * @return ViewerRow | |
185 * @since 3.3 | |
186 */ | |
187 protected ViewerRow internalCreateNewRowPart(int style, int rowIndex) { | |
188 TableItem item; | |
189 | |
190 if (rowIndex >= 0) { | |
191 item = new TableItem(table, style, rowIndex); | |
192 } else { | |
193 item = new TableItem(table, style); | |
194 } | |
195 | |
196 return getViewerRowFromItem(item); | |
197 } | |
198 | |
199 protected Item getItemAt(Point p) { | |
200 TableItem[] selection = table.getSelection(); | |
201 | |
202 if( selection.length is 1 ) { | |
203 int columnCount = table.getColumnCount(); | |
204 | |
205 for( int i = 0; i < columnCount; i++ ) { | |
206 if( selection[0].getBounds(i).contains(p) ) { | |
207 return selection[0]; | |
208 } | |
209 } | |
210 } | |
211 | |
212 return table.getItem(p); | |
213 } | |
214 | |
215 // Methods to provide widget independency | |
216 | |
217 protected int doGetItemCount() { | |
218 return table.getItemCount(); | |
219 } | |
220 | |
221 protected int doIndexOf(Item item) { | |
222 return table.indexOf(cast(TableItem)item); | |
223 } | |
224 | |
225 protected void doSetItemCount(int count) { | |
226 table.setItemCount(count); | |
227 } | |
228 | |
229 protected Item[] doGetItems() { | |
230 return table.getItems(); | |
231 } | |
232 | |
233 protected int doGetColumnCount() { | |
234 return table.getColumnCount(); | |
235 } | |
236 | |
237 protected Widget doGetColumn(int index) { | |
238 return table.getColumn(index); | |
239 } | |
240 | |
241 protected Item doGetItem(int index) { | |
242 return table.getItem(index); | |
243 } | |
244 | |
245 protected Item[] doGetSelection() { | |
246 return table.getSelection(); | |
247 } | |
248 | |
249 protected int[] doGetSelectionIndices() { | |
250 return table.getSelectionIndices(); | |
251 } | |
252 | |
253 protected void doClearAll() { | |
254 table.clearAll(); | |
255 } | |
256 | |
257 protected void doResetItem(Item item) { | |
258 TableItem tableItem = cast(TableItem) item; | |
259 int columnCount = Math.max(1, table.getColumnCount()); | |
260 for (int i = 0; i < columnCount; i++) { | |
261 tableItem.setText(i, ""); //$NON-NLS-1$ | |
262 if (tableItem.getImage(i) !is null) { | |
263 tableItem.setImage(i, null); | |
264 } | |
265 } | |
266 } | |
267 | |
268 protected void doRemove(int start, int end) { | |
269 table.remove(start, end); | |
270 } | |
271 | |
272 protected void doRemoveAll() { | |
273 table.removeAll(); | |
274 } | |
275 | |
276 protected void doRemove(int[] indices) { | |
277 table.remove(indices); | |
278 } | |
279 | |
280 protected void doShowItem(Item item) { | |
281 table.showItem(cast(TableItem)item); | |
282 } | |
283 | |
284 protected void doDeselectAll() { | |
285 table.deselectAll(); | |
286 } | |
287 | |
288 protected void doSetSelection(Item[] items) { | |
289 // Assert.isNotNull(items, "Items-Array can not be null"); //$NON-NLS-1$ | |
290 | |
291 TableItem[] t = new TableItem[items.length]; | |
292 System.arraycopy(items, 0, t, 0, t.length); | |
293 | |
294 table.setSelection(t); | |
295 } | |
296 | |
297 protected void doShowSelection() { | |
298 table.showSelection(); | |
299 } | |
300 | |
301 protected void doSetSelection(int[] indices) { | |
302 table.setSelection(indices); | |
303 } | |
304 | |
305 protected void doClear(int index) { | |
306 table.clear(index); | |
307 } | |
308 | |
309 protected void doSelect(int[] indices) { | |
310 table.select(indices); | |
311 } | |
312 | |
313 /** | |
314 * Refreshes this viewer starting with the given element. Labels are updated | |
315 * as described in <code>refresh(bool updateLabels)</code>. The | |
316 * methods attempts to preserve the selection. | |
317 * <p> | |
318 * Unlike the <code>update</code> methods, this handles structural changes | |
319 * to the given element (e.g. addition or removal of children). If only the | |
320 * given element needs updating, it is more efficient to use the | |
321 * <code>update</code> methods. | |
322 * </p> | |
323 * | |
324 * <p> | |
325 * Subclasses who can provide this feature can open this method for the | |
326 * public | |
327 * </p> | |
328 * | |
329 * @param element | |
330 * the element | |
331 * @param updateLabels | |
332 * <code>true</code> to update labels for existing elements, | |
333 * <code>false</code> to only update labels as needed, assuming | |
334 * that labels for existing elements are unchanged. | |
335 * @param reveal | |
336 * <code>true</code> to make the preserved selection visible | |
337 * afterwards | |
338 * | |
339 * @since 3.3 | |
340 */ | |
341 public void refresh(Object element, bool updateLabels, | |
342 bool reveal) { | |
343 if (isBusy()) | |
344 return; | |
345 | |
346 if( isCellEditorActive() ) { | |
347 cancelEditing(); | |
348 } | |
349 | |
350 preservingSelection(new class Runnable { | |
351 Object element_; | |
352 bool updateLabels_; | |
353 this(){ | |
354 element_ = element; | |
355 updateLabels_ = updateLabels; | |
356 } | |
357 public void run() { | |
358 internalRefresh(element_, updateLabels_); | |
359 } | |
360 }, reveal); | |
361 } | |
362 | |
363 /** | |
364 * Refreshes this viewer with information freshly obtained from this | |
365 * viewer's model. If <code>updateLabels</code> is <code>true</code> | |
366 * then labels for otherwise unaffected elements are updated as well. | |
367 * Otherwise, it assumes labels for existing elements are unchanged, and | |
368 * labels are only obtained as needed (for example, for new elements). | |
369 * <p> | |
370 * Calling <code>refresh(true)</code> has the same effect as | |
371 * <code>refresh()</code>. | |
372 * <p> | |
373 * Note that the implementation may still obtain labels for existing | |
374 * elements even if <code>updateLabels</code> is false. The intent is | |
375 * simply to allow optimization where possible. | |
376 * | |
377 * @param updateLabels | |
378 * <code>true</code> to update labels for existing elements, | |
379 * <code>false</code> to only update labels as needed, assuming | |
380 * that labels for existing elements are unchanged. | |
381 * @param reveal | |
382 * <code>true</code> to make the preserved selection visible | |
383 * afterwards | |
384 * | |
385 * @since 3.3 | |
386 */ | |
387 public void refresh(bool updateLabels, bool reveal) { | |
388 refresh(getRoot(), updateLabels, reveal); | |
389 } | |
390 } |