1 /*******************************************************************************
2 * Copyright (c) 2010 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 * Patrick Tasse - Initial API and implementation
11 ******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.widgets
;
15 import java
.util
.ArrayList
;
17 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEvent
;
18 import org
.eclipse
.linuxtools
.tmf
.trace
.ITmfLocation
;
19 import org
.eclipse
.linuxtools
.tmf
.trace
.ITmfTrace
;
20 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfContext
;
21 import org
.eclipse
.swt
.SWT
;
22 import org
.eclipse
.swt
.custom
.CaretEvent
;
23 import org
.eclipse
.swt
.custom
.CaretListener
;
24 import org
.eclipse
.swt
.custom
.ScrolledComposite
;
25 import org
.eclipse
.swt
.custom
.StyledText
;
26 import org
.eclipse
.swt
.events
.ControlEvent
;
27 import org
.eclipse
.swt
.events
.ControlListener
;
28 import org
.eclipse
.swt
.events
.KeyEvent
;
29 import org
.eclipse
.swt
.events
.KeyListener
;
30 import org
.eclipse
.swt
.events
.MouseAdapter
;
31 import org
.eclipse
.swt
.events
.MouseEvent
;
32 import org
.eclipse
.swt
.events
.MouseMoveListener
;
33 import org
.eclipse
.swt
.events
.MouseTrackListener
;
34 import org
.eclipse
.swt
.events
.MouseWheelListener
;
35 import org
.eclipse
.swt
.events
.SelectionEvent
;
36 import org
.eclipse
.swt
.events
.SelectionListener
;
37 import org
.eclipse
.swt
.graphics
.Color
;
38 import org
.eclipse
.swt
.graphics
.Font
;
39 import org
.eclipse
.swt
.graphics
.FontData
;
40 import org
.eclipse
.swt
.graphics
.Point
;
41 import org
.eclipse
.swt
.layout
.GridData
;
42 import org
.eclipse
.swt
.layout
.GridLayout
;
43 import org
.eclipse
.swt
.widgets
.Composite
;
44 import org
.eclipse
.swt
.widgets
.Control
;
45 import org
.eclipse
.swt
.widgets
.Display
;
46 import org
.eclipse
.swt
.widgets
.Event
;
47 import org
.eclipse
.swt
.widgets
.Listener
;
48 import org
.eclipse
.swt
.widgets
.Menu
;
49 import org
.eclipse
.swt
.widgets
.Slider
;
50 import org
.eclipse
.swt
.widgets
.TypedListener
;
53 * <b><u>TmfRawEventViewer</u></b>
55 * TmfRawEventViewer allows for the display of the raw data for an arbitrarily
56 * large number of TMF events.
58 * It is essentially a Composite of a StyledText area and a Slider, where the number
59 * of visible lines in the StyledText control is set to fill the viewer display area.
60 * An underlying data model is used to store a cache of event raw text line data.
61 * The slider is rank-based.
63 public class TmfRawEventViewer
extends Composite
implements ControlListener
, SelectionListener
,
64 KeyListener
, CaretListener
, MouseMoveListener
, MouseTrackListener
, MouseWheelListener
{
66 private static final Color COLOR_BACKGROUND_ODD
= Display
.getCurrent().getSystemColor(SWT
.COLOR_WHITE
);
67 private static final Color COLOR_BACKGROUND_EVEN
= new Color(Display
.getDefault(), 242, 242, 242);
68 private static final Color COLOR_BACKGROUND_SELECTED
= new Color(Display
.getDefault(), 231, 246, 254);
69 private static final Color COLOR_BACKGROUND_HIGHLIGHTED
= new Color(Display
.getDefault(), 246, 252, 255);
70 private static final int MAX_LINE_DATA_SIZE
= 1000;
71 private static final int SLIDER_MAX
= 1000000;
73 private ITmfTrace fTrace
;
74 private TmfContext fBottomContext
;
76 private ScrolledComposite fScrolledComposite
;
77 private Composite fTextArea
;
78 private StyledText fStyledText
;
79 private Font fFixedFont
;
80 private Slider fSlider
;
82 private ArrayList
<LineData
> fLines
= new ArrayList
<LineData
>();
83 private boolean fActualRanks
= false;
84 private int fTopLineIndex
;
85 private int fLastTopLineIndex
;
86 private CaretPosition
[] fStoredCaretPosition
= new CaretPosition
[]
87 { new CaretPosition(0, 0), new CaretPosition(0,0)};
88 private int fNumVisibleLines
;
89 private ITmfLocation
<?
> fSelectedLocation
= null;
90 private long fHighlightedRank
= Long
.MIN_VALUE
;
91 private int fCursorYCoordinate
= -1;
92 private int fHoldSelection
= 0;
96 ITmfLocation
<?
> location
;
98 public LineData(long rank
, ITmfLocation
<?
> location
, String string
) {
100 this.location
= location
;
101 if (string
.length() == 0) {
102 this.string
= " "; // workaround for setLineBackground has no effect on empty line //$NON-NLS-1$
104 this.string
= string
;
108 public String
toString() {
109 return rank
+ " [" + location
+ "]: " + string
; //$NON-NLS-1$ //$NON-NLS-2$
113 class CaretPosition
{
116 public CaretPosition(int time
, int caretOffset
) {
118 this.caretOffset
= caretOffset
;
122 // ------------------------------------------------------------------------
124 // ------------------------------------------------------------------------
130 public TmfRawEventViewer(Composite parent
, int style
) {
131 super(parent
, style
& (~SWT
.H_SCROLL
) & (~SWT
.V_SCROLL
));
134 GridLayout gridLayout
= new GridLayout();
135 gridLayout
.numColumns
= 2;
136 gridLayout
.horizontalSpacing
= 0;
137 gridLayout
.verticalSpacing
= 0;
138 gridLayout
.marginWidth
= 0;
139 gridLayout
.marginHeight
= 0;
140 setLayout(gridLayout
);
142 // Create the controls
143 createTextArea(style
& SWT
.H_SCROLL
);
144 createSlider(style
& SWT
.V_SCROLL
);
146 // Prevent the slider from being traversed
147 setTabList(new Control
[] { fScrolledComposite
});
151 public void dispose() {
152 if (fFixedFont
!= null) {
153 fFixedFont
.dispose();
159 // ------------------------------------------------------------------------
160 // Text area handling
161 // ------------------------------------------------------------------------
164 * Create the text area and add listeners
166 private void createTextArea(int style
) {
167 fScrolledComposite
= new ScrolledComposite(this, style
);
168 fScrolledComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
169 fTextArea
= new Composite(fScrolledComposite
, SWT
.NONE
);
170 fTextArea
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
171 fScrolledComposite
.setContent(fTextArea
);
172 fScrolledComposite
.setExpandHorizontal(true);
173 fScrolledComposite
.setExpandVertical(true);
174 fScrolledComposite
.setAlwaysShowScrollBars(true);
175 fScrolledComposite
.setMinSize(fTextArea
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
));
176 fScrolledComposite
.addControlListener(this);
178 GridLayout textAreaGridLayout
= new GridLayout();
179 textAreaGridLayout
.marginHeight
= 0;
180 textAreaGridLayout
.marginWidth
= 0;
181 fTextArea
.setLayout(textAreaGridLayout
);
183 if (fFixedFont
== null) {
184 if (System
.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$
185 fFixedFont
= new Font(Display
.getCurrent(), new FontData("Courier New", 10, SWT
.NORMAL
)); //$NON-NLS-1$
187 fFixedFont
= new Font(Display
.getCurrent(), new FontData("Monospace", 10, SWT
.NORMAL
)); //$NON-NLS-1$
191 fStyledText
= new StyledText(fTextArea
, SWT
.READ_ONLY
);
192 fStyledText
.setFont(fFixedFont
);
193 fStyledText
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, false));
195 fStyledText
.addCaretListener(this);
196 fStyledText
.addMouseMoveListener(this);
197 fStyledText
.addMouseTrackListener(this);
198 fStyledText
.addMouseWheelListener(this);
199 fStyledText
.addListener(SWT
.MouseWheel
, new Listener() { // disable mouse scroll of horizontal scroll bar
201 public void handleEvent(Event event
) { event
.doit
= false; }});
202 fStyledText
.addKeyListener(this);
204 fTextArea
.setBackground(fStyledText
.getBackground());
205 fTextArea
.addMouseListener(new MouseAdapter() {
207 public void mouseDown(MouseEvent e
) {
208 fTextArea
.setFocus();
212 // ------------------------------------------------------------------------
214 // ------------------------------------------------------------------------
216 private void createSlider(int style
) {
217 fSlider
= new Slider(this, SWT
.VERTICAL
);
218 fSlider
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, false, true));
219 fSlider
.setValues(0, 0, SLIDER_MAX
, SLIDER_MAX
, 1, 1);
220 fSlider
.addSelectionListener(this);
221 if ((style
& SWT
.V_SCROLL
) == 0) {
222 fSlider
.setVisible(false);
226 // ------------------------------------------------------------------------
227 // Controls interactions
228 // ------------------------------------------------------------------------
231 public boolean setFocus() {
232 boolean isVisible
= isVisible();
234 fTextArea
.setFocus();
240 public void setMenu(Menu menu
) {
241 fStyledText
.setMenu(menu
);
244 public void setTrace(ITmfTrace trace
) {
251 public void refreshEventCount() {
252 if (fTrace
!= null) {
253 if (fTrace
.getNbEvents() > 0) {
254 fSlider
.setThumb((int) Math
.max(SLIDER_MAX
/ fTrace
.getNbEvents(), 1));
256 fSlider
.setThumb(SLIDER_MAX
);
259 if (!isVisible()) return;
261 if (fLines
.size() == 0) {
263 } else if (fLines
.size() < fNumVisibleLines
) {
264 fBottomContext
= null;
267 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
268 fSlider
.setSelection((int) (SLIDER_MAX
* fTrace
.getLocationRatio(fLines
.get(fTopLineIndex
).location
)));
273 public void selectAndReveal(long rank
) {
274 if (fTrace
== null || !isVisible()) {
277 if (fActualRanks
&& fTopLineIndex
< fLines
.size() && rank
>= fLines
.get(fTopLineIndex
).rank
) {
278 int lastVisibleIndex
= Math
.min(fTopLineIndex
+ fNumVisibleLines
, fLines
.size()) - 1;
279 if (rank
<= fLines
.get(lastVisibleIndex
).rank
) {
280 for (int i
= fTopLineIndex
; i
< fLines
.size(); i
++) {
281 if (fLines
.get(i
).rank
== rank
) {
282 fSelectedLocation
= fLines
.get(i
).location
;
286 refreshLineBackgrounds();
291 if (fLines
.size() > 0 && fHoldSelection
== 0) {
292 fSelectedLocation
= fLines
.get(0).location
;
293 refreshLineBackgrounds();
297 public void addSelectionListener(SelectionListener listener
) {
299 if (listener
== null) SWT
.error (SWT
.ERROR_NULL_ARGUMENT
);
300 TypedListener typedListener
= new TypedListener(listener
);
301 addListener (SWT
.Selection
, typedListener
);
304 public void removeSelectionListener(SelectionListener listener
) {
306 if (listener
== null) SWT
.error (SWT
.ERROR_NULL_ARGUMENT
);
307 removeListener(SWT
.Selection
, listener
);
310 private void sendSelectionEvent(LineData lineData
) {
311 Event event
= new Event();
313 event
.data
= new Long(lineData
.rank
);
315 event
.data
= lineData
.location
;
317 notifyListeners(SWT
.Selection
, event
);
320 private void setTopRank(long rank
) {
321 fBottomContext
= fTrace
.seekEvent(rank
);
322 if (fBottomContext
== null) {
330 if (fLines
.size() == 0) {
331 fSlider
.setSelection(0);
333 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
334 fSlider
.setSelection((int) (SLIDER_MAX
* fTrace
.getLocationRatio(fLines
.get(fTopLineIndex
).location
)));
338 private void setTopPosition(double ratio
) {
339 fBottomContext
= fTrace
.seekLocation(ratio
);
340 if (fBottomContext
== null) {
343 fBottomContext
.setRank(0);
345 fActualRanks
= false;
351 private void loadLineData() {
352 if (fTopLineIndex
< 0) {
353 //if (fLines.size() > 0 && fLines.get(0).rank > 0) {
354 //long endRank = fLines.get(0).rank;
355 //long startRank = Math.max(0, endRank - fNumVisibleLines);
356 //TmfContext context = fTrace.seekEvent(startRank);
358 //while (context.getRank() < endRank) {
359 //long rank = context.getRank();
360 //ITmfLocation<?> location = context.getLocation();
361 //TmfEvent event = fTrace.getNextEvent(context);
362 //String[] lines = event.getRawText().split("\r?\n");
363 //for (int i = 0; i < lines.length; i++) {
364 //String line = lines[i];
365 //LineData lineData = new LineData(rank, location, line);
366 //fLines.add(index++, lineData);
368 //fLastTopLineIndex++;
372 if (fLines
.size() > 0 && fTrace
.getLocationRatio(fLines
.get(0).location
) > 0) {
373 double lastRatio
= fTrace
.getLocationRatio(fLines
.get(fLines
.size() - 1).location
);
374 double firstRatio
= fTrace
.getLocationRatio(fLines
.get(0).location
);
376 boolean singleEvent
= false;
377 if (firstRatio
!= lastRatio
) {
378 // approximate ratio of at least 20 items
379 delta
= Math
.max(20, fNumVisibleLines
) * (lastRatio
- firstRatio
) / (fLines
.size() - 1);
381 delta
= Math
.pow(10, -15);
384 while (fTopLineIndex
< 0) {
385 ITmfLocation
<?
> endLocation
= fLines
.get(0).location
;
386 firstRatio
= Math
.max(0, firstRatio
- delta
);
387 TmfContext context
= fTrace
.seekLocation(firstRatio
);
388 ITmfLocation
<?
> location
= context
.getLocation();
391 while (!context
.getLocation().equals(endLocation
)) {
392 location
= context
.getLocation();
393 TmfEvent event
= fTrace
.getNextEvent(context
);
397 String
[] lines
= event
.getRawText().split("\r?\n"); //$NON-NLS-1$
398 for (int i
= 0; i
< lines
.length
; i
++) {
399 String line
= lines
[i
];
400 LineData lineData
= new LineData(rank
, location
, line
);
401 fLines
.add(index
++, lineData
);
407 long rankOffset
= fLines
.get(index
).rank
- rank
;
408 for (int i
= 0; i
< index
; i
++) {
409 fLines
.get(i
).rank
+= rankOffset
;
411 if (firstRatio
== 0) {
415 delta
= Math
.min(delta
* 10, 0.1);
419 if (fTopLineIndex
< 0) {
424 while (fLines
.size() - fTopLineIndex
< fNumVisibleLines
) {
425 if (fBottomContext
== null) {
426 if (fLines
.size() == 0) {
427 fBottomContext
= fTrace
.seekEvent(0);
429 //fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).rank + 1);
430 fBottomContext
= fTrace
.seekLocation(fLines
.get(fLines
.size() - 1).location
);
431 fTrace
.getNextEvent(fBottomContext
);
433 if (fBottomContext
== null) {
437 long rank
= fBottomContext
.getRank();
438 ITmfLocation
<?
> location
= fBottomContext
.getLocation();
439 TmfEvent event
= fTrace
.getNextEvent(fBottomContext
);
443 for (String line
: event
.getRawText().split("\r?\n")) { //$NON-NLS-1$
445 if ((crPos
= line
.indexOf('\r')) != -1) {
446 line
= line
.substring(0, crPos
);
448 LineData lineData
= new LineData(rank
, location
, line
);
449 fLines
.add(lineData
);
452 fTopLineIndex
= Math
.max(0, Math
.min(fTopLineIndex
, fLines
.size() - 1));
454 if (fLines
.size() > MAX_LINE_DATA_SIZE
) {
455 if (fTopLineIndex
< MAX_LINE_DATA_SIZE
/ 2) {
456 long rank
= fLines
.get(MAX_LINE_DATA_SIZE
- 1).rank
;
457 for (int i
= MAX_LINE_DATA_SIZE
; i
< fLines
.size(); i
++) {
458 if (fLines
.get(i
).rank
> rank
) {
459 fLines
.subList(i
, fLines
.size()).clear();
460 fBottomContext
= null;
465 long rank
= fLines
.get(fLines
.size() - MAX_LINE_DATA_SIZE
).rank
;
466 for (int i
= fLines
.size() - MAX_LINE_DATA_SIZE
- 1; i
>= 0; i
--) {
467 if (fLines
.get(i
).rank
< rank
) {
468 fLines
.subList(0, i
+ 1).clear();
469 fTopLineIndex
-= (i
+ 1);
470 fLastTopLineIndex
-= (i
+ 1);
478 private void refreshTextArea() {
479 fStyledText
.setText(""); //$NON-NLS-1$
480 for (int i
= 0; i
< fLines
.size() - fTopLineIndex
&& i
< fNumVisibleLines
; i
++) {
481 if (i
> 0) fStyledText
.append("\n"); //$NON-NLS-1$
482 LineData lineData
= fLines
.get(fTopLineIndex
+ i
);
483 fStyledText
.append(lineData
.string
);
484 setLineBackground(i
, lineData
);
487 fScrolledComposite
.setMinSize(fTextArea
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
));
488 fLastTopLineIndex
= fTopLineIndex
;
491 private void fillTextArea() {
492 int nextLine
= fStyledText
.getCharCount() == 0 ?
0 : fStyledText
.getLineCount();
493 for (int i
= nextLine
; i
< fLines
.size() - fTopLineIndex
&& i
< fNumVisibleLines
; i
++) {
494 if (i
> 0) fStyledText
.append("\n"); //$NON-NLS-1$
495 LineData lineData
= fLines
.get(fTopLineIndex
+ i
);
496 fStyledText
.append(lineData
.string
);
497 setLineBackground(i
, lineData
);
499 int endLine
= Math
.min(fNumVisibleLines
, fLines
.size());
500 if (endLine
< fStyledText
.getLineCount()) {
501 int endOffset
= fStyledText
.getOffsetAtLine(endLine
) - 1;
502 if (endOffset
> fStyledText
.getCharCount()) {
504 fStyledText
.replaceTextRange(endOffset
, fStyledText
.getCharCount() - endOffset
, ""); //$NON-NLS-1$
509 fScrolledComposite
.setMinSize(fTextArea
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
));
512 private void updateTextArea() {
513 if (fTopLineIndex
< fLastTopLineIndex
) {
514 StringBuffer insertedText
= new StringBuffer();
515 for (int i
= fTopLineIndex
; i
< fLastTopLineIndex
; i
++) {
516 insertedText
.append(fLines
.get(i
).string
+ "\n"); //$NON-NLS-1$
518 fStyledText
.replaceTextRange(0, 0, insertedText
.toString());
519 for (int i
= 0; i
< fLastTopLineIndex
- fTopLineIndex
; i
++) {
520 LineData lineData
= fLines
.get(fTopLineIndex
+ i
);
521 setLineBackground(i
, lineData
);
523 fLastTopLineIndex
= fTopLineIndex
;
524 } else if (fTopLineIndex
> fLastTopLineIndex
) {
526 for (int i
= 0; i
< fTopLineIndex
- fLastTopLineIndex
&& i
< fNumVisibleLines
; i
++) {
527 length
+= fLines
.get(i
+ fLastTopLineIndex
).string
.length();
528 if (i
< fStyledText
.getLineCount()) length
+= 1;
530 fStyledText
.replaceTextRange(0, length
, ""); //$NON-NLS-1$
531 fLastTopLineIndex
= fTopLineIndex
;
534 int endLine
= Math
.min(fNumVisibleLines
, fLines
.size());
535 if (endLine
< fStyledText
.getLineCount()) {
536 int endOffset
= fStyledText
.getOffsetAtLine(endLine
) - 1;
537 if (endOffset
> fStyledText
.getCharCount()) {
538 fStyledText
.replaceTextRange(endOffset
, fStyledText
.getCharCount() - endOffset
, ""); //$NON-NLS-1$
542 fScrolledComposite
.setMinSize(fTextArea
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
));
545 private void refreshLineBackgrounds() {
546 for (int i
= 0; (i
< fStyledText
.getLineCount()) && (i
< fNumVisibleLines
) && (i
< fLines
.size() - fTopLineIndex
); i
++) {
547 LineData lineData
= fLines
.get(fTopLineIndex
+ i
);
548 setLineBackground(i
, lineData
);
552 private void setLineBackground(int index
, LineData lineData
) {
553 if (lineData
.location
.equals(fSelectedLocation
)) {
554 fStyledText
.setLineBackground(index
, 1, COLOR_BACKGROUND_SELECTED
);
555 } else if (lineData
.rank
== fHighlightedRank
) {
556 fStyledText
.setLineBackground(index
, 1, COLOR_BACKGROUND_HIGHLIGHTED
);
557 } else if (lineData
.rank
% 2 == 0) {
558 fStyledText
.setLineBackground(index
, 1, COLOR_BACKGROUND_EVEN
);
560 fStyledText
.setLineBackground(index
, 1, COLOR_BACKGROUND_ODD
);
564 private void storeCaretPosition(int time
, int caretOffset
) {
565 if (fStoredCaretPosition
[0].time
== time
) {
566 fStoredCaretPosition
[0].caretOffset
= caretOffset
;
568 fStoredCaretPosition
[1] = fStoredCaretPosition
[0];
569 fStoredCaretPosition
[0] = new CaretPosition(time
, caretOffset
);
573 private int getPreviousCaretOffset(int time
) {
574 if (fStoredCaretPosition
[0].time
== time
) {
575 return fStoredCaretPosition
[1].caretOffset
;
577 return fStoredCaretPosition
[0].caretOffset
;
581 private void updateHighlightedRank() {
582 if (fCursorYCoordinate
< 0 || fCursorYCoordinate
> fStyledText
.getSize().y
) {
583 if (fHighlightedRank
!= Long
.MIN_VALUE
) {
584 fHighlightedRank
= Long
.MIN_VALUE
;
585 refreshLineBackgrounds();
589 int offset
= fStyledText
.getOffsetAtLocation(new Point(0, fCursorYCoordinate
));
590 int line
= fStyledText
.getLineAtOffset(offset
);
591 if (line
< fLines
.size() - fTopLineIndex
) {
592 LineData lineData
= fLines
.get(fTopLineIndex
+ line
);
593 if (fHighlightedRank
!= lineData
.rank
) {
594 fHighlightedRank
= lineData
.rank
;
595 refreshLineBackgrounds();
598 if (fHighlightedRank
!= Long
.MIN_VALUE
) {
599 fHighlightedRank
= Long
.MIN_VALUE
;
600 refreshLineBackgrounds();
605 // ------------------------------------------------------------------------
606 // ControlListener (ScrolledComposite)
607 // ------------------------------------------------------------------------
610 public void controlResized(ControlEvent event
) {
611 int areaHeight
= fScrolledComposite
.getSize().y
;
612 if (fScrolledComposite
.getHorizontalBar() != null) {
613 areaHeight
-= fScrolledComposite
.getHorizontalBar().getSize().y
;
615 int lineHeight
= fStyledText
.getLineHeight();
616 fNumVisibleLines
= Math
.max((areaHeight
+ lineHeight
- 1) / lineHeight
, 1);
618 if (fBottomContext
!= null) {
625 public void controlMoved(ControlEvent e
) {
628 // ------------------------------------------------------------------------
629 // SelectionListener (Slider)
630 // ------------------------------------------------------------------------
633 public void widgetSelected(SelectionEvent e
) {
634 fTextArea
.setFocus();
635 if (fLines
.size() == 0) {
638 if (e
.detail
== SWT
.DRAG
) {
644 //long rank = (long) (fTrace.getNbEvents() * ((double) fSlider.getSelection() / SLIDER_MAX));
646 if (fSlider
.getSelection() == 0 || fSlider
.getThumb() == SLIDER_MAX
) {
651 double ratio
= (double) fSlider
.getSelection() / (SLIDER_MAX
- fSlider
.getThumb());
652 double delta
= Math
.pow(10, -15);
654 while (fLines
.size() == 0) {
655 setTopPosition(ratio
);
656 if (ratio
== 0.0) break;
657 delta
= Math
.min(delta
* 10, 0.1);
658 ratio
= Math
.max(ratio
- delta
, 0.0);
662 case SWT
.ARROW_DOWN
: {
663 if (fTopLineIndex
>= fLines
.size()) {
671 case SWT
.PAGE_DOWN
: {
672 fTopLineIndex
+= Math
.max(fNumVisibleLines
- 1, 1);
678 //if (fLines.size() == 0 || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
679 if (fLines
.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
688 fTopLineIndex
-= Math
.max(fNumVisibleLines
- 1, 1);
694 //selectAndReveal(0);
699 //if (fTrace.getNbEvents() > 0) {
700 //selectAndReveal(fTrace.getNbEvents() - 1);
703 double delta
= Math
.pow(10, -15);
705 while (fLines
.size() == 0) {
706 setTopPosition(ratio
);
707 if (ratio
== 0.0) break;
708 delta
= Math
.min(delta
* 10, 0.1);
709 ratio
= Math
.max(ratio
- delta
, 0.0);
714 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
715 if (e
.detail
!= SWT
.NONE
) {
716 fSlider
.setSelection((int) (SLIDER_MAX
* fTrace
.getLocationRatio(fLines
.get(fTopLineIndex
).location
)));
723 public void widgetDefaultSelected(SelectionEvent e
) {
726 // ------------------------------------------------------------------------
727 // KeyListener (StyledText)
728 // ------------------------------------------------------------------------
731 public void keyPressed(KeyEvent e
) {
732 if (fLines
.size() == 0) {
735 int caretOffset
= fStyledText
.getCaretOffset();
736 int previousCaretOffset
= getPreviousCaretOffset(e
.time
);
737 int previousLineAtCaretPosition
= fStyledText
.getLineAtOffset(previousCaretOffset
);
738 int previousColumnAtCaretPosition
= getPreviousCaretOffset(e
.time
) - fStyledText
.getOffsetAtLine(previousLineAtCaretPosition
);
740 case SWT
.ARROW_DOWN
: {
741 if (previousLineAtCaretPosition
< (fNumVisibleLines
- 2)) {
749 LineData lineData
= fLines
.get(fTopLineIndex
+ fStyledText
.getLineAtOffset(fStyledText
.getCaretOffset()));
750 if (!lineData
.location
.equals(fSelectedLocation
)) {
751 fSelectedLocation
= lineData
.location
;
752 refreshLineBackgrounds();
753 sendSelectionEvent(lineData
);
757 case SWT
.PAGE_DOWN
: {
758 if (previousLineAtCaretPosition
>= (fNumVisibleLines
- 1)) {
760 if (fLines
.get(fTopLineIndex
+ previousLineAtCaretPosition
).rank
% 2 == 0) {
761 fStyledText
.setLineBackground(previousLineAtCaretPosition
, 1, COLOR_BACKGROUND_EVEN
);
763 fStyledText
.setLineBackground(previousLineAtCaretPosition
, 1, COLOR_BACKGROUND_ODD
);
765 fSelectedLocation
= null;
766 fTopLineIndex
+= Math
.max(fNumVisibleLines
- 1, 1);
771 int line
= Math
.min(fNumVisibleLines
- 1, fStyledText
.getLineCount() - 1);
772 int offset
= fStyledText
.getOffsetAtLine(line
);
773 fStyledText
.setSelection(offset
+ Math
.min(previousColumnAtCaretPosition
, fLines
.get(fTopLineIndex
+ line
).string
.length()));
776 case SWT
.ARROW_RIGHT
: {
777 if (previousCaretOffset
< fStyledText
.getCharCount() || previousLineAtCaretPosition
< (fNumVisibleLines
- 2)) {
785 fStyledText
.setSelection(fStyledText
.getCaretOffset() + 1);
789 if (previousLineAtCaretPosition
> 0) {
792 if (fLines
.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
800 LineData lineData
= fLines
.get(fTopLineIndex
);
801 if (!lineData
.location
.equals(fSelectedLocation
)) {
802 fSelectedLocation
= lineData
.location
;
803 refreshLineBackgrounds();
804 sendSelectionEvent(lineData
);
806 fStyledText
.setSelection(caretOffset
);
810 if (previousLineAtCaretPosition
> 0) {
814 fTopLineIndex
-= Math
.max(fNumVisibleLines
- 1, 1);
818 LineData lineData
= fLines
.get(fTopLineIndex
);
819 if (!lineData
.location
.equals(fSelectedLocation
)) {
820 fSelectedLocation
= lineData
.location
;
821 refreshLineBackgrounds();
822 sendSelectionEvent(lineData
);
824 fStyledText
.setSelection(caretOffset
);
827 case SWT
.ARROW_LEFT
: {
828 if (previousCaretOffset
> 0) {
831 if (fLines
.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
834 long topRank
= fLines
.get(fTopLineIndex
).rank
;
840 LineData lineData
= fLines
.get(fTopLineIndex
);
841 if (!lineData
.location
.equals(fSelectedLocation
)) {
842 fSelectedLocation
= lineData
.location
;
843 refreshLineBackgrounds();
844 sendSelectionEvent(lineData
);
846 if (topRank
!= fLines
.get(fTopLineIndex
).rank
) {
847 fStyledText
.setSelection(fLines
.get(fTopLineIndex
).string
.length());
852 if ((e
.stateMask
& SWT
.CTRL
) == 0) {
855 //selectAndReveal(0);
857 LineData lineData
= fLines
.get(fTopLineIndex
);
858 if (!lineData
.location
.equals(fSelectedLocation
)) {
859 fSelectedLocation
= lineData
.location
;
860 refreshLineBackgrounds();
861 sendSelectionEvent(lineData
);
866 if ((e
.stateMask
& SWT
.CTRL
) == 0) {
869 //if (fTrace.getNbEvents() > 0) {
870 //selectAndReveal(fTrace.getNbEvents() - 1);
873 double delta
= Math
.pow(10, -15);
875 while (fLines
.size() == 0) {
876 setTopPosition(ratio
);
877 if (ratio
== 0.0) break;
878 delta
= Math
.min(delta
* 10, 0.1);
879 ratio
= Math
.max(ratio
- delta
, 0.0);
881 LineData lineData
= fLines
.get(fTopLineIndex
);
882 if (!lineData
.location
.equals(fSelectedLocation
)) {
883 fSelectedLocation
= lineData
.location
;
884 refreshLineBackgrounds();
885 sendSelectionEvent(lineData
);
890 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
891 updateHighlightedRank();
892 fSlider
.setSelection((int) (SLIDER_MAX
* fTrace
.getLocationRatio(fLines
.get(fTopLineIndex
).location
)));
896 public void keyReleased(KeyEvent e
) {
899 // ------------------------------------------------------------------------
900 // CaretListener (StyledText)
901 // ------------------------------------------------------------------------
904 public void caretMoved(CaretEvent event
) {
905 if (fHoldSelection
== 0) {
906 int line
= fStyledText
.getLineAtOffset(event
.caretOffset
);
907 if (fTopLineIndex
+ line
< fLines
.size()) {
908 LineData lineData
= fLines
.get(fTopLineIndex
+ line
);
909 if (!lineData
.location
.equals(fSelectedLocation
)) {
910 fSelectedLocation
= lineData
.location
;
911 refreshLineBackgrounds();
912 sendSelectionEvent(lineData
);
916 storeCaretPosition(event
.time
, event
.caretOffset
);
917 if (fHoldSelection
== 0) {
918 Point caret
= fStyledText
.getLocationAtOffset(fStyledText
.getCaretOffset());
919 Point origin
= fScrolledComposite
.getOrigin();
920 if (origin
.x
> caret
.x
) {
922 } else if (caret
.x
- origin
.x
> fScrolledComposite
.getSize().x
) {
923 origin
.x
= caret
.x
- fScrolledComposite
.getSize().x
+ 1;
925 fScrolledComposite
.setOrigin(origin
);
929 // ------------------------------------------------------------------------
930 // MouseMoveListener (StyledText)
931 // ------------------------------------------------------------------------
934 public void mouseMove(MouseEvent e
) {
935 fCursorYCoordinate
= e
.y
;
936 if (e
.y
< 0 || e
.y
> fStyledText
.getSize().y
) {
937 if (fHighlightedRank
!= Long
.MIN_VALUE
) {
938 fHighlightedRank
= Long
.MIN_VALUE
;
939 refreshLineBackgrounds();
943 int offset
= fStyledText
.getOffsetAtLocation(new Point(0, e
.y
));
944 int line
= fStyledText
.getLineAtOffset(offset
);
945 if (line
< fLines
.size() - fTopLineIndex
) {
946 LineData lineData
= fLines
.get(fTopLineIndex
+ line
);
947 if (fHighlightedRank
!= lineData
.rank
) {
948 fHighlightedRank
= lineData
.rank
;
949 refreshLineBackgrounds();
952 if (fHighlightedRank
!= Long
.MIN_VALUE
) {
953 fHighlightedRank
= Long
.MIN_VALUE
;
954 refreshLineBackgrounds();
959 // ------------------------------------------------------------------------
960 // MouseTrackListener (StyledText)
961 // ------------------------------------------------------------------------
964 public void mouseExit(MouseEvent e
) {
965 fCursorYCoordinate
= -1;
966 if (fHighlightedRank
!= Long
.MIN_VALUE
) {
967 fHighlightedRank
= Long
.MIN_VALUE
;
968 refreshLineBackgrounds();
973 public void mouseEnter(MouseEvent e
) {
974 fCursorYCoordinate
= e
.y
;
978 public void mouseHover(MouseEvent e
) {
981 // ------------------------------------------------------------------------
982 // MouseWheelListener (StyledText)
983 // ------------------------------------------------------------------------
986 public void mouseScrolled(MouseEvent e
) {
987 if (fLines
.size() == 0) {
991 fTopLineIndex
-= e
.count
;
995 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
996 updateHighlightedRank();
997 fSlider
.setSelection((int) (SLIDER_MAX
* fTrace
.getLocationRatio(fLines
.get(fTopLineIndex
).location
)));