Mercurial > projects > dwt-addons
diff dwtx/jface/text/reconciler/Reconciler.d @ 129:eb30df5ca28b
Added JFace Text sources
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 23 Aug 2008 19:10:48 +0200 |
parents | |
children | c4fb132a086c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/text/reconciler/Reconciler.d Sat Aug 23 19:10:48 2008 +0200 @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * 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 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.text.reconciler.Reconciler; + +import dwt.dwthelper.utils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IProgressMonitor; +import dwtx.jface.text.BadLocationException; +import dwtx.jface.text.IDocument; +import dwtx.jface.text.IDocumentExtension3; +import dwtx.jface.text.IRegion; +import dwtx.jface.text.ITypedRegion; +import dwtx.jface.text.Region; +import dwtx.jface.text.TextUtilities; +import dwtx.jface.text.TypedRegion; + + +/** + * Standard implementation of {@link dwtx.jface.text.reconciler.IReconciler}. + * The reconciler is configured with a set of {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconciling strategies} + * each of which is responsible for a particular content type. + * <p> + * Usually, clients instantiate this class and configure it before using it. + * </p> + * + * @see dwtx.jface.text.IDocumentListener + * @see dwtx.jface.text.ITextInputListener + * @see dwtx.jface.text.reconciler.DirtyRegion + */ +public class Reconciler : AbstractReconciler , IReconcilerExtension { + + /** The map of reconciling strategies. */ + private Map fStrategies; + + /** + * The partitioning this reconciler uses. + *@since 3.0 + */ + private String fPartitioning; + + /** + * Creates a new reconciler with the following configuration: it is + * an incremental reconciler with a standard delay of 500 milliseconds. There + * are no predefined reconciling strategies. The partitioning it uses + * is the default partitioning {@link IDocumentExtension3#DEFAULT_PARTITIONING}. + */ + public Reconciler() { + super(); + fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; + } + + /** + * Sets the document partitioning for this reconciler. + * + * @param partitioning the document partitioning for this reconciler + * @since 3.0 + */ + public void setDocumentPartitioning(String partitioning) { + Assert.isNotNull(partitioning); + fPartitioning= partitioning; + } + + /* + * @see dwtx.jface.text.reconciler.IReconcilerExtension#getDocumentPartitioning() + * @since 3.0 + */ + public String getDocumentPartitioning() { + return fPartitioning; + } + + /** + * Registers a given reconciling strategy for a particular content type. + * If there is already a strategy registered for this type, the new strategy + * is registered instead of the old one. + * + * @param strategy the reconciling strategy to register, or <code>null</code> to remove an existing one + * @param contentType the content type under which to register + */ + public void setReconcilingStrategy(IReconcilingStrategy strategy, String contentType) { + + Assert.isNotNull(contentType); + + if (fStrategies is null) + fStrategies= new HashMap(); + + if (strategy is null) + fStrategies.remove(contentType); + else { + fStrategies.put(contentType, strategy); + if (strategy instanceof IReconcilingStrategyExtension && getProgressMonitor() !is null) { + IReconcilingStrategyExtension extension= (IReconcilingStrategyExtension) strategy; + extension.setProgressMonitor(getProgressMonitor()); + } + } + } + + /* + * @see IReconciler#getReconcilingStrategy(String) + */ + public IReconcilingStrategy getReconcilingStrategy(String contentType) { + + Assert.isNotNull(contentType); + + if (fStrategies is null) + return null; + + return (IReconcilingStrategy) fStrategies.get(contentType); + } + + /** + * Processes a dirty region. If the dirty region is <code>null</code> the whole + * document is consider being dirty. The dirty region is partitioned by the + * document and each partition is handed over to a reconciling strategy registered + * for the partition's content type. + * + * @param dirtyRegion the dirty region to be processed + * @see AbstractReconciler#process(DirtyRegion) + */ + protected void process(DirtyRegion dirtyRegion) { + + IRegion region= dirtyRegion; + + if (region is null) + region= new Region(0, getDocument().getLength()); + + ITypedRegion[] regions= computePartitioning(region.getOffset(), region.getLength()); + + for (int i= 0; i < regions.length; i++) { + ITypedRegion r= regions[i]; + IReconcilingStrategy s= getReconcilingStrategy(r.getType()); + if (s is null) + continue; + + if(dirtyRegion !is null) + s.reconcile(dirtyRegion, r); + else + s.reconcile(r); + } + } + + /* + * @see AbstractReconciler#reconcilerDocumentChanged(IDocument) + * @since 2.0 + */ + protected void reconcilerDocumentChanged(IDocument document) { + if (fStrategies !is null) { + Iterator e= fStrategies.values().iterator(); + while (e.hasNext()) { + IReconcilingStrategy strategy= (IReconcilingStrategy) e.next(); + strategy.setDocument(document); + } + } + } + + /* + * @see AbstractReconciler#setProgressMonitor(IProgressMonitor) + * @since 2.0 + */ + public void setProgressMonitor(IProgressMonitor monitor) { + super.setProgressMonitor(monitor); + + if (fStrategies !is null) { + Iterator e= fStrategies.values().iterator(); + while (e.hasNext()) { + IReconcilingStrategy strategy= (IReconcilingStrategy) e.next(); + if (strategy instanceof IReconcilingStrategyExtension) { + IReconcilingStrategyExtension extension= (IReconcilingStrategyExtension) strategy; + extension.setProgressMonitor(monitor); + } + } + } + } + + /* + * @see AbstractReconciler#initialProcess() + * @since 2.0 + */ + protected void initialProcess() { + ITypedRegion[] regions= computePartitioning(0, getDocument().getLength()); + List contentTypes= new ArrayList(regions.length); + for (int i= 0; i < regions.length; i++) { + String contentType= regions[i].getType(); + if( contentTypes.contains(contentType)) + continue; + contentTypes.add(contentType); + IReconcilingStrategy s= getReconcilingStrategy(contentType); + if (s instanceof IReconcilingStrategyExtension) { + IReconcilingStrategyExtension e= (IReconcilingStrategyExtension) s; + e.initialReconcile(); + } + } + } + + /** + * Computes and returns the partitioning for the given region of the input document + * of the reconciler's connected text viewer. + * + * @param offset the region offset + * @param length the region length + * @return the computed partitioning + * @since 3.0 + */ + private ITypedRegion[] computePartitioning(int offset, int length) { + ITypedRegion[] regions= null; + try { + regions= TextUtilities.computePartitioning(getDocument(), getDocumentPartitioning(), offset, length, false); + } catch (BadLocationException x) { + regions= new TypedRegion[0]; + } + return regions; + } +}