Convert Windows line delimiters to Unix.
authorPatrick Tasse <patrick.tasse@gmail.com>
Mon, 22 Oct 2012 20:03:41 +0000 (16:03 -0400)
committerPatrick Tasse <patrick.tasse@gmail.com>
Mon, 22 Oct 2012 20:03:41 +0000 (16:03 -0400)
Change-Id: Ia737c3c468c739a7da20561e11d756036fc8d049

org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/rawviewer/TmfRawEventViewer.java

index 4931aef197d567ff76ed7516a793f58dee210ded..2570033c2ae9da660971044a97448d8a54ccff0c 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2010, 2012 Ericsson\r
- *\r
- * All rights reserved. This program and the accompanying materials are\r
- * made available under the terms of the Eclipse Public License v1.0 which\r
- * accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *   Patrick Tasse - Initial API and implementation\r
- ******************************************************************************/\r
-\r
-package org.eclipse.linuxtools.tmf.ui.widgets.rawviewer;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;\r
-import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;\r
-import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;\r
-import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.custom.CaretEvent;\r
-import org.eclipse.swt.custom.CaretListener;\r
-import org.eclipse.swt.custom.ScrolledComposite;\r
-import org.eclipse.swt.custom.StyledText;\r
-import org.eclipse.swt.events.ControlEvent;\r
-import org.eclipse.swt.events.ControlListener;\r
-import org.eclipse.swt.events.KeyEvent;\r
-import org.eclipse.swt.events.KeyListener;\r
-import org.eclipse.swt.events.MouseAdapter;\r
-import org.eclipse.swt.events.MouseEvent;\r
-import org.eclipse.swt.events.MouseMoveListener;\r
-import org.eclipse.swt.events.MouseTrackListener;\r
-import org.eclipse.swt.events.MouseWheelListener;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.events.SelectionListener;\r
-import org.eclipse.swt.graphics.Color;\r
-import org.eclipse.swt.graphics.Font;\r
-import org.eclipse.swt.graphics.FontData;\r
-import org.eclipse.swt.graphics.Point;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Event;\r
-import org.eclipse.swt.widgets.Listener;\r
-import org.eclipse.swt.widgets.Menu;\r
-import org.eclipse.swt.widgets.Slider;\r
-\r
-/**\r
- * TmfRawEventViewer allows for the display of the raw data for an arbitrarily\r
- * large number of TMF events.\r
- *\r
- * It is essentially a Composite of a StyledText area and a Slider, where the number\r
- * of visible lines in the StyledText control is set to fill the viewer display area.\r
- * An underlying data model is used to store a cache of event raw text line data.\r
- * The slider is ratio-based.\r
- *\r
- * @version 1.0\r
- * @author Patrick Tasse\r
- */\r
-public class TmfRawEventViewer extends Composite implements ControlListener, SelectionListener,\r
-                KeyListener, CaretListener, MouseMoveListener, MouseTrackListener, MouseWheelListener {\r
-\r
-    private static final Color COLOR_BACKGROUND_ODD = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);\r
-    private static final Color COLOR_BACKGROUND_EVEN = new Color(Display.getDefault(), 242, 242, 242);\r
-    private static final Color COLOR_BACKGROUND_SELECTED = new Color(Display.getDefault(), 231, 246, 254);\r
-    private static final Color COLOR_BACKGROUND_HIGHLIGHTED = new Color(Display.getDefault(), 246, 252, 255);\r
-    private static final int MAX_LINE_DATA_SIZE = 1000;\r
-    private static final int SLIDER_MAX = 1000000;\r
-\r
-    private ITmfTrace fTrace;\r
-    private ITmfContext fBottomContext;\r
-\r
-    private ScrolledComposite fScrolledComposite;\r
-    private Composite fTextArea;\r
-    private StyledText fStyledText;\r
-    private Font fFixedFont;\r
-       private Slider fSlider;\r
-\r
-       private final List<LineData> fLines = new ArrayList<LineData>();\r
-       private boolean fActualRanks = false;\r
-       private int fTopLineIndex;\r
-       private int fLastTopLineIndex;\r
-       private final CaretPosition[] fStoredCaretPosition = new CaretPosition[]\r
-                   { new CaretPosition(0, 0), new CaretPosition(0,0)};\r
-       private int fNumVisibleLines;\r
-    private ITmfLocation fSelectedLocation = null;\r
-    private long fHighlightedRank = Long.MIN_VALUE;\r
-    private int fCursorYCoordinate = -1;\r
-    private int fHoldSelection = 0;\r
-\r
-       private static class LineData {\r
-           long rank;\r
-           ITmfLocation location;\r
-           String string;\r
-           public LineData(long rank, ITmfLocation location, String string) {\r
-               this.rank = rank;\r
-               this.location = location;\r
-            if (string.length() == 0) {\r
-                this.string = " "; // workaround for setLineBackground has no effect on empty line //$NON-NLS-1$\r
-            } else {\r
-                this.string = string;\r
-            }\r
-           }\r
-        @Override\r
-        public String toString() {\r
-            return rank + " [" + location + "]: " + string; //$NON-NLS-1$ //$NON-NLS-2$\r
-        }\r
-       }\r
-\r
-       private static class CaretPosition {\r
-           int time;\r
-           int caretOffset;\r
-           public CaretPosition(int time, int caretOffset) {\r
-               this.time = time;\r
-               this.caretOffset = caretOffset;\r
-           }\r
-       }\r
-\r
-       // ------------------------------------------------------------------------\r
-       // Constructor\r
-       // ------------------------------------------------------------------------\r
-\r
-       /**\r
-        * Constructor\r
-        * @param parent The parent composite\r
-        * @param style The style bits\r
-        */\r
-       public TmfRawEventViewer(Composite parent, int style) {\r
-               super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL));\r
-\r
-               // Set the layout\r
-               GridLayout gridLayout = new GridLayout();\r
-               gridLayout.numColumns = 2;\r
-               gridLayout.horizontalSpacing = 0;\r
-               gridLayout.verticalSpacing = 0;\r
-        gridLayout.marginWidth = 0;\r
-        gridLayout.marginHeight = 0;\r
-               setLayout(gridLayout);\r
-\r
-               // Create the controls\r
-               createTextArea(style & SWT.H_SCROLL);\r
-               createSlider(style & SWT.V_SCROLL);\r
-\r
-               // Prevent the slider from being traversed\r
-               setTabList(new Control[] { fScrolledComposite });\r
-       }\r
-\r
-    @Override\r
-       public void dispose() {\r
-        if (fFixedFont != null) {\r
-            fFixedFont.dispose();\r
-            fFixedFont = null;\r
-        }\r
-           super.dispose();\r
-       }\r
-\r
-       // ------------------------------------------------------------------------\r
-       // Text area handling\r
-       // ------------------------------------------------------------------------\r
-\r
-    /**\r
-        * Create the text area and add listeners\r
-        */\r
-       private void createTextArea(int style) {\r
-           fScrolledComposite = new ScrolledComposite(this, style);\r
-           fScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
-           fTextArea = new Composite(fScrolledComposite, SWT.NONE);\r
-        fTextArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
-        fScrolledComposite.setContent(fTextArea);\r
-        fScrolledComposite.setExpandHorizontal(true);\r
-        fScrolledComposite.setExpandVertical(true);\r
-        fScrolledComposite.setAlwaysShowScrollBars(true);\r
-        fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
-        fScrolledComposite.addControlListener(this);\r
-\r
-        GridLayout textAreaGridLayout = new GridLayout();\r
-        textAreaGridLayout.marginHeight = 0;\r
-        textAreaGridLayout.marginWidth = 0;\r
-        fTextArea.setLayout(textAreaGridLayout);\r
-\r
-        if (fFixedFont == null) {\r
-            if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$\r
-                fFixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$\r
-            } else {\r
-                fFixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$\r
-            }\r
-        }\r
-\r
-        fStyledText = new StyledText(fTextArea, SWT.READ_ONLY);\r
-        fStyledText.setFont(fFixedFont);\r
-        fStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));\r
-\r
-        fStyledText.addCaretListener(this);\r
-        fStyledText.addMouseMoveListener(this);\r
-        fStyledText.addMouseTrackListener(this);\r
-        fStyledText.addMouseWheelListener(this);\r
-        fStyledText.addListener(SWT.MouseWheel, new Listener() { // disable mouse scroll of horizontal scroll bar\r
-            @Override\r
-            public void handleEvent(Event event) { event.doit = false; }});\r
-        fStyledText.addKeyListener(this);\r
-\r
-        fTextArea.setBackground(fStyledText.getBackground());\r
-        fTextArea.addMouseListener(new MouseAdapter() {\r
-                       @Override\r
-            public void mouseDown(MouseEvent e) {\r
-                               fTextArea.setFocus();\r
-            }});\r
-       }\r
-\r
-       // ------------------------------------------------------------------------\r
-       // Slider handling\r
-       // ------------------------------------------------------------------------\r
-\r
-       private void createSlider(int style) {\r
-               fSlider = new Slider(this, SWT.VERTICAL);\r
-        fSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));\r
-        fSlider.setValues(0, 0, SLIDER_MAX, SLIDER_MAX, 1, 1);\r
-               fSlider.addSelectionListener(this);\r
-        if ((style & SWT.V_SCROLL) == 0) {\r
-            fSlider.setVisible(false);\r
-        }\r
-       }\r
-\r
-       // ------------------------------------------------------------------------\r
-       // Controls interactions\r
-       // ------------------------------------------------------------------------\r
-\r
-       @Override\r
-       public boolean setFocus() {\r
-               boolean isVisible = isVisible();\r
-               if (isVisible) {\r
-                       fTextArea.setFocus();\r
-               }\r
-               return isVisible;\r
-       }\r
-\r
-    @Override\r
-    public void setMenu(Menu menu) {\r
-        fStyledText.setMenu(menu);\r
-    }\r
-\r
-    /**\r
-     * Sets the trace and updates the content\r
-     * @param trace The trace to set\r
-     */\r
-    public void setTrace(ITmfTrace trace) {\r
-           fTrace = trace;\r
-           fTopLineIndex = 0;\r
-           fLines.clear();\r
-           refreshEventCount();\r
-       }\r
-\r
-    /**\r
-     * Refreshes the event count, updates the slider thumb and loads display\r
-     */\r
-       public void refreshEventCount() {\r
-               if (fTrace != null) {\r
-                       if (fTrace.getNbEvents() > 0) {\r
-                               fSlider.setThumb((int) Math.max(SLIDER_MAX / fTrace.getNbEvents(), 1));\r
-                       } else {\r
-                               fSlider.setThumb(SLIDER_MAX);\r
-                       }\r
-\r
-                       if (!isVisible()) {\r
-                return;\r
-            }\r
-\r
-                       if (fLines.size() == 0) {\r
-                       setTopRank(0);\r
-                   } else if (fLines.size() < fNumVisibleLines) {\r
-                       fBottomContext = null;\r
-                       loadLineData();\r
-                       fillTextArea();\r
-                   //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
-                   fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
-                   }\r
-        } else {\r
-            fBottomContext = null;\r
-            fillTextArea();\r
-            fSlider.setThumb(SLIDER_MAX);\r
-            fSlider.setSelection(0);\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Selects the event of given rank and makes it visible.\r
-        * @param rank The rank of event\r
-        */\r
-    public void selectAndReveal(long rank) {\r
-        if (fTrace == null || !isVisible()) {\r
-            return;\r
-        }\r
-        if (fActualRanks && fTopLineIndex < fLines.size() && rank >= fLines.get(fTopLineIndex).rank) {\r
-            int lastVisibleIndex = Math.min(fTopLineIndex + fNumVisibleLines, fLines.size()) - 1;\r
-            if (rank <= fLines.get(lastVisibleIndex).rank) {\r
-                for (int i = fTopLineIndex; i < fLines.size(); i++) {\r
-                    if (fLines.get(i).rank == rank) {\r
-                        fSelectedLocation = fLines.get(i).location;\r
-                        break;\r
-                    }\r
-                }\r
-                refreshLineBackgrounds();\r
-                return;\r
-            }\r
-        }\r
-        setTopRank(rank);\r
-        if (fLines.size() > 0 && fHoldSelection == 0) {\r
-            fSelectedLocation = fLines.get(0).location;\r
-            refreshLineBackgrounds();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Add a selection listener\r
-     * @param listener A listener to add\r
-     */\r
-    public void addSelectionListener(Listener listener) {\r
-        checkWidget();\r
-        if (listener == null) {\r
-            SWT.error (SWT.ERROR_NULL_ARGUMENT);\r
-        }\r
-        addListener (SWT.Selection, listener);\r
-    }\r
-\r
-    /**\r
-     * Remove selection listener\r
-     * @param listener A listener to remove\r
-     */\r
-    public void removeSelectionListener(Listener listener) {\r
-        checkWidget();\r
-        if (listener == null) {\r
-            SWT.error (SWT.ERROR_NULL_ARGUMENT);\r
-        }\r
-        removeListener(SWT.Selection, listener);\r
-    }\r
-\r
-    private void sendSelectionEvent(LineData lineData) {\r
-        Event event = new Event();\r
-        if (fActualRanks) {\r
-            event.data = Long.valueOf(lineData.rank);\r
-        } else {\r
-            event.data = lineData.location;\r
-        }\r
-        notifyListeners(SWT.Selection, event);\r
-    }\r
-\r
-    private void setTopRank(long rank) {\r
-        fBottomContext = fTrace.seekEvent(rank);\r
-        if (fBottomContext == null) {\r
-            return;\r
-        }\r
-        fLines.clear();\r
-        fActualRanks = true;\r
-        fTopLineIndex = 0;\r
-        loadLineData();\r
-        refreshTextArea();\r
-        if (fLines.size() == 0) {\r
-            fSlider.setSelection(0);\r
-        } else {\r
-            //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
-            fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
-        }\r
-    }\r
-\r
-    private void setTopPosition(double ratio) {\r
-        fBottomContext = fTrace.seekEvent(ratio);\r
-        if (fBottomContext == null) {\r
-            return;\r
-        }\r
-        fBottomContext.setRank(0);\r
-        fLines.clear();\r
-        fActualRanks = false;\r
-        fTopLineIndex = 0;\r
-        loadLineData();\r
-        refreshTextArea();\r
-    }\r
-\r
-       private void loadLineData() {\r
-        if (fTopLineIndex < 0) {\r
-            //if (fLines.size() > 0 && fLines.get(0).rank > 0) {\r
-                //long endRank = fLines.get(0).rank;\r
-                //long startRank = Math.max(0, endRank - fNumVisibleLines);\r
-                //TmfContext context = fTrace.seekEvent(startRank);\r
-                //int index = 0;\r
-                //while (context.getRank() < endRank) {\r
-                    //long rank = context.getRank();\r
-                    //ITmfLocation<?> location = context.getLocation();\r
-                    //TmfEvent event = fTrace.getNextEvent(context);\r
-                    //String[] lines = event.getRawText().split("\r?\n");\r
-                    //for (int i = 0; i < lines.length; i++) {\r
-                        //String line = lines[i];\r
-                        //LineData lineData = new LineData(rank, location, line);\r
-                        //fLines.add(index++, lineData);\r
-                        //fTopLineIndex++;\r
-                        //fLastTopLineIndex++;\r
-                    //}\r
-                //}\r
-            //}\r
-            if (fLines.size() > 0 && fTrace.getLocationRatio(fLines.get(0).location) > 0) {\r
-               double lastRatio = fTrace.getLocationRatio(fLines.get(fLines.size() - 1).location);\r
-                double firstRatio = fTrace.getLocationRatio(fLines.get(0).location);\r
-                double delta;\r
-                boolean singleEvent = false;\r
-                if (firstRatio != lastRatio) {\r
-                    // approximate ratio of at least 20 items\r
-                    delta = Math.max(20, fNumVisibleLines) * (lastRatio - firstRatio) / (fLines.size() - 1);\r
-                } else {\r
-                    delta = Math.pow(10, -15);\r
-                    singleEvent = true;\r
-                }\r
-                while (fTopLineIndex < 0) {\r
-                    ITmfLocation endLocation = fLines.get(0).location;\r
-                    firstRatio = Math.max(0, firstRatio - delta);\r
-                    ITmfContext context = fTrace.seekEvent(firstRatio);\r
-                    ITmfLocation location;\r
-                    int index = 0;\r
-                    long rank = 0;\r
-                    while (!context.getLocation().equals(endLocation)) {\r
-                        location = context.getLocation();\r
-                        ITmfEvent event = fTrace.getNext(context);\r
-                        if (event == null) {\r
-                               break;\r
-                        }\r
-                        if (event.getContent() != null && event.getContent().getValue() != null) {\r
-                            String[] lines = event.getContent().getValue().toString().split("\r?\n"); //$NON-NLS-1$\r
-                            for (int i = 0; i < lines.length; i++) {\r
-                                String line = lines[i];\r
-                                LineData lineData = new LineData(rank, location, line);\r
-                                fLines.add(index++, lineData);\r
-                                fTopLineIndex++;\r
-                                fLastTopLineIndex++;\r
-                            }\r
-                        } else {\r
-                            LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$\r
-                            fLines.add(index++, lineData);\r
-                            fTopLineIndex++;\r
-                            fLastTopLineIndex++;\r
-                        }\r
-                        rank++;\r
-                    }\r
-                    long rankOffset = fLines.get(index).rank - rank;\r
-                    for (int i = 0; i < index; i++) {\r
-                        fLines.get(i).rank += rankOffset;\r
-                    }\r
-                    if (firstRatio == 0) {\r
-                        break;\r
-                    }\r
-                    if (singleEvent) {\r
-                       delta = Math.min(delta * 10, 0.1);\r
-                    }\r
-                }\r
-            }\r
-            if (fTopLineIndex < 0) {\r
-                fTopLineIndex = 0;\r
-            }\r
-        }\r
-\r
-           while (fLines.size() - fTopLineIndex < fNumVisibleLines) {\r
-               if (fBottomContext == null) {\r
-                   if (fLines.size() == 0) {\r
-                       fBottomContext = fTrace.seekEvent(0);\r
-                   } else {\r
-                    //fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).rank + 1);\r
-                       fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).location);\r
-                       fTrace.getNext(fBottomContext);\r
-                   }\r
-                   if (fBottomContext == null) {\r
-                       break;\r
-                   }\r
-               }\r
-            long rank = fBottomContext.getRank();\r
-            ITmfLocation location = fBottomContext.getLocation() != null ? fBottomContext.getLocation() : null;\r
-            ITmfEvent event = fTrace.getNext(fBottomContext);\r
-            if (event == null) {\r
-                break;\r
-            }\r
-            if (event.getContent() != null && event.getContent().getValue() != null) {\r
-                for (String line : event.getContent().getValue().toString().split("\r?\n")) { //$NON-NLS-1$\r
-                    int crPos;\r
-                    if ((crPos = line.indexOf('\r')) != -1) {\r
-                       line = line.substring(0, crPos);\r
-                    }\r
-                    LineData lineData = new LineData(rank, location, line);\r
-                    fLines.add(lineData);\r
-                }\r
-            } else {\r
-                LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$\r
-                fLines.add(lineData);\r
-            }\r
-           }\r
-           fTopLineIndex = Math.max(0, Math.min(fTopLineIndex, fLines.size() - 1));\r
-\r
-           if (fLines.size() > MAX_LINE_DATA_SIZE) {\r
-               if (fTopLineIndex < MAX_LINE_DATA_SIZE / 2) {\r
-                   long rank = fLines.get(MAX_LINE_DATA_SIZE - 1).rank;\r
-                   for (int i = MAX_LINE_DATA_SIZE; i < fLines.size(); i++) {\r
-                       if (fLines.get(i).rank > rank) {\r
-                           fLines.subList(i, fLines.size()).clear();\r
-                           fBottomContext = null;\r
-                           break;\r
-                       }\r
-                   }\r
-               } else {\r
-                   long rank = fLines.get(fLines.size() - MAX_LINE_DATA_SIZE).rank;\r
-                   for (int i = fLines.size() - MAX_LINE_DATA_SIZE - 1; i >= 0; i--) {\r
-                    if (fLines.get(i).rank < rank) {\r
-                        fLines.subList(0, i + 1).clear();\r
-                        fTopLineIndex -= (i + 1);\r
-                        fLastTopLineIndex -= (i + 1);\r
-                        break;\r
-                    }\r
-                   }\r
-               }\r
-           }\r
-       }\r
-\r
-    private void refreshTextArea() {\r
-        fStyledText.setText(""); //$NON-NLS-1$\r
-        for (int i = 0; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {\r
-            if (i > 0)\r
-             {\r
-                fStyledText.append("\n"); //$NON-NLS-1$\r
-            }\r
-            LineData lineData = fLines.get(fTopLineIndex + i);\r
-            fStyledText.append(lineData.string);\r
-            setLineBackground(i, lineData);\r
-        }\r
-        fTextArea.layout();\r
-        fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
-        fLastTopLineIndex = fTopLineIndex;\r
-    }\r
-\r
-    private void fillTextArea() {\r
-        int nextLine = fStyledText.getCharCount() == 0 ? 0 : fStyledText.getLineCount();\r
-        for (int i = nextLine; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {\r
-            if (i > 0)\r
-             {\r
-                fStyledText.append("\n"); //$NON-NLS-1$\r
-            }\r
-            LineData lineData = fLines.get(fTopLineIndex + i);\r
-            fStyledText.append(lineData.string);\r
-            setLineBackground(i, lineData);\r
-        }\r
-        int endLine = Math.min(fNumVisibleLines, fLines.size());\r
-        if (endLine < fStyledText.getLineCount()) {\r
-           int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;\r
-           if (endOffset > fStyledText.getCharCount()) {\r
-                fHoldSelection++;\r
-               fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$\r
-                fHoldSelection--;\r
-           }\r
-        }\r
-        fTextArea.layout();\r
-        fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
-    }\r
-\r
-       private void updateTextArea() {\r
-           if (fTopLineIndex < fLastTopLineIndex) {\r
-               StringBuffer insertedText = new StringBuffer();\r
-               for (int i = fTopLineIndex; i < fLastTopLineIndex; i++) {\r
-                   insertedText.append(fLines.get(i).string + "\n"); //$NON-NLS-1$\r
-               }\r
-               fStyledText.replaceTextRange(0, 0, insertedText.toString());\r
-            for (int i = 0; i < fLastTopLineIndex - fTopLineIndex; i++) {\r
-                LineData lineData = fLines.get(fTopLineIndex + i);\r
-                setLineBackground(i, lineData);\r
-            }\r
-               fLastTopLineIndex = fTopLineIndex;\r
-           } else if (fTopLineIndex > fLastTopLineIndex) {\r
-               int length = 0;\r
-               for (int i = 0; i < fTopLineIndex - fLastTopLineIndex && i < fNumVisibleLines; i++) {\r
-                   length += fLines.get(i + fLastTopLineIndex).string.length();\r
-                   if (i < fStyledText.getLineCount()) {\r
-                    length += 1;\r
-                }\r
-               }\r
-               fStyledText.replaceTextRange(0, length, ""); //$NON-NLS-1$\r
-            fLastTopLineIndex = fTopLineIndex;\r
-            fillTextArea();\r
-           }\r
-        int endLine = Math.min(fNumVisibleLines, fLines.size());\r
-        if (endLine < fStyledText.getLineCount()) {\r
-           int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;\r
-           if (endOffset > fStyledText.getCharCount()) {\r
-               fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$\r
-           }\r
-        }\r
-           fTextArea.layout();\r
-           fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
-       }\r
-\r
-       private void refreshLineBackgrounds() {\r
-        for (int i = 0; (i < fStyledText.getLineCount()) && (i < fNumVisibleLines) && (i < fLines.size() - fTopLineIndex); i++) {\r
-            LineData lineData = fLines.get(fTopLineIndex + i);\r
-            setLineBackground(i, lineData);\r
-        }\r
-       }\r
-\r
-       private void setLineBackground(int index, LineData lineData) {\r
-        if (lineData.location.equals(fSelectedLocation)) {\r
-            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_SELECTED);\r
-        } else if (lineData.rank == fHighlightedRank) {\r
-            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_HIGHLIGHTED);\r
-        } else if (lineData.rank % 2 == 0) {\r
-            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_EVEN);\r
-        } else {\r
-            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_ODD);\r
-        }\r
-       }\r
-\r
-       private void storeCaretPosition(int time, int caretOffset) {\r
-           if (fStoredCaretPosition[0].time == time) {\r
-               fStoredCaretPosition[0].caretOffset = caretOffset;\r
-           } else {\r
-               fStoredCaretPosition[1] = fStoredCaretPosition[0];\r
-               fStoredCaretPosition[0] = new CaretPosition(time, caretOffset);\r
-           }\r
-       }\r
-\r
-       private int getPreviousCaretOffset(int time) {\r
-           if (fStoredCaretPosition[0].time == time) {\r
-               return fStoredCaretPosition[1].caretOffset;\r
-           }\r
-        return fStoredCaretPosition[0].caretOffset;\r
-       }\r
-\r
-       private void updateHighlightedRank() {\r
-        if (fCursorYCoordinate < 0 || fCursorYCoordinate > fStyledText.getSize().y) {\r
-            if (fHighlightedRank != Long.MIN_VALUE) {\r
-                fHighlightedRank = Long.MIN_VALUE;\r
-                refreshLineBackgrounds();\r
-            }\r
-            return;\r
-        }\r
-        int offset = fStyledText.getOffsetAtLocation(new Point(0, fCursorYCoordinate));\r
-        int line = fStyledText.getLineAtOffset(offset);\r
-        if (line < fLines.size() - fTopLineIndex) {\r
-            LineData lineData = fLines.get(fTopLineIndex + line);\r
-            if (fHighlightedRank != lineData.rank) {\r
-                fHighlightedRank = lineData.rank;\r
-                refreshLineBackgrounds();\r
-            }\r
-        } else {\r
-            if (fHighlightedRank != Long.MIN_VALUE) {\r
-                fHighlightedRank = Long.MIN_VALUE;\r
-                refreshLineBackgrounds();\r
-            }\r
-        }\r
-       }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // ControlListener (ScrolledComposite)\r
-    // ------------------------------------------------------------------------\r
-\r
-    @Override\r
-    public void controlResized(ControlEvent event) {\r
-        int areaHeight = fScrolledComposite.getSize().y;\r
-        if (fScrolledComposite.getHorizontalBar() != null) {\r
-            areaHeight -= fScrolledComposite.getHorizontalBar().getSize().y;\r
-        }\r
-        int lineHeight = fStyledText.getLineHeight();\r
-        fNumVisibleLines = Math.max((areaHeight + lineHeight - 1) / lineHeight, 1);\r
-\r
-        if (fBottomContext != null) {\r
-            loadLineData();\r
-            fillTextArea();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void controlMoved(ControlEvent e) {\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // SelectionListener (Slider)\r
-    // ------------------------------------------------------------------------\r
-\r
-    @Override\r
-    public void widgetSelected(SelectionEvent e) {\r
-       fTextArea.setFocus();\r
-        if (fLines.size() == 0) {\r
-            return;\r
-        }\r
-        if (e.detail == SWT.DRAG) {\r
-            return;\r
-        }\r
-        fHoldSelection++;\r
-        switch (e.detail) {\r
-            case SWT.NONE: {\r
-                //long rank = (long) (fTrace.getNbEvents() * ((double) fSlider.getSelection() / SLIDER_MAX));\r
-                //setTopRank(rank);\r
-               if (fSlider.getSelection() == 0 || fSlider.getThumb() == SLIDER_MAX) {\r
-                    fLines.clear();\r
-                    setTopPosition(0.0);\r
-                    break;\r
-               }\r
-                double ratio = (double) fSlider.getSelection() / (SLIDER_MAX - fSlider.getThumb());\r
-                double delta = Math.pow(10, -15);\r
-                fLines.clear();\r
-                while (fLines.size() == 0) {\r
-                    setTopPosition(ratio);\r
-                    if (ratio == 0.0) {\r
-                        break;\r
-                    }\r
-                    delta = Math.min(delta * 10, 0.1);\r
-                    ratio = Math.max(ratio - delta, 0.0);\r
-                }\r
-                break;\r
-            }\r
-            case SWT.ARROW_DOWN: {\r
-                if (fTopLineIndex >= fLines.size()) {\r
-                    break;\r
-                }\r
-                fTopLineIndex++;\r
-                loadLineData();\r
-                updateTextArea();\r
-                break;\r
-            }\r
-            case SWT.PAGE_DOWN: {\r
-                fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);\r
-                loadLineData();\r
-                updateTextArea();\r
-                break;\r
-            }\r
-            case SWT.ARROW_UP: {\r
-                //if (fLines.size() == 0 || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
-                if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
-                    break;\r
-                }\r
-                fTopLineIndex--;\r
-                loadLineData();\r
-                updateTextArea();\r
-                break;\r
-            }\r
-            case SWT.PAGE_UP: {\r
-                fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);\r
-                loadLineData();\r
-                updateTextArea();\r
-                break;\r
-            }\r
-            case SWT.HOME: {\r
-                //selectAndReveal(0);\r
-                setTopPosition(0.0);\r
-                break;\r
-            }\r
-            case SWT.END: {\r
-                //if (fTrace.getNbEvents() > 0) {\r
-                    //selectAndReveal(fTrace.getNbEvents() - 1);\r
-                //}\r
-                double ratio = 1.0;\r
-                double delta = Math.pow(10, -15);\r
-                fLines.clear();\r
-                while (fLines.size() == 0) {\r
-                    setTopPosition(ratio);\r
-                    if (ratio == 0.0) {\r
-                        break;\r
-                    }\r
-                    delta = Math.min(delta * 10, 0.1);\r
-                    ratio = Math.max(ratio - delta, 0.0);\r
-                }\r
-                break;\r
-            }\r
-            default:\r
-                break;\r
-        }\r
-        //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
-        if (e.detail != SWT.NONE) {\r
-            fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
-        }\r
-\r
-        fHoldSelection = 0;\r
-    }\r
-\r
-    @Override\r
-    public void widgetDefaultSelected(SelectionEvent e) {\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // KeyListener (StyledText)\r
-    // ------------------------------------------------------------------------\r
-\r
-    @Override\r
-    public void keyPressed(KeyEvent e) {\r
-        if (fLines.size() == 0) {\r
-            return;\r
-        }\r
-        int caretOffset = fStyledText.getCaretOffset();\r
-        int previousCaretOffset = getPreviousCaretOffset(e.time);\r
-        int previousLineAtCaretPosition = fStyledText.getLineAtOffset(previousCaretOffset);\r
-        int previousColumnAtCaretPosition = getPreviousCaretOffset(e.time) - fStyledText.getOffsetAtLine(previousLineAtCaretPosition);\r
-        switch (e.keyCode) {\r
-            case SWT.ARROW_DOWN: {\r
-                if (previousLineAtCaretPosition < (fNumVisibleLines - 2)) {\r
-                    break;\r
-                }\r
-                fHoldSelection++;\r
-                fTopLineIndex++;\r
-                loadLineData();\r
-                updateTextArea();\r
-                fHoldSelection--;\r
-                LineData lineData = fLines.get(fTopLineIndex + fStyledText.getLineAtOffset(fStyledText.getCaretOffset()));\r
-                if (!lineData.location.equals(fSelectedLocation)) {\r
-                    fSelectedLocation = lineData.location;\r
-                    refreshLineBackgrounds();\r
-                    sendSelectionEvent(lineData);\r
-                }\r
-                break;\r
-            }\r
-            case SWT.PAGE_DOWN: {\r
-                if (previousLineAtCaretPosition >= (fNumVisibleLines - 1)) {\r
-                    fHoldSelection++;\r
-                    if (fLines.get(fTopLineIndex + previousLineAtCaretPosition).rank % 2 == 0) {\r
-                        fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_EVEN);\r
-                    } else {\r
-                        fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_ODD);\r
-                    }\r
-                    fSelectedLocation = null;\r
-                    fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);\r
-                    loadLineData();\r
-                    updateTextArea();\r
-                    fHoldSelection--;\r
-                }\r
-                int line = Math.min(fNumVisibleLines - 1, fStyledText.getLineCount() - 1);\r
-                int offset = fStyledText.getOffsetAtLine(line);\r
-                fStyledText.setSelection(offset + Math.min(previousColumnAtCaretPosition, fLines.get(fTopLineIndex + line).string.length()));\r
-                break;\r
-            }\r
-            case SWT.ARROW_RIGHT: {\r
-                if (previousCaretOffset < fStyledText.getCharCount() || previousLineAtCaretPosition < (fNumVisibleLines - 2)) {\r
-                    break;\r
-                }\r
-                fHoldSelection++;\r
-                fTopLineIndex++;\r
-                loadLineData();\r
-                updateTextArea();\r
-                fHoldSelection--;\r
-                fStyledText.setSelection(fStyledText.getCaretOffset() + 1);\r
-                break;\r
-            }\r
-            case SWT.ARROW_UP: {\r
-                if (previousLineAtCaretPosition > 0) {\r
-                    break;\r
-                }\r
-                if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
-                    break;\r
-                }\r
-                fHoldSelection++;\r
-                fTopLineIndex--;\r
-                loadLineData();\r
-                updateTextArea();\r
-                fHoldSelection--;\r
-                LineData lineData = fLines.get(fTopLineIndex);\r
-                if (!lineData.location.equals(fSelectedLocation)) {\r
-                    fSelectedLocation = lineData.location;\r
-                    refreshLineBackgrounds();\r
-                    sendSelectionEvent(lineData);\r
-                }\r
-                fStyledText.setSelection(caretOffset);\r
-                break;\r
-            }\r
-            case SWT.PAGE_UP: {\r
-                if (previousLineAtCaretPosition > 0) {\r
-                    break;\r
-                }\r
-                fHoldSelection++;\r
-                fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);\r
-                loadLineData();\r
-                updateTextArea();\r
-                fHoldSelection--;\r
-                LineData lineData = fLines.get(fTopLineIndex);\r
-                if (!lineData.location.equals(fSelectedLocation)) {\r
-                    fSelectedLocation = lineData.location;\r
-                    refreshLineBackgrounds();\r
-                    sendSelectionEvent(lineData);\r
-                }\r
-                fStyledText.setSelection(caretOffset);\r
-                break;\r
-            }\r
-            case SWT.ARROW_LEFT: {\r
-                if (previousCaretOffset > 0) {\r
-                    break;\r
-                }\r
-                if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
-                    break;\r
-                }\r
-                long topRank = fLines.get(fTopLineIndex).rank;\r
-                fHoldSelection++;\r
-                fTopLineIndex--;\r
-                loadLineData();\r
-                updateTextArea();\r
-                fHoldSelection--;\r
-                LineData lineData = fLines.get(fTopLineIndex);\r
-                if (!lineData.location.equals(fSelectedLocation)) {\r
-                    fSelectedLocation = lineData.location;\r
-                    refreshLineBackgrounds();\r
-                    sendSelectionEvent(lineData);\r
-                }\r
-                if (topRank != fLines.get(fTopLineIndex).rank) {\r
-                    fStyledText.setSelection(fLines.get(fTopLineIndex).string.length());\r
-                }\r
-                break;\r
-            }\r
-            case SWT.HOME: {\r
-                if ((e.stateMask & SWT.CTRL) == 0) {\r
-                    break;\r
-                }\r
-                //selectAndReveal(0);\r
-                setTopPosition(0.0);\r
-                LineData lineData = fLines.get(fTopLineIndex);\r
-                if (!lineData.location.equals(fSelectedLocation)) {\r
-                    fSelectedLocation = lineData.location;\r
-                    refreshLineBackgrounds();\r
-                    sendSelectionEvent(lineData);\r
-                }\r
-                break;\r
-            }\r
-            case SWT.END: {\r
-                if ((e.stateMask & SWT.CTRL) == 0) {\r
-                    break;\r
-                }\r
-                //if (fTrace.getNbEvents() > 0) {\r
-                    //selectAndReveal(fTrace.getNbEvents() - 1);\r
-                //}\r
-                double ratio = 1.0;\r
-                double delta = Math.pow(10, -15);\r
-                fLines.clear();\r
-                while (fLines.size() == 0) {\r
-                    setTopPosition(ratio);\r
-                    if (ratio == 0.0) {\r
-                        break;\r
-                    }\r
-                    delta = Math.min(delta * 10, 0.1);\r
-                    ratio = Math.max(ratio - delta, 0.0);\r
-                }\r
-                LineData lineData = fLines.get(fTopLineIndex);\r
-                if (!lineData.location.equals(fSelectedLocation)) {\r
-                    fSelectedLocation = lineData.location;\r
-                    refreshLineBackgrounds();\r
-                    sendSelectionEvent(lineData);\r
-                }\r
-                break;\r
-            }\r
-            default:\r
-                break;\r
-        }\r
-        //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
-        updateHighlightedRank();\r
-        fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
-    }\r
-\r
-    @Override\r
-    public void keyReleased(KeyEvent e) {\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // CaretListener (StyledText)\r
-    // ------------------------------------------------------------------------\r
-\r
-    @Override\r
-    public void caretMoved(CaretEvent event) {\r
-        if (fHoldSelection == 0) {\r
-            int line = fStyledText.getLineAtOffset(event.caretOffset);\r
-            if (fTopLineIndex + line < fLines.size()) {\r
-                LineData lineData = fLines.get(fTopLineIndex + line);\r
-                if (!lineData.location.equals(fSelectedLocation)) {\r
-                    fSelectedLocation = lineData.location;\r
-                    refreshLineBackgrounds();\r
-                    sendSelectionEvent(lineData);\r
-                }\r
-            }\r
-        }\r
-        storeCaretPosition(event.time, event.caretOffset);\r
-        if (fHoldSelection == 0) {\r
-            Point caret = fStyledText.getLocationAtOffset(fStyledText.getCaretOffset());\r
-            Point origin = fScrolledComposite.getOrigin();\r
-            if (origin.x > caret.x) {\r
-                origin.x = caret.x;\r
-            } else if (caret.x - origin.x > fScrolledComposite.getSize().x) {\r
-                origin.x = caret.x - fScrolledComposite.getSize().x + 1;\r
-            }\r
-            fScrolledComposite.setOrigin(origin);\r
-        }\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // MouseMoveListener (StyledText)\r
-    // ------------------------------------------------------------------------\r
-\r
-    @Override\r
-    public void mouseMove(MouseEvent e) {\r
-        fCursorYCoordinate = e.y;\r
-        if (e.y < 0 || e.y > fStyledText.getSize().y) {\r
-            if (fHighlightedRank != Long.MIN_VALUE) {\r
-                fHighlightedRank = Long.MIN_VALUE;\r
-                refreshLineBackgrounds();\r
-            }\r
-            return;\r
-        }\r
-        int offset = fStyledText.getOffsetAtLocation(new Point(0, e.y));\r
-        int line = fStyledText.getLineAtOffset(offset);\r
-        if (line < fLines.size() - fTopLineIndex) {\r
-            LineData lineData = fLines.get(fTopLineIndex + line);\r
-            if (fHighlightedRank != lineData.rank) {\r
-                fHighlightedRank = lineData.rank;\r
-                refreshLineBackgrounds();\r
-            }\r
-        } else {\r
-            if (fHighlightedRank != Long.MIN_VALUE) {\r
-                fHighlightedRank = Long.MIN_VALUE;\r
-                refreshLineBackgrounds();\r
-            }\r
-        }\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // MouseTrackListener (StyledText)\r
-    // ------------------------------------------------------------------------\r
-\r
-    @Override\r
-    public void mouseExit(MouseEvent e) {\r
-        fCursorYCoordinate = -1;\r
-        if (fHighlightedRank != Long.MIN_VALUE) {\r
-            fHighlightedRank = Long.MIN_VALUE;\r
-            refreshLineBackgrounds();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void mouseEnter(MouseEvent e) {\r
-        fCursorYCoordinate = e.y;\r
-    }\r
-\r
-    @Override\r
-    public void mouseHover(MouseEvent e) {\r
-    }\r
-\r
-    // ------------------------------------------------------------------------\r
-    // MouseWheelListener (StyledText)\r
-    // ------------------------------------------------------------------------\r
-\r
-    @Override\r
-    public void mouseScrolled(MouseEvent e) {\r
-        if (fLines.size() == 0) {\r
-            return;\r
-        }\r
-        fHoldSelection++;\r
-        fTopLineIndex -= e.count;\r
-        loadLineData();\r
-        updateTextArea();\r
-        fHoldSelection = 0;\r
-        //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
-        updateHighlightedRank();\r
-        fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Patrick Tasse - Initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.widgets.rawviewer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CaretEvent;
+import org.eclipse.swt.custom.CaretListener;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.MouseWheelListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Slider;
+
+/**
+ * TmfRawEventViewer allows for the display of the raw data for an arbitrarily
+ * large number of TMF events.
+ *
+ * It is essentially a Composite of a StyledText area and a Slider, where the number
+ * of visible lines in the StyledText control is set to fill the viewer display area.
+ * An underlying data model is used to store a cache of event raw text line data.
+ * The slider is ratio-based.
+ *
+ * @version 1.0
+ * @author Patrick Tasse
+ */
+public class TmfRawEventViewer extends Composite implements ControlListener, SelectionListener,
+                KeyListener, CaretListener, MouseMoveListener, MouseTrackListener, MouseWheelListener {
+
+    private static final Color COLOR_BACKGROUND_ODD = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
+    private static final Color COLOR_BACKGROUND_EVEN = new Color(Display.getDefault(), 242, 242, 242);
+    private static final Color COLOR_BACKGROUND_SELECTED = new Color(Display.getDefault(), 231, 246, 254);
+    private static final Color COLOR_BACKGROUND_HIGHLIGHTED = new Color(Display.getDefault(), 246, 252, 255);
+    private static final int MAX_LINE_DATA_SIZE = 1000;
+    private static final int SLIDER_MAX = 1000000;
+
+    private ITmfTrace fTrace;
+    private ITmfContext fBottomContext;
+
+    private ScrolledComposite fScrolledComposite;
+    private Composite fTextArea;
+    private StyledText fStyledText;
+    private Font fFixedFont;
+       private Slider fSlider;
+
+       private final List<LineData> fLines = new ArrayList<LineData>();
+       private boolean fActualRanks = false;
+       private int fTopLineIndex;
+       private int fLastTopLineIndex;
+       private final CaretPosition[] fStoredCaretPosition = new CaretPosition[]
+                   { new CaretPosition(0, 0), new CaretPosition(0,0)};
+       private int fNumVisibleLines;
+    private ITmfLocation fSelectedLocation = null;
+    private long fHighlightedRank = Long.MIN_VALUE;
+    private int fCursorYCoordinate = -1;
+    private int fHoldSelection = 0;
+
+       private static class LineData {
+           long rank;
+           ITmfLocation location;
+           String string;
+           public LineData(long rank, ITmfLocation location, String string) {
+               this.rank = rank;
+               this.location = location;
+            if (string.length() == 0) {
+                this.string = " "; // workaround for setLineBackground has no effect on empty line //$NON-NLS-1$
+            } else {
+                this.string = string;
+            }
+           }
+        @Override
+        public String toString() {
+            return rank + " [" + location + "]: " + string; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+       }
+
+       private static class CaretPosition {
+           int time;
+           int caretOffset;
+           public CaretPosition(int time, int caretOffset) {
+               this.time = time;
+               this.caretOffset = caretOffset;
+           }
+       }
+
+       // ------------------------------------------------------------------------
+       // Constructor
+       // ------------------------------------------------------------------------
+
+       /**
+        * Constructor
+        * @param parent The parent composite
+        * @param style The style bits
+        */
+       public TmfRawEventViewer(Composite parent, int style) {
+               super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL));
+
+               // Set the layout
+               GridLayout gridLayout = new GridLayout();
+               gridLayout.numColumns = 2;
+               gridLayout.horizontalSpacing = 0;
+               gridLayout.verticalSpacing = 0;
+        gridLayout.marginWidth = 0;
+        gridLayout.marginHeight = 0;
+               setLayout(gridLayout);
+
+               // Create the controls
+               createTextArea(style & SWT.H_SCROLL);
+               createSlider(style & SWT.V_SCROLL);
+
+               // Prevent the slider from being traversed
+               setTabList(new Control[] { fScrolledComposite });
+       }
+
+    @Override
+       public void dispose() {
+        if (fFixedFont != null) {
+            fFixedFont.dispose();
+            fFixedFont = null;
+        }
+           super.dispose();
+       }
+
+       // ------------------------------------------------------------------------
+       // Text area handling
+       // ------------------------------------------------------------------------
+
+    /**
+        * Create the text area and add listeners
+        */
+       private void createTextArea(int style) {
+           fScrolledComposite = new ScrolledComposite(this, style);
+           fScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+           fTextArea = new Composite(fScrolledComposite, SWT.NONE);
+        fTextArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+        fScrolledComposite.setContent(fTextArea);
+        fScrolledComposite.setExpandHorizontal(true);
+        fScrolledComposite.setExpandVertical(true);
+        fScrolledComposite.setAlwaysShowScrollBars(true);
+        fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+        fScrolledComposite.addControlListener(this);
+
+        GridLayout textAreaGridLayout = new GridLayout();
+        textAreaGridLayout.marginHeight = 0;
+        textAreaGridLayout.marginWidth = 0;
+        fTextArea.setLayout(textAreaGridLayout);
+
+        if (fFixedFont == null) {
+            if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$
+                fFixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$
+            } else {
+                fFixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$
+            }
+        }
+
+        fStyledText = new StyledText(fTextArea, SWT.READ_ONLY);
+        fStyledText.setFont(fFixedFont);
+        fStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+        fStyledText.addCaretListener(this);
+        fStyledText.addMouseMoveListener(this);
+        fStyledText.addMouseTrackListener(this);
+        fStyledText.addMouseWheelListener(this);
+        fStyledText.addListener(SWT.MouseWheel, new Listener() { // disable mouse scroll of horizontal scroll bar
+            @Override
+            public void handleEvent(Event event) { event.doit = false; }});
+        fStyledText.addKeyListener(this);
+
+        fTextArea.setBackground(fStyledText.getBackground());
+        fTextArea.addMouseListener(new MouseAdapter() {
+                       @Override
+            public void mouseDown(MouseEvent e) {
+                               fTextArea.setFocus();
+            }});
+       }
+
+       // ------------------------------------------------------------------------
+       // Slider handling
+       // ------------------------------------------------------------------------
+
+       private void createSlider(int style) {
+               fSlider = new Slider(this, SWT.VERTICAL);
+        fSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
+        fSlider.setValues(0, 0, SLIDER_MAX, SLIDER_MAX, 1, 1);
+               fSlider.addSelectionListener(this);
+        if ((style & SWT.V_SCROLL) == 0) {
+            fSlider.setVisible(false);
+        }
+       }
+
+       // ------------------------------------------------------------------------
+       // Controls interactions
+       // ------------------------------------------------------------------------
+
+       @Override
+       public boolean setFocus() {
+               boolean isVisible = isVisible();
+               if (isVisible) {
+                       fTextArea.setFocus();
+               }
+               return isVisible;
+       }
+
+    @Override
+    public void setMenu(Menu menu) {
+        fStyledText.setMenu(menu);
+    }
+
+    /**
+     * Sets the trace and updates the content
+     * @param trace The trace to set
+     */
+    public void setTrace(ITmfTrace trace) {
+           fTrace = trace;
+           fTopLineIndex = 0;
+           fLines.clear();
+           refreshEventCount();
+       }
+
+    /**
+     * Refreshes the event count, updates the slider thumb and loads display
+     */
+       public void refreshEventCount() {
+               if (fTrace != null) {
+                       if (fTrace.getNbEvents() > 0) {
+                               fSlider.setThumb((int) Math.max(SLIDER_MAX / fTrace.getNbEvents(), 1));
+                       } else {
+                               fSlider.setThumb(SLIDER_MAX);
+                       }
+
+                       if (!isVisible()) {
+                return;
+            }
+
+                       if (fLines.size() == 0) {
+                       setTopRank(0);
+                   } else if (fLines.size() < fNumVisibleLines) {
+                       fBottomContext = null;
+                       loadLineData();
+                       fillTextArea();
+                   //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
+                   fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
+                   }
+        } else {
+            fBottomContext = null;
+            fillTextArea();
+            fSlider.setThumb(SLIDER_MAX);
+            fSlider.setSelection(0);
+               }
+       }
+
+       /**
+        * Selects the event of given rank and makes it visible.
+        * @param rank The rank of event
+        */
+    public void selectAndReveal(long rank) {
+        if (fTrace == null || !isVisible()) {
+            return;
+        }
+        if (fActualRanks && fTopLineIndex < fLines.size() && rank >= fLines.get(fTopLineIndex).rank) {
+            int lastVisibleIndex = Math.min(fTopLineIndex + fNumVisibleLines, fLines.size()) - 1;
+            if (rank <= fLines.get(lastVisibleIndex).rank) {
+                for (int i = fTopLineIndex; i < fLines.size(); i++) {
+                    if (fLines.get(i).rank == rank) {
+                        fSelectedLocation = fLines.get(i).location;
+                        break;
+                    }
+                }
+                refreshLineBackgrounds();
+                return;
+            }
+        }
+        setTopRank(rank);
+        if (fLines.size() > 0 && fHoldSelection == 0) {
+            fSelectedLocation = fLines.get(0).location;
+            refreshLineBackgrounds();
+        }
+    }
+
+    /**
+     * Add a selection listener
+     * @param listener A listener to add
+     */
+    public void addSelectionListener(Listener listener) {
+        checkWidget();
+        if (listener == null) {
+            SWT.error (SWT.ERROR_NULL_ARGUMENT);
+        }
+        addListener (SWT.Selection, listener);
+    }
+
+    /**
+     * Remove selection listener
+     * @param listener A listener to remove
+     */
+    public void removeSelectionListener(Listener listener) {
+        checkWidget();
+        if (listener == null) {
+            SWT.error (SWT.ERROR_NULL_ARGUMENT);
+        }
+        removeListener(SWT.Selection, listener);
+    }
+
+    private void sendSelectionEvent(LineData lineData) {
+        Event event = new Event();
+        if (fActualRanks) {
+            event.data = Long.valueOf(lineData.rank);
+        } else {
+            event.data = lineData.location;
+        }
+        notifyListeners(SWT.Selection, event);
+    }
+
+    private void setTopRank(long rank) {
+        fBottomContext = fTrace.seekEvent(rank);
+        if (fBottomContext == null) {
+            return;
+        }
+        fLines.clear();
+        fActualRanks = true;
+        fTopLineIndex = 0;
+        loadLineData();
+        refreshTextArea();
+        if (fLines.size() == 0) {
+            fSlider.setSelection(0);
+        } else {
+            //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
+            fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
+        }
+    }
+
+    private void setTopPosition(double ratio) {
+        fBottomContext = fTrace.seekEvent(ratio);
+        if (fBottomContext == null) {
+            return;
+        }
+        fBottomContext.setRank(0);
+        fLines.clear();
+        fActualRanks = false;
+        fTopLineIndex = 0;
+        loadLineData();
+        refreshTextArea();
+    }
+
+       private void loadLineData() {
+        if (fTopLineIndex < 0) {
+            //if (fLines.size() > 0 && fLines.get(0).rank > 0) {
+                //long endRank = fLines.get(0).rank;
+                //long startRank = Math.max(0, endRank - fNumVisibleLines);
+                //TmfContext context = fTrace.seekEvent(startRank);
+                //int index = 0;
+                //while (context.getRank() < endRank) {
+                    //long rank = context.getRank();
+                    //ITmfLocation<?> location = context.getLocation();
+                    //TmfEvent event = fTrace.getNextEvent(context);
+                    //String[] lines = event.getRawText().split("\r?\n");
+                    //for (int i = 0; i < lines.length; i++) {
+                        //String line = lines[i];
+                        //LineData lineData = new LineData(rank, location, line);
+                        //fLines.add(index++, lineData);
+                        //fTopLineIndex++;
+                        //fLastTopLineIndex++;
+                    //}
+                //}
+            //}
+            if (fLines.size() > 0 && fTrace.getLocationRatio(fLines.get(0).location) > 0) {
+               double lastRatio = fTrace.getLocationRatio(fLines.get(fLines.size() - 1).location);
+                double firstRatio = fTrace.getLocationRatio(fLines.get(0).location);
+                double delta;
+                boolean singleEvent = false;
+                if (firstRatio != lastRatio) {
+                    // approximate ratio of at least 20 items
+                    delta = Math.max(20, fNumVisibleLines) * (lastRatio - firstRatio) / (fLines.size() - 1);
+                } else {
+                    delta = Math.pow(10, -15);
+                    singleEvent = true;
+                }
+                while (fTopLineIndex < 0) {
+                    ITmfLocation endLocation = fLines.get(0).location;
+                    firstRatio = Math.max(0, firstRatio - delta);
+                    ITmfContext context = fTrace.seekEvent(firstRatio);
+                    ITmfLocation location;
+                    int index = 0;
+                    long rank = 0;
+                    while (!context.getLocation().equals(endLocation)) {
+                        location = context.getLocation();
+                        ITmfEvent event = fTrace.getNext(context);
+                        if (event == null) {
+                               break;
+                        }
+                        if (event.getContent() != null && event.getContent().getValue() != null) {
+                            String[] lines = event.getContent().getValue().toString().split("\r?\n"); //$NON-NLS-1$
+                            for (int i = 0; i < lines.length; i++) {
+                                String line = lines[i];
+                                LineData lineData = new LineData(rank, location, line);
+                                fLines.add(index++, lineData);
+                                fTopLineIndex++;
+                                fLastTopLineIndex++;
+                            }
+                        } else {
+                            LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$
+                            fLines.add(index++, lineData);
+                            fTopLineIndex++;
+                            fLastTopLineIndex++;
+                        }
+                        rank++;
+                    }
+                    long rankOffset = fLines.get(index).rank - rank;
+                    for (int i = 0; i < index; i++) {
+                        fLines.get(i).rank += rankOffset;
+                    }
+                    if (firstRatio == 0) {
+                        break;
+                    }
+                    if (singleEvent) {
+                       delta = Math.min(delta * 10, 0.1);
+                    }
+                }
+            }
+            if (fTopLineIndex < 0) {
+                fTopLineIndex = 0;
+            }
+        }
+
+           while (fLines.size() - fTopLineIndex < fNumVisibleLines) {
+               if (fBottomContext == null) {
+                   if (fLines.size() == 0) {
+                       fBottomContext = fTrace.seekEvent(0);
+                   } else {
+                    //fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).rank + 1);
+                       fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).location);
+                       fTrace.getNext(fBottomContext);
+                   }
+                   if (fBottomContext == null) {
+                       break;
+                   }
+               }
+            long rank = fBottomContext.getRank();
+            ITmfLocation location = fBottomContext.getLocation() != null ? fBottomContext.getLocation() : null;
+            ITmfEvent event = fTrace.getNext(fBottomContext);
+            if (event == null) {
+                break;
+            }
+            if (event.getContent() != null && event.getContent().getValue() != null) {
+                for (String line : event.getContent().getValue().toString().split("\r?\n")) { //$NON-NLS-1$
+                    int crPos;
+                    if ((crPos = line.indexOf('\r')) != -1) {
+                       line = line.substring(0, crPos);
+                    }
+                    LineData lineData = new LineData(rank, location, line);
+                    fLines.add(lineData);
+                }
+            } else {
+                LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$
+                fLines.add(lineData);
+            }
+           }
+           fTopLineIndex = Math.max(0, Math.min(fTopLineIndex, fLines.size() - 1));
+
+           if (fLines.size() > MAX_LINE_DATA_SIZE) {
+               if (fTopLineIndex < MAX_LINE_DATA_SIZE / 2) {
+                   long rank = fLines.get(MAX_LINE_DATA_SIZE - 1).rank;
+                   for (int i = MAX_LINE_DATA_SIZE; i < fLines.size(); i++) {
+                       if (fLines.get(i).rank > rank) {
+                           fLines.subList(i, fLines.size()).clear();
+                           fBottomContext = null;
+                           break;
+                       }
+                   }
+               } else {
+                   long rank = fLines.get(fLines.size() - MAX_LINE_DATA_SIZE).rank;
+                   for (int i = fLines.size() - MAX_LINE_DATA_SIZE - 1; i >= 0; i--) {
+                    if (fLines.get(i).rank < rank) {
+                        fLines.subList(0, i + 1).clear();
+                        fTopLineIndex -= (i + 1);
+                        fLastTopLineIndex -= (i + 1);
+                        break;
+                    }
+                   }
+               }
+           }
+       }
+
+    private void refreshTextArea() {
+        fStyledText.setText(""); //$NON-NLS-1$
+        for (int i = 0; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {
+            if (i > 0)
+             {
+                fStyledText.append("\n"); //$NON-NLS-1$
+            }
+            LineData lineData = fLines.get(fTopLineIndex + i);
+            fStyledText.append(lineData.string);
+            setLineBackground(i, lineData);
+        }
+        fTextArea.layout();
+        fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+        fLastTopLineIndex = fTopLineIndex;
+    }
+
+    private void fillTextArea() {
+        int nextLine = fStyledText.getCharCount() == 0 ? 0 : fStyledText.getLineCount();
+        for (int i = nextLine; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {
+            if (i > 0)
+             {
+                fStyledText.append("\n"); //$NON-NLS-1$
+            }
+            LineData lineData = fLines.get(fTopLineIndex + i);
+            fStyledText.append(lineData.string);
+            setLineBackground(i, lineData);
+        }
+        int endLine = Math.min(fNumVisibleLines, fLines.size());
+        if (endLine < fStyledText.getLineCount()) {
+           int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;
+           if (endOffset > fStyledText.getCharCount()) {
+                fHoldSelection++;
+               fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$
+                fHoldSelection--;
+           }
+        }
+        fTextArea.layout();
+        fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+    }
+
+       private void updateTextArea() {
+           if (fTopLineIndex < fLastTopLineIndex) {
+               StringBuffer insertedText = new StringBuffer();
+               for (int i = fTopLineIndex; i < fLastTopLineIndex; i++) {
+                   insertedText.append(fLines.get(i).string + "\n"); //$NON-NLS-1$
+               }
+               fStyledText.replaceTextRange(0, 0, insertedText.toString());
+            for (int i = 0; i < fLastTopLineIndex - fTopLineIndex; i++) {
+                LineData lineData = fLines.get(fTopLineIndex + i);
+                setLineBackground(i, lineData);
+            }
+               fLastTopLineIndex = fTopLineIndex;
+           } else if (fTopLineIndex > fLastTopLineIndex) {
+               int length = 0;
+               for (int i = 0; i < fTopLineIndex - fLastTopLineIndex && i < fNumVisibleLines; i++) {
+                   length += fLines.get(i + fLastTopLineIndex).string.length();
+                   if (i < fStyledText.getLineCount()) {
+                    length += 1;
+                }
+               }
+               fStyledText.replaceTextRange(0, length, ""); //$NON-NLS-1$
+            fLastTopLineIndex = fTopLineIndex;
+            fillTextArea();
+           }
+        int endLine = Math.min(fNumVisibleLines, fLines.size());
+        if (endLine < fStyledText.getLineCount()) {
+           int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;
+           if (endOffset > fStyledText.getCharCount()) {
+               fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$
+           }
+        }
+           fTextArea.layout();
+           fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+       }
+
+       private void refreshLineBackgrounds() {
+        for (int i = 0; (i < fStyledText.getLineCount()) && (i < fNumVisibleLines) && (i < fLines.size() - fTopLineIndex); i++) {
+            LineData lineData = fLines.get(fTopLineIndex + i);
+            setLineBackground(i, lineData);
+        }
+       }
+
+       private void setLineBackground(int index, LineData lineData) {
+        if (lineData.location.equals(fSelectedLocation)) {
+            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_SELECTED);
+        } else if (lineData.rank == fHighlightedRank) {
+            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_HIGHLIGHTED);
+        } else if (lineData.rank % 2 == 0) {
+            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_EVEN);
+        } else {
+            fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_ODD);
+        }
+       }
+
+       private void storeCaretPosition(int time, int caretOffset) {
+           if (fStoredCaretPosition[0].time == time) {
+               fStoredCaretPosition[0].caretOffset = caretOffset;
+           } else {
+               fStoredCaretPosition[1] = fStoredCaretPosition[0];
+               fStoredCaretPosition[0] = new CaretPosition(time, caretOffset);
+           }
+       }
+
+       private int getPreviousCaretOffset(int time) {
+           if (fStoredCaretPosition[0].time == time) {
+               return fStoredCaretPosition[1].caretOffset;
+           }
+        return fStoredCaretPosition[0].caretOffset;
+       }
+
+       private void updateHighlightedRank() {
+        if (fCursorYCoordinate < 0 || fCursorYCoordinate > fStyledText.getSize().y) {
+            if (fHighlightedRank != Long.MIN_VALUE) {
+                fHighlightedRank = Long.MIN_VALUE;
+                refreshLineBackgrounds();
+            }
+            return;
+        }
+        int offset = fStyledText.getOffsetAtLocation(new Point(0, fCursorYCoordinate));
+        int line = fStyledText.getLineAtOffset(offset);
+        if (line < fLines.size() - fTopLineIndex) {
+            LineData lineData = fLines.get(fTopLineIndex + line);
+            if (fHighlightedRank != lineData.rank) {
+                fHighlightedRank = lineData.rank;
+                refreshLineBackgrounds();
+            }
+        } else {
+            if (fHighlightedRank != Long.MIN_VALUE) {
+                fHighlightedRank = Long.MIN_VALUE;
+                refreshLineBackgrounds();
+            }
+        }
+       }
+
+    // ------------------------------------------------------------------------
+    // ControlListener (ScrolledComposite)
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void controlResized(ControlEvent event) {
+        int areaHeight = fScrolledComposite.getSize().y;
+        if (fScrolledComposite.getHorizontalBar() != null) {
+            areaHeight -= fScrolledComposite.getHorizontalBar().getSize().y;
+        }
+        int lineHeight = fStyledText.getLineHeight();
+        fNumVisibleLines = Math.max((areaHeight + lineHeight - 1) / lineHeight, 1);
+
+        if (fBottomContext != null) {
+            loadLineData();
+            fillTextArea();
+        }
+    }
+
+    @Override
+    public void controlMoved(ControlEvent e) {
+    }
+
+    // ------------------------------------------------------------------------
+    // SelectionListener (Slider)
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void widgetSelected(SelectionEvent e) {
+       fTextArea.setFocus();
+        if (fLines.size() == 0) {
+            return;
+        }
+        if (e.detail == SWT.DRAG) {
+            return;
+        }
+        fHoldSelection++;
+        switch (e.detail) {
+            case SWT.NONE: {
+                //long rank = (long) (fTrace.getNbEvents() * ((double) fSlider.getSelection() / SLIDER_MAX));
+                //setTopRank(rank);
+               if (fSlider.getSelection() == 0 || fSlider.getThumb() == SLIDER_MAX) {
+                    fLines.clear();
+                    setTopPosition(0.0);
+                    break;
+               }
+                double ratio = (double) fSlider.getSelection() / (SLIDER_MAX - fSlider.getThumb());
+                double delta = Math.pow(10, -15);
+                fLines.clear();
+                while (fLines.size() == 0) {
+                    setTopPosition(ratio);
+                    if (ratio == 0.0) {
+                        break;
+                    }
+                    delta = Math.min(delta * 10, 0.1);
+                    ratio = Math.max(ratio - delta, 0.0);
+                }
+                break;
+            }
+            case SWT.ARROW_DOWN: {
+                if (fTopLineIndex >= fLines.size()) {
+                    break;
+                }
+                fTopLineIndex++;
+                loadLineData();
+                updateTextArea();
+                break;
+            }
+            case SWT.PAGE_DOWN: {
+                fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);
+                loadLineData();
+                updateTextArea();
+                break;
+            }
+            case SWT.ARROW_UP: {
+                //if (fLines.size() == 0 || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
+                if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
+                    break;
+                }
+                fTopLineIndex--;
+                loadLineData();
+                updateTextArea();
+                break;
+            }
+            case SWT.PAGE_UP: {
+                fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);
+                loadLineData();
+                updateTextArea();
+                break;
+            }
+            case SWT.HOME: {
+                //selectAndReveal(0);
+                setTopPosition(0.0);
+                break;
+            }
+            case SWT.END: {
+                //if (fTrace.getNbEvents() > 0) {
+                    //selectAndReveal(fTrace.getNbEvents() - 1);
+                //}
+                double ratio = 1.0;
+                double delta = Math.pow(10, -15);
+                fLines.clear();
+                while (fLines.size() == 0) {
+                    setTopPosition(ratio);
+                    if (ratio == 0.0) {
+                        break;
+                    }
+                    delta = Math.min(delta * 10, 0.1);
+                    ratio = Math.max(ratio - delta, 0.0);
+                }
+                break;
+            }
+            default:
+                break;
+        }
+        //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
+        if (e.detail != SWT.NONE) {
+            fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
+        }
+
+        fHoldSelection = 0;
+    }
+
+    @Override
+    public void widgetDefaultSelected(SelectionEvent e) {
+    }
+
+    // ------------------------------------------------------------------------
+    // KeyListener (StyledText)
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void keyPressed(KeyEvent e) {
+        if (fLines.size() == 0) {
+            return;
+        }
+        int caretOffset = fStyledText.getCaretOffset();
+        int previousCaretOffset = getPreviousCaretOffset(e.time);
+        int previousLineAtCaretPosition = fStyledText.getLineAtOffset(previousCaretOffset);
+        int previousColumnAtCaretPosition = getPreviousCaretOffset(e.time) - fStyledText.getOffsetAtLine(previousLineAtCaretPosition);
+        switch (e.keyCode) {
+            case SWT.ARROW_DOWN: {
+                if (previousLineAtCaretPosition < (fNumVisibleLines - 2)) {
+                    break;
+                }
+                fHoldSelection++;
+                fTopLineIndex++;
+                loadLineData();
+                updateTextArea();
+                fHoldSelection--;
+                LineData lineData = fLines.get(fTopLineIndex + fStyledText.getLineAtOffset(fStyledText.getCaretOffset()));
+                if (!lineData.location.equals(fSelectedLocation)) {
+                    fSelectedLocation = lineData.location;
+                    refreshLineBackgrounds();
+                    sendSelectionEvent(lineData);
+                }
+                break;
+            }
+            case SWT.PAGE_DOWN: {
+                if (previousLineAtCaretPosition >= (fNumVisibleLines - 1)) {
+                    fHoldSelection++;
+                    if (fLines.get(fTopLineIndex + previousLineAtCaretPosition).rank % 2 == 0) {
+                        fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_EVEN);
+                    } else {
+                        fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_ODD);
+                    }
+                    fSelectedLocation = null;
+                    fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);
+                    loadLineData();
+                    updateTextArea();
+                    fHoldSelection--;
+                }
+                int line = Math.min(fNumVisibleLines - 1, fStyledText.getLineCount() - 1);
+                int offset = fStyledText.getOffsetAtLine(line);
+                fStyledText.setSelection(offset + Math.min(previousColumnAtCaretPosition, fLines.get(fTopLineIndex + line).string.length()));
+                break;
+            }
+            case SWT.ARROW_RIGHT: {
+                if (previousCaretOffset < fStyledText.getCharCount() || previousLineAtCaretPosition < (fNumVisibleLines - 2)) {
+                    break;
+                }
+                fHoldSelection++;
+                fTopLineIndex++;
+                loadLineData();
+                updateTextArea();
+                fHoldSelection--;
+                fStyledText.setSelection(fStyledText.getCaretOffset() + 1);
+                break;
+            }
+            case SWT.ARROW_UP: {
+                if (previousLineAtCaretPosition > 0) {
+                    break;
+                }
+                if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
+                    break;
+                }
+                fHoldSelection++;
+                fTopLineIndex--;
+                loadLineData();
+                updateTextArea();
+                fHoldSelection--;
+                LineData lineData = fLines.get(fTopLineIndex);
+                if (!lineData.location.equals(fSelectedLocation)) {
+                    fSelectedLocation = lineData.location;
+                    refreshLineBackgrounds();
+                    sendSelectionEvent(lineData);
+                }
+                fStyledText.setSelection(caretOffset);
+                break;
+            }
+            case SWT.PAGE_UP: {
+                if (previousLineAtCaretPosition > 0) {
+                    break;
+                }
+                fHoldSelection++;
+                fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);
+                loadLineData();
+                updateTextArea();
+                fHoldSelection--;
+                LineData lineData = fLines.get(fTopLineIndex);
+                if (!lineData.location.equals(fSelectedLocation)) {
+                    fSelectedLocation = lineData.location;
+                    refreshLineBackgrounds();
+                    sendSelectionEvent(lineData);
+                }
+                fStyledText.setSelection(caretOffset);
+                break;
+            }
+            case SWT.ARROW_LEFT: {
+                if (previousCaretOffset > 0) {
+                    break;
+                }
+                if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {
+                    break;
+                }
+                long topRank = fLines.get(fTopLineIndex).rank;
+                fHoldSelection++;
+                fTopLineIndex--;
+                loadLineData();
+                updateTextArea();
+                fHoldSelection--;
+                LineData lineData = fLines.get(fTopLineIndex);
+                if (!lineData.location.equals(fSelectedLocation)) {
+                    fSelectedLocation = lineData.location;
+                    refreshLineBackgrounds();
+                    sendSelectionEvent(lineData);
+                }
+                if (topRank != fLines.get(fTopLineIndex).rank) {
+                    fStyledText.setSelection(fLines.get(fTopLineIndex).string.length());
+                }
+                break;
+            }
+            case SWT.HOME: {
+                if ((e.stateMask & SWT.CTRL) == 0) {
+                    break;
+                }
+                //selectAndReveal(0);
+                setTopPosition(0.0);
+                LineData lineData = fLines.get(fTopLineIndex);
+                if (!lineData.location.equals(fSelectedLocation)) {
+                    fSelectedLocation = lineData.location;
+                    refreshLineBackgrounds();
+                    sendSelectionEvent(lineData);
+                }
+                break;
+            }
+            case SWT.END: {
+                if ((e.stateMask & SWT.CTRL) == 0) {
+                    break;
+                }
+                //if (fTrace.getNbEvents() > 0) {
+                    //selectAndReveal(fTrace.getNbEvents() - 1);
+                //}
+                double ratio = 1.0;
+                double delta = Math.pow(10, -15);
+                fLines.clear();
+                while (fLines.size() == 0) {
+                    setTopPosition(ratio);
+                    if (ratio == 0.0) {
+                        break;
+                    }
+                    delta = Math.min(delta * 10, 0.1);
+                    ratio = Math.max(ratio - delta, 0.0);
+                }
+                LineData lineData = fLines.get(fTopLineIndex);
+                if (!lineData.location.equals(fSelectedLocation)) {
+                    fSelectedLocation = lineData.location;
+                    refreshLineBackgrounds();
+                    sendSelectionEvent(lineData);
+                }
+                break;
+            }
+            default:
+                break;
+        }
+        //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
+        updateHighlightedRank();
+        fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
+    }
+
+    @Override
+    public void keyReleased(KeyEvent e) {
+    }
+
+    // ------------------------------------------------------------------------
+    // CaretListener (StyledText)
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void caretMoved(CaretEvent event) {
+        if (fHoldSelection == 0) {
+            int line = fStyledText.getLineAtOffset(event.caretOffset);
+            if (fTopLineIndex + line < fLines.size()) {
+                LineData lineData = fLines.get(fTopLineIndex + line);
+                if (!lineData.location.equals(fSelectedLocation)) {
+                    fSelectedLocation = lineData.location;
+                    refreshLineBackgrounds();
+                    sendSelectionEvent(lineData);
+                }
+            }
+        }
+        storeCaretPosition(event.time, event.caretOffset);
+        if (fHoldSelection == 0) {
+            Point caret = fStyledText.getLocationAtOffset(fStyledText.getCaretOffset());
+            Point origin = fScrolledComposite.getOrigin();
+            if (origin.x > caret.x) {
+                origin.x = caret.x;
+            } else if (caret.x - origin.x > fScrolledComposite.getSize().x) {
+                origin.x = caret.x - fScrolledComposite.getSize().x + 1;
+            }
+            fScrolledComposite.setOrigin(origin);
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseMoveListener (StyledText)
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void mouseMove(MouseEvent e) {
+        fCursorYCoordinate = e.y;
+        if (e.y < 0 || e.y > fStyledText.getSize().y) {
+            if (fHighlightedRank != Long.MIN_VALUE) {
+                fHighlightedRank = Long.MIN_VALUE;
+                refreshLineBackgrounds();
+            }
+            return;
+        }
+        int offset = fStyledText.getOffsetAtLocation(new Point(0, e.y));
+        int line = fStyledText.getLineAtOffset(offset);
+        if (line < fLines.size() - fTopLineIndex) {
+            LineData lineData = fLines.get(fTopLineIndex + line);
+            if (fHighlightedRank != lineData.rank) {
+                fHighlightedRank = lineData.rank;
+                refreshLineBackgrounds();
+            }
+        } else {
+            if (fHighlightedRank != Long.MIN_VALUE) {
+                fHighlightedRank = Long.MIN_VALUE;
+                refreshLineBackgrounds();
+            }
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseTrackListener (StyledText)
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void mouseExit(MouseEvent e) {
+        fCursorYCoordinate = -1;
+        if (fHighlightedRank != Long.MIN_VALUE) {
+            fHighlightedRank = Long.MIN_VALUE;
+            refreshLineBackgrounds();
+        }
+    }
+
+    @Override
+    public void mouseEnter(MouseEvent e) {
+        fCursorYCoordinate = e.y;
+    }
+
+    @Override
+    public void mouseHover(MouseEvent e) {
+    }
+
+    // ------------------------------------------------------------------------
+    // MouseWheelListener (StyledText)
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void mouseScrolled(MouseEvent e) {
+        if (fLines.size() == 0) {
+            return;
+        }
+        fHoldSelection++;
+        fTopLineIndex -= e.count;
+        loadLineData();
+        updateTextArea();
+        fHoldSelection = 0;
+        //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));
+        updateHighlightedRank();
+        fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));
+    }
+
+}
This page took 0.071199 seconds and 5 git commands to generate.