Added SCL Script Output console view. 75/1075/3
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 4 Oct 2017 13:09:02 +0000 (16:09 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Wed, 4 Oct 2017 19:59:02 +0000 (22:59 +0300)
refs #7528

Change-Id: I2a6230c39ca4f292866125911b2b5c74da6362ff

bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/SCLScripts.java
bundles/org.simantics.scl.ui/icons/application_xp.png [new file with mode: 0644]
bundles/org.simantics.scl.ui/plugin.xml
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/AbstractCommandConsole.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/ConsoleActions.java [new file with mode: 0644]
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/SCLConsole.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/SCLConsoleView.java
bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/SCLScriptConsoleView.java [new file with mode: 0644]

index 350a819fd94b9af2755c2fa28c36a33fef0ccc79..3cd006fce736d3282e1e94e2fae2a93e692f2f61 100644 (file)
@@ -39,7 +39,7 @@ public class SCLScripts {
 
        private static final Logger LOGGER = LoggerFactory.getLogger(SCLScripts.class);
 
-       private static final String SCL_CONSOLE_ID = "org.simantics.scl.ui.console";
+       private static final String SCL_SCRIPT_CONSOLE_ID = "org.simantics.scl.ui.scriptConsole";
 
        /**
         * @param processor database handle
@@ -78,16 +78,16 @@ public class SCLScripts {
 
        public static Pair<CommandSession, SCLReportingHandler> getSCLConsoleCommandSession(boolean createIfNecessary) {
                IWorkbenchPart part;
+               SCLReportingHandler handler = SCLReportingHandler.DEFAULT_WITHOUT_ECHO;
                try {
                        part = createIfNecessary
-                                       ? WorkbenchUtils.showView(SCL_CONSOLE_ID, IWorkbenchPage.VIEW_VISIBLE)
-                                       : WorkbenchUtils.findView(SCL_CONSOLE_ID);
+                                       ? WorkbenchUtils.showView(SCL_SCRIPT_CONSOLE_ID, IWorkbenchPage.VIEW_VISIBLE)
+                                       : WorkbenchUtils.findView(SCL_SCRIPT_CONSOLE_ID);
                        if (part != null)
-                               return Pair.make(part.getAdapter(CommandSession.class), part.getAdapter(SCLReportingHandler.class));
+                               return Pair.make(new CommandSession(SCLOsgi.MODULE_REPOSITORY, handler), part.getAdapter(SCLReportingHandler.class));
                } catch (PartInitException e) {
                        LOGGER.error("Failed to open SCL Console view. Using new CommandSession, reporting to stdout via Logger.", e);
                }
-               SCLReportingHandler handler = SCLReportingHandler.DEFAULT_WITHOUT_ECHO;
                return Pair.make(new CommandSession(SCLOsgi.MODULE_REPOSITORY, handler), SCLReportingHandler.DEFAULT);
        }
 
diff --git a/bundles/org.simantics.scl.ui/icons/application_xp.png b/bundles/org.simantics.scl.ui/icons/application_xp.png
new file mode 100644 (file)
index 0000000..d22860a
Binary files /dev/null and b/bundles/org.simantics.scl.ui/icons/application_xp.png differ
index ad9e3baf02c1cc2fbaa7019dfff9fe7dfcd2d063..be5735e6e3d826452477320389b9495626ec7538 100644 (file)
             id="org.simantics.scl.ui.editor2"
             name="SCL Module Editor">
       </editor>
-      <editor
-            class="org.simantics.scl.ui.script.SCLScriptEditor"
-            contributorClass="org.eclipse.ui.texteditor.BasicTextEditorActionContributor"
-            default="true"
-            extensions="scls"
-            filenames="*.scls"
-            id="org.simantics.scl.ui.script.editor"
-            name="SCL Script Editor">
-      </editor>
    </extension>
    <extension
          point="org.eclipse.core.filebuffers.documentSetup">
             name="SCL Console"
             restorable="true">
       </view>
+      <view
+            allowMultiple="true"
+            category="org.simantics.scl.ui.category"
+            class="org.simantics.scl.ui.console.SCLScriptConsoleView"
+            icon="icons/application_xp.png"
+            id="org.simantics.scl.ui.scriptConsole"
+            name="SCL Script Output"
+            restorable="true">
+      </view>
       <view
             allowMultiple="false"
             category="org.simantics.scl.ui.category"
index 8039d4662a0d67c6c55a4e93b9fabb55ed8585fb..a98d65715c7fa89a652ac6a0293667027bfda51a 100644 (file)
@@ -11,6 +11,7 @@ import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.preferences.InstanceScope;
 import org.eclipse.jface.preference.IPersistentPreferenceStore;
 import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.FontDescriptor;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.resource.LocalResourceManager;
 import org.eclipse.jface.window.DefaultToolTip;
@@ -18,9 +19,6 @@ import org.eclipse.jface.window.ToolTip;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyleRange;
 import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.custom.VerifyKeyListener;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.VerifyEvent;
 import org.eclipse.swt.events.VerifyListener;
 import org.eclipse.swt.graphics.Color;
@@ -33,11 +31,13 @@ import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
 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.Sash;
 import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.simantics.scl.runtime.tuple.Tuple2;
 
 /**
  * A console with input and output area that can be embedded
@@ -46,6 +46,11 @@ import org.eclipse.ui.preferences.ScopedPreferenceStore;
  */
 public abstract class AbstractCommandConsole extends Composite {
 
+    /**
+     * Use this option mask to hide and disable the console input field.
+     */
+    public static final int HIDE_INPUT = 1 << 0;
+
     public static final String PLUGIN_ID = "org.simantics.scl.ui";
 
     public static final int COMMAND_HISTORY_SIZE = 50;
@@ -53,7 +58,9 @@ public abstract class AbstractCommandConsole extends Composite {
     public static final int SASH_HEIGHT = 3;
     
     LocalResourceManager resourceManager;
-    
+
+    protected final int options;
+
     StyledText output;
     Sash sash;
     protected StyledText input;
@@ -63,7 +70,8 @@ public abstract class AbstractCommandConsole extends Composite {
     
     protected Color greenColor;
     protected Color redColor;
-    
+    protected Font textFont;
+
     ArrayList<String> commandHistory = new ArrayList<String>();
     int commandHistoryPos = 0;
     
@@ -73,29 +81,33 @@ public abstract class AbstractCommandConsole extends Composite {
     Shell tip = null;
     Label label = null;
     */
-    
-    public AbstractCommandConsole(Composite parent, int style) {
-        super(parent, style);      
+
+    public AbstractCommandConsole(Composite parent, int style, int options) {
+        super(parent, style);
+        this.options = options;
         createControl();
     }
-    
+
     @Override
     public boolean setFocus() {
-        return input.setFocus();
+        return input != null ? input.setFocus() : output.setFocus();
     }
-    
+
     protected boolean canExecuteCommand() {
         return true;
     }
 
+    private boolean hasOption(int mask) {
+        return (options & mask) != 0;
+    }
+
     private void createControl() {
         resourceManager = new LocalResourceManager(JFaceResources.getResources(), this);
         greenColor = resourceManager.createColor(new RGB(0, 128, 0));
         redColor = resourceManager.createColor(new RGB(172, 0, 0));
-        
+        textFont = resourceManager.createFont( FontDescriptor.createFrom("Courier New", 12, SWT.NONE) );
+
         setLayout(new FormLayout());
-        
-        Font textFont = new Font(getDisplay(),"Courier New",12,SWT.NONE);
 
         // Sash
         sash = new Sash(this, /*SWT.BORDER |*/ SWT.HORIZONTAL);
@@ -115,121 +127,111 @@ public abstract class AbstractCommandConsole extends Composite {
         // Upper
         output = new StyledText(this, SWT.MULTI /*| SWT.READ_ONLY*/ | SWT.V_SCROLL | SWT.H_SCROLL);
         output.setFont(textFont);
-        {
-            FormData formData = new FormData();
-            formData.top = new FormAttachment(0);      
-            formData.bottom = new FormAttachment(sash);
-            formData.left = new FormAttachment(0);
-            formData.right = new FormAttachment(100);
-            output.setLayoutData(formData);
-        }
+        output.setLayoutData( formData(0, sash, 0, 100) );
         output.addVerifyListener(new VerifyListener() {
             @Override
             public void verifyText(VerifyEvent e) {
                 if(outputModiLock)
                     return;
-                input.append(e.text);
-                input.setFocus();
-                input.setCaretOffset(input.getText().length());
+                if (input != null) {
+                    input.append(e.text);
+                    input.setFocus();
+                    input.setCaretOffset(input.getText().length());
+                }
                 e.doit = false;
             }
         });
 
-        // Deco
-        StyledText deco = new StyledText(this, SWT.MULTI | SWT.READ_ONLY);   
+        if (hasOption(HIDE_INPUT)) {
+            sash.setLayoutData( formData(new Tuple2(100, 0), null, 0, 100, 0) );
+            layout(true);
+        } else {
+            createInputArea();
+        }
+
+        readPreferences();
+
+        addListener(SWT.Dispose, event -> {
+            try {
+                writePreferences();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+
+    protected void createInputArea() {
+        // "> " Decoration
+        StyledText deco = new StyledText(this, SWT.MULTI | SWT.READ_ONLY);
         deco.setFont(textFont);
         deco.setEnabled(false);
         GC gc = new GC(deco);
         int inputLeftPos = gc.getFontMetrics().getAverageCharWidth()*2;
+        gc.dispose();
         deco.setText(">");
-        {
-            FormData formData = new FormData();
-            formData.top = new FormAttachment(sash);
-            formData.bottom = new FormAttachment(100);
-            formData.left = new FormAttachment(0);
-            formData.right = new FormAttachment(0, inputLeftPos);
-            deco.setLayoutData(formData);
-        }
-        
-        // Input area        
-        input = new StyledText(this, SWT.MULTI);        
+        deco.setLayoutData( formData(sash, 100, 0, new Tuple2(0, inputLeftPos)) );
+
+        // Input area
+        input = new StyledText(this, SWT.MULTI);
         input.setFont(textFont);
-        {
-            FormData formData = new FormData();
-            formData.top = new FormAttachment(sash);
-            formData.bottom = new FormAttachment(100);
-            formData.left = new FormAttachment(0, inputLeftPos);
-            formData.right = new FormAttachment(100);
-            input.setLayoutData(formData);
-        }
+        input.setLayoutData( formData(sash, 100, new Tuple2(0, inputLeftPos), 100) );
         adjustInputSize("");
-        input.addVerifyKeyListener(new VerifyKeyListener() {
-            
-            @Override
-            public void verifyKey(VerifyEvent event) {
-                switch(event.keyCode) {
-                case SWT.KEYPAD_CR:
-                case SWT.CR:
-                    if((event.stateMask & SWT.CTRL) == 0) {
-                        if(canExecuteCommand())
-                            execute();
-                        event.doit = false;
+        input.addVerifyKeyListener(event -> {
+            switch(event.keyCode) {
+            case SWT.KEYPAD_CR:
+            case SWT.CR:
+                if((event.stateMask & SWT.CTRL) == 0) {
+                    if(canExecuteCommand())
+                        execute();
+                    event.doit = false;
+                }
+                break;
+            case SWT.ARROW_UP:
+            case SWT.ARROW_DOWN: 
+                if((event.stateMask & SWT.CTRL) != 0) {
+                    int targetHistoryPos = commandHistoryPos;
+                    if(event.keyCode == SWT.ARROW_UP) {
+                        if(commandHistoryPos <= 0)
+                            return;
+                        --targetHistoryPos;
                     }
-                    break;
-                case SWT.ARROW_UP:
-                case SWT.ARROW_DOWN: 
-                    if((event.stateMask & SWT.CTRL) != 0) {
-                        int targetHistoryPos = commandHistoryPos;
-                        if(event.keyCode == SWT.ARROW_UP) {
-                            if(commandHistoryPos <= 0)
-                                return;
-                            --targetHistoryPos;
-                        }
-                        else {
-                            if(commandHistoryPos >= commandHistory.size()-1)
-                                return;
-                            ++targetHistoryPos;
-                        }
-                        setInputText(commandHistory.get(targetHistoryPos));
-                        commandHistoryPos = targetHistoryPos;
-                        event.doit = false;
+                    else {
+                        if(commandHistoryPos >= commandHistory.size()-1)
+                            return;
+                        ++targetHistoryPos;
                     }
-                    break;                
-//                case SWT.ESC:
-//                    setInputText("");
-//                    commandHistoryPos = commandHistory.size();
-//                    break;
-                }
-            }
-            
-        });        
-        input.addVerifyListener(new VerifyListener() {
-            @Override
-            public void verifyText(VerifyEvent e) {
-                if(e.text.contains("\n")) {
-                    int lineId = input.getLineAtOffset(e.start);
-                    int lineOffset = input.getOffsetAtLine(lineId);
-                    int indentAmount;
-                    for(indentAmount=0;
-                            lineOffset+indentAmount < input.getCharCount() && 
-                            input.getTextRange(lineOffset+indentAmount, 1).equals(" ");
-                            ++indentAmount);
-                    StringBuilder indent = new StringBuilder();
-                    indent.append('\n');
-                    for(int i=0;i<indentAmount;++i)
-                        indent.append(' ');
-                    e.text = e.text.replace("\n", indent);
+                    setInputText(commandHistory.get(targetHistoryPos));
+                    commandHistoryPos = targetHistoryPos;
+                    event.doit = false;
                 }
+                break;
+//            case SWT.ESC:
+//                setInputText("");
+//                commandHistoryPos = commandHistory.size();
+//                break;
             }
         });
-        input.addModifyListener(new ModifyListener() {
-            @Override
-            public void modifyText(ModifyEvent e) {
-                adjustInputSize(input.getText());
-                commandHistoryPos = commandHistory.size();
-                //asyncValidate();
+        input.addVerifyListener(e -> {
+            if(e.text.contains("\n")) {
+                int lineId = input.getLineAtOffset(e.start);
+                int lineOffset = input.getOffsetAtLine(lineId);
+                int indentAmount;
+                for(indentAmount=0;
+                        lineOffset+indentAmount < input.getCharCount() && 
+                        input.getTextRange(lineOffset+indentAmount, 1).equals(" ");
+                        ++indentAmount);
+                StringBuilder indent = new StringBuilder();
+                indent.append('\n');
+                for(int i=0;i<indentAmount;++i)
+                    indent.append(' ');
+                e.text = e.text.replace("\n", indent);
             }
         });
+        input.addModifyListener(e -> {
+            adjustInputSize(input.getText());
+            commandHistoryPos = commandHistory.size();
+            //asyncValidate();
+        });
         Listener hoverListener = new Listener() {
             
             DefaultToolTip toolTip = new DefaultToolTip(input, ToolTip.RECREATE, true);
@@ -285,30 +287,42 @@ public abstract class AbstractCommandConsole extends Composite {
                         toolTipVisible = false;
                     }
                     return;
-                }                
-            }            
+                }
+            }
         };
         input.addListener(SWT.MouseHover, hoverListener);
         input.addListener(SWT.MouseMove, hoverListener);
         input.addListener(SWT.MouseExit, hoverListener);
-        
-        readPreferences();
-        
-        addListener(SWT.Dispose, new Listener() {
-            
-            @Override
-            public void handleEvent(Event event) {
-                try {
-                    writePreferences();
-                } catch (IOException e) {
-                    e.printStackTrace();
-               }
-            }
-            
-        });
-        
     }
-    
+
+    private FormData formData(Object top, Object bottom, Object left, Object right) {
+        return formData(top, bottom, left, right, null);
+    }
+
+    private FormData formData(Object top, Object bottom, Object left, Object right, Integer height) {
+        FormData d = new FormData();
+        d.top = formAttachment(top);
+        d.bottom = formAttachment(bottom);
+        d.left = formAttachment(left);
+        d.right = formAttachment(right);
+        d.height = height != null ? (Integer) height : SWT.DEFAULT;
+        return d;
+    }
+
+    private FormAttachment formAttachment(Object o) {
+        if (o == null)
+            return null;
+        if (o instanceof Control)
+            return new FormAttachment((Control) o);
+        if (o instanceof Integer)
+            return new FormAttachment((Integer) o);
+        if (o instanceof Tuple2) {
+            Tuple2 t = (Tuple2) o;
+            return new FormAttachment((Integer) t.c0, (Integer) t.c1);
+        }
+        throw new IllegalArgumentException("argument not supported: " + o);
+    }
+
     private int getOffsetInInput(int x, int y) {
         int offset;
         try {
@@ -327,6 +341,8 @@ public abstract class AbstractCommandConsole extends Composite {
     }
     
     public void setInputText(String text) {
+        if (input == null)
+            return;
         input.setText(text);
         input.setCaretOffset(text.length());
         adjustInputSize(text);
@@ -345,20 +361,17 @@ public abstract class AbstractCommandConsole extends Composite {
         
     };
     
-    Job preValidationJob = new Job("SCL input validation") {        
+    Job preValidationJob = new Job("SCL input validation") {
         @Override
         protected IStatus run(IProgressMonitor monitor) {
             if(!input.isDisposed()) {
-                input.getDisplay().asyncExec(new Runnable() {
-                    @Override
-                    public void run() {
-                        if(!input.isDisposed()) {
-                            validatedText = input.getText();
-                            validationJob.setPriority(Job.BUILD);
-                            validationJob.schedule();
-                        }                     
-                    }                    
-                });                
+                input.getDisplay().asyncExec(() -> {
+                    if(!input.isDisposed()) {
+                        validatedText = input.getText();
+                        validationJob.setPriority(Job.BUILD);
+                        validationJob.schedule();
+                    }
+                });
             }
             
             return Status.OK_STATUS;
@@ -391,19 +404,14 @@ public abstract class AbstractCommandConsole extends Composite {
     }
     
     private void setInputHeight(int inputHeight) {
-        FormData formData = new FormData();
-        formData.top = new FormAttachment(100, -inputHeight);
-        formData.left = new FormAttachment(0);
-        formData.right = new FormAttachment(100);
-        formData.height = SASH_HEIGHT;
-        sash.setLayoutData(formData);
+        sash.setLayoutData( formData(new Tuple2(100, -inputHeight), null, 0, 100, SASH_HEIGHT) );
         AbstractCommandConsole.this.layout(true);
     }
 
     private StringBuilder outputBuffer = new StringBuilder();
     private ArrayList<StyleRange> styleRanges = new ArrayList<StyleRange>();
     private volatile boolean outputScheduled = false;
-    
+
     public void appendOutput(final String text, final Color foreground, final Color background) {
         synchronized (outputBuffer) {
             styleRanges.add(new StyleRange(outputBuffer.length(), text.length(), foreground, background));
@@ -413,40 +421,37 @@ public abstract class AbstractCommandConsole extends Composite {
             outputScheduled = true;
             final Display display = Display.getDefault();
             if(display.isDisposed()) return;
-            display.asyncExec(new Runnable() {
-                @Override
-                public void run() {
-                    if(output.isDisposed()) return;
-                    String outputText;
-                    StyleRange[] styleRangeArray;
-                    synchronized(outputBuffer) {
-                        outputScheduled = false;
-                        
-                        outputText = outputBuffer.toString();
-                        outputBuffer = new StringBuilder();
-                        
-                        styleRangeArray = styleRanges.toArray(new StyleRange[styleRanges.size()]);
-                        styleRanges.clear();
-                    }
-                    int pos = output.getCharCount();
+            display.asyncExec(() -> {
+                if(output.isDisposed()) return;
+                String outputText;
+                StyleRange[] styleRangeArray;
+                synchronized(outputBuffer) {
+                    outputScheduled = false;
 
-                    outputModiLock = true;
-                    output.replaceTextRange(pos, 0, outputText);
-                    outputModiLock = false;
-                    
-                    for(StyleRange styleRange : styleRangeArray) {
-                        styleRange.start += pos;
-                        output.setStyleRange(styleRange);
-                    }
+                    outputText = outputBuffer.toString();
+                    outputBuffer = new StringBuilder();
+
+                    styleRangeArray = styleRanges.toArray(new StyleRange[styleRanges.size()]);
+                    styleRanges.clear();
+                }
+                int pos = output.getCharCount();
 
-                    output.setCaretOffset(output.getCharCount());
-                    output.showSelection();
+                outputModiLock = true;
+                output.replaceTextRange(pos, 0, outputText);
+                outputModiLock = false;
+
+                for(StyleRange styleRange : styleRangeArray) {
+                    styleRange.start += pos;
+                    output.setStyleRange(styleRange);
                 }
+
+                output.setCaretOffset(output.getCharCount());
+                output.showSelection();
             });
         }
     }
-    
-    private void execute() {        
+
+    private void execute() {
         String command = input.getText().trim();
         if(command.isEmpty())
             return;
@@ -514,7 +519,7 @@ public abstract class AbstractCommandConsole extends Composite {
                 if(input.isDisposed())
                     return;
                 if(!input.getText().equals(forCommand))
-                    return;                
+                    return;
                 syncSetErrorAnnotations(forCommand, annotations);
             }
         });
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/ConsoleActions.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/ConsoleActions.java
new file mode 100644 (file)
index 0000000..744b83c
--- /dev/null
@@ -0,0 +1,41 @@
+package org.simantics.scl.ui.console;
+
+import org.eclipse.jface.action.Action;
+import org.simantics.scl.ui.Activator;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+class ConsoleActions {
+
+    public static Action createInterruptAction(SCLConsole console) {
+        Action interruptAction = new Action("Interrupt current command",
+                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop.png")) {
+            @Override
+            public void run() {
+                console.interruptCurrentCommands();
+            }
+        };
+        interruptAction.setDisabledImageDescriptor(
+                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop_disabled.png"));
+        interruptAction.setEnabled(false);
+        return interruptAction;
+    }
+
+    public static Action createClearAction(SCLConsole console) {
+        Action clearAction = new Action("Clear console",
+                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console.png")) {
+            @Override
+            public void run() {
+                setEnabled(false);
+                console.clear();
+            }
+        };
+        clearAction.setDisabledImageDescriptor(
+                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console_disabled.png"));
+        clearAction.setEnabled(false);
+        return clearAction;
+    }
+
+}
index 16a946fbebb86922ee99bd9ad481b5e547d37fd1..dcb56cc3a72d7d29354efd6544fc11af7ff8dcd0 100644 (file)
@@ -58,13 +58,23 @@ public class SCLConsole extends AbstractCommandConsole {
 
     CommandSession session = new CommandSession(SCLOsgi.MODULE_REPOSITORY, handler);
     ContentProposalAdapter contentProposalAdapter;
-    
+
     public SCLConsole(Composite parent, int style) {
-        super(parent, style);
-        
+        this(parent, style, 0);
+    }
+
+    public SCLConsole(Composite parent, int style, int options) {
+        super(parent, style, options);
+        createContentProposalAdapter();
+        addContributedListeners();
+    }
+
+    protected void createContentProposalAdapter() {
+        if (input == null)
+            return;
+
         StyledTextContentAdapter styledTextContentAdapter = new StyledTextContentAdapter();
         SCLContentProposalProvider contentProvider = new SCLContentProposalProvider(session);
-        
         try {
             contentProposalAdapter = new ContentProposalAdapter(
                     input, 
@@ -76,15 +86,13 @@ public class SCLConsole extends AbstractCommandConsole {
         } catch (ParseException e) {
             // No content assist then.
         }
-        
-        addContributedListeners();
     }
 
     @Override
     protected boolean canExecuteCommand() {
-        return !contentProposalAdapter.isProposalPopupOpen();
+        return contentProposalAdapter == null || !contentProposalAdapter.isProposalPopupOpen();
     }
-    
+
     @Override
     public ErrorAnnotation[] validate(String command) {
         if(command.isEmpty())
@@ -216,7 +224,7 @@ public class SCLConsole extends AbstractCommandConsole {
         consoleIsEmpty = true;
     }
 
-    private void addContributedListeners() {
+    protected void addContributedListeners() {
         final BundleContext context = Activator.getInstance().getBundle().getBundleContext();
         new ServiceTracker<SCLConsoleListener, SCLConsoleListener>(context,
                 SCLConsoleListener.class, null) {
index 8b49ea345fac656a70b4027959b297f7c4cfa889..4c0d829f350580386299bef6ac222bcc1cdbeb71 100644 (file)
@@ -182,31 +182,13 @@ public class SCLConsoleView extends ViewPart {
         IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
         
         // Interrupt action
-        final Action interruptAction = new Action("Interrupt current command",
-                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop.png")) {
-            @Override
-            public void run() {
-                console.interruptCurrentCommands();
-            }
-        };
-        interruptAction.setDisabledImageDescriptor(
-                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop_disabled.png"));
-        interruptAction.setEnabled(false);
+        Action interruptAction = ConsoleActions.createInterruptAction(console);
         toolBarManager.add(interruptAction);
         
         // Clear console action
-        final Action clearAction = new Action("Clear console",
-                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console.png")) {
-            @Override
-            public void run() {
-                setEnabled(false);
-                console.clear();
-            }
-        };
-        clearAction.setDisabledImageDescriptor(
-                Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console_disabled.png"));
-        clearAction.setEnabled(false);
+        Action clearAction = ConsoleActions.createClearAction(console);
         toolBarManager.add(clearAction);
+        
         console.addListener(new SCLConsoleListener() {
             @Override
             public void startedExecution() {
diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/SCLScriptConsoleView.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/console/SCLScriptConsoleView.java
new file mode 100644 (file)
index 0000000..8df0caa
--- /dev/null
@@ -0,0 +1,76 @@
+package org.simantics.scl.ui.console;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.part.ViewPart;
+import org.simantics.scl.compiler.commands.SCLConsoleListener;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.31.0
+ */
+public class SCLScriptConsoleView extends ViewPart {
+
+    static class SCLOutputConsole extends SCLConsole {
+        public SCLOutputConsole(Composite parent, int style) {
+            super(parent, style, AbstractCommandConsole.HIDE_INPUT);
+        }
+
+        @Override
+        protected void addContributedListeners() {
+        }
+    }
+
+    SCLOutputConsole console;
+
+    @Override
+    public void createPartControl(Composite parent) {
+        this.console = new SCLOutputConsole(parent, SWT.NONE);
+
+        IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
+        Action interruptAction = ConsoleActions.createInterruptAction(console);
+        Action clearAction = ConsoleActions.createClearAction(console);
+        toolBarManager.add(interruptAction);
+        toolBarManager.add(clearAction);
+
+        console.addListener(new SCLConsoleListener() {
+            @Override
+            public void startedExecution() {
+                interruptAction.setEnabled(true);
+            }
+            @Override
+            public void finishedExecution() {
+                interruptAction.setEnabled(false);
+            }
+            @Override
+            public void consoleIsNotEmptyAnymore() {
+                clearAction.setEnabled(true);
+            }
+        });
+
+        toolBarManager.update(true);
+    }
+
+    @Override
+    public void setFocus() {
+        console.setFocus();
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+        console.dispose();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T getAdapter(Class<T> adapter) {
+        if (adapter == SCLReportingHandler.class)
+            return (T) console.getHandler();
+        return super.getAdapter(adapter);
+    }
+
+}