2010-11-18 Francois Chouinard <fchouinard@gmail.com> Set the java compliance level...
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / viewers / events / TmfEventsTable.java
CommitLineData
abfad0aa
FC
1/*******************************************************************************\r
2 * Copyright (c) 2010 Ericsson\r
3 * \r
4 * All rights reserved. This program and the accompanying materials are\r
5 * made available under the terms of the Eclipse Public License v1.0 which\r
6 * accompanies this distribution, and is available at\r
7 * http://www.eclipse.org/legal/epl-v10.html\r
8 * \r
9 * Contributors:\r
10 * Francois Chouinard - Initial API and implementation\r
11 * Patrick Tasse - Factored out from events view\r
9ccc6d01 12 * Francois Chouinard - Replaced Table by TmfVirtualTable\r
abfad0aa
FC
13 *******************************************************************************/\r
14\r
15package org.eclipse.linuxtools.tmf.ui.viewers.events;\r
16\r
17import org.eclipse.linuxtools.tmf.component.ITmfDataProvider;\r
18import org.eclipse.linuxtools.tmf.component.TmfComponent;\r
19import org.eclipse.linuxtools.tmf.event.TmfEvent;\r
20import org.eclipse.linuxtools.tmf.event.TmfTimestamp;\r
c1c69938
FC
21import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;\r
22import org.eclipse.linuxtools.tmf.request.ITmfDataRequest.ExecutionType;\r
abfad0aa
FC
23import org.eclipse.linuxtools.tmf.request.TmfDataRequest;\r
24import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal;\r
25import org.eclipse.linuxtools.tmf.signal.TmfRangeSynchSignal;\r
26import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;\r
27import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;\r
28import org.eclipse.linuxtools.tmf.signal.TmfTraceUpdatedSignal;\r
29import org.eclipse.linuxtools.tmf.trace.ITmfTrace;\r
9ccc6d01
FC
30import org.eclipse.linuxtools.tmf.ui.widgets.ColumnData;\r
31import org.eclipse.linuxtools.tmf.ui.widgets.TmfVirtualTable;\r
abfad0aa
FC
32import org.eclipse.swt.SWT;\r
33import org.eclipse.swt.events.SelectionAdapter;\r
34import org.eclipse.swt.events.SelectionEvent;\r
35import org.eclipse.swt.layout.GridData;\r
36import org.eclipse.swt.widgets.Composite;\r
37import org.eclipse.swt.widgets.Event;\r
38import org.eclipse.swt.widgets.Listener;\r
abfad0aa
FC
39import org.eclipse.swt.widgets.TableColumn;\r
40import org.eclipse.swt.widgets.TableItem;\r
41\r
42/**\r
43 * <b><u>TmfEventsTable</u></b>\r
44 */\r
45public class TmfEventsTable extends TmfComponent {\r
46\r
abfad0aa
FC
47 // ------------------------------------------------------------------------\r
48 // Table data\r
49 // ------------------------------------------------------------------------\r
50\r
9ccc6d01 51 protected TmfVirtualTable fTable;\r
abfad0aa
FC
52 protected ITmfTrace fTrace;\r
53 protected boolean fPackDone = false;\r
54\r
55 // Table column names\r
529ee6a9
FC
56 static private final String TIMESTAMP_COLUMN = "Timestamp";\r
57 static private final String SOURCE_COLUMN = "Source";\r
58 static private final String TYPE_COLUMN = "Type";\r
59 static private final String REFERENCE_COLUMN = "File";\r
60 static private final String CONTENT_COLUMN = "Content";\r
61 static private final String[] COLUMN_NAMES = new String[] {\r
abfad0aa
FC
62 TIMESTAMP_COLUMN,\r
63 SOURCE_COLUMN,\r
64 TYPE_COLUMN,\r
65 REFERENCE_COLUMN,\r
66 CONTENT_COLUMN\r
67 };\r
68\r
529ee6a9
FC
69 static private ColumnData[] COLUMN_DATA = new ColumnData[] {\r
70 new ColumnData(COLUMN_NAMES[0], 100, SWT.LEFT),\r
71 new ColumnData(COLUMN_NAMES[1], 100, SWT.LEFT),\r
72 new ColumnData(COLUMN_NAMES[2], 100, SWT.LEFT),\r
73 new ColumnData(COLUMN_NAMES[3], 100, SWT.LEFT),\r
74 new ColumnData(COLUMN_NAMES[4], 100, SWT.LEFT)\r
abfad0aa
FC
75 };\r
76\r
77 // ------------------------------------------------------------------------\r
78 // Event cache\r
79 // ------------------------------------------------------------------------\r
80\r
9ccc6d01
FC
81 private final int fCacheSize;\r
82 private TmfEvent[] fCache;\r
83 private int fCacheStartIndex = 0;\r
84 private int fCacheEndIndex = 0;\r
85\r
529ee6a9 86 private boolean fDisposeOnClose;\r
abfad0aa
FC
87\r
88 // ------------------------------------------------------------------------\r
89 // Constructor\r
90 // ------------------------------------------------------------------------\r
91\r
92 public TmfEventsTable(Composite parent, int cacheSize) {\r
9ccc6d01
FC
93 this(parent, cacheSize, COLUMN_DATA);\r
94 }\r
95\r
96 public TmfEventsTable(Composite parent, int cacheSize, ColumnData[] columnData) {\r
3b38ea61 97 super("TmfEventsTable"); //$NON-NLS-1$\r
abfad0aa
FC
98 \r
99 fCacheSize = cacheSize;\r
9ccc6d01 100 fCache = new TmfEvent[fCacheSize];\r
abfad0aa
FC
101 \r
102 // Create a virtual table\r
9ccc6d01
FC
103 final int style = SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER;\r
104 fTable = new TmfVirtualTable(parent, style);\r
abfad0aa
FC
105\r
106 // Set the table layout\r
107 GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);\r
108 fTable.setLayoutData(layoutData);\r
109\r
110 // Some cosmetic enhancements\r
111 fTable.setHeaderVisible(true);\r
112 fTable.setLinesVisible(true);\r
113\r
114 // Set the columns\r
9ccc6d01 115 setColumnHeaders(columnData);\r
abfad0aa
FC
116\r
117 // Handle the table item requests \r
118 fTable.addSelectionListener(new SelectionAdapter() {\r
abfad0aa
FC
119 @Override\r
120 public void widgetSelected(SelectionEvent e) {\r
121 TmfTimestamp ts = (TmfTimestamp) fTable.getSelection()[0].getData();\r
122 broadcast(new TmfTimeSynchSignal(fTable, ts));\r
123 }\r
124 });\r
125\r
126 // Handle the table item requests \r
127 fTable.addListener(SWT.SetData, new Listener() {\r
128\r
d4011df2
FC
129 @Override\r
130 @SuppressWarnings("unchecked")\r
abfad0aa
FC
131 public void handleEvent(Event event) {\r
132\r
133 final TableItem item = (TableItem) event.item;\r
134 final int index = fTable.indexOf(item);\r
135\r
136 // Note: this works because handleEvent() is called once for each row, in sequence \r
9ccc6d01
FC
137 if ((index >= fCacheStartIndex) && (index < fCacheEndIndex)) {\r
138 int i = index - fCacheStartIndex;\r
139 item.setText(extractItemFields(fCache[i]));\r
140 item.setData(new TmfTimestamp(fCache[i].getTimestamp()));\r
abfad0aa
FC
141 return;\r
142 }\r
143\r
f9673903
FC
144 fCacheStartIndex = index;\r
145 fCacheEndIndex = index;\r
146\r
abfad0aa 147 TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(TmfEvent.class, index, fCacheSize) {\r
f9673903
FC
148 private int count = 0;\r
149\r
150 @Override\r
151 public void handleData(TmfEvent event) {\r
152 super.handleData(event);\r
153 if (event != null) {\r
154 fCache[count++] = event.clone();\r
155 fCacheEndIndex++;\r
abfad0aa
FC
156 }\r
157 }\r
f9673903 158\r
abfad0aa 159 };\r
f9673903 160\r
abfad0aa
FC
161 ((ITmfDataProvider<TmfEvent>) fTrace).sendRequest(request);\r
162 try {\r
163 request.waitForCompletion();\r
164 } catch (InterruptedException e) {\r
165 e.printStackTrace();\r
166 }\r
167 \r
9ccc6d01
FC
168 if (fCache[0] != null && fCacheStartIndex == index) {\r
169 item.setText(extractItemFields(fCache[0]));\r
170 item.setData(new TmfTimestamp(fCache[0].getTimestamp()));\r
171 packColumns();\r
abfad0aa
FC
172 }\r
173 \r
174 }\r
175 });\r
176\r
177 fTable.setItemCount(0);\r
178 }\r
179\r
9ccc6d01
FC
180 @Override\r
181 public void dispose() {\r
abfad0aa 182 fTable.dispose();\r
529ee6a9 183 if (fTrace != null && fDisposeOnClose) {\r
abfad0aa
FC
184 fTrace.dispose();\r
185 }\r
186 super.dispose();\r
187 }\r
188\r
9ccc6d01 189 public TmfVirtualTable getTable() {\r
abfad0aa
FC
190 return fTable;\r
191 }\r
192 \r
193 /**\r
194 * @param table\r
195 * \r
196 * FIXME: Add support for column selection\r
197 */\r
9ccc6d01
FC
198 protected void setColumnHeaders(ColumnData[] columnData) {\r
199 fTable.setColumnHeaders(columnData);\r
abfad0aa
FC
200 }\r
201\r
9ccc6d01 202 protected void packColumns() {\r
abfad0aa
FC
203 if (fPackDone) return;\r
204 for (TableColumn column : fTable.getColumns()) {\r
205 int headerWidth = column.getWidth();\r
206 column.pack();\r
207 if (column.getWidth() < headerWidth) {\r
208 column.setWidth(headerWidth);\r
209 }\r
210 }\r
211 fPackDone = true;\r
212 }\r
213 \r
214 /**\r
215 * @param event\r
216 * @return\r
217 * \r
218 * FIXME: Add support for column selection\r
219 */\r
78c0de16 220 protected String[] extractItemFields(TmfEvent event) {\r
abfad0aa
FC
221 String[] fields = new String[0];\r
222 if (event != null) {\r
223 fields = new String[] {\r
224 new Long(event.getTimestamp().getValue()).toString(), \r
225 event.getSource().getSourceId().toString(),\r
226 event.getType().getTypeId().toString(),\r
227 event.getReference().getReference().toString(),\r
228 event.getContent().toString()\r
229 };\r
230 }\r
231 return fields;\r
232 }\r
233\r
234 public void setFocus() {\r
235 fTable.setFocus();\r
236 }\r
237\r
529ee6a9
FC
238 /**\r
239 * @param trace\r
240 * @param disposeOnClose true if the trace should be disposed when the table is disposed\r
241 */\r
242 public void setTrace(ITmfTrace trace, boolean disposeOnClose) {\r
243 if (fTrace != null && fDisposeOnClose) {\r
244 fTrace.dispose();\r
245 }\r
abfad0aa 246 fTrace = trace;\r
529ee6a9 247 fDisposeOnClose = disposeOnClose;\r
abfad0aa
FC
248 \r
249 // Perform the updates on the UI thread\r
250 fTable.getDisplay().syncExec(new Runnable() {\r
d4011df2
FC
251 @Override\r
252 public void run() {\r
529ee6a9 253 //fTable.setSelection(0);\r
abfad0aa 254 fTable.removeAll();\r
9ccc6d01 255 fCacheStartIndex = fCacheEndIndex = 0; // Clear the cache\r
abfad0aa
FC
256 \r
257 if (!fTable.isDisposed() && fTrace != null) {\r
258 //int nbEvents = (int) fTrace.getNbEvents();\r
259 //fTable.setItemCount((nbEvents > 100) ? nbEvents : 100);\r
260 fTable.setItemCount((int) fTrace.getNbEvents());\r
261 }\r
262 }\r
263 });\r
abfad0aa
FC
264 }\r
265\r
266 // ------------------------------------------------------------------------\r
267 // Signal handlers\r
268 // ------------------------------------------------------------------------\r
269 \r
270 @TmfSignalHandler\r
271 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {\r
db1ea19b 272 if ((signal.getExperiment() != fTrace) || fTable.isDisposed()) return;\r
abfad0aa
FC
273 // Perform the refresh on the UI thread\r
274 fTable.getDisplay().asyncExec(new Runnable() {\r
d4011df2
FC
275 @Override\r
276 public void run() {\r
abfad0aa
FC
277 if (!fTable.isDisposed() && fTrace != null) {\r
278 fTable.setItemCount((int) fTrace.getNbEvents());\r
9ccc6d01 279 fTable.refresh();\r
abfad0aa
FC
280 }\r
281 }\r
282 });\r
283 }\r
284 \r
285 @TmfSignalHandler\r
286 public void traceUpdated(TmfTraceUpdatedSignal signal) {\r
db1ea19b 287 if ((signal.getTrace() != fTrace ) || fTable.isDisposed()) return;\r
abfad0aa
FC
288 // Perform the refresh on the UI thread\r
289 fTable.getDisplay().asyncExec(new Runnable() {\r
d4011df2
FC
290 @Override\r
291 public void run() {\r
abfad0aa
FC
292 if (!fTable.isDisposed() && fTrace != null) {\r
293 //int nbEvents = (int) fTrace.getNbEvents();\r
294 //fTable.setItemCount((nbEvents > 100) ? nbEvents : 100);\r
295 fTable.setItemCount((int) fTrace.getNbEvents());\r
296 }\r
297 }\r
298 });\r
299 }\r
300\r
301 private boolean fRefreshPending = false;\r
302 @TmfSignalHandler\r
303 public synchronized void rangeSynched(TmfRangeSynchSignal signal) {\r
db1ea19b 304 if (!fRefreshPending && !fTable.isDisposed()) {\r
abfad0aa
FC
305 // Perform the refresh on the UI thread\r
306 fRefreshPending = true;\r
307 fTable.getDisplay().asyncExec(new Runnable() {\r
d4011df2
FC
308 @Override\r
309 public void run() {\r
abfad0aa
FC
310 fRefreshPending = false;\r
311 if (!fTable.isDisposed() && fTrace != null) {\r
312 fTable.setItemCount((int) fTrace.getNbEvents());\r
313 }\r
314 }\r
315 });\r
316 }\r
317 }\r
318 \r
319 @TmfSignalHandler\r
529ee6a9 320 public void currentTimeUpdated(final TmfTimeSynchSignal signal) {\r
c1c69938
FC
321 if ((signal.getSource() != fTable) && (fTrace != null) && (!fTable.isDisposed())) {\r
322\r
323 // Create a request for one event that will be queued after other ongoing requests. When this request is completed \r
324 // do the work to select the actual event with the timestamp specified in the signal. This procedure prevents \r
325 // the method fTrace.getRank() from interfering and delaying ongoing requests.\r
326 final TmfDataRequest<TmfEvent> subRequest = new TmfDataRequest<TmfEvent>(TmfEvent.class, 0, 1, ExecutionType.FOREGROUND) {\r
327\r
328 @Override\r
329 public void handleData(TmfEvent event) {\r
330 super.handleData(event);\r
331 }\r
332\r
333 @Override\r
334 public void handleCompleted() {\r
335 // Get the rank for the event selection in the table\r
336 final int index = (int) fTrace.getRank(signal.getCurrentTime());\r
337\r
338 fTable.getDisplay().asyncExec(new Runnable() {\r
339 @Override\r
340 public void run() {\r
341 // Return if table is disposed\r
342 if (fTable.isDisposed()) return;\r
343\r
344 fTable.setSelection(index);\r
345 // The timestamp might not correspond to an actual event\r
346 // and the selection will point to the next experiment event.\r
347 // But we would like to display both the event before and\r
348 // after the selected timestamp.\r
349 // This works fine by default except when the selected event\r
350 // is the top displayed event. The following ensures that we\r
351 // always see both events.\r
352 if ((index > 0) && (index == fTable.getTopIndex())) {\r
353 fTable.setTopIndex(index - 1);\r
354 }\r
355 }\r
356 });\r
357 super.handleCompleted();\r
358 }\r
359 };\r
360\r
361 @SuppressWarnings("unchecked")\r
362 TmfExperiment<TmfEvent> experiment = (TmfExperiment<TmfEvent>)TmfExperiment.getCurrentExperiment();\r
363 if (experiment != null) {\r
364 experiment.sendRequest(subRequest);\r
365 }\r
366 }\r
367 }\r
368\r
abfad0aa 369}\r
This page took 0.043015 seconds and 5 git commands to generate.