Commit | Line | Data |
---|---|---|
b0d3496e | 1 | /******************************************************************************* |
3231fbd9 | 2 | * Copyright (c) 2009 Ericsson |
b0d3496e ASL |
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; | |
b0d3496e | 17 | import org.eclipse.linuxtools.tmf.request.TmfDataRequest; |
b0d3496e ASL |
18 | import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler; |
19 | import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal; | |
62d1696a FC |
20 | import org.eclipse.linuxtools.tmf.trace.TmfExperiment; |
21 | import org.eclipse.linuxtools.tmf.trace.TmfExperimentSelectedSignal; | |
4e3aa37d | 22 | import org.eclipse.linuxtools.tmf.trace.TmfExperimentUpdatedSignal; |
b0d3496e | 23 | import org.eclipse.swt.SWT; |
b0d3496e | 24 | import org.eclipse.swt.events.SelectionEvent; |
3231fbd9 | 25 | import org.eclipse.swt.events.SelectionListener; |
b0d3496e ASL |
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 | */ | |
79a3a76e | 42 | public class TmfEventsView extends TmfView { |
b0d3496e | 43 | |
3231fbd9 | 44 | public static final String ID = "org.eclipse.linuxtools.tmf.ui.viewer.events"; |
b0d3496e | 45 | |
62d1696a FC |
46 | private TmfExperiment fExperiment; |
47 | private String fTitlePrefix; | |
b0d3496e | 48 | |
3231fbd9 | 49 | // ======================================================================== |
b0d3496e | 50 | // Table data |
3231fbd9 | 51 | // ======================================================================== |
b0d3496e ASL |
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[] { | |
3231fbd9 | 62 | TIMESTAMP_COLUMN, |
b0d3496e ASL |
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 | ||
3231fbd9 | 90 | // ======================================================================== |
b0d3496e | 91 | // Constructor |
3231fbd9 | 92 | // ======================================================================== |
b0d3496e ASL |
93 | |
94 | public TmfEventsView() { | |
3231fbd9 | 95 | super(); |
b0d3496e ASL |
96 | } |
97 | ||
3231fbd9 FC |
98 | /* (non-Javadoc) |
99 | * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) | |
100 | */ | |
101 | @Override | |
b0d3496e ASL |
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); | |
3231fbd9 | 111 | layoutData.horizontalSpan= columnData.length; |
b0d3496e ASL |
112 | fTable.setLayoutData(layoutData); |
113 | ||
114 | // Some cosmetic enhancements | |
115 | fTable.setHeaderVisible(true); | |
116 | fTable.setLinesVisible(true); | |
117 | ||
118 | // Set the columns | |
3231fbd9 | 119 | setColumnHeaders(fTable); |
b0d3496e ASL |
120 | |
121 | // Handle the table item requests | |
3231fbd9 FC |
122 | fTable.addSelectionListener(new SelectionListener() { |
123 | ||
124 | public void widgetDefaultSelected(SelectionEvent e) { | |
125 | // TODO Auto-generated method stub | |
126 | } | |
b0d3496e | 127 | |
b0d3496e | 128 | public void widgetSelected(SelectionEvent e) { |
8d2e2848 | 129 | TmfTimestamp ts = extractTimestamp(fTable.getSelection()[0].getText()); |
d15fd570 | 130 | broadcastSignal(new TmfTimeSynchSignal(fTable, ts)); |
b0d3496e ASL |
131 | } |
132 | }); | |
133 | ||
134 | // Handle the table item requests | |
135 | fTable.addListener(SWT.SetData, new Listener() { | |
b0d3496e | 136 | public void handleEvent(Event event) { |
3231fbd9 | 137 | TableItem item = (TableItem) event.item; |
98029bc9 FC |
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 | } | |
28b94d61 FC |
144 | |
145 | // *** TODO *** | |
146 | // This is broken! | |
147 | // | |
148 | // This one fails to return any result : | |
149 | // TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(fExperiment.getTimeRange(), index, 1) { | |
150 | // All these will return THE SAME RESULT! | |
151 | // TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(index, 1) { | |
152 | // TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(index+10, 1) { | |
153 | // TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(null, 1) { | |
154 | // | |
155 | // THIS IS ONLY A TEMPORARY FIX! | |
156 | ||
157 | TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(index, 1) { | |
b0d3496e ASL |
158 | @Override |
159 | public void handleData() { | |
28b94d61 FC |
160 | TmfEvent[] tmpEvent = getData(); |
161 | if ( (tmpEvent != null) && (tmpEvent.length > 0) ) { | |
162 | cache = tmpEvent; | |
163 | } | |
164 | // cacheStartIndex = index; | |
165 | // cacheEndIndex = index + cache.length; | |
b0d3496e ASL |
166 | } |
167 | }; | |
62d1696a | 168 | fExperiment.processRequest(request, true); |
28b94d61 FC |
169 | |
170 | if (cache[0] != null) { | |
171 | item.setText(extractItemFields(cache[0])); | |
172 | } | |
173 | ||
b0d3496e ASL |
174 | } |
175 | }); | |
176 | ||
177 | fTable.setItemCount(0); | |
62d1696a | 178 | fTitlePrefix = getTitle(); |
8d2e2848 FC |
179 | |
180 | // If an experiment is already selected, update the table | |
181 | fExperiment = TmfExperiment.getCurrentExperiment(); | |
182 | if (fExperiment != null) { | |
183 | experimentSelected(new TmfExperimentSelectedSignal(fTable, fExperiment)); | |
184 | } | |
185 | } | |
186 | ||
98029bc9 | 187 | // Events cache - temporary stuff |
28b94d61 | 188 | private final int CACHE_SIZE = 1; |
98029bc9 FC |
189 | private TmfEvent[] cache; |
190 | private int cacheStartIndex = 0; | |
191 | private int cacheEndIndex = 0; | |
192 | ||
193 | ||
8d2e2848 FC |
194 | private TmfTimestamp extractTimestamp(String entry) { |
195 | TmfTimestamp ts = null; | |
196 | ||
197 | int pos = entry.indexOf('.'); | |
198 | if (pos > 0) { | |
199 | String integer = entry.substring(0, pos); | |
200 | String fraction = entry.substring(pos + 1); | |
201 | ||
202 | byte exponent = (byte) -fraction.length(); | |
203 | String value = integer + fraction; | |
204 | ts = new TmfTimestamp(new Long(value), exponent); | |
205 | } | |
206 | ||
207 | return ts; | |
b0d3496e ASL |
208 | } |
209 | ||
210 | /** | |
211 | * @param table | |
212 | * | |
213 | * FIXME: Add support for column selection | |
214 | */ | |
3231fbd9 | 215 | protected void setColumnHeaders(Table table) { |
b0d3496e ASL |
216 | for (int i = 0; i < columnData.length; i++) { |
217 | TableColumn column = new TableColumn(table, columnData[i].alignment, i); | |
218 | column.setText(columnData[i].header); | |
219 | column.setWidth(columnData[i].width); | |
220 | } | |
221 | } | |
222 | ||
223 | /** | |
224 | * @param event | |
225 | * @return | |
226 | * | |
227 | * FIXME: Add support for column selection | |
228 | */ | |
229 | protected String[] extractItemFields(TmfEvent event) { | |
230 | String[] fields = new String[0]; | |
231 | if (event != null) { | |
232 | fields = new String[] { | |
233 | new Long(event.getTimestamp().getValue()).toString(), | |
234 | event.getSource().getSourceId().toString(), | |
235 | event.getType().getTypeId().toString(), | |
28b94d61 FC |
236 | event.getReference().getReference().toString(), |
237 | event.getContent().toString() | |
b0d3496e ASL |
238 | }; |
239 | } | |
240 | return fields; | |
241 | } | |
242 | ||
243 | /* (non-Javadoc) | |
244 | * @see org.eclipse.ui.part.WorkbenchPart#setFocus() | |
245 | */ | |
246 | @Override | |
247 | public void setFocus() { | |
248 | } | |
249 | ||
8d2e2848 FC |
250 | /* (non-Javadoc) |
251 | * @see java.lang.Object#toString() | |
252 | */ | |
253 | @Override | |
254 | public String toString() { | |
255 | return "[TmfEventsView]"; | |
256 | } | |
257 | ||
3231fbd9 | 258 | // ======================================================================== |
b0d3496e | 259 | // Signal handlers |
3231fbd9 | 260 | // ======================================================================== |
b0d3496e | 261 | |
b0d3496e | 262 | @TmfSignalHandler |
62d1696a | 263 | public void experimentSelected(TmfExperimentSelectedSignal signal) { |
b0d3496e | 264 | // Update the trace reference |
62d1696a FC |
265 | fExperiment = signal.getExperiment(); |
266 | setPartName(fTitlePrefix + " - " + fExperiment.getExperimentId()); | |
b0d3496e ASL |
267 | |
268 | // Perform the updates on the UI thread | |
269 | fTable.getDisplay().asyncExec(new Runnable() { | |
270 | public void run() { | |
28b94d61 | 271 | // // TODO: Potentially long operation. Add some feedback for the user |
8d2e2848 | 272 | fTable.setSelection(0); |
b0d3496e | 273 | fTable.clearAll(); |
62d1696a | 274 | fTable.setItemCount(fExperiment.getNbEvents()); |
b0d3496e ASL |
275 | } |
276 | }); | |
277 | } | |
278 | ||
279 | @TmfSignalHandler | |
4e3aa37d | 280 | public void experimentUpdated(TmfExperimentUpdatedSignal signal) { |
b0d3496e ASL |
281 | // Perform the refresh on the UI thread |
282 | fTable.getDisplay().asyncExec(new Runnable() { | |
283 | public void run() { | |
4e3aa37d | 284 | if (!fTable.isDisposed() && fExperiment != null) { |
62d1696a | 285 | fTable.setItemCount(fExperiment.getNbEvents()); |
b0d3496e ASL |
286 | } |
287 | } | |
288 | }); | |
289 | } | |
290 | ||
d15fd570 FC |
291 | @TmfSignalHandler |
292 | public void currentTimeUpdated(TmfTimeSynchSignal signal) { | |
293 | if (signal.getSource() != fTable && fExperiment != null) { | |
294 | final int index = (int) fExperiment.getIndex(signal.getCurrentTime()); | |
295 | // Perform the updates on the UI thread | |
296 | fTable.getDisplay().asyncExec(new Runnable() { | |
297 | public void run() { | |
298 | fTable.setSelection(index); | |
299 | // The timestamp might not correspond to an actual event | |
300 | // and the selection will point to the next experiment event. | |
301 | // But we would like to display both the event before and | |
302 | // after the selected timestamp. | |
303 | // This works fine by default except when the selected event | |
304 | // is the top displayed event. The following ensures that we | |
305 | // always see both events. | |
306 | if ((index > 0) && (index == fTable.getTopIndex())) { | |
307 | fTable.setTopIndex(index - 1); | |
308 | } | |
309 | } | |
310 | }); | |
311 | } | |
312 | } | |
9aae0442 | 313 | |
28b94d61 | 314 | } |