--- /dev/null
+package org.simantics.scl.ui.console;\r
+\r
+import java.nio.file.Files;\r
+import java.nio.file.Path;\r
+import java.nio.file.Paths;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.eclipse.jface.action.Action;\r
+import org.eclipse.jface.action.IToolBarManager;\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.preference.IPersistentPreferenceStore;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.dnd.DND;\r
+import org.eclipse.swt.dnd.DropTarget;\r
+import org.eclipse.swt.dnd.DropTargetAdapter;\r
+import org.eclipse.swt.dnd.DropTargetEvent;\r
+import org.eclipse.swt.dnd.FileTransfer;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
+import org.simantics.scl.compiler.commands.CommandSessionImportEntry;\r
+import org.simantics.scl.compiler.commands.SCLConsoleListener;\r
+import org.simantics.scl.compiler.testing.TestRunnable;\r
+import org.simantics.scl.osgi.internal.TestUtils;\r
+import org.simantics.scl.ui.Activator;\r
+import org.simantics.scl.ui.imports.internal.ManageImportsDialog;\r
+import org.simantics.scl.ui.tests.SCLTestsDialog;\r
+\r
+public class SCLConsoleView extends ViewPart {\r
+\r
+ public static final String PLUGIN_ID = "org.simantics.scl.ui";\r
+ public static final String IMPORTS = "imports";\r
+ public static final String SEPARATOR = ";";\r
+ public static final String DISABLED_TAG = "[DISABLED]";\r
+ \r
+ SCLConsole console;\r
+ \r
+ private ArrayList<CommandSessionImportEntry> readImportPreferences() {\r
+ IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_ID);\r
+ String importsString = store.getString(IMPORTS);\r
+ \r
+ String[] splitted = importsString.split(SEPARATOR);\r
+ ArrayList<CommandSessionImportEntry> result = new ArrayList<CommandSessionImportEntry>(splitted.length);\r
+ for(String entryString : splitted) {\r
+ if(entryString.isEmpty())\r
+ continue;\r
+ boolean disabled = false;\r
+ if(entryString.startsWith(DISABLED_TAG)) {\r
+ disabled = true;\r
+ entryString = entryString.substring(DISABLED_TAG.length());\r
+ }\r
+ String[] parts = entryString.split("=");\r
+ CommandSessionImportEntry entry;\r
+ if(parts.length == 1)\r
+ entry = new CommandSessionImportEntry(parts[0], "", true);\r
+ else\r
+ entry = new CommandSessionImportEntry(parts[1], parts[0], true);\r
+ entry.disabled = disabled;\r
+ result.add(entry);\r
+ }\r
+ return result;\r
+ }\r
+ \r
+ private void writeImportPreferences(ArrayList<CommandSessionImportEntry> entries) {\r
+ StringBuilder b = new StringBuilder();\r
+ \r
+ boolean first = true;\r
+ for(CommandSessionImportEntry entry : entries)\r
+ if(entry.persistent) {\r
+ if(first)\r
+ first = false;\r
+ else\r
+ b.append(SEPARATOR);\r
+ if(entry.disabled)\r
+ b.append(DISABLED_TAG);\r
+ if(!entry.localName.isEmpty()) {\r
+ b.append(entry.localName);\r
+ b.append("=");\r
+ }\r
+ b.append(entry.moduleName);\r
+ }\r
+ \r
+ IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_ID);\r
+ store.putValue(IMPORTS, b.toString());\r
+ }\r
+ \r
+ private ArrayList<CommandSessionImportEntry> getCurrentImports() {\r
+ return console.getSession().getImportEntries();\r
+ }\r
+ \r
+ private void setCurrentImports(ArrayList<CommandSessionImportEntry> entries) {\r
+ console.getSession().setImportEntries(entries);\r
+ }\r
+ \r
+ private void manageImports() {\r
+ ManageImportsDialog dialog = new ManageImportsDialog(\r
+ getSite().getShell(),\r
+ getCurrentImports());\r
+ if(dialog.open() == Dialog.OK) {\r
+ writeImportPreferences(dialog.getImports());\r
+ setCurrentImports(dialog.getImports());\r
+ }\r
+ }\r
+ \r
+ private void sclTestDialog() {\r
+ List<TestRunnable> tests = TestUtils.getTests();\r
+ SCLTestsDialog dialog = new SCLTestsDialog(\r
+ getSite().getShell(),\r
+ tests, true);\r
+ if(dialog.open() == Dialog.OK) {\r
+ for(Object result : dialog.getResult()) {\r
+ TestRunnable test = (TestRunnable) result;\r
+ try {\r
+ // Bit of a haxx solution to get around a deadlock caused by simply\r
+ // running the test with test.run()\r
+ console.execute("import \"Commands/Tests\"");\r
+ console.execute("runByName \"" + test.getName() + "\"");\r
+// test.run();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void createPartControl(Composite parent) {\r
+ this.console = new SCLConsole(parent, SWT.NONE);\r
+ setCurrentImports(readImportPreferences());\r
+\r
+ addScriptDropSupport(console);\r
+\r
+ IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();\r
+ \r
+ // Interrupt action\r
+ final Action interruptAction = new Action("Interrupt current command",\r
+ Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop.png")) {\r
+ @Override\r
+ public void run() {\r
+ console.interruptCurrentCommands();\r
+ }\r
+ };\r
+ interruptAction.setDisabledImageDescriptor(\r
+ Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop_disabled.png"));\r
+ interruptAction.setEnabled(false);\r
+ toolBarManager.add(interruptAction);\r
+ \r
+ // Clear console action\r
+ final Action clearAction = new Action("Clear console",\r
+ Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console.png")) {\r
+ @Override\r
+ public void run() {\r
+ setEnabled(false);\r
+ console.clear();\r
+ }\r
+ };\r
+ clearAction.setDisabledImageDescriptor(\r
+ Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console_disabled.png"));\r
+ clearAction.setEnabled(false);\r
+ toolBarManager.add(clearAction);\r
+ console.addListener(new SCLConsoleListener() {\r
+ @Override\r
+ public void startedExecution() {\r
+ interruptAction.setEnabled(true);\r
+ }\r
+ @Override\r
+ public void finishedExecution() {\r
+ interruptAction.setEnabled(false);\r
+ }\r
+ @Override\r
+ public void consoleIsNotEmptyAnymore() {\r
+ clearAction.setEnabled(true);\r
+ }\r
+ });\r
+ \r
+ // Refresh action\r
+ toolBarManager.add(new Action("Refresh modules",\r
+ Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/arrow_refresh.png")) {\r
+ @Override\r
+ public void run() {\r
+ console.getSession().getModuleRepository().getSourceRepository().checkUpdates();\r
+ console.getSession().updateRuntimeEnvironment(true);\r
+ console.appendOutput("refresh completed\n", console.greenColor, null);\r
+ }\r
+ });\r
+ toolBarManager.add(new Action("Manage imports",\r
+ Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/configure_imports.png")) {\r
+ @Override\r
+ public void run() {\r
+ manageImports();\r
+ }\r
+ });\r
+ \r
+ // Show action for running SCL tests if in development mode\r
+ if (Platform.inDevelopmentMode()) {\r
+ toolBarManager.add(new Action("Run tests",\r
+ Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/run_tests.png")) {\r
+ @Override\r
+ public void run() {\r
+ sclTestDialog();\r
+ }\r
+ });\r
+ }\r
+ \r
+ toolBarManager.update(true);\r
+ }\r
+\r
+ private class ScriptRunningDropTarget extends DropTargetAdapter {\r
+ public void drop(DropTargetEvent event) {\r
+ if (FileTransfer.getInstance().isSupportedType(event.currentDataType)) {\r
+ String[] files = ((String[]) event.data).clone();\r
+ // Sort files by name to allow deterministic multi-file drop\r
+ Arrays.sort(files);\r
+ for (String file : files) {\r
+ Path p = Paths.get(file).toAbsolutePath();\r
+ if (isScriptFile(p)) {\r
+ console.execute("runFromFile \"" + p.toString().replace('\\', '/') + "\"");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ private boolean isScriptFile(Path p) {\r
+ return Files.isRegularFile(p)\r
+ //&& p.toString().toLowerCase().endsWith(".scl")\r
+ ;\r
+ }\r
+ }\r
+\r
+ private void addScriptDropSupport(SCLConsole console) {\r
+ DropTarget target = new DropTarget(console.getOutputWidget(), DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);\r
+ target.setTransfer(new Transfer[] { FileTransfer.getInstance() });\r
+ target.addDropListener(new ScriptRunningDropTarget());\r
+ }\r
+\r
+ @Override\r
+ public void setFocus() {\r
+ console.setFocus();\r
+ }\r
+ \r
+ @Override\r
+ public void dispose() {\r
+ super.dispose();\r
+ console.dispose();\r
+ }\r
+\r
+}\r