/******************************************************************************* * Copyright (c) 2009 Red Hat, Inc. * 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: * Red Hat - initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.internal.callgraph.core; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; public class SystemTapTextView extends SystemTapView { private StyledText viewer; private Display display; private int previousEnd; /** * Passing the focus request to the viewer's control. */ @Override public void setFocus() { if (viewer != null && !viewer.isDisposed()) { viewer.setFocus(); } } private void createViewer(Composite parent) { viewer = new StyledText(parent, SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP); viewer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Font font = new Font(parent.getDisplay(), "Monospace", 11, SWT.NORMAL); //$NON-NLS-1$ viewer.setFont(font); masterComposite = parent; display = masterComposite.getDisplay(); } /** * Print with colour codes. Colour codes accepted in the form of ~(R,G,B)~, * and apply for the rest of the line or until another code is encountered * @param text */ private void prettyPrintln(String text) { List<StyleRange> styles = new ArrayList<>(); String[] txt = text.split("\\n"); //$NON-NLS-1$ int lineOffset = 0; int inLineOffset; // txt[] contains text, with one entry for each new line for (String line: txt) { // Skip blank strings if (line.isEmpty()) { viewer.append(PluginConstants.NEW_LINE); continue; } // Search for colour codes, if none exist then continue String[] split_txt = line.split("~\\("); //$NON-NLS-1$ if (split_txt.length == 1) { viewer.append(split_txt[0]); viewer.append(PluginConstants.NEW_LINE); continue; } inLineOffset = 0; for (String split: split_txt) { // Skip blank substrings if (split.isEmpty()) { continue; } // Split for the number codes String[] coloursAndText = split.split("\\)~"); //$NON-NLS-1$ // If the string is properly formatted, colours should be length // 2 // If it is not properly formatted, don't colour (just print) if (coloursAndText.length != 2) { for (String colourAndText: coloursAndText) { viewer.append(colourAndText); inLineOffset += colourAndText.length(); } continue; } // The first element in the array should contain the colours String[] colours = coloursAndText[0].split(","); //$NON-NLS-1$ if (colours.length < 3) { continue; } // The second element in the array should contain the text viewer.append(coloursAndText[1]); // Create a colour based on the 3 integers (if there are any // more integers, just ignore) int R = Integer.valueOf(colours[0].replaceAll(" ", "")).intValue(); //$NON-NLS-1$ //$NON-NLS-2$ int G = Integer.valueOf(colours[1].replaceAll(" ", "")).intValue(); //$NON-NLS-1$ //$NON-NLS-2$ int B = Integer.valueOf(colours[2].replaceAll(" ", "")).intValue(); //$NON-NLS-1$ //$NON-NLS-2$ if (R > 255) R = 255; if (G > 255) G = 255; if (B > 255) B = 255; if (R < 0) R = 0; if (G < 0) G = 0; if (B < 0) B = 0; Color newColor = new Color(display, R, G, B); // Find the offset of the current line lineOffset = viewer.getOffsetAtLine(viewer.getLineCount() - 1); // Create a new style that lasts no further than the length of // the line StyleRange newStyle = new StyleRange(lineOffset + inLineOffset, coloursAndText[1].length(), newColor, null); styles.add(newStyle); inLineOffset += coloursAndText[1].length(); } viewer.append(PluginConstants.NEW_LINE); } // Create a new style range StyleRange[] s = new StyleRange[styles.size()]; styles.toArray(s); int cnt = viewer.getCharCount(); // Using replaceStyleRanges with previousEnd, etc, effectively adds // the StyleRange to the existing set of Style Ranges (so we don't // waste time fudging with old style ranges that haven't changed) viewer.replaceStyleRanges(previousEnd, cnt - previousEnd, s); previousEnd = cnt; // Change focus and update viewer.setTopIndex(viewer.getLineCount() - 1); viewer.update(); } /** * Default print, just dumps text into the viewer. * @param text */ public void println(String text) { if (viewer != null && !viewer.isDisposed()) { viewer.append(text); viewer.setTopIndex(viewer.getLineCount() - 1); viewer.update(); } } public void clearAll() { if (viewer != null && !viewer.isDisposed()) { previousEnd = 0; viewer.setText(""); //$NON-NLS-1$ viewer.update(); } } /** * Testing convenience method to see what was printed * * @return viewer text */ public String getText() { return viewer.getText(); } @Override public IStatus initializeView(Display targetDisplay, IProgressMonitor monitor) { previousEnd = 0; viewer.setText(""); //$NON-NLS-1$ viewer.update(); return Status.OK_STATUS; } @Override public void createPartControl(Composite parent) { createViewer(parent); addKillButton(); addFileMenu(); addHelpMenu(); ViewFactory.addView(this); } @Override public void updateMethod() { if (getParser().getData() instanceof String) { String data = (String) getParser().getData(); if (!data.isEmpty()) { prettyPrintln((String) getParser().getData()); } } } @Override public void setViewID() { viewID = "org.eclipse.linuxtools.callgraph.core.staptextview"; //$NON-NLS-1$ } @Override protected boolean createOpenAction() { return false; } @Override protected boolean createOpenDefaultAction() { return false; } }