1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
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
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.views
;
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
;
35 * <b><u>TmfEventsView</u></b>
38 * TODO: Implement me. Please.
39 * TODO: Handle column selection, sort, ... generically (nothing less...)
40 * TODO: Implement hide/display columns
42 public class TmfEventsView
extends TmfView
{
44 public static final String ID
= "org.eclipse.linuxtools.tmf.ui.viewer.events";
46 private TmfExperiment fExperiment
;
47 private String fTitlePrefix
;
49 // ========================================================================
51 // ========================================================================
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
[] {
70 private class ColumnData
{
71 public final String header
;
72 public final int width
;
73 public final int alignment
;
75 public ColumnData(String h
, int w
, int a
) {
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
)
90 // ========================================================================
92 // ========================================================================
94 public TmfEventsView() {
99 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
102 public void createPartControl(Composite parent
) {
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
);
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
);
114 // Some cosmetic enhancements
115 fTable
.setHeaderVisible(true);
116 fTable
.setLinesVisible(true);
119 setColumnHeaders(fTable
);
121 // Handle the table item requests
122 fTable
.addSelectionListener(new SelectionListener() {
124 public void widgetDefaultSelected(SelectionEvent e
) {
125 // TODO Auto-generated method stub
128 public void widgetSelected(SelectionEvent e
) {
129 TmfTimestamp ts
= extractTimestamp(fTable
.getSelection()[0].getText());
130 broadcastSignal(new TmfTimeSynchSignal(fTable
, ts
));
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
]));
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) {
155 // THIS IS ONLY A TEMPORARY FIX!
157 TmfDataRequest
<TmfEvent
> request
= new TmfDataRequest
<TmfEvent
>(index
, 1) {
159 public void handleData() {
160 TmfEvent
[] tmpEvent
= getData();
161 if ( (tmpEvent
!= null) && (tmpEvent
.length
> 0) ) {
164 // cacheStartIndex = index;
165 // cacheEndIndex = index + cache.length;
168 fExperiment
.processRequest(request
, true);
170 if (cache
[0] != null) {
171 item
.setText(extractItemFields(cache
[0]));
177 fTable
.setItemCount(0);
178 fTitlePrefix
= getTitle();
180 // If an experiment is already selected, update the table
181 fExperiment
= TmfExperiment
.getCurrentExperiment();
182 if (fExperiment
!= null) {
183 experimentSelected(new TmfExperimentSelectedSignal(fTable
, fExperiment
));
187 // Events cache - temporary stuff
188 private final int CACHE_SIZE
= 1;
189 private TmfEvent
[] cache
;
190 private int cacheStartIndex
= 0;
191 private int cacheEndIndex
= 0;
194 private TmfTimestamp
extractTimestamp(String entry
) {
195 TmfTimestamp ts
= null;
197 int pos
= entry
.indexOf('.');
199 String integer
= entry
.substring(0, pos
);
200 String fraction
= entry
.substring(pos
+ 1);
202 byte exponent
= (byte) -fraction
.length();
203 String value
= integer
+ fraction
;
204 ts
= new TmfTimestamp(new Long(value
), exponent
);
213 * FIXME: Add support for column selection
215 protected void setColumnHeaders(Table table
) {
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
);
227 * FIXME: Add support for column selection
229 protected String
[] extractItemFields(TmfEvent event
) {
230 String
[] fields
= new String
[0];
232 fields
= new String
[] {
233 new Long(event
.getTimestamp().getValue()).toString(),
234 event
.getSource().getSourceId().toString(),
235 event
.getType().getTypeId().toString(),
236 event
.getReference().getReference().toString(),
237 event
.getContent().toString()
244 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
247 public void setFocus() {
251 * @see java.lang.Object#toString()
254 public String
toString() {
255 return "[TmfEventsView]";
258 // ========================================================================
260 // ========================================================================
263 public void experimentSelected(TmfExperimentSelectedSignal signal
) {
264 // Update the trace reference
265 fExperiment
= signal
.getExperiment();
266 setPartName(fTitlePrefix
+ " - " + fExperiment
.getExperimentId());
268 // Perform the updates on the UI thread
269 fTable
.getDisplay().asyncExec(new Runnable() {
271 // // TODO: Potentially long operation. Add some feedback for the user
272 fTable
.setSelection(0);
274 fTable
.setItemCount(fExperiment
.getNbEvents());
280 public void experimentUpdated(TmfExperimentUpdatedSignal signal
) {
281 // Perform the refresh on the UI thread
282 fTable
.getDisplay().asyncExec(new Runnable() {
284 if (!fTable
.isDisposed() && fExperiment
!= null) {
285 fTable
.setItemCount(fExperiment
.getNbEvents());
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() {
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);