1 package net.sourceforge.phpeclipse.wiki.editor;
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.HashSet;
6 import java.util.Iterator;
11 import net.sourceforge.phpeclipse.wiki.editor.model.WikipediaText;
12 import net.sourceforge.phpeclipse.wiki.editor.model.WikipediaSection;
14 import org.eclipse.core.runtime.IProgressMonitor;
16 import org.eclipse.jface.text.BadLocationException;
17 import org.eclipse.jface.text.IDocument;
18 import org.eclipse.jface.text.Position;
19 import org.eclipse.jface.text.source.Annotation;
20 import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
21 import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
23 public class WikiFoldingStructureProvider {
25 private WikiEditor fEditor;
27 private IDocument fDocument;
29 private IProgressMonitor fProgressMonitor;
31 public WikiFoldingStructureProvider(WikiEditor editor) {
35 public void setProgressMonitor(IProgressMonitor progressMonitor) {
36 fProgressMonitor = progressMonitor;
39 public void setDocument(IDocument document) {
43 public void updateFoldingRegions(WikipediaSection section) {
46 ProjectionAnnotationModel model = (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
50 Set currentRegions = new HashSet();
51 addFoldingRegions(currentRegions, section.getChildren());
52 updateFoldingRegions(model, currentRegions);
53 } catch (BadLocationException e) {
58 private void updateFoldingRegions(ProjectionAnnotationModel model, Set currentRegions) {
59 Annotation[] deletions = computeDifferences(model, currentRegions);
61 Map additionsMap = new HashMap();
62 for (Iterator iter = currentRegions.iterator(); iter.hasNext();)
63 additionsMap.put(new ProjectionAnnotation(), iter.next());
65 if ((deletions.length != 0 || additionsMap.size() != 0) && (fProgressMonitor == null || !fProgressMonitor.isCanceled()))
66 model.modifyAnnotations(deletions, additionsMap, new Annotation[] {});
69 private Annotation[] computeDifferences(ProjectionAnnotationModel model, Set current) {
70 List deletions = new ArrayList();
71 for (Iterator iter = model.getAnnotationIterator(); iter.hasNext();) {
72 Object annotation = iter.next();
73 if (annotation instanceof ProjectionAnnotation) {
74 Position position = model.getPosition((Annotation) annotation);
75 if (current.contains(position))
76 current.remove(position);
78 deletions.add(annotation);
81 return (Annotation[]) deletions.toArray(new Annotation[deletions.size()]);
84 private void addFoldingRegions(Set regions, Object[] elements) throws BadLocationException {
85 for (int i = 0; i < elements.length; i++) {
86 WikipediaSection element = (WikipediaSection) elements[i];
87 if (element.getOffset() >= 0) {
88 int startLine = fDocument.getLineOfOffset(element.getOffset());
89 int endLine = fDocument.getLineOfOffset(element.getOffset() + element.getLength());
90 if (startLine < endLine) {
91 int start = fDocument.getLineOffset(startLine);
92 int end = fDocument.getLineOffset(endLine) + fDocument.getLineLength(endLine);
93 Position position = new Position(start, end - start);
94 regions.add(position);
97 Object[] children = element.getChildren();
98 if (children != null) {
99 addFoldingRegions(regions, children);