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