/* * $Id$ * * Copyright (c) 2004-2005 by the TeXlapse Team. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package net.sourceforge.texlipse.bibeditor; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import net.sourceforge.texlipse.TexlipsePlugin; import net.sourceforge.texlipse.model.ReferenceEntry; import net.sourceforge.texlipse.properties.TexlipseProperties; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel; /** * Does code-folding for the BibTeX-editor. * * @author Oskar Ojala */ public class BibCodeFolder { private BibEditor editor; private ProjectionAnnotationModel model; private ArrayList oldNodes; //private ArrayList<TexProjectionAnnotation> oldNodes; private boolean firstRun; /** * Creates a new code folder. * * @param editor The editor to which this folder is associated */ public BibCodeFolder(BibEditor editor) { this.editor = editor; this.firstRun = true; } /** * 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); } } /** * Manages adding and removing the folding marks from the editor. * * @param outline The outline data structure containing the document positions */ private void addMarks(List outline) { if (firstRun) { Map map = new HashMap(); fillAnnotationMap(outline, map, TexlipsePlugin.getDefault().getPreferenceStore().getBoolean(TexlipseProperties.BIB_FOLD_INITIAL)); model.modifyAnnotations(null, map, null); firstRun = false; } else { oldNodes = new ArrayList(); // save old nodes for (Iterator iter = model.getAnnotationIterator(); iter.hasNext();) { oldNodes.add((BibProjectionAnnotation) iter.next()); } markTreeNodes(outline); BibProjectionAnnotation[] deletes = new BibProjectionAnnotation[oldNodes.size()]; oldNodes.toArray(deletes); model.modifyAnnotations(deletes, null, null); } } /** * Adds new folding markers for positions that do not yet have markers. * * @param outline The outline data structure containing the document positions */ private void markTreeNodes(List outline) { markloop: for (ListIterator iter = outline.listIterator(); iter.hasNext();) { ReferenceEntry re = (ReferenceEntry) iter.next(); Position pos = re.position; for (ListIterator li2 = oldNodes.listIterator(); li2.hasNext();) { BibProjectionAnnotation cAnnotation = (BibProjectionAnnotation) li2.next(); if (cAnnotation.isSame(re)) { oldNodes.remove(cAnnotation); // model.modifyAnnotationPosition(cAnnotation, pos); continue markloop; } } model.addAnnotation(new BibProjectionAnnotation(re), pos); } } /** * Fills the given annotation map with all the annotations from this document. * * @param documentTree Document tree representing this document * @param map The annotation map to fill * @param fold Whether entries should be set as folded or not */ private void fillAnnotationMap(List documentTree, Map map, boolean fold) { for (ListIterator iter = documentTree.listIterator(); iter.hasNext();) { ReferenceEntry node = (ReferenceEntry) iter.next(); Position pos = node.position; BibProjectionAnnotation tpa = new BibProjectionAnnotation(node, fold); map.put(tpa, pos); } } }