ZRH build submission 20020408
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/ITextViewerExtension.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/ITextViewerExtension.java
index 181eadd..3a80c76 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/ITextViewerExtension.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/ITextViewerExtension.java
@@ -7,6 +7,7 @@
 
 
 import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.widgets.Control;
 
  
 /**
@@ -48,4 +49,11 @@
 	 * @param listener the listener to be removed
 	 */
 	void removeVerifyKeyListener(VerifyKeyListener listener);
+	
+	/**
+	 * Returns the control of this viewer.
+	 * 
+	 * @return the control of this viewer
+	 */ 
+	Control getControl();
 }
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/TextViewer.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/TextViewer.java
index 1ffd6b8..93e5623 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/TextViewer.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/TextViewer.java
@@ -2772,19 +2772,19 @@
 			

 			Iterator e= presentation.getAllStyleRangeIterator();

 			

-//			// use optimized StyledText

-//			StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()];

-//			for (int i= 0; i < ranges.length; i++)

-//				ranges[i]= (StyleRange) e.next();

-//				

-//			IRegion region= presentation.getCoverage();

-//			fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges);

+			// use optimized StyledText

+			StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()];

+			for (int i= 0; i < ranges.length; i++)

+				ranges[i]= (StyleRange) e.next();

+				

+			IRegion region= presentation.getCoverage();

+			fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges);

 			

-			// use unoptimized StyledText

-			while (e.hasNext()) {

-				StyleRange r= (StyleRange) e.next();

-				fTextWidget.setStyleRange(r);

-			}

+//			// use unoptimized StyledText

+//			while (e.hasNext()) {

+//				StyleRange r= (StyleRange) e.next();

+//				fTextWidget.setStyleRange(r);

+//			}

 			

 		}	

 	}

diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java
index 6ef7917..b14f25c 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/contentassist/CompletionProposalPopup.java
@@ -138,8 +138,7 @@
 			}

 

 			public void widgetDefaultSelected(SelectionEvent e) {

-				insertSelectedProposal();

-				hide();

+				selectProposal();

 			}

 		});

 

@@ -155,9 +154,10 @@
 			return null;

 		return fFilteredProposals[i];

 	}

-	

-	private void insertSelectedProposal() {

+		

+	private void selectProposal() {

 		ICompletionProposal p= getSelectedProposal();

+		hide();

 		if (p != null)

 			insertProposal(p, (char) 0, fViewer.getSelectedRange().x);

 	}

@@ -341,8 +341,7 @@
 					

 				case 0x0D : // Enter

 					e.doit= false;

-					insertSelectedProposal();

-					hide();

+					selectProposal();

 					break;

 					

 				default:

@@ -352,8 +351,8 @@
 						char[] triggers= t.getTriggerCharacters();

 						if (contains(triggers, key)) {		

 							e.doit= false;

-							insertProposal(p, key, fViewer.getSelectedRange().x);

 							hide();

+							insertProposal(p, key, fViewer.getSelectedRange().x);

 						}

 					}

 			}

diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/AbstractReconciler.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/AbstractReconciler.java
index 033430e..f1d7c83 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/AbstractReconciler.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/AbstractReconciler.java
@@ -12,6 +12,8 @@
 

 import org.eclipse.swt.widgets.Listener;

 

+import org.eclipse.core.runtime.IProgressMonitor;

+

 import org.eclipse.jface.text.BadLocationException;

 import org.eclipse.jface.text.DocumentEvent;

 import org.eclipse.jface.text.IDocument;

@@ -121,6 +123,16 @@
 		 * first change from the queue and process it.

 		 */

 		public void run() {

+			

+			synchronized (fDirtyRegionQueue) {

+				try {

+					fDirtyRegionQueue.wait(fDelay);

+				} catch (InterruptedException x) {

+				}

+			}

+			

+			initialProcess();

+			

 			while (!fCanceled) {

 				

 				synchronized (fDirtyRegionQueue) {

@@ -150,7 +162,11 @@
 					

 				fIsActive= true;

 				

+				if (fProgressMonitor != null)

+					fProgressMonitor.setCanceled(false);

+					

 				process(r);

+				

 				synchronized (this) {

 					fIsDirty= false;

 				}

@@ -175,8 +191,13 @@
 		 * @see IDocumentListener#documentChanged

 		 */

 		public void documentChanged(DocumentEvent e) {

+			

+			if (fProgressMonitor != null && fThread.isActive())

+				fProgressMonitor.setCanceled(true);

+				

 			if (fIsIncrementalReconciler)

 				createDirtyRegion(e);

+				

 			fThread.reset();

 		}

 		

@@ -220,7 +241,10 @@
 				createDirtyRegion(e);

 			}

 			

-			fThread.reset();

+			if (oldInput == null && !fThread.isAlive())

+				fThread.start();

+			else

+				fThread.reset();

 		}

 	};

 	

@@ -234,6 +258,8 @@
 	private int fDelay= 500;

 	/** Are there incremental reconciling strategies? */

 	private boolean fIsIncrementalReconciler= true;

+	/** The progress monitor used by this reconciler */

+	private IProgressMonitor fProgressMonitor;

 

 	/** The text viewer's document */

 	private IDocument fDocument;

@@ -298,6 +324,15 @@
 	}

 	

 	/**

+	 * Sets the progress monitor of this reconciler.

+	 * 

+	 * @param monitor the monitor to be used

+	 */

+	public void setProgressMonitor(IProgressMonitor monitor) {

+		fProgressMonitor= monitor;

+	}

+	

+	/**

 	 * Returns whether any of the reconciling strategies is interested in

 	 * detailed dirty region information.

 	 * 

@@ -327,6 +362,15 @@
 		return fViewer;

 	}

 	

+	/**

+	 * Returns the progress monitor of this reconciler.

+	 * 

+	 * @return the progress monitor of this reconciler

+	 */

+	protected IProgressMonitor getProgressMonitor() {

+		return fProgressMonitor;

+	}

+	

 	/*

 	 * @see IReconciler#install

 	 */

@@ -341,7 +385,6 @@
 		

 		fDirtyRegionQueue= new DirtyRegionQueue();

 		fThread= new BackgroundThread(getClass().getName());

-		fThread.start();

 	}

 	

 	/*

@@ -349,14 +392,17 @@
 	 */

 	public void uninstall() {

 		if (fListener != null) {

+			

 			fViewer.removeTextInputListener(fListener);

+			if (fDocument != null) fDocument.removeDocumentListener(fListener);

 			fListener= null;

+			

 			fThread.cancel();

 			fThread= null;

 		}

 	}

 		

-	/*

+	/**

 	 * Creates a dirty region for a document event and adds it to the queue.

 	 *

 	 * @param e the document event for which to create a dirty region

@@ -377,4 +423,11 @@
 			fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText()));

 		}

 	}

+	

+	/**

+	 * This method is called on startup of the background activity. It is called only

+	 * once during the life time of the reconciler. Clients may reimplement this method.

+	 */

+	protected void initialProcess() {

+	}

 }

diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/IReconcilingStrategyExtension.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/IReconcilingStrategyExtension.java
new file mode 100644
index 0000000..8e4f96c
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/IReconcilingStrategyExtension.java
@@ -0,0 +1,30 @@
+package org.eclipse.jface.text.reconciler;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+ 
+/**
+ * Extends <code>IReconcilingStrategy</code> with new functionality.
+ */
+public interface IReconcilingStrategyExtension {
+
+	/**
+	 * Tells this reconciling strategy with which progress monitor
+	 * it will work. This method will be called before any other 
+	 * method and can be called multiple times.
+	 *
+	 * @param monitor the progress monitor with which this strategy will work
+	 */
+	void setProgressMonitor(IProgressMonitor monitor);
+	
+	/**
+	 * Called only once in the life time of this reconciling strategy.
+	 */
+	void initialReconcile();
+}
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/MonoReconciler.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/MonoReconciler.java
index 3175757..fd93e39 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/MonoReconciler.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/MonoReconciler.java
Binary files differ
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/Reconciler.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/Reconciler.java
index 0334b66..ca88805 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/Reconciler.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/reconciler/Reconciler.java
Binary files differ
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/AnnotationColumn.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/AnnotationColumn.java
new file mode 100644
index 0000000..b74159b
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/AnnotationColumn.java
@@ -0,0 +1,347 @@
+package org.eclipse.jface.text.source;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+
+import java.util.Iterator;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.IViewportListener;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TextEvent;
+
+
+/**
+ * A vertical ruler column displaying the graphics of annotations *
+ */
+public final class AnnotationColumn implements IVerticalRulerColumn {
+	
+	/**
+	 * Internal listener class.
+	 */
+	class InternalListener implements IViewportListener, IAnnotationModelListener, ITextListener {
+		
+		/*
+		 * @see IViewportListener#viewportChanged
+		 */
+		public void viewportChanged(int verticalPosition) {
+			if (verticalPosition != fScrollPos)
+				redraw();
+		}
+		
+		/*
+		 * @see IAnnotationModelListener#modelChanged
+		 */
+		public void modelChanged(IAnnotationModel model) {
+			postRedraw();
+		}
+		
+		/*
+		 * @see ITextListener#textChanged
+		 */
+		public void textChanged(TextEvent e) {
+			redraw();
+		}
+	};
+	
+	
+	/** This column's parent ruler */
+	private CompositeRuler fParentRuler;
+	/** The cached text viewer */
+	private ITextViewer fCachedTextViewer;
+	/** The cached text widget */
+	private StyledText fCachedTextWidget;
+	/** The ruler's canvas */
+	private Canvas fCanvas;
+	/** The vertical ruler's model */
+	private IAnnotationModel fModel;
+	/** Cache for the actual scroll position in pixels */
+	private int fScrollPos;
+	/** The drawable for double buffering */
+	private Image fBuffer;
+	/** The internal listener */
+	private InternalListener fInternalListener= new InternalListener();
+	/** The width of this vertical ruler */
+	private int fWidth;
+	
+	/**
+	 * Constructs this column with the given width.
+	 *
+	 * @param width the width of the vertical ruler
+	 */
+	public AnnotationColumn(int width) {
+		fWidth= width;
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#getControl()
+	 */
+	public Control getControl() {
+		return fCanvas;
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#getWidth()
+	 */
+	public int getWidth() {
+		return fWidth;
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite)
+	 */
+	public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+		
+		fParentRuler= parentRuler;
+		fCachedTextViewer= parentRuler.getTextViewer();
+		fCachedTextWidget= fCachedTextViewer.getTextWidget();
+		
+		fCanvas= new Canvas(parentControl, SWT.NO_BACKGROUND);
+		
+		fCanvas.addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent event) {
+				if (fCachedTextViewer != null)
+					doubleBufferPaint(event.gc);
+			}
+		});
+		
+		fCanvas.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				handleDispose();
+				fCachedTextViewer= null;
+				fCachedTextWidget= null;
+			}
+		});
+		
+		fCanvas.addMouseListener(new MouseListener() {
+			public void mouseUp(MouseEvent event) {
+			}
+			
+			public void mouseDown(MouseEvent event) {
+				fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+			}
+			
+			public void mouseDoubleClick(MouseEvent event) {
+				fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+			}
+		});
+		
+		if (fCachedTextViewer != null) {
+			fCachedTextViewer.addViewportListener(fInternalListener);
+			fCachedTextViewer.addTextListener(fInternalListener);
+		}
+		
+		return fCanvas;
+	}
+	
+	/**
+	 * Disposes the ruler's resources.
+	 */
+	private void handleDispose() {
+		
+		if (fCachedTextViewer != null) {
+			fCachedTextViewer.removeViewportListener(fInternalListener);
+			fCachedTextViewer.removeTextListener(fInternalListener);
+		}
+		
+		if (fModel != null)
+			fModel.removeAnnotationModelListener(fInternalListener);
+		
+		if (fBuffer != null) {
+			fBuffer.dispose();
+			fBuffer= null;
+		}
+	}
+	
+	/**
+	 * Double buffer drawing.
+	 */
+	private void doubleBufferPaint(GC dest) {
+		
+		Point size= fCanvas.getSize();
+		
+		if (size.x <= 0 || size.y <= 0)
+			return;
+		
+		if (fBuffer != null) {
+			Rectangle r= fBuffer.getBounds();
+			if (r.width != size.x || r.height != size.y) {
+				fBuffer.dispose();
+				fBuffer= null;
+			}
+		}
+		if (fBuffer == null)
+			fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+			
+		GC gc= new GC(fBuffer);
+		try {
+			gc.setBackground(fCanvas.getBackground());
+			gc.fillRectangle(0, 0, size.x, size.y);
+			doPaint(gc);
+		} finally {
+			gc.dispose();
+		}
+		
+		dest.drawImage(fBuffer, 0, 0);
+	}
+	
+	/**
+	 * Draws the vertical ruler w/o drawing the Canvas background.
+	 */
+	private void doPaint(GC gc) {
+	
+		if (fModel == null || fCachedTextViewer == null)
+			return;
+
+		int topLeft= fCachedTextViewer.getTopIndexStartOffset();
+		int bottomRight= fCachedTextViewer.getBottomIndexEndOffset();
+		int viewPort= bottomRight - topLeft;
+		
+		fScrollPos= fCachedTextWidget.getTopPixel();
+		int lineheight= fCachedTextWidget.getLineHeight();
+		Point dimension= fCanvas.getSize();
+		int shift= fCachedTextViewer.getTopInset();
+
+		IDocument doc= fCachedTextViewer.getDocument();		
+		
+		int topLine= -1, bottomLine= -1;
+		try {
+			IRegion region= fCachedTextViewer.getVisibleRegion();
+			topLine= doc.getLineOfOffset(region.getOffset());
+			bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength());
+		} catch (BadLocationException x) {
+			return;
+		}
+				
+		// draw Annotations
+		Rectangle r= new Rectangle(0, 0, 0, 0);
+		int maxLayer= 1;	// loop at least once thru layers.
+		
+		for (int layer= 0; layer < maxLayer; layer++) {
+			Iterator iter= fModel.getAnnotationIterator();
+			while (iter.hasNext()) {
+				Annotation annotation= (Annotation) iter.next();
+				
+				int lay= annotation.getLayer();
+				maxLayer= Math.max(maxLayer, lay+1);	// dynamically update layer maximum
+				if (lay != layer)	// wrong layer: skip annotation
+					continue;
+				
+				Position position= fModel.getPosition(annotation);
+				if (position == null)
+					continue;
+					
+				if (!position.overlapsWith(topLeft, viewPort))
+					continue;
+					
+				try {
+					
+					int offset= position.getOffset();
+					int length= position.getLength();
+					
+					int startLine= doc.getLineOfOffset(offset);
+					if (startLine < topLine)
+						startLine= topLine;
+					startLine -= topLine;
+					
+					int endLine= startLine;
+					if (length > 0)
+						endLine= doc.getLineOfOffset(offset + length - 1);
+					if (endLine > bottomLine)
+						endLine= bottomLine;
+					endLine -= topLine;
+					
+					r.x= 0;
+					r.y= (startLine * lineheight) - fScrollPos + shift;
+					r.width= dimension.x;
+					int lines= endLine - startLine;
+					if (lines < 0)
+						lines= -lines;
+					r.height= (lines+1) * lineheight;
+					
+					if (r.y < dimension.y)  // annotation within visible area
+						annotation.paint(gc, fCanvas, r);
+					
+				} catch (BadLocationException e) {
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Post a redraw request for thsi column  into the UI thread.
+	 */
+	private void postRedraw() {
+		if (fCanvas != null && !fCanvas.isDisposed()) {
+			Display d= fCanvas.getDisplay();
+			if (d != null) {
+				d.asyncExec(new Runnable() {
+					public void run() {
+						redraw();
+					}
+				});
+			}	
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#redraw()
+	 */
+	public void redraw() {
+		if (fCanvas != null && !fCanvas.isDisposed()) {
+			GC gc= new GC(fCanvas);
+			doubleBufferPaint(gc);
+			gc.dispose();
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#setModel
+	 */
+	public void setModel(IAnnotationModel model) {
+		if (model != fModel) {
+			
+			if (fModel != null)
+				fModel.removeAnnotationModelListener(fInternalListener);
+			
+			fModel= model;
+			
+			if (fModel != null)
+				fModel.addAnnotationModelListener(fInternalListener);
+			
+			postRedraw();
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#setFont(Font)
+	 */
+	public void setFont(Font font) {
+	}
+}
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/CompositeRuler.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/CompositeRuler.java
new file mode 100644
index 0000000..7362d6e
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/CompositeRuler.java
@@ -0,0 +1,323 @@
+package org.eclipse.jface.text.source;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Layout;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.Position;
+
+
+/**
+ * A vertical ruler which is connected to a text viewer.
+ * Standard implementation of <code>IVerticalRuler</code>.
+ * Clients may use this class as is.
+ *
+ * @see ITextViewer
+ */
+public final class CompositeRuler implements IVerticalRuler, IVerticalRulerExtension, IVerticalRulerInfo {
+	
+	
+	/**
+	 * Layout of  composite vertical ruler.
+	 */
+	class RulerLayout extends Layout {
+		
+		protected RulerLayout() {
+		}
+		
+		protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
+			Control[] children= composite.getChildren();
+			Point size= new Point(0, 0);
+			for (int i= 0; i < children.length; i++) {
+				Point s= children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
+				size.x += s.x;
+				size.y= Math.max(size.y, s.y);
+			}
+			return size;
+		}
+		
+		protected void layout(Composite composite, boolean flushCache) {
+			Rectangle clArea= composite.getClientArea();
+			int rulerHeight= clArea.height;
+			
+			int x= 0;			
+			Iterator e= fDecorators.iterator();
+			while (e.hasNext()) {
+				IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+				int columnWidth= column.getWidth();
+				column.getControl().setBounds(x, 0, columnWidth, rulerHeight);
+				x += columnWidth;
+			}
+		}
+	};
+	
+	
+	private ITextViewer fTextViewer;
+	private Composite fComposite;
+	private List fMouseListeners= new ArrayList(2);
+	
+	private List fDecorators= new ArrayList(2);
+	private IAnnotationModel fModel;
+	
+	private Point fLocation= new Point(-1, -1);
+	private int fLastMouseButtonActivityLine= -1;
+	
+	
+	/**
+	 * Constructs a vertical ruler.
+	 */
+	public CompositeRuler() {
+	}
+	
+	public void addDecorator(int index, IVerticalRulerColumn rulerColumn) {
+		fDecorators.add(index, rulerColumn);
+		if (fComposite != null && !fComposite.isDisposed()) {
+			
+			rulerColumn.createControl(this, fComposite);
+			
+			Control cc= rulerColumn.getControl();
+			Iterator e= fMouseListeners.iterator();
+			while (e.hasNext()) {
+				MouseListener listener= (MouseListener) e.next();
+				cc.addMouseListener(listener);
+			}
+			
+			layoutTextViewer();
+		}
+	}
+	
+	public void removeDecorator(int index) {
+		IVerticalRulerColumn column= (IVerticalRulerColumn) fDecorators.get(index);
+		fDecorators.remove(index);
+		Control cc= column.getControl();
+		if (cc != null && !cc.isDisposed())
+			cc.dispose();
+		layoutTextViewer();
+	}
+	
+	private void layoutTextViewer() {
+		
+		Control parent= fTextViewer.getTextWidget();
+		
+		if (fTextViewer instanceof ITextViewerExtension) {
+			ITextViewerExtension extension= (ITextViewerExtension) fTextViewer;
+			parent= extension.getControl();
+		}
+		
+		if (parent instanceof Composite && !parent.isDisposed())
+			((Composite) parent).layout(true);
+	}
+	
+	/*
+	 * @see IVerticalRuler#getControl()
+	 */
+	public Control getControl() {
+		return fComposite;
+	}
+	
+	/*
+	 * @see IVerticalRuler#createControl(Composite, ITextViewer)
+	 */
+	public Control createControl(Composite parent, ITextViewer textViewer) {
+		
+		fTextViewer= textViewer;
+		
+		fComposite= new Canvas(parent, SWT.NONE);
+		fComposite.setLayout(new RulerLayout());
+		
+		Iterator e= fDecorators.iterator();
+		while (e.hasNext()) {
+			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+			column.createControl(this, fComposite);
+		}
+		
+		fComposite.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				fTextViewer= null;		
+			}
+		});
+		
+		return fComposite;
+	}
+		
+	/*
+	 * @see IVerticalRuler#setModel(IAnnotationModel)
+	 */
+	public void setModel(IAnnotationModel model) {
+		
+		fModel= model;
+		
+		Iterator e= fDecorators.iterator();
+		while (e.hasNext()) {
+			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+			column.setModel(model);
+		}	
+	}
+	
+	/*
+	 * @see IVerticalRuler#getModel()
+	 */
+	public IAnnotationModel getModel() {
+		return fModel;
+	}
+	
+	/*
+	 * @see IVerticalRuler#update()
+	 */
+	public void update() {
+		if (fComposite != null && !fComposite.isDisposed()) {
+			Display d= fComposite.getDisplay();
+			if (d != null) {
+				d.asyncExec(new Runnable() {
+					public void run() {
+						Iterator e= fDecorators.iterator();
+						while (e.hasNext()) {
+							IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+							column.redraw();
+						}	
+					}
+				});
+			}	
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerExtension#setFont(Font)
+	 */
+	public void setFont(Font font) {
+		Iterator e= fDecorators.iterator();
+		while (e.hasNext()) {
+			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+			column.setFont(font);
+		}	
+	}
+	
+	/*
+	 * @see IVerticalRulerInfo#getWidth()
+	 */
+	public int getWidth() {
+		int width= 0;
+		Iterator e= fDecorators.iterator();
+		while (e.hasNext()) {
+			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+			width += column.getWidth();
+		}
+		return width;
+	}
+	
+	/*
+	 * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+	 */
+	public int getLineOfLastMouseButtonActivity() {
+		if (fLastMouseButtonActivityLine == -1)
+			fLastMouseButtonActivityLine= toDocumentLineNumber(fLocation.y);
+		return fLastMouseButtonActivityLine;
+	}
+	
+	/*
+	 * @see IVerticalRulerInfo#toDocumentLineNumber(int)
+	 */
+	public int toDocumentLineNumber(int y_coordinate) {
+		
+		if (fTextViewer == null)
+			return -1;
+			
+		StyledText text= fTextViewer.getTextWidget();
+		int line= ((y_coordinate + text.getTopPixel()) / text.getLineHeight());				
+		try {
+			IRegion r= fTextViewer.getVisibleRegion();
+			IDocument d= fTextViewer.getDocument(); 
+			line += d.getLineOfOffset(r.getOffset());
+		} catch (BadLocationException x) {
+		}
+		
+		return line;
+	}
+	
+	/*
+	 * @see IVerticalRulerInfo#addMouseListener
+	 */
+	public void addMouseListener(MouseListener listener) {
+		
+		fMouseListeners.add(listener);
+		
+		Iterator e= fDecorators.iterator();
+		while (e.hasNext()) {
+			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+			Control control= column.getControl();
+			if (control != null && !control.isDisposed())
+				control.addMouseListener(listener);
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerInfo#addMouseListener
+	 */
+	public void removeMouseListener(MouseListener listener) {
+		
+		int size= fMouseListeners.size();
+		for (int i= 0; i < size; i++) {
+			if (listener == fMouseListeners.get(i)) {
+				fMouseListeners.remove(i);
+				break;
+			}
+		}
+		
+		Iterator e= fDecorators.iterator();
+		while (e.hasNext()) {
+			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
+			Control control= column.getControl();
+			if (control != null && !control.isDisposed())
+				control.removeMouseListener(listener);
+		}
+	}
+	
+	/**
+	 * Returns this ruler's text viewer.
+	 * 
+	 * @return this ruler's text viewer
+	 */
+	public ITextViewer getTextViewer() {
+		return fTextViewer;
+	}
+	
+	/**
+	 * Sets the location of the last mouse button activity.
+	 */
+	public void setLocationOfLastMouseButtonActivity(int x, int y) {
+		fLocation.x= x;
+		fLocation.y= y;
+		fLastMouseButtonActivityLine= -1;
+	}
+}
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRuler.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRuler.java
index 943f5c2..be39a8f 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRuler.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRuler.java
@@ -30,9 +30,8 @@
  * by <code>VerticalRuler</code>.

  *  

  * @see ITextViewer

- * @see IVerticalRulerInfo

  */

-public interface IVerticalRuler extends IVerticalRulerInfo {

+public interface IVerticalRuler  {

 

 	/**

 	 * Associates an annotation model with this ruler.

@@ -67,5 +66,35 @@
 	 * @return the ruler's SWT control

 	 */

 	Control createControl(Composite parent, ITextViewer textViewer);

-

+	

+	/**

+	 * Returns the ruler's SWT control.

+	 *

+	 * @return the ruler's SWT control

+	 */

+	Control getControl();

+	

+	/**

+	 * Returns the line number of the last mouse button activity.

+	 * Based on the input document of the connected text viewer.

+	 *

+	 * @return the line number of the last mouse button activity

+	 */

+	int getLineOfLastMouseButtonActivity();

+	

+	/**

+	 * Translates a y-coordinate of the ruler's SWT control into

+	 * the according line number of the document of the connected text viewer.

+	 *

+	 * @param y_coordinate a y-coordinate of the ruler's SWT control

+	 * @return the line number of that coordinate 

+	 */

+	int toDocumentLineNumber(int y_coordinate);

+	

+	/**

+	 * Returns the width of this ruler's control.

+	 *

+	 * @return the width of this ruler's control

+	 */

+	int getWidth();

 }

diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerColumn.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerColumn.java
new file mode 100644
index 0000000..bba70fc
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerColumn.java
@@ -0,0 +1,61 @@
+package org.eclipse.jface.text.source;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+
+/**
+ * @see org.eclipse.jface.text.source.CompositeRuler
+ */
+public interface IVerticalRulerColumn {
+
+	/**
+	 * Associates an annotation model with this ruler column.
+	 * A value <code>null</code> is acceptable and clears the ruler.
+	 *
+	 * @param model the new annotation model, may be <code>null</code>
+	 */
+	void setModel(IAnnotationModel model);
+		
+	/**
+	 * Redraws this column.
+	 */
+	void redraw();
+	
+	/**
+	 * Creates the column's SWT control.
+	 *
+	 * @param parentRuler the parent ruler of this column
+	 * @param parentControl the control of the parent ruler
+	 * @return the column's SWT control
+	 */
+	Control createControl(CompositeRuler parentRuler, Composite parentControl);
+	
+	/**
+	 * Returns the column's SWT control.
+	 *
+	 * @return the column's SWT control
+	 */
+	Control getControl();
+	
+	/**
+	 * Returns the width of this column's control.
+	 *
+	 * @return the width of this column's control
+	 */
+	int getWidth();
+	
+	/**
+	 * Sets the font of this ruler column.
+	 * 
+	 * @param font the new font of the ruler column
+	 */
+	void setFont(Font font);
+}
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerExtension.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerExtension.java
new file mode 100644
index 0000000..e4908f5
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerExtension.java
@@ -0,0 +1,21 @@
+package org.eclipse.jface.text.source;
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+ 
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * Extension interface to <code>IVerticalRuler</code>.
+ */
+public interface IVerticalRulerExtension {
+	
+	/**
+	 * Sets the font of this vertical ruler.
+	 * 
+	 * @param font the new font of the vertical ruler
+	 */
+	void setFont(Font font);
+
+}
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerInfo.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerInfo.java
index b153168..3e3a345 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerInfo.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/IVerticalRulerInfo.java
@@ -10,7 +10,11 @@
 **********************************************************************/
 package org.eclipse.jface.text.source;
 
-import org.eclipse.swt.widgets.Control;
+
+
+import org.eclipse.swt.events.MouseListener;
+
+
 
 /**
  * The ruler info provides interested clients with mapping and
@@ -21,11 +25,18 @@
 public interface IVerticalRulerInfo {
 
 	/**
-	 * Returns the ruler's SWT control.
-	 *
-	 * @return the ruler's SWT control
+	 * Add the given mouse listener to this ruler info.
+	 * 
+	 * @param listener the listener to be added
 	 */
-	Control getControl();
+	void addMouseListener(MouseListener listener);
+	
+	/**
+	 * Remove the given mouse listener from this ruler info.
+	 * 
+	 * @param listener the listener to be removed
+	 */
+	void removeMouseListener(MouseListener listener);
 
 	/**
 	 * Returns the line number of the last mouse button activity.
@@ -50,5 +61,4 @@
 	 * @return the width of this ruler's control
 	 */
 	int getWidth();
-
 }
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/LineNumberRulerColumn.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/LineNumberRulerColumn.java
new file mode 100644
index 0000000..d99b249
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/LineNumberRulerColumn.java
@@ -0,0 +1,392 @@
+package org.eclipse.jface.text.source;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+
+import java.text.NumberFormat;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.IViewportListener;
+import org.eclipse.jface.text.TextEvent;
+
+
+/**
+ * A vertical ruler column displaying line numbers.
+ * Clients may use this class as is.
+ */
+public final class LineNumberRulerColumn implements IVerticalRulerColumn {
+	
+	/**
+	 * Internal listener class.
+	 */
+	class InternalListener implements IViewportListener, ITextListener {
+		
+		/*
+		 * @see IViewportListener#viewportChanged(int)
+		 */
+		public void viewportChanged(int verticalPosition) {
+			if (verticalPosition != fScrollPos)
+				redraw();
+		}
+		
+		/*
+		 * @see ITextListener#textChanged(TextEvent)
+		 */
+		public void textChanged(TextEvent event) {
+			if (fSensitiveToTextChanges || event.getDocumentEvent() == null) {
+				if (fCanvas != null && !fCanvas.isDisposed()) {
+					Display d= fCanvas.getDisplay();
+					if (d != null) {
+						d.asyncExec(new Runnable() {
+							public void run() {
+								redraw();
+							}
+						});
+					}	
+				}
+			}
+		}
+	};
+	
+	private final static int MAXDIGETS= 5;
+	
+	/** This column's parent ruler */
+	private CompositeRuler fParentRuler;
+	/** Cached text viewer */
+	private ITextViewer fCachedTextViewer;
+	/** Cached text widget */
+	private StyledText fCachedTextWidget;
+	/** The columns canvas */
+	private Canvas fCanvas;
+	/** Cache for the actual scroll position in pixels */
+	private int fScrollPos;
+	/** The drawable for double buffering */
+	private Image fBuffer;
+	/** The internal listener */
+	private InternalListener fInternalListener= new InternalListener();
+	/** The font of this column */
+	private Font fFont;
+	/** The indentation cache */
+	private int[] fIndentation;
+	/** Indicates whether this column reacts on text change events */
+	private boolean fSensitiveToTextChanges= false;
+	/** The foreground color */
+	private Color fForeground;
+	/** The background color */
+	private Color fBackground;
+	
+	
+	/**
+	 * Constructs the vertical ruler column.
+	 */
+	public LineNumberRulerColumn() {
+	}
+	
+	public void setForeground(Color foreground) {
+		fForeground= foreground;
+	}
+	
+	public void setBackground(Color background) {
+		fBackground= background;			
+		if (fCanvas != null && !fCanvas.isDisposed())
+			fCanvas.setBackground(getBackground(fCanvas.getDisplay()));
+	}
+	
+	protected Color getBackground(Display display) {
+		if (fBackground == null)
+			return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+		return fBackground;
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#getControl()
+	 */
+	public Control getControl() {
+		return fCanvas;
+	}
+	
+	/*
+	 * @see IVerticalRuleColumnr#getWidth
+	 */
+	public int getWidth() {
+		return fIndentation[0];
+	}
+		
+	/**
+	 * Computes the indentations for the given font.
+	 */
+	protected void computeIndentations() {
+		GC gc= new GC(fCanvas);
+		try {
+			
+			gc.setFont(fCanvas.getFont());
+			NumberFormat nf= NumberFormat.getInstance();
+			
+			fIndentation= new int[MAXDIGETS + 1];
+			
+			double number= Math.pow(10, MAXDIGETS) - 1;
+			Point p= gc.stringExtent(nf.format(number));
+			fIndentation[0]= p.x;
+			
+			for (int i= 1; i <= MAXDIGETS; i++) {
+				number= Math.pow(10, i) - 1;
+				p= gc.stringExtent(nf.format(number));
+				fIndentation[i]= fIndentation[0] - p.x;
+			}
+		
+		} finally {
+			gc.dispose();
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite)
+	 */
+	public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+		
+		fParentRuler= parentRuler;
+		fCachedTextViewer= parentRuler.getTextViewer();
+		fCachedTextWidget= fCachedTextViewer.getTextWidget();
+		
+		fCanvas= new Canvas(parentControl, SWT.NONE);
+		fCanvas.setBackground(getBackground(fCanvas.getDisplay()));
+		fCanvas.setForeground(fForeground);
+			
+		fCanvas.addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent event) {
+				if (fCachedTextViewer != null)
+					doubleBufferPaint(event.gc);
+			}
+		});
+		
+		fCanvas.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				handleDispose();
+				fCachedTextViewer= null;
+				fCachedTextWidget= null;
+			}
+		});
+		
+		fCanvas.addMouseListener(new MouseListener() {
+			public void mouseUp(MouseEvent event) {
+			}
+			
+			public void mouseDown(MouseEvent event) {
+				fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+				selectLine(fParentRuler.getLineOfLastMouseButtonActivity());
+			}
+			
+			public void mouseDoubleClick(MouseEvent event) {
+				fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+			}
+		});
+		
+		if (fCachedTextViewer != null) {
+			
+			fCachedTextViewer.addViewportListener(fInternalListener);
+			fCachedTextViewer.addTextListener(fInternalListener);
+			
+			if (fFont == null) {
+				if (fCachedTextWidget != null && !fCachedTextWidget.isDisposed())
+					fFont= fCachedTextWidget.getFont();
+			}
+		}
+		
+		if (fFont != null)
+			fCanvas.setFont(fFont);
+			
+		computeIndentations();
+		return fCanvas;
+	}
+
+	/**
+	 * Selects the given line in the text viewer.
+	 * @param line
+	 */
+	private void selectLine(int line) {
+		try {
+			IDocument document= fCachedTextViewer.getDocument();
+			int offset= document.getLineOffset(fParentRuler.getLineOfLastMouseButtonActivity());
+			fCachedTextViewer.setSelectedRange(offset, 0);
+		} catch (BadLocationException x) {
+		}
+	}
+	
+	/**
+	 * Disposes the column's resources.
+	 */
+	private void handleDispose() {
+		
+		if (fCachedTextViewer != null) {
+			fCachedTextViewer.removeViewportListener(fInternalListener);
+			fCachedTextViewer.removeTextListener(fInternalListener);
+		}
+		
+		if (fBuffer != null) {
+			fBuffer.dispose();
+			fBuffer= null;
+		}
+	}
+	
+	/**
+	 * Double buffer drawing.
+	 */
+	private void doubleBufferPaint(GC dest) {
+		
+		Point size= fCanvas.getSize();
+		
+		if (size.x <= 0 || size.y <= 0)
+			return;
+		
+		if (fBuffer != null) {
+			Rectangle r= fBuffer.getBounds();
+			if (r.width != size.x || r.height != size.y) {
+				fBuffer.dispose();
+				fBuffer= null;
+			}
+		}
+		if (fBuffer == null)
+			fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+			
+		GC gc= new GC(fBuffer);
+		gc.setFont(fCanvas.getFont());
+		if (fForeground != null)
+			gc.setForeground(fForeground);
+		
+		try {
+			gc.setBackground(getBackground(fCanvas.getDisplay()));
+			gc.fillRectangle(0, 0, size.x, size.y);
+			doPaint(gc);
+		} finally {
+			gc.dispose();
+		}
+		
+		dest.drawImage(fBuffer, 0, 0);
+	}
+	
+	/**
+	 * Returns the viewport height in lines.
+	 *
+	 * @return the viewport height in lines
+	 */
+	protected int getVisibleLinesInViewport() {
+		Rectangle clArea= fCachedTextWidget.getClientArea();
+		if (!clArea.isEmpty())
+			return clArea.height / fCachedTextWidget.getLineHeight();
+		return -1;
+	}
+	
+	/**
+	 * Draws the ruler column.
+	 */
+	private void doPaint(GC gc) {
+		
+		if (fCachedTextViewer == null)
+			return;
+			
+		
+		int firstLine= 0;
+			
+		int topLine= fCachedTextViewer.getTopIndex() -1;
+		int bottomLine= fCachedTextViewer.getBottomIndex() + 1;
+		
+		try {
+			
+			IRegion region= fCachedTextViewer.getVisibleRegion();
+			IDocument doc= fCachedTextViewer.getDocument();
+			
+			firstLine= doc.getLineOfOffset(region.getOffset());
+			if (firstLine > topLine)
+				topLine= firstLine;
+					
+			int lastLine= doc.getLineOfOffset(region.getOffset() + region.getLength());
+			if (lastLine < bottomLine)
+				bottomLine= lastLine;
+				
+		} catch (BadLocationException x) {
+			return;
+		}
+		
+		fSensitiveToTextChanges= bottomLine - topLine < getVisibleLinesInViewport();
+		
+		int lineheight= fCachedTextWidget.getLineHeight();
+		fScrollPos= fCachedTextWidget.getTopPixel();
+		int canvasheight= fCanvas.getSize().y;
+
+		NumberFormat nf= NumberFormat.getInstance();
+		int y= ((topLine - firstLine) * lineheight) - fScrollPos + fCachedTextViewer.getTopInset();
+		for (int line= topLine; line <= bottomLine; line++, y+= lineheight) {
+			
+			if (y >= canvasheight)
+				break;
+				
+			String s= Integer.toString(line + 1);
+			int length= s.length();
+			if (length <= MAXDIGETS) {
+				int indentation= fIndentation[s.length()];
+				gc.drawString(nf.format(line + 1), indentation, y);
+			} else {
+				StringBuffer buffer= new StringBuffer();
+				buffer.append(s.substring(length - MAXDIGETS, length));
+				if (MAXDIGETS >= 2)
+					buffer.replace(0, 2, "..");
+				gc.drawString(buffer.toString(), 0, y);
+			}
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#redraw
+	 */
+	public void redraw() {
+		if (fCanvas != null && !fCanvas.isDisposed()) {
+			GC gc= new GC(fCanvas);
+			doubleBufferPaint(gc);
+			gc.dispose();
+		}
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#setModel(IAnnotationModel)
+	 */
+	public void setModel(IAnnotationModel model) {
+	}
+	
+	/*
+	 * @see IVerticalRulerColumn#setFont(Font)
+	 */
+	public void setFont(Font font) {
+		fFont= font;
+		if (fCanvas != null && !fCanvas.isDisposed()) {
+			fCanvas.setFont(fFont);
+			computeIndentations();
+		}
+	}
+}
diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/SourceViewer.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/SourceViewer.java
index 4a51648..6e3aacc 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/SourceViewer.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/SourceViewer.java
@@ -105,7 +105,7 @@
 	

 	

 	/** The size of the gap between the vertical ruler and the text widget */

-	protected final static int GAP_SIZE= 0;

+	protected final static int GAP_SIZE= 2;

 	

 	/**

 	 * Constructs a new source viewer. The vertical ruler is initially visible.

diff --git a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/VerticalRuler.java b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/VerticalRuler.java
index 2b0323b..de0a506 100644
--- a/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/VerticalRuler.java
+++ b/bundles/org.eclipse.ui/Eclipse JFace Text/org/eclipse/jface/text/source/VerticalRuler.java
@@ -43,7 +43,7 @@
  *

  * @see ITextViewer

  */

-public final class VerticalRuler implements IVerticalRuler {

+public final class VerticalRuler implements IVerticalRuler, IVerticalRulerInfo {

 	

 	/**

 	 * Internal listener class.

@@ -51,7 +51,7 @@
 	class InternalListener implements IViewportListener, IAnnotationModelListener, ITextListener {

 		

 		/*

-		 * @see IViewportListener#viewportChanged

+		 * @see IViewportListener#viewportChanged(int)

 		 */

 		public void viewportChanged(int verticalPosition) {

 			if (verticalPosition != fScrollPos)

@@ -59,14 +59,14 @@
 		}

 		

 		/*

-		 * @see IAnnotationModelListener#modelChanged

+		 * @see IAnnotationModelListener#modelChanged(IAnnotationModel)

 		 */

 		public void modelChanged(IAnnotationModel model) {

 			update();

 		}

 		

 		/*

-		 * @see ITextListener#textChanged

+		 * @see ITextListener#textChanged(TextEvent)

 		 */

 		public void textChanged(TextEvent e) {

 			if (fTextViewer != null)

@@ -101,21 +101,14 @@
 	}

 	

 	/*

-	 * @see IVerticalRuler#getControl

+	 * @see IVerticalRuler#getControl()

 	 */

 	public Control getControl() {

 		return fCanvas;

 	}

 	

 	/*

-	 * @see IVerticalRuler#getWidth

-	 */

-	public int getWidth() {

-		return fWidth;

-	}

-	

-	/*

-	 * @see IVerticalRuler#createControl

+	 * @see IVerticalRuler#createControl(Composite, ITextViewer)

 	 */

 	public Control createControl(Composite parent, ITextViewer textViewer) {

 		

@@ -303,7 +296,7 @@
 	 * Can be called from any thread.

 	 */

 	/*

-	 * @see IVerticalRuler#update

+	 * @see IVerticalRuler#update()

 	 */

 	public void update() {

 		if (fCanvas != null && !fCanvas.isDisposed()) {

@@ -331,7 +324,7 @@
 	}

 	

 	/*

-	 * @see IVerticalRuler#setModel

+	 * @see IVerticalRuler#setModel(IAnnotationModel)

 	 */

 	public void setModel(IAnnotationModel model) {

 		if (model != fModel) {

@@ -349,21 +342,28 @@
 	}

 		

 	/*

-	 * @see IVerticalRuler#getModel

+	 * @see IVerticalRuler#getModel()

 	 */

 	public IAnnotationModel getModel() {

 		return fModel;

 	}

 	

 	/*

-	 * @see IVerticalRuler#getLineOfLastMouseButtonActivity()

+	 * @see IVerticalRulerInfo#getWidth()

+	 */

+	public int getWidth() {

+		return fWidth;

+	}

+	

+	/*

+	 * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()

 	 */

 	public int getLineOfLastMouseButtonActivity() {

 		return fLastMouseButtonActivityLine;

 	}

-		

+	

 	/*

-	 * @see IVerticalRuler#toDocumentLineNumber

+	 * @see IVerticalRulerInfo#toDocumentLineNumber(int)

 	 */

 	public int toDocumentLineNumber(int y_coordinate) {

 		

@@ -381,4 +381,18 @@
 		

 		return line;

 	}

+	

+	/*

+	 * @see IVerticalRulerInfo#addMouseListener

+	 */

+	public void addMouseListener(MouseListener listener) {

+		fCanvas.addMouseListener(listener);

+	}

+	

+	/*

+	 * @see IVerticalRulerInfo#addMouseListener

+	 */

+	public void removeMouseListener(MouseListener listener) {

+		fCanvas.removeMouseListener(listener);

+	}

 }

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/FileDocumentProvider.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/FileDocumentProvider.java
index f566c6c..7b86662 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/FileDocumentProvider.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/FileDocumentProvider.java
@@ -7,6 +7,7 @@
 

 

 import java.io.ByteArrayInputStream;

+import java.io.IOException;

 import java.io.InputStream;

 

 import org.eclipse.core.resources.IFile;

@@ -314,38 +315,47 @@
 		if (element instanceof IFileEditorInput) {

 			

 			IFileEditorInput input= (IFileEditorInput) element;

-			InputStream stream= new ByteArrayInputStream(document.get().getBytes());

 			

+//			try {

+			

+			InputStream stream= new ByteArrayInputStream(document.get().getBytes());

+//			InputStream stream= new ByteArrayInputStream(document.get().getBytes(ResourcesPlugin.getEncoding()));

 			IFile file= input.getFile();

 									

-			if (file.exists()) {				

-				

-				FileInfo info= (FileInfo) getElementInfo(element);

-				

-				if (info != null && !overwrite)

-					checkSynchronizationState(info.fModificationStamp, file);

-				

-				file.setContents(stream, overwrite, true, monitor);

-				

-				if (info != null) {

-										

-					ResourceMarkerAnnotationModel model= (ResourceMarkerAnnotationModel) info.fModel;

-					model.updateMarkers(info.fDocument);

+				if (file.exists()) {

 					

-					info.fModificationStamp= computeModificationStamp(file);

+					FileInfo info= (FileInfo) getElementInfo(element);

+					

+					if (info != null && !overwrite)

+						checkSynchronizationState(info.fModificationStamp, file);

+					

+					file.setContents(stream, overwrite, true, monitor);

+					

+					if (info != null) {

+											

+						ResourceMarkerAnnotationModel model= (ResourceMarkerAnnotationModel) info.fModel;

+						model.updateMarkers(info.fDocument);

+						

+						info.fModificationStamp= computeModificationStamp(file);

+					}

+					

+				} else {

+					try {

+						monitor.beginTask(TextEditorMessages.getString("FileDocumentProvider.task.saving"), 2000); //$NON-NLS-1$

+						ContainerGenerator generator = new ContainerGenerator(file.getParent().getFullPath());

+						generator.generateContainer(new SubProgressMonitor(monitor, 1000));

+						file.create(stream, false, new SubProgressMonitor(monitor, 1000));

+					}

+					finally {

+						monitor.done();

+					}

 				}

 				

-			} else {

-				try {

-					monitor.beginTask(TextEditorMessages.getString("FileDocumentProvider.task.saving"), 2000); //$NON-NLS-1$

-					ContainerGenerator generator = new ContainerGenerator(file.getParent().getFullPath());

-					generator.generateContainer(new SubProgressMonitor(monitor, 1000));

-					file.create(stream, false, new SubProgressMonitor(monitor, 1000));

-				}

-				finally {

-					monitor.done();

-				}

-			}

+//			} catch (IOException x) {

+//				IStatus s= new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, x.getMessage(), x);

+//				throw new CoreException(s);

+//			}

+			

 		} else {

 			super.doSaveDocument(monitor, element, document, overwrite);

 		}

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/StorageDocumentProvider.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/StorageDocumentProvider.java
index 8b12726..9244ac3 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/StorageDocumentProvider.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/StorageDocumentProvider.java
@@ -13,6 +13,7 @@
 import java.io.Reader;

 

 import org.eclipse.core.resources.IStorage;

+import org.eclipse.core.resources.ResourcesPlugin;

 import org.eclipse.core.runtime.CoreException;

 import org.eclipse.core.runtime.ILog;

 import org.eclipse.core.runtime.IProgressMonitor;

@@ -69,6 +70,7 @@
 		try {

 			

 			in= new InputStreamReader(new BufferedInputStream(contentStream));

+//			in= new InputStreamReader(new BufferedInputStream(contentStream), ResourcesPlugin.getEncoding());

 			StringBuffer buffer= new StringBuffer();

 			char[] readBuffer= new char[2048];

 			int n= in.read(readBuffer);

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditor.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditor.java
index ba10f7c..54deebb 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditor.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditor.java
@@ -156,10 +156,10 @@
 	protected void createActions() {

 		super.createActions();

 

-		ResourceAction action= new ConvertLineDelimitersAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToDOS.", this, "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$

-		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONVERT_LINE_DELIMITERS_TO_DOS);

-		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONVERT_LINE_DELIMITERS_TO_DOS);

-		setAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_DOS, action);

+		ResourceAction action= new ConvertLineDelimitersAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToWindows.", this, "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$

+		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONVERT_LINE_DELIMITERS_TO_WINDOWS);

+		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONVERT_LINE_DELIMITERS_TO_WINDOWS);

+		setAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS, action);

 

 		action= new ConvertLineDelimitersAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToUNIX.", this, "\n"); //$NON-NLS-1$ //$NON-NLS-2$

 		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONVERT_LINE_DELIMITERS_TO_UNIX);

@@ -169,7 +169,11 @@
 		action= new ConvertLineDelimitersAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToMac.", this, "\r"); //$NON-NLS-1$ //$NON-NLS-2$

 		action.setHelpContextId(IAbstractTextEditorHelpContextIds.CONVERT_LINE_DELIMITERS_TO_MAC);

 		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONVERT_LINE_DELIMITERS_TO_MAC);

-		setAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC, action);				

+		setAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC, action);

+		

+		markAsContentDependentAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS, true);

+		markAsContentDependentAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX, true);

+		markAsContentDependentAction(ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC, true);

 	}

 

 }

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorActionContributor.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorActionContributor.java
index d3176b1..b81f2ad 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorActionContributor.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorActionContributor.java
@@ -14,8 +14,8 @@
  */
 public class TextEditorActionContributor extends BasicTextEditorActionContributor {
 
-	/** Convert to DOS action. */
-	private RetargetTextEditorAction fConvertToDOS;
+	/** Convert to Windows action. */
+	private RetargetTextEditorAction fConvertToWindows;
 	/** Convert to UNIX action. */
 	private RetargetTextEditorAction fConvertToUNIX;
 	/** Convert to Mac action. */
@@ -24,7 +24,7 @@
 
 	public TextEditorActionContributor() {
 		super();
-		fConvertToDOS= new RetargetTextEditorAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToDOS."); //$NON-NLS-1$ 
+		fConvertToWindows= new RetargetTextEditorAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToWindows."); //$NON-NLS-1$ 
 		fConvertToUNIX= new RetargetTextEditorAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToUNIX."); //$NON-NLS-1$ 
 		fConvertToMac= new RetargetTextEditorAction(TextEditorMessages.getResourceBundle(), "Editor.ConvertToMac."); //$NON-NLS-1$ 
 	}	
@@ -40,7 +40,7 @@
 
 		ITextEditor textEditor= (ITextEditor) part;
 
-		fConvertToDOS.setAction(getAction(textEditor, ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_DOS));
+		fConvertToWindows.setAction(getAction(textEditor, ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS));
 		fConvertToUNIX.setAction(getAction(textEditor, ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX));
 		fConvertToMac.setAction(getAction(textEditor, ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC));
 	}
@@ -53,7 +53,7 @@
 		if (editMenu != null) {
 			MenuManager subMenu= new MenuManager(TextEditorMessages.getString("Editor.ConvertLineDelimiters.label")); //$NON-NLS-1$
 
-			subMenu.add(fConvertToDOS);
+			subMenu.add(fConvertToWindows);
 			subMenu.add(fConvertToUNIX);
 			subMenu.add(fConvertToMac);
 	
diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorMessages.properties b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorMessages.properties
index d37a3a9..7dea5da 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorMessages.properties
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/editors/text/TextEditorMessages.properties
@@ -23,10 +23,10 @@
 

 Editor.ConvertLineDelimiters.label=C&onvert Line Delimiters

 

-Editor.ConvertToDOS.label=To &DOS

-Editor.ConvertToDOS.tooltip=Converts line delimiters to DOS

-Editor.ConvertToDOS.image=

-Editor.ConvertToDOS.description=Converts line delimiters to DOS

+Editor.ConvertToWindows.label=To &Windows

+Editor.ConvertToWindows.tooltip=Converts line delimiters to Windows

+Editor.ConvertToWindows.image=

+Editor.ConvertToWindows.description=Converts line delimiters to Windows

 

 Editor.ConvertToUNIX.label=To &UNIX

 Editor.ConvertToUNIX.tooltip=Converts line delimiters to UNIX

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractDocumentProvider.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractDocumentProvider.java
index 9a5fdbd..b245abe 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractDocumentProvider.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractDocumentProvider.java
@@ -282,11 +282,9 @@
 		

 		if (info.fCount == 1) {

 			

-			removeUnchangedElementListeners(element, info);

-			

-			disposeElementInfo(element, info);

-			

 			fElementInfoMap.remove(element);

+			removeUnchangedElementListeners(element, info);

+			disposeElementInfo(element, info);

 			

 		} else

 		 	-- info.fCount;

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractRulerActionDelegate.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractRulerActionDelegate.java
index eaf714a..684a67f 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractRulerActionDelegate.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractRulerActionDelegate.java
@@ -36,11 +36,8 @@
 	public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) {
 		if (fEditor != null) {
 			IVerticalRulerInfo rulerInfo= (IVerticalRulerInfo) fEditor.getAdapter(IVerticalRulerInfo.class);
-			if (rulerInfo != null) {
-				Control control= rulerInfo.getControl();
-				if (!control.isDisposed())
-					control.removeMouseListener(this);	
-			}
+			if (rulerInfo != null)
+				rulerInfo.removeMouseListener(this);
 		}
 
 		fEditor= targetEditor;		
@@ -52,10 +49,7 @@
 			if (rulerInfo != null) {
 				fAction= createAction((ITextEditor) fEditor, rulerInfo);
 				update();
-
-				Control control= rulerInfo.getControl();
-				if (!control.isDisposed())
-					control.addMouseListener(this);
+				rulerInfo.addMouseListener(this);
 			}
 		}
 	}
diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractTextEditor.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractTextEditor.java
index d279cea..fa804e7 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractTextEditor.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/AbstractTextEditor.java
@@ -15,24 +15,6 @@
 import java.util.Iterator;

 import java.util.List;

 import java.util.Map;

-import java.util.MissingResourceException;

-import java.util.ResourceBundle;

-

-import org.eclipse.core.internal.plugins.ConfigurationElement;

-import org.eclipse.core.resources.IMarker;

-import org.eclipse.core.resources.IStorage;

-import org.eclipse.core.runtime.CoreException;

-import org.eclipse.core.runtime.IConfigurationElement;

-import org.eclipse.core.runtime.IExtensionPoint;

-import org.eclipse.core.runtime.ILog;

-import org.eclipse.core.runtime.IPluginDescriptor;

-import org.eclipse.core.runtime.IPluginPrerequisite;

-import org.eclipse.core.runtime.IPluginRegistry;

-import org.eclipse.core.runtime.IProgressMonitor;

-import org.eclipse.core.runtime.IStatus;

-import org.eclipse.core.runtime.NullProgressMonitor;

-import org.eclipse.core.runtime.Platform;

-import org.eclipse.core.runtime.Status;

 

 import org.eclipse.swt.SWT;

 import org.eclipse.swt.custom.ST;

@@ -44,7 +26,6 @@
 import org.eclipse.swt.events.MouseListener;

 import org.eclipse.swt.events.ShellAdapter;

 import org.eclipse.swt.events.ShellEvent;

-import org.eclipse.swt.events.ShellListener;

 import org.eclipse.swt.events.VerifyEvent;

 import org.eclipse.swt.events.VerifyListener;

 import org.eclipse.swt.graphics.Color;

@@ -59,6 +40,20 @@
 import org.eclipse.swt.widgets.Menu;

 import org.eclipse.swt.widgets.Shell;

 

+import org.eclipse.core.resources.IMarker;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.core.runtime.IConfigurationElement;

+import org.eclipse.core.runtime.IExtensionPoint;

+import org.eclipse.core.runtime.ILog;

+import org.eclipse.core.runtime.IPluginDescriptor;

+import org.eclipse.core.runtime.IPluginPrerequisite;

+import org.eclipse.core.runtime.IPluginRegistry;

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.NullProgressMonitor;

+import org.eclipse.core.runtime.Platform;

+import org.eclipse.core.runtime.Status;

+

 import org.eclipse.jface.action.Action;

 import org.eclipse.jface.action.IAction;

 import org.eclipse.jface.action.IMenuListener;

@@ -67,13 +62,11 @@
 import org.eclipse.jface.action.MenuManager;

 import org.eclipse.jface.action.Separator;

 import org.eclipse.jface.dialogs.ErrorDialog;

-import org.eclipse.jface.dialogs.IDialogConstants;

 import org.eclipse.jface.dialogs.MessageDialog;

 import org.eclipse.jface.preference.IPreferenceStore;

 import org.eclipse.jface.preference.PreferenceConverter;

 import org.eclipse.jface.resource.ImageDescriptor;

 import org.eclipse.jface.resource.JFaceResources;

-

 import org.eclipse.jface.text.BadLocationException;

 import org.eclipse.jface.text.IDocument;

 import org.eclipse.jface.text.IFindReplaceTarget;

@@ -90,11 +83,11 @@
 import org.eclipse.jface.text.source.IAnnotationModel;

 import org.eclipse.jface.text.source.ISourceViewer;

 import org.eclipse.jface.text.source.IVerticalRuler;

+import org.eclipse.jface.text.source.IVerticalRulerExtension;

 import org.eclipse.jface.text.source.IVerticalRulerInfo;

 import org.eclipse.jface.text.source.SourceViewer;

 import org.eclipse.jface.text.source.SourceViewerConfiguration;

 import org.eclipse.jface.text.source.VerticalRuler;

-

 import org.eclipse.jface.util.Assert;

 import org.eclipse.jface.util.IPropertyChangeListener;

 import org.eclipse.jface.util.PropertyChangeEvent;

@@ -107,18 +100,16 @@
 import org.eclipse.ui.IEditorInput;

 import org.eclipse.ui.IEditorRegistry;

 import org.eclipse.ui.IEditorSite;

-import org.eclipse.ui.IFileEditorInput;

 import org.eclipse.ui.IKeyBindingService;

 import org.eclipse.ui.IPartListener;

 import org.eclipse.ui.IReusableEditor;

-import org.eclipse.ui.IStorageEditorInput;

 import org.eclipse.ui.IWorkbenchPart;

 import org.eclipse.ui.IWorkbenchWindow;

 import org.eclipse.ui.PartInitException;

 import org.eclipse.ui.PlatformUI;

 import org.eclipse.ui.actions.WorkspaceModifyOperation;

-import org.eclipse.ui.internal.EditorPluginAction;

 import org.eclipse.ui.help.WorkbenchHelp;

+import org.eclipse.ui.internal.EditorPluginAction;

 import org.eclipse.ui.part.EditorActionBarContributor;

 import org.eclipse.ui.part.EditorPart;

 

@@ -193,23 +184,28 @@
 		 * @see IElementStateListenerExtension#elementStateValidationChanged(Object, boolean)

 		 */

 		public void elementStateValidationChanged(Object element, boolean isStateValidated) {

-			if (isStateValidated && fValidator != null) {

-				ISourceViewer viewer= getSourceViewer();

-				if (viewer != null) {

-					StyledText textWidget= viewer.getTextWidget();

-					if (textWidget != null && !textWidget.isDisposed())

-						textWidget.removeVerifyListener(fValidator);

-					fValidator= null;

-				}

-			} else if (!isStateValidated && fValidator == null) {

-				ISourceViewer viewer= getSourceViewer();

-				if (viewer != null) {

-					StyledText textWidget= viewer.getTextWidget();

-					if (textWidget != null && !textWidget.isDisposed()) {

-						fValidator= new Validator();

-						textWidget.addVerifyListener(fValidator);

+

+			if (element != null && element.equals(getEditorInput())) {

+

+				if (isStateValidated && fValidator != null) {

+					ISourceViewer viewer= getSourceViewer();

+					if (viewer != null) {

+						StyledText textWidget= viewer.getTextWidget();

+						if (textWidget != null && !textWidget.isDisposed())

+							textWidget.removeVerifyListener(fValidator);

+						fValidator= null;

+					}

+				} else if (!isStateValidated && fValidator == null) {

+					ISourceViewer viewer= getSourceViewer();

+					if (viewer != null) {

+						StyledText textWidget= viewer.getTextWidget();

+						if (textWidget != null && !textWidget.isDisposed()) {

+							fValidator= new Validator();

+							textWidget.addVerifyListener(fValidator);

+						}

 					}

 				}

+				

 			}

 		}

 		

@@ -385,7 +381,14 @@
 						if (action instanceof IUpdate)

 							((IUpdate) action).update();

 						

-						if (action.isEnabled()) {

+						if (!action.isEnabled() && action instanceof IReadOnlyDependent) {

+							IReadOnlyDependent dependent= (IReadOnlyDependent) action;

+							boolean writable= dependent.isEnabled(true);

+							if (writable) {

+								event.doit= false;

+								return;

+							}

+						} else if (action.isEnabled()) {

 							event.doit= false;

 							action.run();

 							return;

@@ -566,7 +569,7 @@
 	};

 	

 	/**

-	 * Internal action for scroll the editor's viewer by a specified number of lines.

+	 * Internal action to scroll the editor's viewer by a specified number of lines.

 	 */

 	class ScrollLinesAction extends Action {

 		

@@ -586,6 +589,19 @@
 			viewer.setTopIndex(newTopIndex);

 		}

 	};

+

+	/**

+	 * Internal action to show the editor's ruler context menu (accessibility).

+	 */		

+	private class ShowRulerContextMenuAction extends Action {

+

+		/*

+		 * @see IAction#run()

+		 */

+		public void run() {

+				fRulerContextMenu.setVisible(true);

+		}		

+	}

 	

 	

 	

@@ -1184,7 +1200,7 @@
 	 * source viewer. Subclasses may extend.

 	 */

 	public void createPartControl(Composite parent) {

-				

+		

 		fVerticalRuler= createVerticalRuler();

 		

 		int styles= SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;

@@ -1235,14 +1251,21 @@
 			fEditorContextMenuId= DEFAULT_EDITOR_CONTEXT_MENU_ID;

 		

 		

-		Control ruler= fVerticalRuler.getControl();

 		id= fRulerContextMenuId != null ? fRulerContextMenuId : DEFAULT_RULER_CONTEXT_MENU_ID;

 		manager= new MenuManager(id, id);

 		manager.setRemoveAllWhenShown(true);

 		manager.addMenuListener(getContextMenuListener());		

-		fRulerContextMenu= manager.createContextMenu(ruler);

-		ruler.setMenu(fRulerContextMenu);

-		ruler.addMouseListener(getRulerMouseListener());

+		

+		Control rulerControl= fVerticalRuler.getControl();

+		fRulerContextMenu= manager.createContextMenu(rulerControl);

+		rulerControl.setMenu(fRulerContextMenu);

+		

+		if (fVerticalRuler instanceof IVerticalRulerInfo) {

+			IVerticalRulerInfo info= (IVerticalRulerInfo) fVerticalRuler;

+			info.addMouseListener(getRulerMouseListener());

+		} else {

+			rulerControl.addMouseListener(getRulerMouseListener());

+		}

 		

 		if (fRulerContextMenuId != null)

 			getSite().registerContextMenu(fRulerContextMenuId, manager, getSelectionProvider());

@@ -1262,6 +1285,7 @@
 		

 		fActivationCodeTrigger.install();

 		createNavigationActions();

+		createAccessibilityActions();

 		createActions();

 		

 		initializeSourceViewer(getEditorInput());

@@ -1314,16 +1338,41 @@
 			int topIndex= sourceViewer.getTopIndex();

 			

 			StyledText styledText= sourceViewer.getTextWidget();

-			styledText.setRedraw(false);

+			Control parent= styledText;

+			if (sourceViewer instanceof ITextViewerExtension) {

+				ITextViewerExtension extension= (ITextViewerExtension) sourceViewer;

+				parent= extension.getControl();

+			}

+			

+			parent.setRedraw(false);

 			

 			styledText.setFont(font);

+			

+			if (fVerticalRuler instanceof IVerticalRulerExtension) {

+				IVerticalRulerExtension e= (IVerticalRulerExtension) fVerticalRuler;

+				e.setFont(font);

+			}
+			

 			sourceViewer.setSelectedRange(selection.x , selection.y);

 			sourceViewer.setTopIndex(topIndex);

 			

-			styledText.setRedraw(true);

+			if (parent instanceof Composite) {

+				Composite composite= (Composite) parent;

+				composite.layout(true);

+			}

+			

+			parent.setRedraw(true);

+			

+			

 		} else {

+			

 			StyledText styledText= sourceViewer.getTextWidget();

 			styledText.setFont(font);

+			

+			if (fVerticalRuler instanceof IVerticalRulerExtension) {

+				IVerticalRulerExtension e= (IVerticalRulerExtension) fVerticalRuler;

+				e.setFont(font);

+			}

 		}	

 	}

 	

@@ -1701,7 +1750,14 @@
 		String msg;

 		Shell shell= getSite().getShell();

 		

-		if (getDocumentProvider().isDeleted(getEditorInput())) {

+		IDocumentProvider provider= getDocumentProvider();

+		if (provider == null) {

+			// fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=15066

+			close(false);

+			return;

+		}

+		

+		if (provider.isDeleted(getEditorInput())) {

 			

 			if (isSaveAsAllowed()) {

 			

@@ -1744,9 +1800,13 @@
 					msg= EditorMessages.getString("Editor.error.refresh.outofsync.message"); //$NON-NLS-1$

 					ErrorDialog.openError(shell, title, msg, x.getStatus());

 				}

-			} else {

-				markEditorAsDirty();

-			}

+			} 

+			

+//			// disabled because of http://bugs.eclipse.org/bugs/show_bug.cgi?id=15166

+//			else {

+//				markEditorAsDirty();

+//			}

+

 		}

 	}

 

@@ -2318,6 +2378,15 @@
 		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SCROLL_LINE_DOWN);

 		setAction(ITextEditorActionDefinitionIds.SCROLL_LINE_DOWN, action);

 	}

+

+	/**

+	 * Creates this editor's accessibility actions.

+	 */

+	private void createAccessibilityActions() {

+		IAction action= new ShowRulerContextMenuAction();

+		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_RULER_CONTEXT_MENU);

+		setAction(ITextEditorActionDefinitionIds.SHOW_RULER_CONTEXT_MENU, action);

+	}

 	

 	/**

 	 * Creates this editor's standard actions and connects them with the global

@@ -2365,12 +2434,12 @@
 		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_ALL);

 		setAction(ITextEditorActionConstants.SELECT_ALL, action);

 		

-		action= new TextOperationAction(EditorMessages.getResourceBundle(), "Editor.ShiftRight.", this, ITextOperationTarget.SHIFT_RIGHT); //$NON-NLS-1$

+		action= new ShiftAction(EditorMessages.getResourceBundle(), "Editor.ShiftRight.", this, ITextOperationTarget.SHIFT_RIGHT); //$NON-NLS-1$

 		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SHIFT_RIGHT_ACTION);

 		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHIFT_RIGHT);

 		setAction(ITextEditorActionConstants.SHIFT_RIGHT, action);

 		

-		action= new TextOperationAction(EditorMessages.getResourceBundle(), "Editor.ShiftLeft.", this, ITextOperationTarget.SHIFT_LEFT); //$NON-NLS-1$

+		action= new ShiftAction(EditorMessages.getResourceBundle(), "Editor.ShiftLeft.", this, ITextOperationTarget.SHIFT_LEFT); //$NON-NLS-1$

 		action.setHelpContextId(IAbstractTextEditorHelpContextIds.SHIFT_LEFT_ACTION);

 		action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHIFT_LEFT);

 		setAction(ITextEditorActionConstants.SHIFT_LEFT, action);

@@ -2448,6 +2517,7 @@
 		markAsStateDependentAction(ITextEditorActionConstants.DELETE, true);

 		markAsStateDependentAction(ITextEditorActionConstants.SHIFT_RIGHT, true);

 		markAsStateDependentAction(ITextEditorActionConstants.SHIFT_LEFT, true);

+		markAsStateDependentAction(ITextEditorActionConstants.FIND, true);

 		

 		setActionActivationCode(ITextEditorActionConstants.SHIFT_RIGHT,'\t', 0, 0);

 		setActionActivationCode(ITextEditorActionConstants.SHIFT_LEFT, '\t', 0, SWT.SHIFT);

@@ -2568,8 +2638,10 @@
 	 */

 	public Object getAdapter(Class required) {

 		

-		if (IVerticalRulerInfo.class.equals(required))

-			return fVerticalRuler;

+		if (IVerticalRulerInfo.class.equals(required)) {

+			if (fVerticalRuler  instanceof IVerticalRulerInfo)

+				return fVerticalRuler;

+		}

 		

 		if (IncrementalFindTarget.class.equals(required)) {

 			if (fIncrementalFindTarget == null) {

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ConvertLineDelimitersAction.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ConvertLineDelimitersAction.java
index 6c4592d..e809c31 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ConvertLineDelimitersAction.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ConvertLineDelimitersAction.java
@@ -1,19 +1,30 @@
 package org.eclipse.ui.texteditor;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.ResourceBundle;
 
-import org.eclipse.jface.action.Action;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
 import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
 import org.eclipse.jface.text.IRegion;
 
 /**
  * An action to convert line delimiters of a text editor document to a particular line delimiter.
  */
-public class ConvertLineDelimitersAction extends TextEditorAction {
+public class ConvertLineDelimitersAction extends TextEditorAction implements IDocumentListener {
 
 	/** The target line delimiter. */
 	private final String fLineDelimiter;
+	
+	private boolean fInitialized;
 
 	/**
 	 * Creates a line delimiter conversion action.
@@ -34,6 +45,11 @@
 	public ConvertLineDelimitersAction(ResourceBundle bundle, String prefix, ITextEditor editor, String lineDelimiter) {
 		super(bundle, prefix, editor);
 		fLineDelimiter= lineDelimiter;
+		
+		String platformLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$
+		setText(EditorMessages.getString(getLabelKey(fLineDelimiter, platformLineDelimiter)));
+
+		update();
 	}
 		
 	/*
@@ -42,34 +58,202 @@
 	public void run() {
 
 		try {
-			ITextEditor editor= getTextEditor();
 
-			IDocumentProvider documentProvider= editor.getDocumentProvider();			
-			IDocument document= documentProvider.getDocument(editor.getEditorInput());
+			IDocument document= getDocument();
+			if (document != null) {
+				Shell shell= getTextEditor().getSite().getShell();
+				ConvertRunnable runnable= new ConvertRunnable(document, fLineDelimiter);
 
-			convert(document, fLineDelimiter);
-			
-		} catch (BadLocationException x) {
+				if (document.getNumberOfLines() < 40) {
+					BusyIndicator.showWhile(shell.getDisplay(), runnable);
+					
+				} else {				
+					ProgressMonitorDialog dialog= new ProgressMonitorDialog(shell);
+					dialog.run(false, true, runnable);
+				}
+			}
+
+		} catch (InterruptedException e) {
+			// action cancelled				
+
+		} catch (InvocationTargetException e) {
+			// should not happen
 		}
 	}
 
 	/**
 	 * Converts all line delimiters of the document to <code>lineDelimiter</code>.
 	 */
-	private static void convert(IDocument document, String lineDelimiter) throws BadLocationException {
+	private static class ConvertRunnable implements IRunnableWithProgress, Runnable {
+		
+		private final IDocument fDocument;
+		private final String fLineDelimiter;
+		
+		public ConvertRunnable(IDocument document, String lineDelimiter) {
+			fDocument= document;
+			fLineDelimiter= lineDelimiter;	
+		}
+		
+		private static class DummyMonitor implements IProgressMonitor {		
+			public void beginTask(String name, int totalWork) {}
+			public void done() {}
+			public void internalWorked(double work) {}
+			public boolean isCanceled() {return false;}
+			public void setCanceled(boolean value) {}
+			public void setTaskName(String name) {}
+			public void subTask(String name) {}
+			public void worked(int work) {}
+		}
+		
+		/*
+		 * @see IRunnableWithProgress#run(IProgressMonitor)
+		 */
+		public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+
+			final int lineCount= fDocument.getNumberOfLines();
+			monitor.beginTask(EditorMessages.getString("Editor.ConvertLineDelimiter.title"), lineCount); //$NON-NLS-1$
+			
+			try {
+				for (int i= 0; i < lineCount; i++) {
+					if (monitor.isCanceled())
+						throw new InterruptedException();
+					
+					final String delimiter= fDocument.getLineDelimiter(i);
+					if (delimiter != null && delimiter.length() > 0 && !delimiter.equals(fLineDelimiter)) {
+						IRegion region= fDocument.getLineInformation(i);
+						fDocument.replace(region.getOffset() + region.getLength(), delimiter.length(), fLineDelimiter);
+					}
+
+					monitor.worked(1);
+				}
+
+			} catch (BadLocationException e) {
+				throw new InvocationTargetException(e);
+
+			} finally {
+				monitor.done();
+			}
+		}
+		
+		/*
+		 * @see Runnable#run()
+		 */
+		public void run() {
+			try {
+				run(new DummyMonitor());
+
+			} catch (InterruptedException e) {
+				// cancelled, can't happen with dummy monitor
+				
+			} catch (InvocationTargetException e) {
+				// should not happen				
+			}
+		}
+	}
+
+	private IDocument getDocument() {
+
+		ITextEditor editor= getTextEditor();
+		if (editor == null)
+			return null;
+
+		IDocumentProvider documentProvider= editor.getDocumentProvider();
+		return documentProvider.getDocument(editor.getEditorInput());				
+	}
+
+	private static boolean usesLineDelimiterExclusively(IDocument document, String lineDelimiter) throws BadLocationException {
 
 		try {
 			final int lineCount= document.getNumberOfLines();
 			for (int i= 0; i < lineCount; i++) {
 				final String delimiter= document.getLineDelimiter(i);
-				if (delimiter != null && delimiter.length() > 0 && !delimiter.equals(lineDelimiter)) {
-					IRegion region= document.getLineInformation(i);
-					document.replace(region.getOffset() + region.getLength(), delimiter.length(), lineDelimiter);
-				}
+				if (delimiter != null && delimiter.length() > 0 && !delimiter.equals(lineDelimiter))
+					return false;
 			}
 
 		} catch (BadLocationException e) {
 			throw e;
 		}
+		
+		return true;
 	}
+
+	private static String getLabelKey(String lineDelimiter, String platformLineDelimiter) {
+		if (lineDelimiter.equals(platformLineDelimiter)) {
+
+			if (lineDelimiter.equals("\r\n")) //$NON-NLS-1$
+				return "Editor.ConvertLineDelimiter.toWindows.default.label"; //$NON-NLS-1$
+			
+			if (lineDelimiter.equals("\n")) //$NON-NLS-1$
+				return "Editor.ConvertLineDelimiter.toUNIX.default.label"; //$NON-NLS-1$
+
+			if (lineDelimiter.equals("\r")) //$NON-NLS-1$
+				return "Editor.ConvertLineDelimiter.toMac.default.label"; //$NON-NLS-1$
+			
+		} else {
+
+			if (lineDelimiter.equals("\r\n")) //$NON-NLS-1$
+				return "Editor.ConvertLineDelimiter.toWindows.label"; //$NON-NLS-1$
+			
+			if (lineDelimiter.equals("\n")) //$NON-NLS-1$
+				return "Editor.ConvertLineDelimiter.toUNIX.label"; //$NON-NLS-1$
+
+			if (lineDelimiter.equals("\r")) //$NON-NLS-1$
+				return "Editor.ConvertLineDelimiter.toMac.label"; //$NON-NLS-1$
+		}
+		
+		return null;
+	}
+	
+	/*
+	 * @see IUpdate#update()
+	 */
+	public void update() {
+		super.update();
+
+		try {
+			IDocument document= getDocument();
+			setEnabled(isEnabled() && document != null && !usesLineDelimiterExclusively(document, fLineDelimiter));
+			
+		} catch (BadLocationException e) {
+		}
+	}	
+
+	/*
+	 * @see TextEditorAction#setEditor(ITextEditor)
+	 */
+	public void setEditor(ITextEditor editor) {
+		IDocument document= getDocument();
+		if (document != null)
+			document.removeDocumentListener(this);
+		
+		super.setEditor(editor);
+
+		document= getDocument();
+		if (document != null)
+			document.addDocumentListener(this);
+	}
+
+	/*
+	 * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+	 */
+	public void documentAboutToBeChanged(DocumentEvent event) {
+	}
+
+	/*
+	 * @see IDocumentListener#documentChanged(DocumentEvent)
+	 */
+	public void documentChanged(DocumentEvent event) {
+
+		IDocument document= getDocument();
+
+		// detach from document if no longer connected to editor
+		if (!event.getDocument().equals(document)) {
+			event.getDocument().removeDocumentListener(this);
+			return;
+		}
+
+		update();		
+	}
+
 }
diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/EditorMessages.properties b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/EditorMessages.properties
index 1c1d7bd..890679d 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/EditorMessages.properties
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/EditorMessages.properties
@@ -182,6 +182,14 @@
 Editor.SelectMarker.error.dialog.title=Selecting Marker Range

 Editor.SelectMarker.error.dialog.message=Problems selecting marker range

 

+Editor.ConvertLineDelimiter.title=Converting line delimiters...

+Editor.ConvertLineDelimiter.toWindows.label=to &Windows

+Editor.ConvertLineDelimiter.toWindows.default.label=to &Windows (default)

+Editor.ConvertLineDelimiter.toUNIX.label=to &UNIX

+Editor.ConvertLineDelimiter.toUNIX.default.label=to &UNIX (default)

+Editor.ConvertLineDelimiter.toMac.label=to &Mac

+Editor.ConvertLineDelimiter.toMac.default.label=to &Mac (default)

+

 ## Status line ##

 

 Editor.statusline.state.readonly.label=Read Only

@@ -234,4 +242,3 @@
 

 SelectMarkerRulerAction.getMarker=SelectMarkerRulerAction.getMarker

 SelectMarkerRulerInfoAction.getMarker=SelectMarkerRulerInfoAction.getMarker

-

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceAction.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceAction.java
index 93adc49..196792f 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceAction.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceAction.java
Binary files differ
diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceDialog.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceDialog.java
index 218129a..3993036 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceDialog.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/FindReplaceDialog.java
Binary files differ
diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java
index e8662ff..d00af3e 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java
@@ -39,7 +39,7 @@
 	public static final String REVERT_TO_SAVED_ACTION= PREFIX + ITextEditorActionConstants.REVERT_TO_SAVED + ACTION_POSTFIX;

 	public static final String GOTO_LINE_ACTION= PREFIX + ITextEditorActionConstants.GOTO_LINE + ACTION_POSTFIX;

 	public static final String PRINT_ACTION= PREFIX + ITextEditorActionConstants.PRINT + ACTION_POSTFIX;

-	public static final String CONVERT_LINE_DELIMITERS_TO_DOS= PREFIX + ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_DOS + ACTION_POSTFIX;

+	public static final String CONVERT_LINE_DELIMITERS_TO_WINDOWS= PREFIX + ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_WINDOWS + ACTION_POSTFIX;

 	public static final String CONVERT_LINE_DELIMITERS_TO_UNIX= PREFIX + ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_UNIX + ACTION_POSTFIX;

 	public static final String CONVERT_LINE_DELIMITERS_TO_MAC= PREFIX + ITextEditorActionConstants.CONVERT_LINE_DELIMITERS_TO_MAC + ACTION_POSTFIX;

 	

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/IReadOnlyDependent.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/IReadOnlyDependent.java
new file mode 100644
index 0000000..eff3840
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/IReadOnlyDependent.java
@@ -0,0 +1,35 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp. and others.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html
+
+Contributors:
+    IBM Corporation - Initial API and implementation
+**********************************************************************/
+package org.eclipse.ui.texteditor;
+
+
+
+/**
+ * Extension interface for actions. Actions implementing this interface not
+ * only manage an enable/disable state but also manage a "hypothetical"
+ * enable state, depending on whether the target they work on is writable
+ * or read-only.
+ */
+public interface IReadOnlyDependent {
+
+	/**
+	 * Returns whether the actions would be enabled if its target
+	 * would be enabled given the writable state described by <code>isWritable</code>.
+	 * <code>isEnabled()</code> and <code>isEnabled(boolean)</code> holds the following
+	 * invariants:
+	 * 	isEnabled() == false, iff isEnabled(true) == false || isEnabled(false) == false
+	 * 	isEnabled() == true, iff isEnabled(true) == true || isEnabled(false) == true
+	 * 
+	 * @param isWritable
+	 * @return the hypothetical enable state of the action
+	 */
+	boolean isEnabled(boolean isWritable);
+}
diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionConstants.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionConstants.java
index 4ea619b..59cdac8 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionConstants.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionConstants.java
@@ -84,9 +84,9 @@
 	 */

 	static final String FIND_INCREMENTAL= "FindIncremental"; //$NON-NLS-1$

 	/** 

-	 * Name of the action to convert line delimiters to DOS. 

+	 * Name of the action to convert line delimiters to Windows. 

 	 */

-	static final String CONVERT_LINE_DELIMITERS_TO_DOS= "ConvertLineDelimitersToDOS"; //$NON-NLS-1$

+	static final String CONVERT_LINE_DELIMITERS_TO_WINDOWS= "ConvertLineDelimitersToWindows"; //$NON-NLS-1$

 	/** 

 	 * Name of the action to convert line delimiters to UNIX. 

 	 */

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java
index e6b9b3e..71e5180 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java
@@ -52,10 +52,11 @@
 	public static final String DELETE_NEXT= "org.eclipse.ui.edit.text.deleteNext"; //$NON-NLS-1$
 	public static final String SHIFT_RIGHT= "org.eclipse.ui.edit.text.shiftRight"; //$NON-NLS-1$
 	public static final String SHIFT_LEFT= "org.eclipse.ui.edit.text.shiftLeft"; //$NON-NLS-1$
-	public static final String CONVERT_LINE_DELIMITERS_TO_DOS= "org.eclipse.ui.edit.text.convert.lineDelimiters.toDOS"; //$NON-NLS-1$
+	public static final String CONVERT_LINE_DELIMITERS_TO_WINDOWS= "org.eclipse.ui.edit.text.convert.lineDelimiters.toWindows"; //$NON-NLS-1$
 	public static final String CONVERT_LINE_DELIMITERS_TO_UNIX= "org.eclipse.ui.edit.text.convert.lineDelimiters.toUNIX"; //$NON-NLS-1$
 	public static final String CONVERT_LINE_DELIMITERS_TO_MAC= "org.eclipse.ui.edit.text.convert.lineDelimiters.toMac"; //$NON-NLS-1$
 	
 	// miscellaneous
 	public static final String TOGGLE_OVERWRITE= "org.eclipse.ui.edit.text.toggleOverwrite"; //$NON-NLS-1$
+	public static final String SHOW_RULER_CONTEXT_MENU= "org.eclipse.ui.edit.text.showRulerContextMenu"; //$NON-NLS-1$
 }
diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/MarkerAnnotation.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/MarkerAnnotation.java
index 5f78230..c408ba9 100644
--- a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/MarkerAnnotation.java
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/MarkerAnnotation.java
@@ -35,6 +35,9 @@
  */

 public class MarkerAnnotation extends Annotation {

 	

+	/** The layer in which markers representing problem are located. */

+	public final static int PROBLEM_LAYER= 5;

+	

 	private static Map fgImageRegistry;

 	

 	protected static Image getImage(Display display, ImageDescriptor descriptor) {

@@ -149,7 +152,7 @@
 					name= ISharedImages.IMG_OBJS_WARN_TSK;

 					break;

 				case IMarker.SEVERITY_ERROR:

-					layer= 4;

+					layer= PROBLEM_LAYER;

 					name= ISharedImages.IMG_OBJS_ERROR_TSK;

 					break;

 			};

@@ -170,7 +173,7 @@
 	public void paint(GC gc, Canvas canvas, Rectangle r) {

 		Image image= getImage(canvas.getDisplay());

 		if (image != null)

-			drawImage(image, gc, canvas, r, SWT.CENTER, SWT.TOP);

+			drawImage(image, gc, canvas, r, SWT.CENTER, SWT.CENTER);

 	}

 	

 	/**

diff --git a/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ShiftAction.java b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ShiftAction.java
new file mode 100644
index 0000000..4f899a1
--- /dev/null
+++ b/bundles/org.eclipse.ui/Eclipse UI Text Editor/org/eclipse/ui/texteditor/ShiftAction.java
@@ -0,0 +1,108 @@
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp. and others.
+All rights reserved. This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html
+
+Contributors:
+    IBM Corporation - Initial API and implementation
+**********************************************************************/
+package org.eclipse.ui.texteditor;
+
+
+import java.util.ResourceBundle;
+import org.eclipse.jface.text.ITextOperationTarget;
+
+
+/**
+ * Action for shifting code to the right or left by one indentation level.
+ */
+public final class ShiftAction extends TextEditorAction implements IReadOnlyDependent {
+	
+	/** The text operation code */
+	private int fOperationCode= -1;
+	/** The text operation target */
+	private ITextOperationTarget fOperationTarget;
+	
+	/**
+	 * Creates and initializes the action for the given text editor and operation 
+	 * code. The action configures its visual representation from the given resource
+	 * bundle. The action works by asking the text editor at the time for its 
+	 * text operation target adapter (using
+	 * <code>getAdapter(ITextOperationTarget.class)</code>. The action runs that
+	 * operation with the given opcode.
+	 *
+	 * @param bundle the resource bundle
+	 * @param prefix a prefix to be prepended to the various resource keys
+	 *   (described in <code>ResourceAction</code> constructor), or  <code>null</code> if none
+	 * @param editor the text editor
+	 * @param operationCode the operation code
+	 * @see ResourceAction#ResourceAction
+	 */
+	public ShiftAction(ResourceBundle bundle, String prefix, ITextEditor editor, int operationCode) {
+		super(bundle, prefix, editor);
+		fOperationCode= operationCode;
+		update();
+	}
+	
+	/**
+	 * The <code>TextOperationAction</code> implementation of this 
+	 * <code>IAction</code> method runs the operation with the current
+	 * operation code.
+	 */
+	public void run() {
+		if (fOperationCode != -1 && fOperationTarget != null)
+			fOperationTarget.doOperation(fOperationCode);
+	}
+	
+	/*
+	 * @see IUpdate#update()
+	 */
+	public void update() {
+		
+		ITextEditor editor= getTextEditor();
+		if (editor instanceof ITextEditorExtension) {
+			ITextEditorExtension extension= (ITextEditorExtension) editor;
+			if (extension.isEditorInputReadOnly()) {
+				setEnabled(false);
+				return;
+			}
+		}
+		
+		if (fOperationTarget == null && editor!= null && fOperationCode != -1)
+			fOperationTarget= (ITextOperationTarget) editor.getAdapter(ITextOperationTarget.class);
+			
+		boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
+		setEnabled(isEnabled);
+	}
+	
+	/*
+	 * @see TextEditorAction#setEditor(ITextEditor)
+	 */
+	public void setEditor(ITextEditor editor) {
+		super.setEditor(editor);
+		fOperationTarget= null;
+	}
+	
+	/*
+	 * @see IReadOnlyDependent#isEnabled(boolean)
+	 */
+	public boolean isEnabled(boolean isWritable) {
+		
+		if (!isWritable)
+			return false;
+			
+		/*
+		 * Note that this implementation still honors the result returned by canDoOperation.
+		 * I.e. if the viewer is set to read-only, this method still returns false.
+		 * It covers the case in which the viewer is also writable.
+		 *  
+		 */
+		ITextEditor editor= getTextEditor();
+		if (fOperationTarget == null && editor!= null && fOperationCode != -1)
+			fOperationTarget= (ITextOperationTarget) editor.getAdapter(ITextOperationTarget.class);
+			
+		return (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
+	}
+}
diff --git a/bundles/org.eclipse.ui/buildnotes_text.html b/bundles/org.eclipse.ui/buildnotes_text.html
index 9bc5847..1b6e98f 100644
--- a/bundles/org.eclipse.ui/buildnotes_text.html
+++ b/bundles/org.eclipse.ui/buildnotes_text.html
@@ -14,7 +14,47 @@
 <h1>

 Text Editor Support (including JFace Text)</h1>

 

-<p><br>Eclipse SDK Build 20020430

+<p><br>Eclipse SDK Build 20020508

+<h2>

+Breaking API changes</h2>

+

+<h2>

+Other highlights</h2>

+

+<ul>

+<li>

+The context menu of the vertical ruler can be opened with Ctrl+W when using

+the default key binding. Accelerator for the emac's key binding is still

+to be defined.</li>

+

+<li>

+Added support for composite vertical ruler. See CompositeVerticalRuler.&nbsp;

+A composite vertical ruler is configured with ruler columns. Two ruler

+columns are provided by default: AnnotationRulerColumn and LineNumberRulerColumn.</li>

+

+<li>

+Performance changes to the reconciling mechanism in JFace Text.</li>

+

+<li>

+Changes in handling read only files: All modifying text actions are disabled

+by default.</li>

+

+<li>

+Changes in applying text styles and colors to the editor's text widget.

+Leverage SWT support provided with this build.</li>

+</ul>

+

+<h2>

+Known deficiencies</h2>

+

+<h2>

+Problem reports closed</h2>

+#15071 convert line delimiters - one os missing

+<br>&nbsp;

+<p>

+<hr WIDTH="100%">

+<br>&nbsp;

+<p>Eclipse SDK Build 20020430

 <h2>

 Breaking API changes</h2>

 

diff --git a/bundles/org.eclipse.ui/plugin.xml b/bundles/org.eclipse.ui/plugin.xml
index 724246a..cea4900 100644
--- a/bundles/org.eclipse.ui/plugin.xml
+++ b/bundles/org.eclipse.ui/plugin.xml
@@ -302,6 +302,9 @@
       <actionDefinition

             id="org.eclipse.ui.edit.text.toggleOverwrite">

       </actionDefinition>

+      <actionDefinition

+            id="org.eclipse.ui.edit.text.showRulerContextMenu">

+      </actionDefinition>

    </extension>

 

 

@@ -637,6 +640,10 @@
                key="INSERT"

                id="org.eclipse.ui.edit.text.toggleOverwrite">

          </accelerator>

+         <accelerator

+               key=""

+               id="org.eclipse.ui.edit.text.showRulerContextMenu">

+         </accelerator>

       </acceleratorSet>

       

       <acceleratorSet

@@ -938,6 +945,10 @@
                key="INSERT"

                id="org.eclipse.ui.edit.text.toggleOverwrite">

          </accelerator>

+         <accelerator

+               key="Ctrl+W"

+               id="org.eclipse.ui.edit.text.showRulerContextMenu">

+         </accelerator>

       </acceleratorSet>

    </extension>