下面列出了怎么用org.eclipse.jface.text.source.projection.ProjectionAnnotationModel的API类实例代码及写法,或者点击链接到github查看源代码。
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 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();
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;
}
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()));
foldedPositions = filterFoldedPositions(foldedPositions);
Annotation[] newRegions = mergeFoldingRegions(foldedPositions, projectionAnnotationModel);
updateFoldingRegions(allowCollapse, projectionAnnotationModel, foldedPositions, newRegions);
}
}
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[] {});
}
}
/**
* 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);
}
}
GamaFoldingActionGroup(final ITextEditor editor, final ITextViewer viewer) {
super(editor, viewer);
if (!(viewer instanceof ProjectionViewer)) { return; }
this.pViewer = (ProjectionViewer) viewer;
collapseStrings = new FoldingAction() { // $NON-NLS-1$
// private final EClass type = GamlPackage.
@Override
public void run() {
final ProjectionAnnotationModel model = pViewer.getProjectionAnnotationModel();
final Iterator<?> iterator = model.getAnnotationIterator();
final List<Annotation> toCollapse = new ArrayList<>();
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 IAnnotationModel getAnnotationModel(ITextEditor editor)
{
return (IAnnotationModel) editor.getAdapter(ProjectionAnnotationModel.class);
}
private void reconcile(final IRegion partition, final DirtyRegion dirtyRegion, final IRegion subRegion) {
if (editor != null) {
final HashMap<TLCProjectionAnnotation, Position> regionMap
= determineFoldingRegions(partition, dirtyRegion, subRegion);
final Annotation[] deletions;
final HashMap<TLCProjectionAnnotation, Position> regionsToAdd = new HashMap<>();
synchronized (currentAnnotations) {
for (final Map.Entry<TLCProjectionAnnotation, Position> me : regionMap.entrySet()) {
if (!currentAnnotations.remove(me.getKey())) {
regionsToAdd.put(me.getKey(), me.getValue());
}
}
deletions = currentAnnotations.toArray(new Annotation[currentAnnotations.size()]);
currentAnnotations.clear();
currentAnnotations.addAll(regionMap.keySet());
}
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
editor.modifyProjectionAnnotations(deletions, regionsToAdd);
if (projectionViewer != null) {
final ProjectionAnnotationModel model = projectionViewer.getProjectionAnnotationModel();
final boolean block = foldBlockComments.get();
final boolean pcal = foldPlusCalAlgorithm.get();
final boolean translated = foldTranslatedPlusCalBlock.get();
// We could do even more optimization than this, but this is better than none.
if (block || pcal || translated) {
for (final TLCProjectionAnnotation annotation : currentAnnotations) {
final boolean collapse;
switch (annotation.getTLCType()) {
case BLOCK_COMMENT:
collapse = block;
break;
case PCAL_BLOCK:
collapse = pcal;
break;
default:
collapse = translated;
}
if (collapse) {
model.collapse(annotation);
}
}
}
}
}
});
}
}
private ProjectionAnnotationModel getModel() {
return fModel;
}
private ProjectionAnnotationModel getModel() {
return (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
}