1 /*****************************************************************************
2 * Copyright (c) 2007, Intel Corporation.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * Intel Corporation - Initial API and implementation
10 * Vitaly A. Provodin, Intel - Initial API and implementation
11 * Alvaro Sanchex-Leon - Udpated for TMF
13 * $Id: ThreadsTipHandler.java,v 1.5 2007/06/06 19:16:16 gnagarajan Exp $
14 *****************************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
;
17 import java
.util
.Iterator
;
20 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.Messages
;
21 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeAnalysisProvider
;
22 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.ITimeAnalysisViewer
.TimeFormat
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITimeEvent
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
.Utils
.Resolution
;
26 import org
.eclipse
.swt
.SWT
;
27 import org
.eclipse
.swt
.events
.MouseAdapter
;
28 import org
.eclipse
.swt
.events
.MouseEvent
;
29 import org
.eclipse
.swt
.events
.MouseTrackAdapter
;
30 import org
.eclipse
.swt
.graphics
.Point
;
31 import org
.eclipse
.swt
.graphics
.Rectangle
;
32 import org
.eclipse
.swt
.layout
.GridData
;
33 import org
.eclipse
.swt
.layout
.GridLayout
;
34 import org
.eclipse
.swt
.widgets
.Control
;
35 import org
.eclipse
.swt
.widgets
.Display
;
36 import org
.eclipse
.swt
.widgets
.Shell
;
37 import org
.eclipse
.swt
.widgets
.Table
;
38 import org
.eclipse
.swt
.widgets
.TableColumn
;
39 import org
.eclipse
.swt
.widgets
.TableItem
;
40 import org
.eclipse
.swt
.widgets
.Widget
;
43 public class TmfTimeTipHandler
{
45 private Shell _tipShell
;
46 private Table _tipTable
;
47 private Item _tipItem
;
48 private Point _tipPosition
;
49 private ITimeDataProvider _timeDataProvider
;
50 TmfTimeAnalysisProvider _utilImp
= null;
52 public TmfTimeTipHandler(Shell parent
, TmfTimeAnalysisProvider rUtilImpl
,
53 ITimeDataProvider timeProv
) {
54 final Display display
= parent
.getDisplay();
56 this._utilImp
= rUtilImpl
;
57 this._timeDataProvider
= timeProv
;
58 _tipShell
= new Shell(parent
, SWT
.ON_TOP
| SWT
.TOOL
);
59 GridLayout gridLayout
= new GridLayout();
60 gridLayout
.numColumns
= 2;
61 gridLayout
.marginWidth
= 2;
62 gridLayout
.marginHeight
= 2;
63 _tipShell
.setLayout(gridLayout
);
64 GridData data
= new GridData(GridData
.BEGINNING
, GridData
.BEGINNING
,
66 _tipShell
.setLayoutData(data
);
67 _tipShell
.setBackground(display
68 .getSystemColor(SWT
.COLOR_INFO_BACKGROUND
));
70 _tipTable
= new Table(_tipShell
, SWT
.NONE
);
71 _tipTable
.setForeground(display
72 .getSystemColor(SWT
.COLOR_INFO_FOREGROUND
));
73 _tipTable
.setBackground(display
74 .getSystemColor(SWT
.COLOR_INFO_BACKGROUND
));
75 _tipTable
.setHeaderVisible(false);
76 _tipTable
.setLinesVisible(false);
78 // tipTable.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
79 // | GridData.VERTICAL_ALIGN_CENTER));
82 public void activateHoverHelp(final Control control
) {
83 control
.addMouseListener(new MouseAdapter() {
85 public void mouseDown(MouseEvent e
) {
86 if (_tipShell
.isVisible())
87 _tipShell
.setVisible(false);
91 control
.addMouseTrackListener(new MouseTrackAdapter() {
93 public void mouseExit(MouseEvent e
) {
94 if (_tipShell
.isVisible())
95 _tipShell
.setVisible(false);
100 private void addItem(String name
, String value
) {
101 TableItem line
= new TableItem(_tipTable
, SWT
.NONE
);
102 line
.setText(0, name
);
103 line
.setText(1, value
);
106 private void fillValues(Point pt
, TmfTimeStatesCtrl threadStates
,
108 if (item
instanceof TraceItem
) {
109 ITmfTimeAnalysisEntry thrd
= ((TraceItem
) item
)._trace
;
110 ITimeEvent threadEvent
= Utils
.findEvent(thrd
, threadStates
111 .hitTimeTest(pt
.x
, pt
.y
), 2);
112 ITimeEvent nextEvent
= Utils
.findEvent(thrd
, threadStates
113 .hitTimeTest(pt
.x
, pt
.y
), 1);
115 addItem(Messages
._TRACE_NAME
, thrd
.getName());
117 addItem(Messages
._TRACE_CLASS_NAME
, _utilImp
118 .getTraceClassName(thrd
));
120 addItem(Messages
._TRACE_STATE
, _utilImp
121 .getEventName(threadEvent
));
123 // This block receives a
124 // list of <String, String> values to be added to the tip
126 Map
<String
, String
> eventAddOns
= _utilImp
127 .getEventHoverToolTipInfo(threadEvent
);
128 for (Iterator
<String
> iter
= eventAddOns
.keySet()
129 .iterator(); iter
.hasNext();) {
130 String message
= (String
) iter
.next();
131 addItem(message
, eventAddOns
.get(message
));
134 long eventStartTime
= -1;
135 long eventDuration
= -1;
136 long eventEndTime
= -1;
138 if (threadEvent
!= null) {
139 eventStartTime
= threadEvent
.getTime();
140 eventDuration
= threadEvent
.getDuration();
141 if (eventDuration
< 0 && nextEvent
!= null) {
142 eventEndTime
= nextEvent
.getTime();
143 eventDuration
= eventEndTime
- eventStartTime
;
145 eventEndTime
= eventStartTime
+ eventDuration
;
149 // TODO: Check if we need "format"
150 // TimeFormat format = TimeFormat.RELATIVE;
151 Resolution res
= Resolution
.NANOSEC
;
152 if (_timeDataProvider
.isCalendarFormat()) {
153 // format = TimeFormat.ABSOLUTE; // Absolute format
156 addItem(Messages
._TRACE_DATE
, eventStartTime
> -1 ?
157 Utils
.formatDate(eventStartTime
)
158 : "?"); //$NON-NLS-1$
159 if (eventDuration
> 0) {
160 addItem(Messages
._TRACE_START_TIME
, eventStartTime
> -1 ?
161 Utils
.formatTime(eventStartTime
, TimeFormat
.ABSOLUTE
, res
)
162 : "?"); //$NON-NLS-1$
164 addItem(Messages
._TRACE_STOP_TIME
, eventEndTime
> -1 ?
165 Utils
.formatTime(eventEndTime
, TimeFormat
.ABSOLUTE
, res
)
166 : "?"); //$NON-NLS-1$
168 addItem(Messages
._TRACE_EVENT_TIME
, eventStartTime
> -1 ?
169 Utils
.formatTime(eventStartTime
, TimeFormat
.ABSOLUTE
, res
)
170 : "?"); //$NON-NLS-1$
173 if (eventDuration
> 0) {
174 addItem(Messages
._TRACE_START_TIME
, eventStartTime
> -1 ?
175 Utils
.formatTime(eventStartTime
, TimeFormat
.RELATIVE
, res
)
176 : "?"); //$NON-NLS-1$
178 addItem(Messages
._TRACE_STOP_TIME
, eventEndTime
> -1 ?
179 Utils
.formatTime(eventEndTime
, TimeFormat
.RELATIVE
, res
)
180 : "?"); //$NON-NLS-1$
182 addItem(Messages
._TRACE_EVENT_TIME
, eventStartTime
> -1 ?
183 Utils
.formatTime(eventStartTime
, TimeFormat
.RELATIVE
, res
)
184 : "?"); //$NON-NLS-1$
188 if (eventDuration
> 0) {
189 // Duration in relative format in any case
190 addItem(Messages
._DURATION
, eventDuration
> -1 ?
191 Utils
.formatTime(eventDuration
, TimeFormat
.RELATIVE
, res
)
192 : "?"); //$NON-NLS-1$
195 } else if (item
instanceof GroupItem
) {
196 addItem(Messages
._TRACE_GROUP_NAME
, item
.toString());
197 addItem(Messages
._NUMBER_OF_TRACES
, "" + ((GroupItem
) item
)._traces
.size()); //$NON-NLS-1$
202 public void mouseHover(MouseEvent event
) {
203 Point pt
= new Point(event
.x
, event
.y
);
204 Widget widget
= event
.widget
;
206 if (widget
instanceof TmfTimeStatesCtrl
) {
207 TmfTimeStatesCtrl threadStates
= (TmfTimeStatesCtrl
) widget
;
208 item
= (Item
) threadStates
.getItem(pt
);
209 _tipTable
.remove(0, _tipTable
.getItemCount() - 1);
210 new TableColumn(_tipTable
, SWT
.NONE
);
211 new TableColumn(_tipTable
, SWT
.NONE
);
212 fillValues(pt
, threadStates
, item
);
213 _tipTable
.getColumn(0).setWidth(200);
214 _tipTable
.getColumn(1).pack();
215 _tipTable
.setSize(_tipTable
.computeSize(SWT
.DEFAULT
, 200));
217 } else if (widget
== null) {
218 _tipShell
.setVisible(false);
222 if (item
== _tipItem
)
225 _tipPosition
= control
.toDisplay(pt
);
227 setHoverLocation(_tipShell
, _tipPosition
);
228 _tipShell
.setVisible(true);
233 private void setHoverLocation(Shell shell
, Point position
) {
234 Rectangle displayBounds
= shell
.getDisplay().getBounds();
235 Rectangle shellBounds
= shell
.getBounds();
236 shellBounds
.x
= Math
.max(Math
.min(position
.x
, displayBounds
.width
237 - shellBounds
.width
), 0);
238 shellBounds
.y
= Math
.max(Math
.min(position
.y
+ 16, displayBounds
.height
239 - shellBounds
.height
), 0);
240 shell
.setBounds(shellBounds
);