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