Quick fix for synchronization of the Events View
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / TmfEventsView.java
1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.ui.views;
14
15 import org.eclipse.linuxtools.tmf.event.TmfEvent;
16 import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
17 import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
18 import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
19 import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;
20 import org.eclipse.linuxtools.tmf.trace.TmfExperiment;
21 import org.eclipse.linuxtools.tmf.trace.TmfExperimentSelectedSignal;
22 import org.eclipse.linuxtools.tmf.trace.TmfExperimentUpdatedSignal;
23 import org.eclipse.swt.SWT;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.events.SelectionListener;
26 import org.eclipse.swt.layout.GridData;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Event;
29 import org.eclipse.swt.widgets.Listener;
30 import org.eclipse.swt.widgets.Table;
31 import org.eclipse.swt.widgets.TableColumn;
32 import org.eclipse.swt.widgets.TableItem;
33
34 /**
35 * <b><u>TmfEventsView</u></b>
36 * <p>
37 *
38 * TODO: Implement me. Please.
39 * TODO: Handle column selection, sort, ... generically (nothing less...)
40 * TODO: Implement hide/display columns
41 */
42 public class TmfEventsView extends TmfView {
43
44 public static final String ID = "org.eclipse.linuxtools.tmf.ui.viewer.events";
45
46 private TmfExperiment fExperiment;
47 private String fTitlePrefix;
48
49 // ========================================================================
50 // Table data
51 // ========================================================================
52
53 private Table fTable;
54
55 // Table column names
56 private final String TIMESTAMP_COLUMN = "Timestamp";
57 private final String SOURCE_COLUMN = "Source";
58 private final String TYPE_COLUMN = "Type";
59 private final String REFERENCE_COLUMN = "File";
60 private final String CONTENT_COLUMN = "Content";
61 private final String[] columnProperties = new String[] {
62 TIMESTAMP_COLUMN,
63 SOURCE_COLUMN,
64 TYPE_COLUMN,
65 REFERENCE_COLUMN,
66 CONTENT_COLUMN
67 };
68
69 // Column data
70 private class ColumnData {
71 public final String header;
72 public final int width;
73 public final int alignment;
74
75 public ColumnData(String h, int w, int a) {
76 header = h;
77 width = w;
78 alignment = a;
79 }
80 };
81
82 private ColumnData[] columnData = new ColumnData[] {
83 new ColumnData(columnProperties[0], 100, SWT.LEFT),
84 new ColumnData(columnProperties[1], 100, SWT.LEFT),
85 new ColumnData(columnProperties[2], 100, SWT.LEFT),
86 new ColumnData(columnProperties[3], 100, SWT.LEFT),
87 new ColumnData(columnProperties[4], 100, SWT.LEFT)
88 };
89
90 // ========================================================================
91 // Constructor
92 // ========================================================================
93
94 public TmfEventsView() {
95 super();
96 }
97
98 /* (non-Javadoc)
99 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
100 */
101 @Override
102 public void createPartControl(Composite parent) {
103
104 // Create a virtual table
105 // TODO: change SINGLE to MULTI line selection and adjust the selection listener
106 final int style = SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.VIRTUAL;
107 fTable = new Table(parent, style);
108
109 // Set the table layout
110 GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
111 layoutData.horizontalSpan= columnData.length;
112 fTable.setLayoutData(layoutData);
113
114 // Some cosmetic enhancements
115 fTable.setHeaderVisible(true);
116 fTable.setLinesVisible(true);
117
118 // Set the columns
119 setColumnHeaders(fTable);
120
121 // Handle the table item requests
122 fTable.addSelectionListener(new SelectionListener() {
123
124 public void widgetDefaultSelected(SelectionEvent e) {
125 // TODO Auto-generated method stub
126 }
127
128 public void widgetSelected(SelectionEvent e) {
129 TmfTimestamp ts = extractTimestamp(fTable.getSelection()[0].getText());
130 broadcastSignal(new TmfTimeSynchSignal(fTable, ts));
131 }
132 });
133
134 // Handle the table item requests
135 fTable.addListener(SWT.SetData, new Listener() {
136 public void handleEvent(Event event) {
137 TableItem item = (TableItem) event.item;
138 final int index = fTable.indexOf(item);
139 // Note: this works because handleEvent() is called once for each row, in sequence
140 if ((index >= cacheStartIndex ) && (index < cacheEndIndex)) {
141 item.setText(extractItemFields(cache[index - cacheStartIndex]));
142 return;
143 }
144 TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(index, 0, CACHE_SIZE) {
145 @Override
146 public void handleData() {
147 // No need to synchronize because the request is synchronous
148 cache = getData();
149 cacheStartIndex = index;
150 cacheEndIndex = index + cache.length;
151 }
152 };
153 fExperiment.processRequest(request, true);
154 item.setText(extractItemFields(cache[0]));
155 }
156 });
157
158 fTable.setItemCount(0);
159 fTitlePrefix = getTitle();
160
161 // If an experiment is already selected, update the table
162 fExperiment = TmfExperiment.getCurrentExperiment();
163 if (fExperiment != null) {
164 experimentSelected(new TmfExperimentSelectedSignal(fTable, fExperiment));
165 }
166 }
167
168 // Events cache - temporary stuff
169 private final int CACHE_SIZE = 100;
170 private TmfEvent[] cache;
171 private int cacheStartIndex = 0;
172 private int cacheEndIndex = 0;
173
174
175 private TmfTimestamp extractTimestamp(String entry) {
176 TmfTimestamp ts = null;
177
178 int pos = entry.indexOf('.');
179 if (pos > 0) {
180 String integer = entry.substring(0, pos);
181 String fraction = entry.substring(pos + 1);
182
183 byte exponent = (byte) -fraction.length();
184 String value = integer + fraction;
185 ts = new TmfTimestamp(new Long(value), exponent);
186 }
187
188 return ts;
189 }
190
191 /**
192 * @param table
193 *
194 * FIXME: Add support for column selection
195 */
196 protected void setColumnHeaders(Table table) {
197 for (int i = 0; i < columnData.length; i++) {
198 TableColumn column = new TableColumn(table, columnData[i].alignment, i);
199 column.setText(columnData[i].header);
200 column.setWidth(columnData[i].width);
201 }
202 }
203
204 /**
205 * @param event
206 * @return
207 *
208 * FIXME: Add support for column selection
209 */
210 protected String[] extractItemFields(TmfEvent event) {
211 String[] fields = new String[0];
212 if (event != null) {
213 fields = new String[] {
214 new Long(event.getTimestamp().getValue()).toString(),
215 event.getSource().getSourceId().toString(),
216 event.getType().getTypeId().toString(),
217 event.getReference().getValue().toString(),
218 event.getContent().getContent()
219 };
220 }
221 return fields;
222 }
223
224 /* (non-Javadoc)
225 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
226 */
227 @Override
228 public void setFocus() {
229 }
230
231 /* (non-Javadoc)
232 * @see java.lang.Object#toString()
233 */
234 @Override
235 public String toString() {
236 return "[TmfEventsView]";
237 }
238
239 // ========================================================================
240 // Signal handlers
241 // ========================================================================
242
243 @TmfSignalHandler
244 public void experimentSelected(TmfExperimentSelectedSignal signal) {
245 // Update the trace reference
246 fExperiment = signal.getExperiment();
247 setPartName(fTitlePrefix + " - " + fExperiment.getExperimentId());
248
249 // Perform the updates on the UI thread
250 fTable.getDisplay().asyncExec(new Runnable() {
251 public void run() {
252 // TODO: Potentially long operation. Add some feedback for the user
253 fTable.setSelection(0);
254 fTable.clearAll();
255 fTable.setItemCount(fExperiment.getNbEvents());
256 }
257 });
258 }
259
260 @TmfSignalHandler
261 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
262 // Perform the refresh on the UI thread
263 fTable.getDisplay().asyncExec(new Runnable() {
264 public void run() {
265 if (!fTable.isDisposed() && fExperiment != null) {
266 fTable.setItemCount(fExperiment.getNbEvents());
267 }
268 }
269 });
270 }
271
272 @TmfSignalHandler
273 public void currentTimeUpdated(TmfTimeSynchSignal signal) {
274 if (signal.getSource() != fTable && fExperiment != null) {
275 final int index = (int) fExperiment.getIndex(signal.getCurrentTime());
276 // Perform the updates on the UI thread
277 fTable.getDisplay().asyncExec(new Runnable() {
278 public void run() {
279 fTable.setSelection(index);
280 // The timestamp might not correspond to an actual event
281 // and the selection will point to the next experiment event.
282 // But we would like to display both the event before and
283 // after the selected timestamp.
284 // This works fine by default except when the selected event
285 // is the top displayed event. The following ensures that we
286 // always see both events.
287 if ((index > 0) && (index == fTable.getTopIndex())) {
288 fTable.setTopIndex(index - 1);
289 }
290 }
291 });
292 }
293 }
294
295 }
This page took 0.039606 seconds and 5 git commands to generate.