package com.framsticks.framclipse.editors; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.ResourceBundle; import org.eclipse.jface.action.IAction; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.TextViewer; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.projection.ProjectionAnnotation; import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; import org.eclipse.jface.text.source.projection.ProjectionSupport; import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; import org.eclipse.ui.texteditor.TextOperationAction; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import com.framsticks.framclipse.editors.configuration.FramscriptSourceViewerConfiguration; import com.framsticks.framclipse.editors.folding.FramclipseFoldingAnnotation; import com.framsticks.framclipse.editors.outline.FramclipseEditorOutlinePage; import com.framsticks.framclipse.internal.parser.ElementWithOffset; import com.framsticks.framclipse.internal.parser.Node; public class FramclipseEditor extends TextEditor { protected final EditorType editorType; private ProjectionSupport projectionSupport; private List prevAnnotations = new ArrayList(); private ProjectionAnnotationModel annotationModel; private FramclipseEditorOutlinePage outlinePage = null; private boolean outlineRequested = false; protected Node fileModel = null; public FramclipseEditor(EditorType editorType) { System.out.println("starting framclipse editor of type: " + editorType); this.editorType = editorType; setSourceViewerConfiguration(new FramscriptSourceViewerConfiguration(editorType, this)); } @Override public void createPartControl(Composite parent) { super.createPartControl(parent); ProjectionViewer viewer =(ProjectionViewer)getSourceViewer(); projectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors()); projectionSupport.install(); //turn projection mode on viewer.doOperation(ProjectionViewer.TOGGLE); annotationModel = viewer.getProjectionAnnotationModel(); } /** * The FramscriptEditor implementation of this * AbstractTextEditor method extend the actions to add those * specific to the receiver. */ @Override protected void createActions() { super.createActions(); ResourceBundle resourceBundle = FramclipseEditorMessages.getResourceBundle(); String prefix = "ContentAssistProposal."; int operationCode = ISourceViewer.CONTENTASSIST_PROPOSALS; IAction a = new TextOperationAction(resourceBundle, prefix, this, operationCode); String id = ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS; a.setActionDefinitionId(id); setAction("ContentAssistProposal", a); //$NON-NLS-1$ } public EditorType getEditorType() { return editorType; } @Override protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles); // ensure decoration support has been created and configured. getSourceViewerDecorationSupport(viewer); ((TextViewer)viewer).addPostSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { TextSelection selection = (TextSelection) event.getSelection(); if(getFileModel() != null) { Node element = ((ElementWithOffset)getFileModel()).getElementForOffset(selection.getOffset()); //System.out.println("selected: " + element); if(outlinePage != null) outlinePage.setSelectedElement(element); } } }); return viewer; } public void updateFoldingStructure(List annotations) { List removals = new ArrayList(); HashMap newAnnotations = new HashMap(); //System.out.println("got " + annotations.size() + " annotations."); for(int l = 0; l < prevAnnotations.size(); ++l) { FramclipseFoldingAnnotation equiv = prevAnnotations.get(l).hasEquivalent(annotations, getSourceViewer().getDocument()); if(equiv == null) { removals.add(prevAnnotations.get(l)); } else { annotations.remove(equiv); } } for(Annotation annot : removals) prevAnnotations.remove(annot); for(FramclipseFoldingAnnotation annot : annotations) { //System.out.println("adding for: " + annot.getAnnotatedElement()); prevAnnotations.add(annot); newAnnotations.put(annot, new Position(annot.getAnnotatedElement().getBeginOffset(), annot.getAnnotationLength())); } ProjectionAnnotation[] toDelete = new ProjectionAnnotation[removals.size()]; removals.toArray(toDelete); annotationModel.modifyAnnotations(toDelete,newAnnotations,null); } public Node getFileModel() { return fileModel; } public void setFileModel(Node fileModel) { this.fileModel = fileModel; } @Override public Object getAdapter(Class adapter) { if(IContentOutlinePage.class.equals(adapter)) { outlineRequested = true; if(outlinePage == null) { outlinePage = new FramclipseEditorOutlinePage(this); if(getFileModel() != null) outlinePage.setInput(getFileModel()); } return outlinePage; } return super.getAdapter(adapter); } public void updateOutlinePage() { if(outlineRequested) { if(outlinePage == null) { outlinePage = new FramclipseEditorOutlinePage(this); } //if(getFileModel() != null) outlinePage.setInput(getFileModel()); } } }