/******************************************************************************* * Copyright (c) 2019 Association for Decentralized Information Management * in Industry THTH ry. * 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: * Semantum Oy - initial API and implementation *******************************************************************************/ package org.simantics.platform.ui; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.MessageConsole; import org.eclipse.ui.console.MessageConsoleStream; public class SimanticsConsole extends MessageConsole { // We don't want to constantly lose data, but this is still only half MB private static int HIGH_WATERMARK = 2<<18; // 75% private static int LOW_WATERMARK = 3 * (HIGH_WATERMARK>>2); private ExecutorService executor = Executors.newSingleThreadExecutor(); private Color black; private Color red; private Color green; private Color yellow; private Color blue; private Color magenta; private Color cyan; private Color white; private MessageConsoleStream stream; public SimanticsConsole() { super("Simantics Console", "Simantics Console", null, true); } @Override protected void init() { Display d = Display.getDefault(); black = tuneColor(d, SWT.COLOR_BLACK); red = tuneColor(d, SWT.COLOR_RED); green = tuneColor(d, SWT.COLOR_GREEN); yellow = tuneColor(d, SWT.COLOR_YELLOW); blue = tuneColor(d, SWT.COLOR_BLUE); magenta = tuneColor(d, SWT.COLOR_MAGENTA); cyan = tuneColor(d, SWT.COLOR_CYAN); white = tuneColor(d, SWT.COLOR_WHITE); setBackground(black); stream = newMessageStream(); stream.setFontStyle(SWT.NORMAL); stream.setColor(white); setWaterMarks(LOW_WATERMARK, HIGH_WATERMARK); } @Override protected void dispose() { super.dispose(); executor.shutdown(); try { stream.close(); } catch (IOException e) { // nothing to do } black.dispose(); red.dispose(); green.dispose(); green.dispose(); yellow.dispose(); blue.dispose(); magenta.dispose(); cyan.dispose(); white.dispose(); } private Color tuneColor(Display d, int color) { Color c = d.getSystemColor(color); return new Color(d, (int)(c.getRed() * 0.75), (int)(c.getGreen() * 0.75), (int)(c.getBlue() * 0.75)); } public static SimanticsConsole show() { if(!Thread.currentThread().equals(Display.getDefault().getThread())) { Display.getDefault().asyncExec(() -> show()); return null; } for (IConsole c : ConsolePlugin.getDefault().getConsoleManager().getConsoles()) { if (c instanceof SimanticsConsole) { SimanticsConsole sc = (SimanticsConsole) c; sc.activate(); return sc; } } SimanticsConsole sc = new SimanticsConsole(); ConsolePlugin.getDefault().getConsoleManager().addConsoles(new SimanticsConsole[] {sc}); sc.activate(); return sc; } public static SimanticsConsole findConsole() { for (IConsole c : ConsolePlugin.getDefault().getConsoleManager().getConsoles()) { if (c instanceof SimanticsConsole) { return (SimanticsConsole) c; } } SimanticsConsole sc = new SimanticsConsole(); ConsolePlugin.getDefault().getConsoleManager().addConsoles(new SimanticsConsole[] {sc}); return sc; } public void write(String data) { executor.submit(() -> { Pattern p = Pattern.compile("(\\x1b\\[(?.*?(m)))"); Matcher m = p.matcher(data); int pos = 0; while (m.find()) { if (m.start() > pos) { stream.print(data.substring(pos, m.start())); } pos = m.end(); String cmd = m.group("cmd"); if (cmd.endsWith("m")) { // Stream style can be set only in UI thread Display.getDefault().syncExec(() -> { int fontStyle = stream.getFontStyle(); Color color = stream.getColor(); try { stream.close(); } catch (IOException e) { // nothing to do } stream = newMessageStream(); String attributes[] = cmd.substring(0, cmd.length() - 1).split(";"); for (String attribute : attributes) { switch (Integer.parseInt(attribute)) { case 0: fontStyle = SWT.NORMAL; break; case 1: fontStyle = SWT.BOLD; break; case 4: break; // underline case 5: break; // blink case 7: break; // reverse video case 8: break; // nondisplayed case 30: color = black; break; case 31: color = red; break; case 32: color = green; break; case 33: color = yellow; break; case 34: color = blue; break; case 35: color = magenta; break; case 36: color = cyan; break; case 37: color = white; break; // background colors not supported default:break; } } stream.setColor(color); stream.setFontStyle(fontStyle); }); } } if (pos < data.length()) { stream.print(data.substring(pos)); } stream.println(); }); } }