initial contribution
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.wiki / src / net / sourceforge / phpeclipse / wiki / editor / WikiFoldingStructureProvider.java
diff --git a/archive/net.sourceforge.phpeclipse.wiki/src/net/sourceforge/phpeclipse/wiki/editor/WikiFoldingStructureProvider.java b/archive/net.sourceforge.phpeclipse.wiki/src/net/sourceforge/phpeclipse/wiki/editor/WikiFoldingStructureProvider.java
new file mode 100644 (file)
index 0000000..742ced9
--- /dev/null
@@ -0,0 +1,104 @@
+package net.sourceforge.phpeclipse.wiki.editor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.sourceforge.phpeclipse.wiki.editor.model.WikipediaText;
+import net.sourceforge.phpeclipse.wiki.editor.model.WikipediaSection;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+
+public class WikiFoldingStructureProvider {
+
+  private WikiEditor fEditor;
+
+  private IDocument fDocument;
+
+  private IProgressMonitor fProgressMonitor;
+
+  public WikiFoldingStructureProvider(WikiEditor editor) {
+    fEditor = editor;
+  }
+
+  public void setProgressMonitor(IProgressMonitor progressMonitor) {
+    fProgressMonitor = progressMonitor;
+  }
+
+  public void setDocument(IDocument document) {
+    fDocument = document;
+  }
+
+  public void updateFoldingRegions(WikipediaSection section) {
+    try {
+
+      ProjectionAnnotationModel model = (ProjectionAnnotationModel) fEditor.getAdapter(ProjectionAnnotationModel.class);
+      if (model == null)
+        return;
+
+      Set currentRegions = new HashSet();
+      addFoldingRegions(currentRegions, section.getChildren());
+      updateFoldingRegions(model, currentRegions);
+    } catch (BadLocationException e) {
+      e.printStackTrace();
+    }
+  }
+
+  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[] {});
+  }
+
+  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 void addFoldingRegions(Set regions, Object[] elements) throws BadLocationException {
+    for (int i = 0; i < elements.length; i++) {
+      WikipediaSection element = (WikipediaSection) elements[i];
+      if (element.getOffset() >= 0) {
+        int startLine = fDocument.getLineOfOffset(element.getOffset());
+        int endLine = fDocument.getLineOfOffset(element.getOffset() + element.getLength());
+        if (startLine < endLine) {
+          int start = fDocument.getLineOffset(startLine);
+          int end = fDocument.getLineOffset(endLine) + fDocument.getLineLength(endLine);
+          Position position = new Position(start, end - start);
+          regions.add(position);
+        }
+
+        Object[] children = element.getChildren();
+        if (children != null) {
+          addFoldingRegions(regions, children);
+        }
+      }
+    }
+  }
+}
\ No newline at end of file