package monolipse.ui.editors; import java.io.*; import java.util.*; import monolipse.core.compiler.*; import monolipse.ui.*; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.text.*; import org.eclipse.jface.text.reconciler.*; import org.eclipse.swt.widgets.*; public class BooReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension { private CompilerServices _builder; private BooDocument _document; private BooEditor _editor; public BooReconcilingStrategy() { try { _builder = CompilerServices.getInstance(); } catch (CoreException e) { BooUI.logException(e); } } public void setDocument(IDocument document) { _document = (BooDocument) document; } public void setEditor(BooEditor editor) { _editor = editor; } public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { } public void reconcile(IRegion partition) { new Job("outline update") { @Override protected IStatus run(IProgressMonitor arg0) { reconcileAll(); return Status.OK_STATUS; } }.schedule(); } private void reconcileAll() { if (_document == null) return; OutlineNode outline = getOutline(); _document.updateOutline(outline); updateDocumentFolding(outline); } private OutlineNode getOutline() { OutlineNode outline = buildOutline(); return outline == null ? new OutlineNode() : outline; } ArrayList<Position> positions = new ArrayList<Position>(); private void updateDocumentFolding(OutlineNode outline) { positions = calculatePositions(outline, positions); Display.getDefault().asyncExec(new Runnable() { public void run() { if (_editor != null) _editor.updateFoldingStructure(positions); } }); } private ArrayList<Position> calculatePositions(OutlineNode outline, ArrayList<Position> positions) { getOutlinePositions(outline, positions); return positions; } private void getOutlinePositions(OutlineNode root, ArrayList<Position> collection) { if (shouldFoldBlock(root)) { int start = getPositionForLine(root.startLine()); int length = getPositionForLine(root.endLine() + 1) - start; collection.add(new Position(start, Math.max(1, length))); } for (OutlineNode child : root.children()) { getOutlinePositions(child, collection); } } private boolean shouldFoldBlock(OutlineNode root) { if (root == null || root.type() == null) { return false; } String type = root.type(); return type.equals("ImportCollection") || type.equals("Method") || type.equals("Constructor") || type.equals("ClassDefinition") || type.equals("InterfaceDefinition"); } private int getPositionForLine(int line) { if (null == _document) return 1; try { return _document.getLineOffset(line - 1); } catch (org.eclipse.jface.text.BadLocationException e) { return 1; } } private OutlineNode buildOutline() { if (null == _builder) return null; try { return _builder.getOutline(_document.get()); } catch (IOException e) { BooUI.logException(e); } return null; } public void setProgressMonitor(IProgressMonitor monitor) { } public void initialReconcile() { reconcileAll(); } }