tmf: Switch tmf.ui to Java 7 + fix warnings
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / rawviewer / TmfRawEventViewer.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2012 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 * Patrick Tasse - Initial API and implementation
11 ******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.ui.widgets.rawviewer;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
19 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
20 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
21 import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.custom.CaretEvent;
24 import org.eclipse.swt.custom.CaretListener;
25 import org.eclipse.swt.custom.ScrolledComposite;
26 import org.eclipse.swt.custom.StyledText;
27 import org.eclipse.swt.events.ControlEvent;
28 import org.eclipse.swt.events.ControlListener;
29 import org.eclipse.swt.events.KeyEvent;
30 import org.eclipse.swt.events.KeyListener;
31 import org.eclipse.swt.events.MouseAdapter;
32 import org.eclipse.swt.events.MouseEvent;
33 import org.eclipse.swt.events.MouseMoveListener;
34 import org.eclipse.swt.events.MouseTrackListener;
35 import org.eclipse.swt.events.MouseWheelListener;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.events.SelectionListener;
38 import org.eclipse.swt.graphics.Color;
39 import org.eclipse.swt.graphics.Font;
40 import org.eclipse.swt.graphics.FontData;
41 import org.eclipse.swt.graphics.Point;
42 import org.eclipse.swt.layout.GridData;
43 import org.eclipse.swt.layout.GridLayout;
44 import org.eclipse.swt.widgets.Composite;
45 import org.eclipse.swt.widgets.Control;
46 import org.eclipse.swt.widgets.Display;
47 import org.eclipse.swt.widgets.Event;
48 import org.eclipse.swt.widgets.Listener;
49 import org.eclipse.swt.widgets.Menu;
50 import org.eclipse.swt.widgets.Slider;
51
52 /**
53 * TmfRawEventViewer allows for the display of the raw data for an arbitrarily
54 * large number of TMF events.
55 *
56 * It is essentially a Composite of a StyledText area and a Slider, where the number
57 * of visible lines in the StyledText control is set to fill the viewer display area.
58 * An underlying data model is used to store a cache of event raw text line data.
59 * The slider is ratio-based.
60 *
61 * @version 1.0
62 * @author Patrick Tasse
63 */
64 public class TmfRawEventViewer extends Composite implements ControlListener, SelectionListener,
65 KeyListener, CaretListener, MouseMoveListener, MouseTrackListener, MouseWheelListener {
66
67 private static final Color COLOR_BACKGROUND_ODD = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
68 private static final Color COLOR_BACKGROUND_EVEN = new Color(Display.getDefault(), 242, 242, 242);
69 private static final Color COLOR_BACKGROUND_SELECTED = new Color(Display.getDefault(), 231, 246, 254);
70 private static final Color COLOR_BACKGROUND_HIGHLIGHTED = new Color(Display.getDefault(), 246, 252, 255);
71 private static final int MAX_LINE_DATA_SIZE = 1000;
72 private static final int SLIDER_MAX = 1000000;
73
74 private ITmfTrace fTrace;
75 private ITmfContext fBottomContext;
76
77 private ScrolledComposite fScrolledComposite;
78 private Composite fTextArea;
79 private StyledText fStyledText;
80 private Font fFixedFont;
81 private Slider fSlider;
82
83 private final List<LineData> fLines = new ArrayList<>();
84 private boolean fActualRanks = false;
85 private int fTopLineIndex;
86 private int fLastTopLineIndex;
87 private final CaretPosition[] fStoredCaretPosition = new CaretPosition[]
88 { new CaretPosition(0, 0), new CaretPosition(0,0)};
89 private int fNumVisibleLines;
90 private ITmfLocation fSelectedLocation = null;
91 private long fHighlightedRank = Long.MIN_VALUE;
92 private int fCursorYCoordinate = -1;
93 private int fHoldSelection = 0;
94
95 private static class LineData {
96 long rank;
97 ITmfLocation location;
98 String string;
99 public LineData(long rank, ITmfLocation location, String string) {
100 this.rank = rank;
101 this.location = location;
102 if (string.length() == 0) {
103 this.string = " "; // workaround for setLineBackground has no effect on empty line //$NON-NLS-1$
104 } else {
105 this.string = string;
106 }
107 }
108 @Override
109 public String toString() {
110 return rank + " [" + location + "]: " + string; //$NON-NLS-1$ //$NON-NLS-2$
111 }
112 }
113
114 private static class CaretPosition {
115 int time;
116 int caretOffset;
117 public CaretPosition(int time, int caretOffset) {
118 this.time = time;
119 this.caretOffset = caretOffset;
120 }
121 }
122
123 // ------------------------------------------------------------------------
124 // Constructor
125 // ------------------------------------------------------------------------
126
127 /**
128 * Constructor
129 * @param parent The parent composite
130 * @param style The style bits
131 */
132 public TmfRawEventViewer(Composite parent, int style) {
133 super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL));
134
135 // Set the layout
136 GridLayout gridLayout = new GridLayout();
137 gridLayout.numColumns = 2;
138 gridLayout.horizontalSpacing = 0;
139 gridLayout.verticalSpacing = 0;
140 gridLayout.marginWidth = 0;
141 gridLayout.marginHeight = 0;
142 setLayout(gridLayout);
143
144 // Create the controls
145 createTextArea(style & SWT.H_SCROLL);
146 createSlider(style & SWT.V_SCROLL);
147
148 // Prevent the slider from being traversed
149 setTabList(new Control[] { fScrolledComposite });
150 }
151
152 @Override
153 public void dispose() {
154 if (fFixedFont != null) {
155 fFixedFont.dispose();
156 fFixedFont = null;
157 }
158 super.dispose();
159 }
160
161 // ------------------------------------------------------------------------
162 // Text area handling
163 // ------------------------------------------------------------------------
164
165 /**
166 * Create the text area and add listeners
167 */
168 private void createTextArea(int style) {
169 fScrolledComposite = new ScrolledComposite(this, style);
170 fScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
171 fTextArea = new Composite(fScrolledComposite, SWT.NONE);
172 fTextArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
173 fScrolledComposite.setContent(fTextArea);
174 fScrolledComposite.setExpandHorizontal(true);
175 fScrolledComposite.setExpandVertical(true);
176 fScrolledComposite.setAlwaysShowScrollBars(true);
177 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
178 fScrolledComposite.addControlListener(this);
179
180 GridLayout textAreaGridLayout = new GridLayout();
181 textAreaGridLayout.marginHeight = 0;
182 textAreaGridLayout.marginWidth = 0;
183 fTextArea.setLayout(textAreaGridLayout);
184
185 if (fFixedFont == null) {
186 if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$
187 fFixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$
188 } else {
189 fFixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$
190 }
191 }
192
193 fStyledText = new StyledText(fTextArea, SWT.READ_ONLY);
194 fStyledText.setFont(fFixedFont);
195 fStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
196
197 fStyledText.addCaretListener(this);
198 fStyledText.addMouseMoveListener(this);
199 fStyledText.addMouseTrackListener(this);
200 fStyledText.addMouseWheelListener(this);
201 fStyledText.addListener(SWT.MouseWheel, new Listener() { // disable mouse scroll of horizontal scroll bar
202 @Override
203 public void handleEvent(Event event) { event.doit = false; }});
204 fStyledText.addKeyListener(this);
205
206 fTextArea.setBackground(fStyledText.getBackground());
207 fTextArea.addMouseListener(new MouseAdapter() {
208 @Override
209 public void mouseDown(MouseEvent e) {
210 fTextArea.setFocus();
211 }});
212 }
213
214 // ------------------------------------------------------------------------
215 // Slider handling
216 // ------------------------------------------------------------------------
217
218 private void createSlider(int style) {
219 fSlider = new Slider(this, SWT.VERTICAL);
220 fSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
221 fSlider.setValues(0, 0, SLIDER_MAX, SLIDER_MAX, 1, 1);
222 fSlider.addSelectionListener(this);
223 if ((style & SWT.V_SCROLL) == 0) {
224 fSlider.setVisible(false);
225 }
226 }
227
228 // ------------------------------------------------------------------------
229 // Controls interactions
230 // ------------------------------------------------------------------------
231
232 @Override
233 public boolean setFocus() {
234 boolean isVisible = isVisible();
235 if (isVisible) {
236 fTextArea.setFocus();
237 }
238 return isVisible;
239 }
240
241 @Override
242 public void setMenu(Menu menu) {
243 fStyledText.setMenu(menu);
244 }
245
246 /**
247 * Sets the trace and updates the content
248 * @param trace The trace to set
249 */
250 public void setTrace(ITmfTrace trace) {
251 fTrace = trace;
252 fTopLineIndex = 0;
253 fLines.clear();
254 refreshEventCount();
255 }
256
257 /**
258 * Refreshes the event count, updates the slider thumb and loads display
259 */
260 public void refreshEventCount() {
261 if (fTrace != null) {
262 if (fTrace.getNbEvents() > 0) {
263 fSlider.setThumb((int) Math.max(SLIDER_MAX / fTrace.getNbEvents(), 1));
264 } else {
265 fSlider.setThumb(SLIDER_MAX);
266 }
267
268 if (!isVisible()) {
269 return;
270 }
271
272 if (fLines.size() == 0) {
273 setTopRank(0);
274 } else if (fLines.size() < fNumVisibleLines) {
275 fBottomContext = null;
276 loadLineData();
277 fillTextArea();
278 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
279 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
280 }
281 } else {
282 fBottomContext = null;
283 fillTextArea();
284 fSlider.setThumb(SLIDER_MAX);
285 fSlider.setSelection(0);
286 }
287 }
288
289 /**
290 * Selects the event of given rank and makes it visible.
291 * @param rank The rank of event
292 */
293 public void selectAndReveal(long rank) {
294 if (fTrace == null || !isVisible()) {
295 return;
296 }
297 if (fActualRanks && fTopLineIndex < fLines.size() && rank >= fLines.get(fTopLineIndex).rank) {
298 int lastVisibleIndex = Math.min(fTopLineIndex + fNumVisibleLines, fLines.size()) - 1;
299 if (rank <= fLines.get(lastVisibleIndex).rank) {
300 for (int i = fTopLineIndex; i < fLines.size(); i++) {
301 if (fLines.get(i).rank == rank) {
302 fSelectedLocation = fLines.get(i).location;
303 break;
304 }
305 }
306 refreshLineBackgrounds();
307 return;
308 }
309 }
310 setTopRank(rank);
311 if (fLines.size() > 0 && fHoldSelection == 0) {
312 fSelectedLocation = fLines.get(0).location;
313 refreshLineBackgrounds();
314 }
315 }
316
317 /**
318 * Add a selection listener
319 * @param listener A listener to add
320 */
321 public void addSelectionListener(Listener listener) {
322 checkWidget();
323 if (listener == null) {
324 SWT.error (SWT.ERROR_NULL_ARGUMENT);
325 }
326 addListener (SWT.Selection, listener);
327 }
328
329 /**
330 * Remove selection listener
331 * @param listener A listener to remove
332 */
333 public void removeSelectionListener(Listener listener) {
334 checkWidget();
335 if (listener == null) {
336 SWT.error (SWT.ERROR_NULL_ARGUMENT);
337 }
338 removeListener(SWT.Selection, listener);
339 }
340
341 private void sendSelectionEvent(LineData lineData) {
342 Event event = new Event();
343 if (fActualRanks) {
344 event.data = Long.valueOf(lineData.rank);
345 } else {
346 event.data = lineData.location;
347 }
348 notifyListeners(SWT.Selection, event);
349 }
350
351 private void setTopRank(long rank) {
352 fBottomContext = fTrace.seekEvent(rank);
353 if (fBottomContext == null) {
354 return;
355 }
356 fLines.clear();
357 fActualRanks = true;
358 fTopLineIndex = 0;
359 loadLineData();
360 refreshTextArea();
361 if (fLines.size() == 0) {
362 fSlider.setSelection(0);
363 } else {
364 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
365 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
366 }
367 }
368
369 private void setTopPosition(double ratio) {
370 fBottomContext = fTrace.seekEvent(ratio);
371 if (fBottomContext == null) {
372 return;
373 }
374 fBottomContext.setRank(0);
375 fLines.clear();
376 fActualRanks = false;
377 fTopLineIndex = 0;
378 loadLineData();
379 refreshTextArea();
380 }
381
382 private void loadLineData() {
383 if (fTopLineIndex < 0) {
384 //if (fLines.size() > 0 && fLines.get(0).rank > 0) {
385 //long endRank = fLines.get(0).rank;
386 //long startRank = Math.max(0, endRank - fNumVisibleLines);
387 //TmfContext context = fTrace.seekEvent(startRank);
388 //int index = 0;
389 //while (context.getRank() < endRank) {
390 //long rank = context.getRank();
391 //ITmfLocation<?> location = context.getLocation();
392 //TmfEvent event = fTrace.getNextEvent(context);
393 //String[] lines = event.getRawText().split("\r?\n");
394 //for (int i = 0; i < lines.length; i++) {
395 //String line = lines[i];
396 //LineData lineData = new LineData(rank, location, line);
397 //fLines.add(index++, lineData);
398 //fTopLineIndex++;
399 //fLastTopLineIndex++;
400 //}
401 //}
402 //}
403 if (fLines.size() > 0 && fTrace.getLocationRatio(fLines.get(0).location) > 0) {
404 double lastRatio = fTrace.getLocationRatio(fLines.get(fLines.size() - 1).location);
405 double firstRatio = fTrace.getLocationRatio(fLines.get(0).location);
406 double delta;
407 boolean singleEvent = false;
408 if (firstRatio != lastRatio) {
409 // approximate ratio of at least 20 items
410 delta = Math.max(20, fNumVisibleLines) * (lastRatio - firstRatio) / (fLines.size() - 1);
411 } else {
412 delta = Math.pow(10, -15);
413 singleEvent = true;
414 }
415 while (fTopLineIndex < 0) {
416 ITmfLocation endLocation = fLines.get(0).location;
417 firstRatio = Math.max(0, firstRatio - delta);
418 ITmfContext context = fTrace.seekEvent(firstRatio);
419 ITmfLocation location;
420 int index = 0;
421 long rank = 0;
422 while (!context.getLocation().equals(endLocation)) {
423 location = context.getLocation();
424 ITmfEvent event = fTrace.getNext(context);
425 if (event == null) {
426 break;
427 }
428 if (event.getContent() != null && event.getContent().getValue() != null) {
429 String[] lines = event.getContent().getValue().toString().split("\r?\n"); //$NON-NLS-1$
430 for (int i = 0; i < lines.length; i++) {
431 String line = lines[i];
432 LineData lineData = new LineData(rank, location, line);
433 fLines.add(index++, lineData);
434 fTopLineIndex++;
435 fLastTopLineIndex++;
436 }
437 } else {
438 LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$
439 fLines.add(index++, lineData);
440 fTopLineIndex++;
441 fLastTopLineIndex++;
442 }
443 rank++;
444 }
445 long rankOffset = fLines.get(index).rank - rank;
446 for (int i = 0; i < index; i++) {
447 fLines.get(i).rank += rankOffset;
448 }
449 if (firstRatio == 0) {
450 break;
451 }
452 if (singleEvent) {
453 delta = Math.min(delta * 10, 0.1);
454 }
455 }
456 }
457 if (fTopLineIndex < 0) {
458 fTopLineIndex = 0;
459 }
460 }
461
462 while (fLines.size() - fTopLineIndex < fNumVisibleLines) {
463 if (fBottomContext == null) {
464 if (fLines.size() == 0) {
465 fBottomContext = fTrace.seekEvent(0);
466 } else {
467 //fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).rank + 1);
468 fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).location);
469 fTrace.getNext(fBottomContext);
470 }
471 if (fBottomContext == null) {
472 break;
473 }
474 }
475 long rank = fBottomContext.getRank();
476 ITmfLocation location = fBottomContext.getLocation() != null ? fBottomContext.getLocation() : null;
477 ITmfEvent event = fTrace.getNext(fBottomContext);
478 if (event == null) {
479 break;
480 }
481 if (event.getContent() != null && event.getContent().getValue() != null) {
482 for (String line : event.getContent().getValue().toString().split("\r?\n")) { //$NON-NLS-1$
483 int crPos;
484 if ((crPos = line.indexOf('\r')) != -1) {
485 line = line.substring(0, crPos);
486 }
487 LineData lineData = new LineData(rank, location, line);
488 fLines.add(lineData);
489 }
490 } else {
491 LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$
492 fLines.add(lineData);
493 }
494 }
495 fTopLineIndex = Math.max(0, Math.min(fTopLineIndex, fLines.size() - 1));
496
497 if (fLines.size() > MAX_LINE_DATA_SIZE) {
498 if (fTopLineIndex < MAX_LINE_DATA_SIZE / 2) {
499 long rank = fLines.get(MAX_LINE_DATA_SIZE - 1).rank;
500 for (int i = MAX_LINE_DATA_SIZE; i < fLines.size(); i++) {
501 if (fLines.get(i).rank > rank) {
502 fLines.subList(i, fLines.size()).clear();
503 fBottomContext = null;
504 break;
505 }
506 }
507 } else {
508 long rank = fLines.get(fLines.size() - MAX_LINE_DATA_SIZE).rank;
509 for (int i = fLines.size() - MAX_LINE_DATA_SIZE - 1; i >= 0; i--) {
510 if (fLines.get(i).rank < rank) {
511 fLines.subList(0, i + 1).clear();
512 fTopLineIndex -= (i + 1);
513 fLastTopLineIndex -= (i + 1);
514 break;
515 }
516 }
517 }
518 }
519 }
520
521 private void refreshTextArea() {
522 fStyledText.setText(""); //$NON-NLS-1$
523 for (int i = 0; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {
524 if (i > 0)
525 {
526 fStyledText.append("\n"); //$NON-NLS-1$
527 }
528 LineData lineData = fLines.get(fTopLineIndex + i);
529 fStyledText.append(lineData.string);
530 setLineBackground(i, lineData);
531 }
532 fTextArea.layout();
533 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
534 fLastTopLineIndex = fTopLineIndex;
535 }
536
537 private void fillTextArea() {
538 int nextLine = fStyledText.getCharCount() == 0 ? 0 : fStyledText.getLineCount();
539 for (int i = nextLine; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {
540 if (i > 0)
541 {
542 fStyledText.append("\n"); //$NON-NLS-1$
543 }
544 LineData lineData = fLines.get(fTopLineIndex + i);
545 fStyledText.append(lineData.string);
546 setLineBackground(i, lineData);
547 }
548 int endLine = Math.min(fNumVisibleLines, fLines.size());
549 if (endLine < fStyledText.getLineCount()) {
550 int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;
551 if (endOffset > fStyledText.getCharCount()) {
552 fHoldSelection++;
553 fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$
554 fHoldSelection--;
555 }
556 }
557 fTextArea.layout();
558 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
559 }
560
561 private void updateTextArea() {
562 if (fTopLineIndex < fLastTopLineIndex) {
563 StringBuffer insertedText = new StringBuffer();
564 for (int i = fTopLineIndex; i < fLastTopLineIndex; i++) {
565 insertedText.append(fLines.get(i).string + "\n"); //$NON-NLS-1$
566 }
567 fStyledText.replaceTextRange(0, 0, insertedText.toString());
568 for (int i = 0; i < fLastTopLineIndex - fTopLineIndex; i++) {
569 LineData lineData = fLines.get(fTopLineIndex + i);
570 setLineBackground(i, lineData);
571 }
572 fLastTopLineIndex = fTopLineIndex;
573 } else if (fTopLineIndex > fLastTopLineIndex) {
574 int length = 0;
575 for (int i = 0; i < fTopLineIndex - fLastTopLineIndex && i < fNumVisibleLines; i++) {
576 length += fLines.get(i + fLastTopLineIndex).string.length();
577 if (i < fStyledText.getLineCount()) {
578 length += 1;
579 }
580 }
581 fStyledText.replaceTextRange(0, length, ""); //$NON-NLS-1$
582 fLastTopLineIndex = fTopLineIndex;
583 fillTextArea();
584 }
585 int endLine = Math.min(fNumVisibleLines, fLines.size());
586 if (endLine < fStyledText.getLineCount()) {
587 int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;
588 if (endOffset > fStyledText.getCharCount()) {
589 fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$
590 }
591 }
592 fTextArea.layout();
593 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
594 }
595
596 private void refreshLineBackgrounds() {
597 for (int i = 0; (i < fStyledText.getLineCount()) && (i < fNumVisibleLines) && (i < fLines.size() - fTopLineIndex); i++) {
598 LineData lineData = fLines.get(fTopLineIndex + i);
599 setLineBackground(i, lineData);
600 }
601 }
602
603 private void setLineBackground(int index, LineData lineData) {
604 if (lineData.location.equals(fSelectedLocation)) {
605 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_SELECTED);
606 } else if (lineData.rank == fHighlightedRank) {
607 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_HIGHLIGHTED);
608 } else if (lineData.rank % 2 == 0) {
609 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_EVEN);
610 } else {
611 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_ODD);
612 }
613 }
614
615 private void storeCaretPosition(int time, int caretOffset) {
616 if (fStoredCaretPosition[0].time == time) {
617 fStoredCaretPosition[0].caretOffset = caretOffset;
618 } else {
619 fStoredCaretPosition[1] = fStoredCaretPosition[0];
620 fStoredCaretPosition[0] = new CaretPosition(time, caretOffset);
621 }
622 }
623
624 private int getPreviousCaretOffset(int time) {
625 if (fStoredCaretPosition[0].time == time) {
626 return fStoredCaretPosition[1].caretOffset;
627 }
628 return fStoredCaretPosition[0].caretOffset;
629 }
630
631 private void updateHighlightedRank() {
632 if (fCursorYCoordinate < 0 || fCursorYCoordinate > fStyledText.getSize().y) {
633 if (fHighlightedRank != Long.MIN_VALUE) {
634 fHighlightedRank = Long.MIN_VALUE;
635 refreshLineBackgrounds();
636 }
637 return;
638 }
639 int offset = fStyledText.getOffsetAtLocation(new Point(0, fCursorYCoordinate));
640 int line = fStyledText.getLineAtOffset(offset);
641 if (line < fLines.size() - fTopLineIndex) {
642 LineData lineData = fLines.get(fTopLineIndex + line);
643 if (fHighlightedRank != lineData.rank) {
644 fHighlightedRank = lineData.rank;
645 refreshLineBackgrounds();
646 }
647 } else {
648 if (fHighlightedRank != Long.MIN_VALUE) {
649 fHighlightedRank = Long.MIN_VALUE;
650 refreshLineBackgrounds();
651 }
652 }
653 }
654
655 // ------------------------------------------------------------------------
656 // ControlListener (ScrolledComposite)
657 // ------------------------------------------------------------------------
658
659 @Override
660 public void controlResized(ControlEvent event) {
661 int areaHeight = fScrolledComposite.getSize().y;
662 if (fScrolledComposite.getHorizontalBar() != null) {
663 areaHeight -= fScrolledComposite.getHorizontalBar().getSize().y;
664 }
665 int lineHeight = fStyledText.getLineHeight();
666 fNumVisibleLines = Math.max((areaHeight + lineHeight - 1) / lineHeight, 1);
667
668 if (fBottomContext != null) {
669 loadLineData();
670 fillTextArea();
671 }
672 }
673
674 @Override
675 public void controlMoved(ControlEvent e) {
676 }
677
678 // ------------------------------------------------------------------------
679 // SelectionListener (Slider)
680 // ------------------------------------------------------------------------
681
682 @Override
683 public void widgetSelected(SelectionEvent e) {
684 fTextArea.setFocus();
685 if (fLines.size() == 0) {
686 return;
687 }
688 if (e.detail == SWT.DRAG) {
689 return;
690 }
691 fHoldSelection++;
692 switch (e.detail) {
693 case SWT.NONE: {
694 //long rank = (long) (fTrace.getNbEvents() * ((double) fSlider.getSelection() / SLIDER_MAX));
695 //setTopRank(rank);
696 if (fSlider.getSelection() == 0 || fSlider.getThumb() == SLIDER_MAX) {
697 fLines.clear();
698 setTopPosition(0.0);
699 break;
700 }
701 double ratio = (double) fSlider.getSelection() / (SLIDER_MAX - fSlider.getThumb());
702 double delta = Math.pow(10, -15);
703 fLines.clear();
704 while (fLines.size() == 0) {
705 setTopPosition(ratio);
706 if (ratio == 0.0) {
707 break;
708 }
709 delta = Math.min(delta * 10, 0.1);
710 ratio = Math.max(ratio - delta, 0.0);
711 }
712 break;
713 }
714 case SWT.ARROW_DOWN: {
715 if (fTopLineIndex >= fLines.size()) {
716 break;
717 }
718 fTopLineIndex++;
719 loadLineData();
720 updateTextArea();
721 break;
722 }
723 case SWT.PAGE_DOWN: {
724 fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);
725 loadLineData();
726 updateTextArea();
727 break;
728 }
729 case SWT.ARROW_UP: {
730 //if (fLines.size() == 0 || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
731 if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
732 break;
733 }
734 fTopLineIndex--;
735 loadLineData();
736 updateTextArea();
737 break;
738 }
739 case SWT.PAGE_UP: {
740 fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);
741 loadLineData();
742 updateTextArea();
743 break;
744 }
745 case SWT.HOME: {
746 //selectAndReveal(0);
747 setTopPosition(0.0);
748 break;
749 }
750 case SWT.END: {
751 //if (fTrace.getNbEvents() > 0) {
752 //selectAndReveal(fTrace.getNbEvents() - 1);
753 //}
754 double ratio = 1.0;
755 double delta = Math.pow(10, -15);
756 fLines.clear();
757 while (fLines.size() == 0) {
758 setTopPosition(ratio);
759 if (ratio == 0.0) {
760 break;
761 }
762 delta = Math.min(delta * 10, 0.1);
763 ratio = Math.max(ratio - delta, 0.0);
764 }
765 break;
766 }
767 default:
768 break;
769 }
770 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
771 if (e.detail != SWT.NONE) {
772 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
773 }
774
775 fHoldSelection = 0;
776 }
777
778 @Override
779 public void widgetDefaultSelected(SelectionEvent e) {
780 }
781
782 // ------------------------------------------------------------------------
783 // KeyListener (StyledText)
784 // ------------------------------------------------------------------------
785
786 @Override
787 public void keyPressed(KeyEvent e) {
788 if (fLines.size() == 0) {
789 return;
790 }
791 int caretOffset = fStyledText.getCaretOffset();
792 int previousCaretOffset = getPreviousCaretOffset(e.time);
793 int previousLineAtCaretPosition = fStyledText.getLineAtOffset(previousCaretOffset);
794 int previousColumnAtCaretPosition = getPreviousCaretOffset(e.time) - fStyledText.getOffsetAtLine(previousLineAtCaretPosition);
795 switch (e.keyCode) {
796 case SWT.ARROW_DOWN: {
797 if (previousLineAtCaretPosition < (fNumVisibleLines - 2)) {
798 break;
799 }
800 fHoldSelection++;
801 fTopLineIndex++;
802 loadLineData();
803 updateTextArea();
804 fHoldSelection--;
805 LineData lineData = fLines.get(fTopLineIndex + fStyledText.getLineAtOffset(fStyledText.getCaretOffset()));
806 if (!lineData.location.equals(fSelectedLocation)) {
807 fSelectedLocation = lineData.location;
808 refreshLineBackgrounds();
809 sendSelectionEvent(lineData);
810 }
811 break;
812 }
813 case SWT.PAGE_DOWN: {
814 if (previousLineAtCaretPosition >= (fNumVisibleLines - 1)) {
815 fHoldSelection++;
816 if (fLines.get(fTopLineIndex + previousLineAtCaretPosition).rank % 2 == 0) {
817 fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_EVEN);
818 } else {
819 fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_ODD);
820 }
821 fSelectedLocation = null;
822 fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);
823 loadLineData();
824 updateTextArea();
825 fHoldSelection--;
826 }
827 int line = Math.min(fNumVisibleLines - 1, fStyledText.getLineCount() - 1);
828 int offset = fStyledText.getOffsetAtLine(line);
829 fStyledText.setSelection(offset + Math.min(previousColumnAtCaretPosition, fLines.get(fTopLineIndex + line).string.length()));
830 break;
831 }
832 case SWT.ARROW_RIGHT: {
833 if (previousCaretOffset < fStyledText.getCharCount() || previousLineAtCaretPosition < (fNumVisibleLines - 2)) {
834 break;
835 }
836 fHoldSelection++;
837 fTopLineIndex++;
838 loadLineData();
839 updateTextArea();
840 fHoldSelection--;
841 fStyledText.setSelection(fStyledText.getCaretOffset() + 1);
842 break;
843 }
844 case SWT.ARROW_UP: {
845 if (previousLineAtCaretPosition > 0) {
846 break;
847 }
848 if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
849 break;
850 }
851 fHoldSelection++;
852 fTopLineIndex--;
853 loadLineData();
854 updateTextArea();
855 fHoldSelection--;
856 LineData lineData = fLines.get(fTopLineIndex);
857 if (!lineData.location.equals(fSelectedLocation)) {
858 fSelectedLocation = lineData.location;
859 refreshLineBackgrounds();
860 sendSelectionEvent(lineData);
861 }
862 fStyledText.setSelection(caretOffset);
863 break;
864 }
865 case SWT.PAGE_UP: {
866 if (previousLineAtCaretPosition > 0) {
867 break;
868 }
869 fHoldSelection++;
870 fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);
871 loadLineData();
872 updateTextArea();
873 fHoldSelection--;
874 LineData lineData = fLines.get(fTopLineIndex);
875 if (!lineData.location.equals(fSelectedLocation)) {
876 fSelectedLocation = lineData.location;
877 refreshLineBackgrounds();
878 sendSelectionEvent(lineData);
879 }
880 fStyledText.setSelection(caretOffset);
881 break;
882 }
883 case SWT.ARROW_LEFT: {
884 if (previousCaretOffset > 0) {
885 break;
886 }
887 if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
888 break;
889 }
890 long topRank = fLines.get(fTopLineIndex).rank;
891 fHoldSelection++;
892 fTopLineIndex--;
893 loadLineData();
894 updateTextArea();
895 fHoldSelection--;
896 LineData lineData = fLines.get(fTopLineIndex);
897 if (!lineData.location.equals(fSelectedLocation)) {
898 fSelectedLocation = lineData.location;
899 refreshLineBackgrounds();
900 sendSelectionEvent(lineData);
901 }
902 if (topRank != fLines.get(fTopLineIndex).rank) {
903 fStyledText.setSelection(fLines.get(fTopLineIndex).string.length());
904 }
905 break;
906 }
907 case SWT.HOME: {
908 if ((e.stateMask & SWT.CTRL) == 0) {
909 break;
910 }
911 //selectAndReveal(0);
912 setTopPosition(0.0);
913 LineData lineData = fLines.get(fTopLineIndex);
914 if (!lineData.location.equals(fSelectedLocation)) {
915 fSelectedLocation = lineData.location;
916 refreshLineBackgrounds();
917 sendSelectionEvent(lineData);
918 }
919 break;
920 }
921 case SWT.END: {
922 if ((e.stateMask & SWT.CTRL) == 0) {
923 break;
924 }
925 //if (fTrace.getNbEvents() > 0) {
926 //selectAndReveal(fTrace.getNbEvents() - 1);
927 //}
928 double ratio = 1.0;
929 double delta = Math.pow(10, -15);
930 fLines.clear();
931 while (fLines.size() == 0) {
932 setTopPosition(ratio);
933 if (ratio == 0.0) {
934 break;
935 }
936 delta = Math.min(delta * 10, 0.1);
937 ratio = Math.max(ratio - delta, 0.0);
938 }
939 LineData lineData = fLines.get(fTopLineIndex);
940 if (!lineData.location.equals(fSelectedLocation)) {
941 fSelectedLocation = lineData.location;
942 refreshLineBackgrounds();
943 sendSelectionEvent(lineData);
944 }
945 break;
946 }
947 default:
948 break;
949 }
950 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
951 updateHighlightedRank();
952 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
953 }
954
955 @Override
956 public void keyReleased(KeyEvent e) {
957 }
958
959 // ------------------------------------------------------------------------
960 // CaretListener (StyledText)
961 // ------------------------------------------------------------------------
962
963 @Override
964 public void caretMoved(CaretEvent event) {
965 if (fHoldSelection == 0) {
966 int line = fStyledText.getLineAtOffset(event.caretOffset);
967 if (fTopLineIndex + line < fLines.size()) {
968 LineData lineData = fLines.get(fTopLineIndex + line);
969 if (!lineData.location.equals(fSelectedLocation)) {
970 fSelectedLocation = lineData.location;
971 refreshLineBackgrounds();
972 sendSelectionEvent(lineData);
973 }
974 }
975 }
976 storeCaretPosition(event.time, event.caretOffset);
977 if (fHoldSelection == 0) {
978 Point caret = fStyledText.getLocationAtOffset(fStyledText.getCaretOffset());
979 Point origin = fScrolledComposite.getOrigin();
980 if (origin.x > caret.x) {
981 origin.x = caret.x;
982 } else if (caret.x - origin.x > fScrolledComposite.getSize().x) {
983 origin.x = caret.x - fScrolledComposite.getSize().x + 1;
984 }
985 fScrolledComposite.setOrigin(origin);
986 }
987 }
988
989 // ------------------------------------------------------------------------
990 // MouseMoveListener (StyledText)
991 // ------------------------------------------------------------------------
992
993 @Override
994 public void mouseMove(MouseEvent e) {
995 fCursorYCoordinate = e.y;
996 if (e.y < 0 || e.y > fStyledText.getSize().y) {
997 if (fHighlightedRank != Long.MIN_VALUE) {
998 fHighlightedRank = Long.MIN_VALUE;
999 refreshLineBackgrounds();
1000 }
1001 return;
1002 }
1003 int offset = fStyledText.getOffsetAtLocation(new Point(0, e.y));
1004 int line = fStyledText.getLineAtOffset(offset);
1005 if (line < fLines.size() - fTopLineIndex) {
1006 LineData lineData = fLines.get(fTopLineIndex + line);
1007 if (fHighlightedRank != lineData.rank) {
1008 fHighlightedRank = lineData.rank;
1009 refreshLineBackgrounds();
1010 }
1011 } else {
1012 if (fHighlightedRank != Long.MIN_VALUE) {
1013 fHighlightedRank = Long.MIN_VALUE;
1014 refreshLineBackgrounds();
1015 }
1016 }
1017 }
1018
1019 // ------------------------------------------------------------------------
1020 // MouseTrackListener (StyledText)
1021 // ------------------------------------------------------------------------
1022
1023 @Override
1024 public void mouseExit(MouseEvent e) {
1025 fCursorYCoordinate = -1;
1026 if (fHighlightedRank != Long.MIN_VALUE) {
1027 fHighlightedRank = Long.MIN_VALUE;
1028 refreshLineBackgrounds();
1029 }
1030 }
1031
1032 @Override
1033 public void mouseEnter(MouseEvent e) {
1034 fCursorYCoordinate = e.y;
1035 }
1036
1037 @Override
1038 public void mouseHover(MouseEvent e) {
1039 }
1040
1041 // ------------------------------------------------------------------------
1042 // MouseWheelListener (StyledText)
1043 // ------------------------------------------------------------------------
1044
1045 @Override
1046 public void mouseScrolled(MouseEvent e) {
1047 if (fLines.size() == 0) {
1048 return;
1049 }
1050 fHoldSelection++;
1051 fTopLineIndex -= e.count;
1052 loadLineData();
1053 updateTextArea();
1054 fHoldSelection = 0;
1055 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
1056 updateHighlightedRank();
1057 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
1058 }
1059
1060 }
This page took 0.078452 seconds and 5 git commands to generate.