]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/SCLEditorBase.java
b080c0b1c7607d4c2aff1f6c6c9ae97f2bc05046
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / componentTypeEditor / SCLEditorBase.java
1 package org.simantics.modeling.ui.componentTypeEditor;
2
3 import org.eclipse.core.runtime.IExecutableExtension;
4 import org.eclipse.core.runtime.IProgressMonitor;
5 import org.eclipse.jface.text.ITextListener;
6 import org.eclipse.jface.text.TextEvent;
7 import org.eclipse.swt.widgets.Composite;
8 import org.eclipse.ui.IEditorInput;
9 import org.eclipse.ui.IEditorSite;
10 import org.eclipse.ui.PartInitException;
11 import org.eclipse.ui.part.EditorPart;
12 import org.simantics.Simantics;
13 import org.simantics.databoard.Bindings;
14 import org.simantics.db.ReadGraph;
15 import org.simantics.db.Resource;
16 import org.simantics.db.WriteGraph;
17 import org.simantics.db.common.request.ResourceRead;
18 import org.simantics.db.common.request.UniqueRead;
19 import org.simantics.db.common.request.WriteRequest;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.db.layer0.util.Layer0Utils;
22 import org.simantics.db.procedure.Listener;
23 import org.simantics.layer0.Layer0;
24 import org.simantics.scl.compiler.errors.CompilationError;
25 import org.simantics.scl.ui.editor.SCLTextEditorNew;
26 import org.simantics.scl.ui.editor.TextAndErrors;
27 import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest;
28 import org.simantics.structural2.scl.procedural.ProceduralComponentTypeCompilationException;
29 import org.simantics.ui.workbench.IResourceEditorInput;
30 import org.simantics.ui.workbench.TitleUpdater;
31 import org.simantics.utils.ui.ErrorLogger;
32 import org.simantics.utils.ui.SWTUtils;
33
34 public class SCLEditorBase extends EditorPart implements IExecutableExtension {
35     Resource inputResource;
36     SCLTextEditorNew editor;
37     String originalText;
38
39     protected TextAndErrors getTextAndErrors(ReadGraph graph, Resource resource) throws DatabaseException {
40         Layer0 L0 = Layer0.getInstance(graph);
41         String text = graph.getValue(resource, Bindings.STRING);
42         Resource componentType = graph.getPossibleObject(inputResource, L0.PropertyOf);
43         CompilationError[] errors = CompilationError.EMPTY_ARRAY;
44         if(componentType != null) {
45             try { 
46                 graph.syncRequest(new CompileProceduralComponentTypeRequest(componentType));
47             } catch(ProceduralComponentTypeCompilationException e) {
48                 errors = e.errors;
49             }
50         }
51         return new TextAndErrors(text, errors);
52     }
53     
54     @Override
55     public void createPartControl(Composite parent) {
56         editor = new SCLTextEditorNew(parent, 0);
57         
58         Simantics.getSession().asyncRequest(new ResourceRead<TextAndErrors>(inputResource) {
59             @Override
60             public TextAndErrors perform(ReadGraph graph) throws DatabaseException {
61                 return getTextAndErrors(graph, inputResource);
62             }
63         }, new Listener<TextAndErrors>() {
64             @Override
65             public void execute(final TextAndErrors textAndErrors) {
66                 SWTUtils.asyncExec(editor, new Runnable() {
67                     @Override
68                     public void run() {
69                         
70                         if (editor.isDisposed())
71                             return;
72                         
73                         // FIXME Every graph change new overrides user's current modifications  
74                         
75                         originalText = textAndErrors.text;
76                         boolean textDiffers = !originalText.equals(editor.getContent());
77                         editor.setContent(textDiffers ? originalText : null, textAndErrors.errors);
78                         firePropertyChange(PROP_DIRTY);
79                         
80                         // This condition is only true for the first time when the editor is initialized
81                         // This fixes platform issue #5192 https://www.simantics.org/redmine/issues/5192
82                         if (textDiffers)
83                             editor.getUndoManager().reset();
84                     }
85                 });
86             }
87
88             @Override
89             public void exception(Throwable t) {
90                 ErrorLogger.defaultLogError(t);
91             }
92
93             @Override
94             public boolean isDisposed() {
95                 return editor.isDisposed();
96             }
97
98         });
99
100         editor.viewer.addTextListener(new ITextListener() {
101             @Override
102             public void textChanged(TextEvent event) {
103                 firePropertyChange(PROP_DIRTY);
104             }
105         });
106     }
107     
108     @Override
109     public void setFocus() {
110         editor.setFocus();
111     }
112
113     protected void save(WriteGraph graph, Resource resource, String text) throws DatabaseException {
114         graph.claimValue(resource, text);
115     }
116     
117     @Override
118     public void doSave(IProgressMonitor monitor) {
119         this.originalText = editor.getContent();
120         firePropertyChange(PROP_DIRTY);
121         try {
122             Simantics.getSession().syncRequest(new WriteRequest() {
123                 @Override
124                 public void perform(WriteGraph graph) throws DatabaseException {
125                     graph.markUndoPoint();
126                         save(graph, inputResource, originalText);
127                         Layer0Utils.addCommentMetadata(graph, "Saved SCL Module " + graph.getRelatedValue2(inputResource, Layer0.getInstance(graph).HasName, Bindings.STRING));
128                 }
129             });
130         } catch (DatabaseException e) {
131             e.printStackTrace();
132         }
133     }
134
135     @Override
136     public void doSaveAs() {
137     }
138
139     protected String computeTitle(ReadGraph graph, Resource inputResource) throws DatabaseException {
140         Layer0 L0 = Layer0.getInstance(graph);
141         Resource parent = graph.getPossibleObject(inputResource, L0.PropertyOf);
142         if(parent == null)
143             return "No parent";
144         return graph.getPossibleRelatedValue(parent, L0.HasName) + " (Code)";
145     }
146     
147     @Override
148     public void init(IEditorSite site, final IEditorInput input)
149             throws PartInitException {
150         setSite(site);
151         setInput(input);
152         this.inputResource = ((IResourceEditorInput)input).getResource();
153         
154         Simantics.getSession().asyncRequest(
155                 new UniqueRead<String>() {
156                     @Override
157                     public String perform(ReadGraph graph) throws DatabaseException {
158                         return computeTitle(graph, inputResource);
159                     }
160                 },
161                 new TitleUpdater(site.getShell().getDisplay(), partName -> {
162                     setPartName(partName);
163                     setTitleToolTip(partName);
164                 }, () -> editor != null && editor.isDisposed()));
165     }
166
167     @Override
168     public boolean isDirty() {
169         return !editor.getContent().equals(originalText);
170     }
171
172     @Override
173     public boolean isSaveAsAllowed() {
174         return false;
175     }
176
177 }