+/*******************************************************************************
+ * 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});
+ 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\\[(?<cmd>.*?(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();
+ });
+ }
+}
\ No newline at end of file