package org.simantics.scl.ui.editor; import java.util.Iterator; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IUndoManager; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.TextViewerUndoManager; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.AnnotationModel; import org.eclipse.jface.text.source.AnnotationPainter; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.ISharedTextColors; import org.eclipse.jface.text.source.OverviewRuler; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.jface.text.source.VerticalRuler; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.errors.Locations; public class SCLTextEditorNew extends Composite { private static final int DELAY_BEFORE_COMPILATION = 500 /*ms*/; public SourceViewer viewer; ImageRegistry imageRegistry; SCLAnnotationAccessNew annotationAccess; ISharedTextColors sharedTextColors; IAnnotationModel annotationModel; public SCLTextEditorNew(Composite parent, int style) { super(parent, style); setLayout(new FillLayout()); imageRegistry = new ImageRegistry(parent.getDisplay()); annotationAccess = new SCLAnnotationAccessNew(imageRegistry); sharedTextColors = new SharedTextColorsNew(getDisplay()); annotationModel = new AnnotationModel(); VerticalRuler leftRuler = new VerticalRuler(12, annotationAccess); leftRuler.setModel(annotationModel); OverviewRuler rightRuler = new OverviewRuler(annotationAccess, 12, sharedTextColors); rightRuler.setModel(annotationModel); rightRuler.addAnnotationType("error"); //$NON-NLS-1$ rightRuler.setAnnotationTypeLayer("error", 0); //$NON-NLS-1$ rightRuler.setAnnotationTypeColor("error", sharedTextColors.getColor(new RGB(255,0,128))); //$NON-NLS-1$ viewer = new SourceViewer(this, leftRuler, rightRuler, true, SWT.H_SCROLL | SWT.V_SCROLL); Document document = new Document(); viewer.showAnnotations(false); viewer.showAnnotationsOverview(false); viewer.setDocument(document, annotationModel); viewer.setEditable(true); LocalResourceManager resourceManager = new LocalResourceManager(JFaceResources.getResources(), viewer.getControl()); SCLSourceViewerConfigurationNew sourceViewerConfiguration = new SCLSourceViewerConfigurationNew(resourceManager); viewer.configure(sourceViewerConfiguration); // Annotations to text area AnnotationPainter annotationPainter = new AnnotationPainter(viewer, annotationAccess); annotationPainter.addAnnotationType("error"); //$NON-NLS-1$ annotationPainter.setAnnotationTypeColor("error", sharedTextColors.getColor(new RGB(255,0,128))); //$NON-NLS-1$ viewer.addPainter(annotationPainter); annotationModel.addAnnotationModelListener(annotationPainter); IUndoManager undoManager = new TextViewerUndoManager(100); viewer.setUndoManager(undoManager); undoManager.connect(viewer); // Undo support (maybe not needed in workbench?) /*viewer.getTextWidget().addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if(e.keyCode=='z'&& e.stateMask == SWT.CTRL) { viewer.getUndoManager().undo(); } else if(e.keyCode=='y'&& e.stateMask == SWT.CTRL) { viewer.getUndoManager().redo(); } } });*/ } public IUndoManager getUndoManager() { return viewer.getUndoManager(); } @Override public void dispose() { super.dispose(); sharedTextColors.dispose(); } @SuppressWarnings("unchecked") private void removeAnnotations() { Iterator it = annotationModel.getAnnotationIterator(); while(it.hasNext()) { Annotation annotation = it.next(); annotationModel.removeAnnotation(annotation); } } private void setAnnotations(CompilationError[] errors) { removeAnnotations(); for(CompilationError error : errors) { int begin = Locations.beginOf(error.location); int end = Locations.endOf(error.location); if(begin == end) { if(begin > 0) --begin; else ++end; } annotationModel.addAnnotation( new Annotation("error", true, error.description), //$NON-NLS-1$ new Position(begin, end-begin)); } } public String getContent() { final String[] result = new String[1]; getDisplay().syncExec(new Runnable() { @Override public void run() { result[0] = viewer.getDocument().get(); } }); return result[0]; } public void setContent(final String content, final CompilationError[] errors) { //getDisplay().asyncExec(new Runnable() { getDisplay().syncExec(new Runnable() { @Override public void run() { if (viewer.getTextWidget().isDisposed()) return; if(content != null) viewer.getDocument().set(content); if(errors != null) setAnnotations(errors); } }); } private Point storedSelectedRange; public void storeSelectedRange() { storedSelectedRange = viewer.getSelectedRange(); } public void restoreSelectedRange() { if (storedSelectedRange != null) { viewer.setSelectedRange(storedSelectedRange.x, storedSelectedRange.y); storedSelectedRange = null; } } }