1 package org.simantics.scl.ui.console;
\r
3 import java.nio.file.Files;
\r
4 import java.nio.file.Path;
\r
5 import java.nio.file.Paths;
\r
6 import java.util.ArrayList;
\r
7 import java.util.Arrays;
\r
8 import java.util.List;
\r
10 import org.eclipse.core.runtime.Platform;
\r
11 import org.eclipse.core.runtime.preferences.InstanceScope;
\r
12 import org.eclipse.jface.action.Action;
\r
13 import org.eclipse.jface.action.IToolBarManager;
\r
14 import org.eclipse.jface.dialogs.Dialog;
\r
15 import org.eclipse.jface.preference.IPersistentPreferenceStore;
\r
16 import org.eclipse.swt.SWT;
\r
17 import org.eclipse.swt.dnd.DND;
\r
18 import org.eclipse.swt.dnd.DropTarget;
\r
19 import org.eclipse.swt.dnd.DropTargetAdapter;
\r
20 import org.eclipse.swt.dnd.DropTargetEvent;
\r
21 import org.eclipse.swt.dnd.FileTransfer;
\r
22 import org.eclipse.swt.dnd.Transfer;
\r
23 import org.eclipse.swt.widgets.Composite;
\r
24 import org.eclipse.ui.part.ViewPart;
\r
25 import org.eclipse.ui.preferences.ScopedPreferenceStore;
\r
26 import org.simantics.scl.compiler.commands.CommandSessionImportEntry;
\r
27 import org.simantics.scl.compiler.commands.SCLConsoleListener;
\r
28 import org.simantics.scl.compiler.testing.TestRunnable;
\r
29 import org.simantics.scl.osgi.internal.TestUtils;
\r
30 import org.simantics.scl.ui.Activator;
\r
31 import org.simantics.scl.ui.imports.internal.ManageImportsDialog;
\r
32 import org.simantics.scl.ui.tests.SCLTestsDialog;
\r
34 public class SCLConsoleView extends ViewPart {
\r
36 public static final String PLUGIN_ID = "org.simantics.scl.ui";
\r
37 public static final String IMPORTS = "imports";
\r
38 public static final String SEPARATOR = ";";
\r
39 public static final String DISABLED_TAG = "[DISABLED]";
\r
43 private ArrayList<CommandSessionImportEntry> readImportPreferences() {
\r
44 IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_ID);
\r
45 String importsString = store.getString(IMPORTS);
\r
47 String[] splitted = importsString.split(SEPARATOR);
\r
48 ArrayList<CommandSessionImportEntry> result = new ArrayList<CommandSessionImportEntry>(splitted.length);
\r
49 for(String entryString : splitted) {
\r
50 if(entryString.isEmpty())
\r
52 boolean disabled = false;
\r
53 if(entryString.startsWith(DISABLED_TAG)) {
\r
55 entryString = entryString.substring(DISABLED_TAG.length());
\r
57 String[] parts = entryString.split("=");
\r
58 CommandSessionImportEntry entry;
\r
59 if(parts.length == 1)
\r
60 entry = new CommandSessionImportEntry(parts[0], "", true);
\r
62 entry = new CommandSessionImportEntry(parts[1], parts[0], true);
\r
63 entry.disabled = disabled;
\r
69 private void writeImportPreferences(ArrayList<CommandSessionImportEntry> entries) {
\r
70 StringBuilder b = new StringBuilder();
\r
72 boolean first = true;
\r
73 for(CommandSessionImportEntry entry : entries)
\r
74 if(entry.persistent) {
\r
78 b.append(SEPARATOR);
\r
80 b.append(DISABLED_TAG);
\r
81 if(!entry.localName.isEmpty()) {
\r
82 b.append(entry.localName);
\r
85 b.append(entry.moduleName);
\r
88 IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, PLUGIN_ID);
\r
89 store.putValue(IMPORTS, b.toString());
\r
92 private ArrayList<CommandSessionImportEntry> getCurrentImports() {
\r
93 return console.getSession().getImportEntries();
\r
96 private void setCurrentImports(ArrayList<CommandSessionImportEntry> entries) {
\r
97 console.getSession().setImportEntries(entries);
\r
100 private void manageImports() {
\r
101 ManageImportsDialog dialog = new ManageImportsDialog(
\r
102 getSite().getShell(),
\r
103 getCurrentImports());
\r
104 if(dialog.open() == Dialog.OK) {
\r
105 writeImportPreferences(dialog.getImports());
\r
106 setCurrentImports(dialog.getImports());
\r
110 private void sclTestDialog() {
\r
111 List<TestRunnable> tests = TestUtils.getTests();
\r
112 SCLTestsDialog dialog = new SCLTestsDialog(
\r
113 getSite().getShell(),
\r
115 if(dialog.open() == Dialog.OK) {
\r
116 for(Object result : dialog.getResult()) {
\r
117 TestRunnable test = (TestRunnable) result;
\r
119 // Bit of a haxx solution to get around a deadlock caused by simply
\r
120 // running the test with test.run()
\r
121 console.execute("import \"Commands/Tests\"");
\r
122 console.execute("runByName \"" + test.getName() + "\"");
\r
124 } catch (Exception e) {
\r
125 e.printStackTrace();
\r
132 public void createPartControl(Composite parent) {
\r
133 this.console = new SCLConsole(parent, SWT.NONE);
\r
134 setCurrentImports(readImportPreferences());
\r
136 addScriptDropSupport(console);
\r
138 IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
\r
140 // Interrupt action
\r
141 final Action interruptAction = new Action("Interrupt current command",
\r
142 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop.png")) {
\r
144 public void run() {
\r
145 console.interruptCurrentCommands();
\r
148 interruptAction.setDisabledImageDescriptor(
\r
149 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/stop_disabled.png"));
\r
150 interruptAction.setEnabled(false);
\r
151 toolBarManager.add(interruptAction);
\r
153 // Clear console action
\r
154 final Action clearAction = new Action("Clear console",
\r
155 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console.png")) {
\r
157 public void run() {
\r
162 clearAction.setDisabledImageDescriptor(
\r
163 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/clear_console_disabled.png"));
\r
164 clearAction.setEnabled(false);
\r
165 toolBarManager.add(clearAction);
\r
166 console.addListener(new SCLConsoleListener() {
\r
168 public void startedExecution() {
\r
169 interruptAction.setEnabled(true);
\r
172 public void finishedExecution() {
\r
173 interruptAction.setEnabled(false);
\r
176 public void consoleIsNotEmptyAnymore() {
\r
177 clearAction.setEnabled(true);
\r
182 toolBarManager.add(new Action("Refresh modules",
\r
183 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/arrow_refresh.png")) {
\r
185 public void run() {
\r
186 console.getSession().getModuleRepository().getSourceRepository().checkUpdates();
\r
187 console.getSession().updateRuntimeEnvironment(true);
\r
188 console.appendOutput("refresh completed\n", console.greenColor, null);
\r
191 toolBarManager.add(new Action("Manage imports",
\r
192 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/configure_imports.png")) {
\r
194 public void run() {
\r
199 // Show action for running SCL tests if in development mode
\r
200 if (Platform.inDevelopmentMode()) {
\r
201 toolBarManager.add(new Action("Run tests",
\r
202 Activator.imageDescriptorFromPlugin("org.simantics.scl.ui", "icons/run_tests.png")) {
\r
204 public void run() {
\r
210 toolBarManager.update(true);
\r
213 private class ScriptRunningDropTarget extends DropTargetAdapter {
\r
214 public void drop(DropTargetEvent event) {
\r
215 if (FileTransfer.getInstance().isSupportedType(event.currentDataType)) {
\r
216 String[] files = ((String[]) event.data).clone();
\r
217 // Sort files by name to allow deterministic multi-file drop
\r
218 Arrays.sort(files);
\r
219 for (String file : files) {
\r
220 Path p = Paths.get(file).toAbsolutePath();
\r
221 if (isScriptFile(p)) {
\r
222 console.execute("runFromFile \"" + p.toString().replace('\\', '/') + "\"");
\r
228 private boolean isScriptFile(Path p) {
\r
229 return Files.isRegularFile(p)
\r
230 //&& p.toString().toLowerCase().endsWith(".scl")
\r
235 private void addScriptDropSupport(SCLConsole console) {
\r
236 DropTarget target = new DropTarget(console.getOutputWidget(), DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);
\r
237 target.setTransfer(new Transfer[] { FileTransfer.getInstance() });
\r
238 target.addDropListener(new ScriptRunningDropTarget());
\r
242 public void setFocus() {
\r
243 console.setFocus();
\r
247 public void dispose() {
\r