/** * Copyright (c) 2013-2016 Angelo ZERR. * 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: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation */ package tern.eclipse.ide.internal.ui.console; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleManager; import org.eclipse.ui.console.MessageConsole; import org.eclipse.ui.console.MessageConsoleStream; import tern.eclipse.ide.core.IIDETernProject; import tern.eclipse.ide.internal.ui.TernUIMessages; import tern.eclipse.ide.ui.ImageResource; import tern.eclipse.ide.ui.console.ITernConsole; import tern.eclipse.ide.ui.console.LineType; public class TernConsole extends MessageConsole implements ITernConsole { private static final String CONSOLE_KEY = TernConsole.class.getName(); private boolean showOnMessage; private IConsoleManager consoleManager; private final ConsoleDocument document; private boolean visible = false; private MessageConsoleStream[] streams = new MessageConsoleStream[LineType .values().length]; private boolean initialized; private final IIDETernProject project; public TernConsole(IIDETernProject project) { super(getName(project), ImageResource .getImageDescriptor(ImageResource.IMG_LOGO)); project.setData(CONSOLE_KEY, this); this.project = project; consoleManager = ConsolePlugin.getDefault().getConsoleManager(); document = new ConsoleDocument(); } private static String getName(IIDETernProject project) { return new StringBuilder("Tern [") .append(project.getProject().getName()).append("]").toString(); } protected void init() { // Called when console is added to the console view super.init(); // Ensure that initialization occurs in the ui thread Display.getDefault().asyncExec(new Runnable() { public void run() { initializeStreams(); dump(); } }); } private void initializeStreams() { synchronized (document) { if (!initialized) { for (int i = 0; i < streams.length; i++) { streams[i] = newMessageStream(); } // install colors for (int i = 0; i < LineType.values().length; i++) { initializeStream(LineType.values()[i]); } initialized = true; } } } private void initializeStream(LineType lineType) { Color color = createColor(Display.getDefault(), lineType); streams[lineType.ordinal()].setColor(color); } /** * Returns a color instance based on data from a preference field. */ private Color createColor(Display display, LineType lineType) { RGB rgb = getRGB(lineType); return new Color(display, rgb); } public RGB getRGB(LineType lineType) { switch (lineType) { case PROCESS_INFO: return new RGB(0, 108, 54); case PROCESS_ERROR: return new RGB(255, 0, 0); default: return new RGB(0, 64, 128); } } private void dump() { synchronized (document) { visible = true; ConsoleDocument.ConsoleLine[] lines = document.getLines(); for (int i = 0; i < lines.length; i++) { ConsoleDocument.ConsoleLine line = lines[i]; doAppendLine(line.getType(), line.getLine()); } document.clear(); } } @Override public void doAppendLine(final LineType lineType, final String line) { Job appendJob = new Job(TernUIMessages.TernConsoleJob_name) { @Override protected IStatus run(IProgressMonitor monitor) { internalDoAppendLine(lineType, line); return Status.OK_STATUS; } }; appendJob.setPriority(Job.LONG); appendJob.schedule(); } private void internalDoAppendLine(LineType lineType, String line) { showConsole(); synchronized (document) { if (visible) { streams[lineType.ordinal()].println(line); } else { document.appendConsoleLine(lineType, line); } } } private void showConsole() { show(false); } @Override protected void dispose() { // Here we can't call super.dispose() because we actually want the // partitioner to remain // connected, but we won't show lines until the console is added to the // console manager // again. // Called when console is removed from the console view synchronized (document) { visible = false; } } /** * Show the console. * * @param showNoMatterWhat * ignore preferences if <code>true</code> */ public void show(boolean showNoMatterWhat) { // showOnMessage = true; if (showNoMatterWhat || showOnMessage) { if (!visible) { TernConsoleHelper.showConsole(this); } else { consoleManager.showConsoleView(this); } } } /** * Used to notify this console of lifecycle methods <code>init()</code> and * <code>dispose()</code>. */ public class MyLifecycle implements org.eclipse.ui.console.IConsoleListener { public void consolesAdded(IConsole[] consoles) { for (int i = 0; i < consoles.length; i++) { IConsole console = consoles[i]; if (console == TernConsole.this) { init(); } } } public void consolesRemoved(IConsole[] consoles) { for (int i = 0; i < consoles.length; i++) { IConsole console = consoles[i]; if (console == TernConsole.this) { ConsolePlugin.getDefault().getConsoleManager() .removeConsoleListener(this); dispose(); } } } } public IIDETernProject getProject() { return project; } public static TernConsole getConsole(IIDETernProject project) { return project.getData(CONSOLE_KEY); } public static TernConsole getOrCreateConsole( IIDETernProject project) { TernConsole console = getConsole(project); if (console == null) { console = new TernConsole(project); } return console; } }