public void run(IAction action) { // get the selection and determine if we want to collapse the current fold // or all folds contianed by the current selection TexSelections selection = new TexSelections(getTextEditor()); int firstOffset = selection.getStartLine().getOffset(); int lastOffset = selection.getEndLine().getOffset(); ProjectionAnnotationModel model = (ProjectionAnnotationModel) getTextEditor() .getAdapter(ProjectionAnnotationModel.class); if (model != null) { if (firstOffset == lastOffset) { collapseDeepestMatching(model, firstOffset); } else { collapseAllContained(model, firstOffset, lastOffset); } } }
/** * Collapses the deepest annotation that contains the given offset * * @param model The annotation model to use * @param offset The offset inside the document */ private void collapseDeepestMatching(ProjectionAnnotationModel model, int offset) { TexProjectionAnnotation toCollapse = null; for (Iterator iter = model.getAnnotationIterator(); iter.hasNext();) { TexProjectionAnnotation tpa = (TexProjectionAnnotation) iter.next(); if (tpa.contains(offset)) { if (toCollapse != null) { if (tpa.isDeeperThan(toCollapse)) toCollapse = tpa; } else { toCollapse = tpa; } } } if (toCollapse != null) { model.collapse(toCollapse); } }
private Annotation[] computeDifferences(ProjectionAnnotationModel model, Set current) { List deletions = new ArrayList(); for (Iterator iter = model.getAnnotationIterator(); iter.hasNext();) { Object annotation = iter.next(); if (annotation instanceof ProjectionAnnotation) { Position position = model.getPosition((Annotation) annotation); if (current.contains(position)) current.remove(position); else deletions.add(annotation); } } return (Annotation[]) deletions.toArray(new Annotation[deletions.size()]); }
private FoldingStructureComputationContext createContext(boolean allowCollapse) { if (!isInstalled()) return null; ProjectionAnnotationModel model= getModel(); if (model == null) return null; IDocument doc= getDocument(); if (doc == null) return null; IScanner scanner= null; if (fUpdatingCount == 1) scanner= fSharedScanner; // reuse scanner return new FoldingStructureComputationContext(doc, model, allowCollapse, scanner); }
/** * A semi-hack... This uses stuff that may change at any time in Eclipse. * In the java editor, the projection annotation model contains the collapsible regions which correspond to methods (and other areas * such as import groups). * * This may work in other editor types as well... TBD */ protected int transform(ITextEditor editor, IDocument document, ITextSelection currentSelection, ExecutionEvent event) throws BadLocationException { ITextViewerExtension viewer = MarkUtils.getITextViewer(editor); if (viewer instanceof ProjectionViewer) { ProjectionAnnotationModel projection = ((ProjectionViewer)viewer).getProjectionAnnotationModel(); @SuppressWarnings("unchecked") // the method name says it all Iterator<Annotation> pit = projection.getAnnotationIterator(); while (pit.hasNext()) { Position p = projection.getPosition(pit.next()); if (p.includes(currentSelection.getOffset())) { if (isUniversalPresent()) { // Do this here to prevent subsequent scrolling once range is revealed MarkUtils.setSelection(editor, new TextSelection(document, p.offset, 0)); } // the viewer is pretty much guaranteed to be a TextViewer if (viewer instanceof TextViewer) { ((TextViewer)viewer).revealRange(p.offset, p.length); } break; } } } return NO_OFFSET; }
/** * @param element * @param elements * @param model * @return */ protected boolean isInsideLast(PyProjectionAnnotation element, List elements, ProjectionAnnotationModel model) { if (elements.size() == 0) { return false; } PyProjectionAnnotation top = (PyProjectionAnnotation) elements.get(elements.size() - 1); Position p1 = model.getPosition(element); Position pTop = model.getPosition(top); int p1Offset = p1.getOffset(); int pTopoffset = pTop.getOffset(); int pTopLen = pTopoffset + pTop.getLength(); if (p1Offset > pTopoffset && p1Offset < pTopLen) { return true; } return false; }
@Override public synchronized void modelChanged(final ISimpleNode ast) { final SimpleNode root2 = (SimpleNode) ast; if (!firstInputChangedCalled) { asyncUpdateWaitingFormModelAndInputChanged(root2); return; } ProjectionAnnotationModel model = (ProjectionAnnotationModel) editor .getAdapter(ProjectionAnnotationModel.class); if (model == null) { asyncUpdateWaitingFormModelAndInputChanged(root2); } else { addMarksToModel(root2, model); } }
/** * @return an annotation that should be added (or null if that entry already has an annotation * added for it). */ private Tuple<ProjectionAnnotation, Position> getAnnotationToAdd(FoldingEntry node, int start, int end, ProjectionAnnotationModel model, List<Annotation> existing) throws BadLocationException { try { IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput()); int offset = document.getLineOffset(start); int endOffset = offset; try { endOffset = document.getLineOffset(end); } catch (Exception e) { //sometimes when we are at the last line, the command above will not work very well IRegion lineInformation = document.getLineInformation(end); endOffset = lineInformation.getOffset() + lineInformation.getLength(); } Position position = new Position(offset, endOffset - offset); return getAnnotationToAdd(position, node, model, existing); } catch (BadLocationException x) { //this could happen } return null; }
/** * Adds all children of CommonModel as folding regions and folds these regions * if <code>bDoFold</code> is <code>true</code>. * * @param commonModel * the document model * @param bDoFolding * resets the folding */ public void updateFoldingRegions(CommonModel commonModel, boolean bDoFold) { try { ProjectionAnnotationModel model = (ProjectionAnnotationModel)fEditor .getAdapter(ProjectionAnnotationModel.class); if (model == null) return; Set<Position> currentRegions = new HashSet<Position>(); Map<Annotation,Position> map = new HashMap<Annotation, Position>(); addFoldingRegions(currentRegions, commonModel.getAllChildren(), map); if (bDoFold) { model.removeAllAnnotations(); model.replaceAnnotations(null, map); } updateFoldingRegions(model, currentRegions); } catch (BadLocationException e) { e.printStackTrace(); } }
/** * Updates the code folds. * * @param outline The outline data structure containing the document positions */ public void update(List outline) { model = (ProjectionAnnotationModel)editor.getAdapter(ProjectionAnnotationModel.class); if (model != null) { this.addMarks(outline); } }
public void run(IAction action) { TexSelections selection = new TexSelections(getTextEditor()); int firstOffset = selection.getStartLine().getOffset(); int lastOffset = selection.getEndLine().getOffset(); ProjectionAnnotationModel model = (ProjectionAnnotationModel) getTextEditor() .getAdapter(ProjectionAnnotationModel.class); if (model != null) { // the predefined method permits us to do this, even if length=0 model.expandAll(firstOffset, lastOffset - firstOffset); } }
/** * Collapses all annotations that are completely contained in the interval * defined by <code>startOffset</code> and <code>endOffset</code>. * * @param model The annotation model to use * @param startOffset The document offset of the start of the interval * @param endOffset The document offset of the end of the interval */ private void collapseAllContained(ProjectionAnnotationModel model, int startOffset, int endOffset) { for (Iterator iter = model.getAnnotationIterator(); iter.hasNext();) { TexProjectionAnnotation tpa = (TexProjectionAnnotation) iter.next(); if (tpa.isBetween(startOffset, endOffset)) { model.collapse(tpa); } } }
/** * Updates the code folds of the editor. * * @param outline The document outline data structure containing the document positions */ public void update(ArrayList outline) { model = (ProjectionAnnotationModel)editor.getAdapter(ProjectionAnnotationModel.class); if (model != null) { this.addMarks(outline); } }
@SuppressWarnings({ "unchecked" }) public <T> T getAdapter(Class<T> target) { if (IContentOutlinePage.class.equals(target)) { if (!isOutlinePageValid()) { outlinePage = createOutlinePage(); } return (T) outlinePage; } if (SmartBackspaceManager.class.equals(target)) { if (getSourceViewer() instanceof FluentMkSourceViewer) { return (T) ((FluentMkSourceViewer) getSourceViewer()).getBackspaceManager(); } } if (PagePart.class.equals(target)) { return (T) getPageModel(); } if (ProjectionAnnotationModel.class.equals(target)) { if (projectionSupport != null) { Object adapter = projectionSupport.getAdapter(getSourceViewer(), target); if (adapter != null) return (T) adapter; } } if (target == IFoldingStructureProvider.class) { return (T) projectionProvider; } return super.getAdapter(target); }
FoldingStructureComputationContext(IDocument document, ProjectionAnnotationModel model, boolean allowCollapsing) { Assert.isNotNull(document); Assert.isNotNull(model); fDocument = document; fModel = model; fAllowCollapsing = allowCollapsing; }
private FoldingStructureComputationContext createContext(boolean allowCollapse) { if (!isInstalled()) return null; ProjectionAnnotationModel model = getModel(); if (model == null) return null; IDocument doc = getDocument(); if (doc == null) return null; return new FoldingStructureComputationContext(doc, model, allowCollapse); }
protected void calculateProjectionAnnotationModel(boolean allowCollapse) { ProjectionAnnotationModel projectionAnnotationModel = this.viewer.getProjectionAnnotationModel(); if (projectionAnnotationModel != null) { // make a defensive copy as we modify the folded positions in subsequent operations Collection<FoldedPosition> foldedPositions = Sets.newLinkedHashSet(foldingRegionProvider.getFoldingRegions(editor.getDocument())); Annotation[] newRegions = mergeFoldingRegions(foldedPositions, projectionAnnotationModel); updateFoldingRegions(allowCollapse, projectionAnnotationModel, foldedPositions, newRegions); } }
@SuppressWarnings("unchecked") protected Annotation[] mergeFoldingRegions(Collection<FoldedPosition> foldedPositions, ProjectionAnnotationModel projectionAnnotationModel) { List<Annotation> deletions = new ArrayList<Annotation>(); for (Iterator<Annotation> iterator = projectionAnnotationModel.getAnnotationIterator(); iterator.hasNext();) { Annotation annotation = iterator.next(); if (annotation instanceof ProjectionAnnotation) { Position position = projectionAnnotationModel.getPosition(annotation); if (!foldedPositions.remove(position)) { deletions.add(annotation); } } } return deletions.toArray(new Annotation[deletions.size()]); }
protected void updateFoldingRegions(boolean allowCollapse, ProjectionAnnotationModel model, Collection<FoldedPosition> foldedPositions, Annotation[] deletions) { Map<ProjectionAnnotation, Position> additionsMap = Maps.newHashMap(); for (FoldedPosition foldedPosition: foldedPositions) { addProjectionAnnotation(allowCollapse, foldedPosition, additionsMap); } if (deletions.length != 0 || additionsMap.size() != 0) { model.modifyAnnotations(deletions, additionsMap, new Annotation[] {}); } }
private void updateFoldingRegions(ProjectionAnnotationModel model, Set currentRegions) { Annotation[] deletions = computeDifferences(model, currentRegions); Map additionsMap = new HashMap(); for (Iterator iter = currentRegions.iterator(); iter.hasNext();) additionsMap.put(new ProjectionAnnotation(), iter.next()); if ((deletions.length != 0 || additionsMap.size() != 0) && (fProgressMonitor == null || !fProgressMonitor.isCanceled())) model.modifyAnnotations(deletions, additionsMap, new Annotation[] {}); }
GamaFoldingActionGroup(final ITextEditor editor, final ITextViewer viewer) { super(editor, viewer); if (!(viewer instanceof ProjectionViewer)) { return; } this.viewwer = (ProjectionViewer) viewer; collapseStrings = new FoldingAction() { // $NON-NLS-1$ // private final EClass type = GamlPackage. @Override public void run() { final ProjectionAnnotationModel model = viewwer.getProjectionAnnotationModel(); final Iterator<?> iterator = model.getAnnotationIterator(); final List<Annotation> toCollapse = new ArrayList<Annotation>(); while (iterator.hasNext()) { final Object next = iterator.next(); if (next instanceof ProjectionAnnotation) { final ProjectionAnnotation pa = (ProjectionAnnotation) next; final Position position = model.getPosition(pa); if (position instanceof TypedFoldedPosition) if (((TypedFoldedPosition) position).getType().equals("__comment")) { pa.markCollapsed(); toCollapse.add(pa); } } } model.modifyAnnotations(null, null, toCollapse.toArray(new Annotation[0])); } }; collapseStrings.setActionDefinitionId("org.xtext.example.folding.ui.folding.collapseStrings"); editor.setAction("FoldingCollapseStrings", collapseStrings); //$NON-NLS-1$ }
public void updateFoldingStructure(Map<ProjectionAnnotation, Position> annotations) { synchronized (lockUpdateFoldingStructure) { List<Annotation> deletions = new ArrayList<Annotation>(); Collection<Position> additions = annotations.values(); ProjectionAnnotationModel currentModel = getAnnotationModel(); if (currentModel == null) { return; } for (@SuppressWarnings("rawtypes") Iterator iter = currentModel.getAnnotationIterator(); iter.hasNext();) { Object annotation = iter.next(); if (annotation instanceof ProjectionAnnotation) { Position position = currentModel.getPosition((Annotation) annotation); if (additions.contains(position)) { additions.remove(position); } else { deletions.add((Annotation) annotation); } } } if (annotations.size() != 0 || deletions.size() != 0) { currentModel.modifyAnnotations(deletions.toArray(new Annotation[deletions.size()]), annotations, null); } } }
protected ProjectionAnnotationModel getAnnotationModel() { ISourceViewer viewer = getSourceViewer(); if (viewer instanceof ProjectionViewer) { return ((ProjectionViewer) viewer).getProjectionAnnotationModel(); } return null; }
private FoldingStructureComputationContext(IDocument document, ProjectionAnnotationModel model, boolean allowCollapsing, IScanner scanner) { Assert.isNotNull(document); Assert.isNotNull(model); fDocument= document; fModel= model; fAllowCollapsing= allowCollapsing; fScanner= scanner; }
/** * Collapses or expands all annotations matched by the passed filter. * * @param filter the filter to use to select which annotations to collapse * @param expand <code>true</code> to expand the matched annotations, <code>false</code> to * collapse them */ private void modifyFiltered(Filter filter, boolean expand) { if (!isInstalled()) return; ProjectionAnnotationModel model= getModel(); if (model == null) return; List<JavaProjectionAnnotation> modified= new ArrayList<JavaProjectionAnnotation>(); Iterator<Annotation> iter= model.getAnnotationIterator(); while (iter.hasNext()) { Object annotation= iter.next(); if (annotation instanceof JavaProjectionAnnotation) { JavaProjectionAnnotation java= (JavaProjectionAnnotation) annotation; if (expand == java.isCollapsed() && filter.match(java)) { if (expand) java.markExpanded(); else java.markCollapsed(); modified.add(java); } } } model.modifyAnnotations(null, null, modified.toArray(new Annotation[modified.size()])); }
/** * Collapses all item with the specified style. * * @param style * the style to collapse */ private void collapseStyle( int style ) { ISourceViewer viewer = getViewer( ); if ( !( viewer instanceof ProjectionViewer ) ) { return; } ProjectionAnnotationModel model = ( (ProjectionViewer) viewer ).getProjectionAnnotationModel( ); if ( model == null ) { return; } List modified = new ArrayList( ); Iterator iter = model.getAnnotationIterator( ); while ( iter.hasNext( ) ) { Object annotation = iter.next( ); if ( annotation instanceof ScriptProjectionAnnotation ) { ScriptProjectionAnnotation scriptAnnotation = (ScriptProjectionAnnotation) annotation; if ( !scriptAnnotation.isCollapsed( ) && scriptAnnotation.isStyle( style ) ) { scriptAnnotation.markCollapsed( ); modified.add( scriptAnnotation ); } } } model.modifyAnnotations( null, null, (Annotation[]) modified.toArray( new Annotation[modified.size( )] ) ); }
@Override public void run(IAction action) { final ProjectionAnnotationModel model = getModel(); if (model != null) { Iterator<Annotation> iter = getAnnotationsIterator(model, true); if (iter != null) { //we just want to expand the roots, and we are working only with the collapsed sorted by offset. List<PyProjectionAnnotation> elements = new ArrayList<PyProjectionAnnotation>(); //used to know the context while (iter.hasNext()) { PyProjectionAnnotation element = (PyProjectionAnnotation) iter.next(); //special case, we have none in our context if (elements.size() == 0) { model.expand(element); elements.add(element); } else { if (isInsideLast(element, elements, model)) { //ignore } else { //ok, the one in the top has to be collapsed ( and this one added ) model.expand(element); elements.add(element); } } } } } }
/** * @param model * @return */ protected Iterator<Annotation> getAnnotationsIterator(final ProjectionAnnotationModel model, boolean useExpanded) { //put annotations in array list. Iterator<Annotation> iter = model.getAnnotationIterator(); if (iter != null) { //get the not collapsed (expanded) and sort them ArrayList<Annotation> expanded = new ArrayList<Annotation>(); while (iter.hasNext()) { PyProjectionAnnotation element = (PyProjectionAnnotation) iter.next(); if (element.isCollapsed() == useExpanded) { expanded.add(element); } } Collections.sort(expanded, new Comparator() { @Override public int compare(Object o1, Object o2) { PyProjectionAnnotation e1 = (PyProjectionAnnotation) o1; PyProjectionAnnotation e2 = (PyProjectionAnnotation) o2; int e1Off = model.getPosition(e1).getOffset(); int e2Off = model.getPosition(e2).getOffset(); if (e1Off < e2Off) { return -1; } if (e1Off > e2Off) { return 1; } return 0; } }); iter = expanded.iterator(); } return iter; }
@Override public void run(IAction action) { PySelection ps = PySelectionFromEditor.createPySelectionFromEditor(getTextEditor()); ProjectionAnnotationModel model = getTextEditor().getAdapter( ProjectionAnnotationModel.class); if (model != null) { model.expandAll(ps.getAbsoluteCursorOffset(), ps.getSelLength()); } }
@Override public void run(IAction action) { PySelection ps = PySelectionFromEditor.createPySelectionFromEditor(getTextEditor()); ProjectionAnnotationModel model = getTextEditor().getAdapter( ProjectionAnnotationModel.class); try { if (model != null) { //put annotations in array list. Iterator iter = model.getAnnotationIterator(); while (iter != null && iter.hasNext()) { PyProjectionAnnotation element = (PyProjectionAnnotation) iter.next(); Position position = model.getPosition(element); int line = ps.getDoc().getLineOfOffset(position.offset); int start = ps.getStartLineIndex(); int end = ps.getEndLineIndex(); for (int i = start; i <= end; i++) { if (i == line) { model.collapse(element); break; } } } } } catch (BadLocationException e) { Log.log(IStatus.ERROR, "Unexpected error collapsing", e); } }
/** * Given the ast, create the needed marks and set them in the passed model. */ private synchronized void addMarksToModel(SimpleNode root2, ProjectionAnnotationModel model) { try { if (model != null) { ArrayList<Annotation> existing = new ArrayList<Annotation>(); //get the existing annotations Iterator<Annotation> iter = model.getAnnotationIterator(); while (iter != null && iter.hasNext()) { Annotation element = iter.next(); existing.add(element); } //now, remove the annotations not used and add the new ones needed IDocument doc = editor.getDocument(); if (doc != null) { //this can happen if we change the input of the editor very quickly. boolean foldInitial = initialFolding; initialFolding = false; List<FoldingEntry> marks = getMarks(doc, root2, foldInitial); Map<ProjectionAnnotation, Position> annotationsToAdd; if (marks.size() > OptimizationRelatedConstants.MAXIMUM_NUMBER_OF_CODE_FOLDING_MARKS) { annotationsToAdd = new HashMap<ProjectionAnnotation, Position>(); } else { annotationsToAdd = getAnnotationsToAdd(marks, model, existing); } model.replaceAnnotations(existing.toArray(new Annotation[existing.size()]), annotationsToAdd); } } } catch (Exception e) { Log.log(e); } }
/** * We have to be careful not to remove existing annotations because if this happens, previous code folding is not correct. */ private Tuple<ProjectionAnnotation, Position> getAnnotationToAdd(Position position, FoldingEntry node, ProjectionAnnotationModel model, List<Annotation> existing) { for (Iterator<Annotation> iter = existing.iterator(); iter.hasNext();) { Annotation element = iter.next(); Position existingPosition = model.getPosition(element); if (existingPosition.equals(position)) { //ok, do nothing to this annotation (neither remove nor add, as it already exists in the correct place). existing.remove(element); return null; } } return new Tuple<ProjectionAnnotation, Position>(new PyProjectionAnnotation(node.getAstEntry(), node.isCollapsed), position); }
private void updateFoldingRegions(ProjectionAnnotationModel model, Set<Position> currentRegions) { Annotation[] deletions = computeDifferences(model, currentRegions); Map<ProjectionAnnotation,Position> additionsMap = new HashMap<ProjectionAnnotation,Position>(); for (Iterator<Position> iter = currentRegions.iterator(); iter.hasNext();) additionsMap.put(new ProjectionAnnotation(), iter.next()); if ((deletions.length != 0 || additionsMap.size() != 0) && (fProgressMonitor == null || !fProgressMonitor.isCanceled())) model.modifyAnnotations( deletions, additionsMap, new Annotation[] {}); }
private Annotation[] computeDifferences(ProjectionAnnotationModel model, Set<Position> current) { List<Object> deletions = new ArrayList<Object>(); for (Iterator<?> iter = model.getAnnotationIterator(); iter.hasNext();) { Object annotation = iter.next(); if (annotation instanceof ProjectionAnnotation) { Position position = model.getPosition((Annotation)annotation); if (current.contains(position)) current.remove(position); else deletions.add(annotation); } } return (Annotation[])deletions.toArray(new Annotation[deletions.size()]); }
private IAnnotationModel getAnnotationModel(ITextEditor editor) { return (IAnnotationModel) editor.getAdapter(ProjectionAnnotationModel.class); }
ProjectionAnnotationModel getModel() { return fModel; }
private ProjectionAnnotationModel getModel() { return (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class); }