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