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