Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Maetzel2002-12-03 13:53:47 +0000
committerKai Maetzel2002-12-03 13:53:47 +0000
commit12a19d1dcedb0e74ec7448608e801550e9ddf756 (patch)
tree666fd0e3d69aeaa61cae9fc0a44a95a6eb6614c1
parentcca5d0bee1158d234c5366d10b4dcb9126932563 (diff)
downloadeclipse.platform.text-12a19d1dcedb0e74ec7448608e801550e9ddf756.tar.gz
eclipse.platform.text-12a19d1dcedb0e74ec7448608e801550e9ddf756.tar.xz
eclipse.platform.text-12a19d1dcedb0e74ec7448608e801550e9ddf756.zip
projection
-rw-r--r--org.eclipse.jface.text/.classpath2
-rw-r--r--org.eclipse.jface.text/.project1
-rw-r--r--org.eclipse.jface.text/build.properties3
-rw-r--r--org.eclipse.jface.text/projection/org/eclipse/jface/text/source/OutlinerRulerColumn.java110
-rw-r--r--org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotation.java101
-rw-r--r--org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotationModel.java162
-rw-r--r--org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionSourceViewer.java194
-rw-r--r--org.eclipse.jface.text/scripts/exportplugin.xml1
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/DefaultUndoManager.java26
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/DocumentCommand.java29
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/ITextViewerExtension3.java27
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java775
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewerHoverManager.java49
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java31
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java17
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationBarHoverManager.java16
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java94
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/CompositeRuler.java22
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java69
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java2
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java90
-rw-r--r--org.eclipse.text/.classpath2
-rw-r--r--org.eclipse.text/.project1
-rw-r--r--org.eclipse.text/build.properties3
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/CoordinatesTranslator.java288
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/Fragment.java43
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/FragmentUpdater.java104
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocument.java745
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocumentManager.java287
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPosition.java42
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPositionUpdater.java51
-rw-r--r--org.eclipse.text/projection/org/eclipse/jface/text/ProjectionTextStore.java132
-rw-r--r--org.eclipse.text/scripts/exportplugin.xml1
-rw-r--r--org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java2
-rw-r--r--org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentEvent.java39
-rw-r--r--org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentManager.java92
-rw-r--r--org.eclipse.text/src/org/eclipse/jface/text/IDocumentInformationMapping.java27
-rw-r--r--org.eclipse.text/src/org/eclipse/jface/text/ISlaveDocumentManager.java57
-rw-r--r--org.eclipse.text/src/org/eclipse/jface/text/ParentChildMapping.java139
-rw-r--r--org.eclipse.text/src/org/eclipse/jface/text/SlaveDocumentEvent.java45
-rw-r--r--org.eclipse.ui.editors/.classpath1
-rw-r--r--org.eclipse.ui.editors/build.properties3
-rw-r--r--org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/DefineProjectionAction.java65
-rw-r--r--org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.java30
-rw-r--r--org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.properties3
-rw-r--r--org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionPainter.java124
-rw-r--r--org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionTextEditor.java119
-rw-r--r--org.eclipse.ui.editors/scripts/exportplugin.xml1
-rw-r--r--org.eclipse.ui.examples.javaeditor/.classpath20
-rw-r--r--org.eclipse.ui.examples.javaeditor/.project6
-rw-r--r--org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaActionContributor.java28
-rw-r--r--org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaDocumentProvider.java17
-rw-r--r--org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaEditor.java21
-rw-r--r--org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaSourceViewerConfiguration.java47
-rw-r--r--org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/PresentationAction.java15
-rw-r--r--org.eclipse.ui.workbench.texteditor/scripts/exportplugin.xml1
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java165
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IncrementalFindTarget.java1
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/MarkRegionTarget.java20
59 files changed, 4030 insertions, 578 deletions
diff --git a/org.eclipse.jface.text/.classpath b/org.eclipse.jface.text/.classpath
index f5dc5a4c919..df6a2a79e66 100644
--- a/org.eclipse.jface.text/.classpath
+++ b/org.eclipse.jface.text/.classpath
@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/"/>
+ <classpathentry kind="src" path="projection"/>
<classpathentry exported="true" kind="src" path="/org.eclipse.text"/>
<classpathentry kind="src" path="/org.eclipse.swt"/>
<classpathentry kind="src" path="/org.eclipse.jface"/>
<classpathentry kind="src" path="/org.eclipse.core.runtime"/>
<classpathentry kind="src" path="/org.eclipse.core.boot"/>
<classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
+ <classpathentry kind="src" path="/org.junit"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/org.eclipse.jface.text/.project b/org.eclipse.jface.text/.project
index 31de145d9fa..e27fdaa5b36 100644
--- a/org.eclipse.jface.text/.project
+++ b/org.eclipse.jface.text/.project
@@ -8,6 +8,7 @@
<project>org.eclipse.jface</project>
<project>org.eclipse.swt</project>
<project>org.eclipse.text</project>
+ <project>org.junit</project>
</projects>
<buildSpec>
<buildCommand>
diff --git a/org.eclipse.jface.text/build.properties b/org.eclipse.jface.text/build.properties
index d435043c207..a9253db9e6f 100644
--- a/org.eclipse.jface.text/build.properties
+++ b/org.eclipse.jface.text/build.properties
@@ -1,4 +1,5 @@
bin.includes = plugin.properties,\
plugin.xml,\
*.jar
-source.jfacetext.jar = src/
+source.jfacetext.jar = src/,\
+ projection/
diff --git a/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/OutlinerRulerColumn.java b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/OutlinerRulerColumn.java
new file mode 100644
index 00000000000..4596a96fb2d
--- /dev/null
+++ b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/OutlinerRulerColumn.java
@@ -0,0 +1,110 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+package org.eclipse.jface.text.source;
+
+
+import java.util.Iterator;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+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.Position;
+
+
+/**
+ * OutlinerRulerColumn.java
+ */
+public class OutlinerRulerColumn extends AnnotationRulerColumn {
+
+ /**
+ * Constructor for OutlinerRulerColumn.
+ * @param model
+ * @param width
+ */
+ public OutlinerRulerColumn(IAnnotationModel model, int width) {
+ super(model, width);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.ProjectionRulerColumn#mouseDoubleClicked(int)
+ */
+ protected void mouseDoubleClicked(int line) {
+ ProjectionAnnotation annotation= findAnnotation(line);
+ if (annotation != null) {
+ annotation.run(getCachedTextViewer());
+ redraw();
+ }
+ }
+
+ /**
+ * Method findAnnotation.
+ * @return ProjectionAnnotation
+ */
+ private ProjectionAnnotation findAnnotation(int line) {
+ IAnnotationModel model= getModel();
+ if (model != null) {
+ Iterator e= model.getAnnotationIterator();
+ while (e.hasNext()) {
+ Object next= e.next();
+ if (next instanceof ProjectionAnnotation) {
+ ProjectionAnnotation annotation= (ProjectionAnnotation) next;
+ Position p= model.getPosition(annotation);
+ if (contains(p, line))
+ return annotation;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Method contains.
+ * @param p
+ * @param line
+ * @return boolean
+ */
+ private boolean contains(Position p, int line) {
+
+ IDocument document= getCachedTextViewer().getDocument();
+
+ try {
+
+ int startLine= document.getLineOfOffset(p.getOffset());
+ if (line < startLine)
+ return false;
+ if (line == startLine)
+ return true;
+
+ int endLine= document.getLineOfOffset(p.getOffset() + Math.max(p.getLength() -1, 0));
+ return (startLine < line && line <= endLine) ;
+
+ } catch (BadLocationException x) {
+ }
+
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.IVerticalRulerColumn#createControl(org.eclipse.jface.text.source.CompositeRuler, org.eclipse.swt.widgets.Composite)
+ */
+ public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+ Control control= super.createControl(parentRuler, parentControl);
+ Display display= parentControl.getDisplay();
+ Color background= display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ control.setBackground(background);
+ return control;
+ }
+}
diff --git a/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotation.java b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotation.java
new file mode 100644
index 00000000000..3f05d2b7484
--- /dev/null
+++ b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotation.java
@@ -0,0 +1,101 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+package org.eclipse.jface.text.source;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+
+/**
+ * ProjectionAnnotation.java
+ */
+public class ProjectionAnnotation extends Annotation {
+
+ private static final int OUTER_MARGIN= 1;
+ private static final int INNER_MARGIN= 1;
+ private static final int PIXELS= 1;
+ private static final int LEGS= 2;
+ private static final int MIDDLE= PIXELS + INNER_MARGIN + LEGS;
+ private static final int SIZE= 2 * MIDDLE + PIXELS;
+
+
+ private Position fProjectionRange;
+ private boolean fIsFolded= false;
+
+
+ public ProjectionAnnotation(Position range) {
+ fProjectionRange= range;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.Annotation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle)
+ */
+ public void paint(GC gc, Canvas canvas, Rectangle rectangle) {
+ Color fg= gc.getForeground();
+ gc.setForeground(canvas.getDisplay().getSystemColor(SWT.COLOR_BLUE));
+
+
+ Rectangle r= new Rectangle(rectangle.x + OUTER_MARGIN, rectangle.y + OUTER_MARGIN, SIZE , SIZE);
+ gc.drawRectangle(r);
+ gc.drawLine(r.x + PIXELS + INNER_MARGIN, r.y + MIDDLE, r.x + r.width - PIXELS - INNER_MARGIN , r.y + MIDDLE);
+ if (fIsFolded) {
+ gc.drawLine(r.x + MIDDLE, r.y + PIXELS + INNER_MARGIN, r.x + MIDDLE, r.y + r.height - PIXELS - INNER_MARGIN);
+ } else {
+ gc.drawLine(r.x + MIDDLE, r.y + r.height, r.x + MIDDLE, rectangle.y + rectangle.height - OUTER_MARGIN);
+ gc.drawLine(r.x + MIDDLE, rectangle.y + rectangle.height - OUTER_MARGIN, r.x + r.width - INNER_MARGIN, rectangle.y + rectangle.height - OUTER_MARGIN);
+ }
+
+ gc.setForeground(fg);
+ }
+
+ public void run(ITextViewer viewer) {
+
+ if (viewer instanceof ProjectionSourceViewer) {
+ ProjectionSourceViewer projectionViewer= (ProjectionSourceViewer) viewer;
+
+ if (fIsFolded) {
+
+ fIsFolded= false;
+ projectionViewer.expand(fProjectionRange.getOffset(), fProjectionRange.getLength());
+
+ } else {
+
+ try {
+ IDocument document= projectionViewer.getDocument();
+ int line= document.getLineOfOffset(fProjectionRange.getOffset());
+ int offset= document.getLineOffset(line + 1);
+
+ int length= fProjectionRange.getLength() - (offset - fProjectionRange.getOffset());
+ if (length > 0) {
+ fIsFolded= true;
+ projectionViewer.collapse(offset, length);
+ }
+ } catch (BadLocationException x) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the fIsFolded.
+ * @return boolean
+ */
+ public boolean isFolded() {
+ return fIsFolded;
+ }
+}
diff --git a/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotationModel.java b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotationModel.java
new file mode 100644
index 00000000000..f684d0cb614
--- /dev/null
+++ b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionAnnotationModel.java
@@ -0,0 +1,162 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text.source;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.ProjectionDocumentManager;
+
+/**
+ * ProjectionAnnotationModel.java
+ */
+public class ProjectionAnnotationModel implements IAnnotationModel {
+
+ private class ProjectionIterator implements Iterator {
+
+ private Position[] fPositions;
+ private int fIndex;
+
+ public ProjectionIterator(Position[] positions) {
+ fPositions= positions;
+ fIndex= 0;
+ }
+
+ /*
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ return fIndex < fPositions.length;
+ }
+
+ /*
+ * @see java.util.Iterator#next()
+ */
+ public Object next() {
+ Position p= fPositions[fIndex++];
+ return new ProjectionAnnotation(p);
+ }
+
+ /*
+ * @see java.util.Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ private static class EmptyIterator implements Iterator {
+ /*
+ * @see java.util.Iterator#hasNext()
+ */
+ public boolean hasNext() {
+ return false;
+ }
+
+ /*
+ * @see java.util.Iterator#next()
+ */
+ public Object next() {
+ throw new NoSuchElementException();
+ }
+
+ /*
+ * @see java.util.Iterator#remove()
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+
+ private ITextViewer fTextViewer;
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#IAnnotationModel()
+ */
+ public ProjectionAnnotationModel() {
+ }
+
+ public void setTextViewer(ITextViewer viewer) {
+ fTextViewer= viewer;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#addAnnotationModelListener(org.eclipse.jface.text.source.IAnnotationModelListener)
+ */
+ public void addAnnotationModelListener(IAnnotationModelListener listener) {
+// throw new UnsupportedOperationException();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#removeAnnotationModelListener(org.eclipse.jface.text.source.IAnnotationModelListener)
+ */
+ public void removeAnnotationModelListener(IAnnotationModelListener listener) {
+// throw new UnsupportedOperationException();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#connect(org.eclipse.jface.text.IDocument)
+ */
+ public void connect(IDocument document) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#disconnect(org.eclipse.jface.text.IDocument)
+ */
+ public void disconnect(IDocument document) {
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#addAnnotation(org.eclipse.jface.text.source.Annotation, org.eclipse.jface.text.Position)
+ */
+ public void addAnnotation(Annotation annotation, Position position) {
+// throw new UnsupportedOperationException();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#removeAnnotation(org.eclipse.jface.text.source.Annotation)
+ */
+ public void removeAnnotation(Annotation annotation) {
+// throw new UnsupportedOperationException();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#getAnnotationIterator()
+ */
+ public Iterator getAnnotationIterator() {
+ IDocument document= fTextViewer.getDocument();
+ if (document != null) {
+ try {
+ return new ProjectionIterator(document.getPositions(ProjectionDocumentManager.PROJECTION_DOCUMENTS));
+ } catch (BadPositionCategoryException x) {
+ }
+ }
+ return new EmptyIterator();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationModel#getPosition(org.eclipse.jface.text.source.Annotation)
+ */
+ public Position getPosition(Annotation annotation) {
+// if (annotation instanceof ProjectionAnnotation) {
+// Position p= ((ProjectionAnnotation) annotation).getProjectionRange();
+// if (p.getOffset() + p.getLength() < fTextViewer.getDocument().getLength())
+// return new Position(p.getOffset() + Math.max(p.getLength() -1, 0));
+// }
+ return null;
+ }
+}
diff --git a/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionSourceViewer.java b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionSourceViewer.java
new file mode 100644
index 00000000000..4fc40b5044f
--- /dev/null
+++ b/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/ProjectionSourceViewer.java
@@ -0,0 +1,194 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text.source;
+
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ISlaveDocumentManager;
+import org.eclipse.jface.text.ITextViewerExtension3;
+import org.eclipse.jface.text.ProjectionDocument;
+import org.eclipse.jface.text.ProjectionDocumentManager;
+
+
+public class ProjectionSourceViewer extends SourceViewer implements ISourceViewer, ITextViewerExtension3 {
+
+ /** The projection annotation model */
+ private IAnnotationModel fProjectionAnnotationModel;
+
+
+ /**
+ * Constructor for ProjectionSourceViewer.
+ * @param parent
+ * @param ruler
+ * @param styles
+ */
+ public ProjectionSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+ super(parent, ruler, styles);
+ }
+
+ /*
+ * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
+ */
+ public void setDocument(IDocument document, IAnnotationModel annotationModel, int visibleRegionOffset, int visibleRegionLength) {
+ if (getDocument() != null && fProjectionAnnotationModel != null)
+ fProjectionAnnotationModel.disconnect(getDocument());
+
+ super.setDocument(document, annotationModel, visibleRegionOffset, visibleRegionLength);
+
+ if (getDocument() != null && fProjectionAnnotationModel != null)
+ fProjectionAnnotationModel.connect(getDocument());
+ }
+
+ /*
+ * @see TextViewer#handleDispose
+ */
+ protected void handleDispose() {
+
+ if (getDocument() != null && fProjectionAnnotationModel != null) {
+ fProjectionAnnotationModel.disconnect(getDocument());
+ fProjectionAnnotationModel= null;
+ }
+
+ super.handleDispose();
+ }
+
+ /**
+ * Returns the projectionAnnotationModel.
+ * @return IAnnotationModel
+ */
+ public IAnnotationModel getProjectionAnnotationModel() {
+ return fProjectionAnnotationModel;
+ }
+
+ /**
+ * Sets the projectionAnnotationModel.
+ * @param projectionAnnotationModel The projectionAnnotationModel to set
+ */
+ public void setProjectionAnnotationModel(IAnnotationModel projectionAnnotationModel) {
+ fProjectionAnnotationModel= projectionAnnotationModel;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.TextViewer#createSlaveDocumentManager()
+ */
+ protected ISlaveDocumentManager createSlaveDocumentManager() {
+ return new ProjectionDocumentManager();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.TextViewer#updateVisibleDocument(org.eclipse.jface.text.IDocument, int, int)
+ */
+ protected boolean updateVisibleDocument(IDocument visibleDocument, int visibleRegionOffset, int visibleRegionLength) throws BadLocationException {
+ if (visibleDocument instanceof ProjectionDocument) {
+ ProjectionDocument document= (ProjectionDocument) visibleDocument;
+ document.addFragment(visibleRegionOffset, visibleRegionLength);
+ }
+ return true;
+ }
+
+ /**
+ * Hides the given range by collapsing it.
+ *
+ * @param offset
+ * @param length
+ */
+ public void collapse(int offset, int length) {
+
+ IDocument previous= getVisibleDocument();
+ IDocument slave= createSlaveDocument(previous);
+
+ if (slave instanceof ProjectionDocument) {
+
+ StyledText textWidget= getTextWidget();
+ try {
+
+ if (textWidget != null)
+ textWidget.setRedraw(false);
+
+ int topIndex= getTopIndex();
+ ((ProjectionDocument) slave).hide(offset, length);
+ setVisibleDocument(slave);
+ setTopIndex(topIndex);
+
+ } finally {
+ if(textWidget != null)
+ textWidget.setRedraw(true);
+ }
+ }
+ }
+
+ /**
+ * Makes all hidden ranges in the given range visible again.
+ *
+ * @param offset
+ * @param length
+ */
+ public void expand(int offset, int length) {
+ if (getVisibleDocument() instanceof ProjectionDocument) {
+ ProjectionDocument document= (ProjectionDocument) getVisibleDocument();
+
+ StyledText textWidget= getTextWidget();
+ try {
+
+ if (textWidget != null)
+ textWidget.setRedraw(false);
+
+ int topIndex= getTopIndex();
+ document.show(offset, length);
+ setVisibleDocument(document);
+ setTopIndex(topIndex);
+
+ } finally {
+ if (textWidget != null)
+ textWidget.setRedraw(true);
+ }
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewer#_getVisibleRegion()
+ */
+ public IRegion getVisibleRegion() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.TextViewer#_getVisibleRegionOffset()
+ */
+ protected int _getVisibleRegionOffset() {
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.TextViewer#_internalGetVisibleRegion()
+ */
+ protected IRegion _internalGetVisibleRegion() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewer#_overlapsWithVisibleRegion(int, int)
+ */
+ public boolean overlapsWithVisibleRegion(int offset, int length) {
+ return false;
+ }
+
+ public IDocument getVisibleDocument() {
+ return super.getVisibleDocument();
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.jface.text/scripts/exportplugin.xml b/org.eclipse.jface.text/scripts/exportplugin.xml
index 3831f586340..40eae04fff2 100644
--- a/org.eclipse.jface.text/scripts/exportplugin.xml
+++ b/org.eclipse.jface.text/scripts/exportplugin.xml
@@ -23,6 +23,7 @@
<copy file="plugin.properties" todir="${dest}"/>
<zip zipfile="${dest}/jfacetextsrc.zip">
<fileset dir="src" />
+ <fileset dir="projection"/>
</zip>
</target>
</project>
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/DefaultUndoManager.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/DefaultUndoManager.java
index 58ca1ea89ba..b73e2e3ef5a 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/DefaultUndoManager.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/DefaultUndoManager.java
@@ -89,14 +89,10 @@ public class DefaultUndoManager implements IUndoManager {
* @param text the text widget to be modified
*/
protected void undo(StyledText text) {
-
undoTextChange(text);
-
- int length= fPreservedText == null ? 0 : fPreservedText.length();
- IRegion visible= fTextViewer.getVisibleRegion();
- int offset= fStart + visible.getOffset();
- fTextViewer.setSelectedRange(offset, length);
- fTextViewer.revealRange(offset, length);
+ IRegion modelRange= widgetRange2ModelRange(fStart, fPreservedText == null ? 0 : fPreservedText.length());
+ fTextViewer.setSelectedRange(modelRange.getOffset(), modelRange.getLength());
+ fTextViewer.revealRange(modelRange.getOffset(), modelRange.getLength());
}
/**
@@ -116,14 +112,20 @@ public class DefaultUndoManager implements IUndoManager {
* @param text the text widget to be modified
*/
protected void redo(StyledText text) {
-
redoTextChange(text);
+ IRegion modelRange= widgetRange2ModelRange(fStart, fText == null ? 0 : fText.length());
+ fTextViewer.setSelectedRange(modelRange.getOffset(), modelRange.getLength());
+ fTextViewer.revealRange(modelRange.getOffset(), modelRange.getLength());
+ }
+
+ protected IRegion widgetRange2ModelRange(int offset, int length) {
+ if (fTextViewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fTextViewer;
+ return extension.widgetRange2ModelRange(new Region(offset, length));
+ }
- int length= fText == null ? 0 : fText.length();
IRegion visible= fTextViewer.getVisibleRegion();
- int offset= fStart + visible.getOffset();
- fTextViewer.setSelectedRange(offset, length);
- fTextViewer.revealRange(offset, length);
+ return new Region(offset + visible.getOffset(), length);
}
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/DocumentCommand.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/DocumentCommand.java
index 0a3a1f45f9b..a9872d25af7 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/DocumentCommand.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/DocumentCommand.java
@@ -250,24 +250,16 @@ public class DocumentCommand {
* Translates a verify event into a document replace command using the given offset.
*
* @param event the event to be translated
- * @param offset the offset used for the translation
+ * @param modelRange the event range as model range
*/
- void setEvent(VerifyEvent event, int offset) {
+ void setEvent(VerifyEvent event, IRegion modelRange) {
doit= true;
+ text= event.text;
- text= event.text;
-
- this.offset= event.start;
- length= event.end - event.start;
-
- if (length < 0) {
- this.offset += length;
- length= -length;
- }
-
- this.offset += offset;
-
+ offset= modelRange.getOffset();
+ length= modelRange.getLength();
+
owner= null;
caretOffset= -1;
fCommands.clear();
@@ -279,15 +271,12 @@ public class DocumentCommand {
* covers the same range as the verify event considering the given offset.
*
* @param event the event to be changed
- * @param offset to be considered for range comparison
+ * @param modelRange to be considered for range comparison
* @return <code>true</code> if this command and the event cover the same range
*/
- boolean fillEvent(VerifyEvent event, int offset) {
-
- int start= this.offset - offset;
-
+ boolean fillEvent(VerifyEvent event, IRegion modelRange) {
event.text= text;
- event.doit= (start == event.start && start + length == event.end) && doit;
+ event.doit= (offset == modelRange.getOffset() && length == modelRange.getLength());
return event.doit;
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextViewerExtension3.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextViewerExtension3.java
new file mode 100644
index 00000000000..39050040a64
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/ITextViewerExtension3.java
@@ -0,0 +1,27 @@
+package org.eclipse.jface.text;
+
+
+/**
+ * Translates between model and presentation coordinates.
+ */
+public interface ITextViewerExtension3 {
+
+
+ public IRegion getModelCoverage();
+
+
+ public int modelLine2WidgetLine(int modelLine);
+
+ public int modelOffset2WidgetOffset(int modelOffset);
+
+ public IRegion modelRange2WidgetRange(IRegion modelRange);
+
+
+ public int widgetOffset2ModelOffset(int widgetOffset);
+
+ public IRegion widgetRange2ModelRange(IRegion widgetRange);
+
+ public int widgetlLine2ModelLine(int widgetLine);
+
+ public int widgetLineOfWidgetOffset(int widgetOffset);
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java
index aff73caf0fb..6b10e2c53cd 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java
@@ -75,9 +75,9 @@ import org.eclipse.jface.viewers.Viewer;
* @see ITextViewer
*/
public class TextViewer extends Viewer implements
- ITextViewer, ITextViewerExtension, ITextViewerExtension2,
- ITextOperationTarget, ITextOperationTargetExtension,
- IWidgetTokenOwner {
+ ITextViewer, ITextViewerExtension, ITextViewerExtension2,
+ ITextOperationTarget, ITextOperationTargetExtension,
+ IWidgetTokenOwner {
/** Internal flag to indicate the debug state. */
public static boolean TRACE_ERRORS= false;
@@ -551,8 +551,7 @@ public class TextViewer extends Viewer implements
/* Don't use cached line information because of patched redrawing events. */
if (fTextWidget != null) {
- int offset= event.lineOffset + TextViewer.this.getVisibleRegionOffset();
-
+ int offset= widgetOffset2ModelOffset(event.lineOffset);
if (fPosition.includes(offset))
event.lineBackground= fHighlightColor;
}
@@ -615,8 +614,10 @@ public class TextViewer extends Viewer implements
* Paints the highlighting of this range.
*/
private void paint() {
- int offset= fPosition.getOffset() - TextViewer.this.getVisibleRegionOffset();
- int length= fPosition.getLength();
+
+ IRegion widgetRegion= modelRange2WidgetRange(fPosition);
+ int offset= widgetRegion.getOffset();
+ int length= widgetRegion.getLength();
int count= fTextWidget.getCharCount();
if (offset + length >= count) {
@@ -712,27 +713,24 @@ public class TextViewer extends Viewer implements
*/
public Point getSelection() {
Point point= TextViewer.this.getSelectedRange();
- point.x -= TextViewer.this.getVisibleRegionOffset();
- return point;
+ return modelSelection2WidgetSelection(point);
}
/*
* @see IFindReplaceTarget#findAndSelect(int, String, boolean, boolean, boolean)
*/
public int findAndSelect(int offset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord) {
- if (offset != -1)
- offset += TextViewer.this.getVisibleRegionOffset();
+ int modelOffset= offset == -1 ? -1 : widgetOffset2ModelOffset(offset);
+
if (fRange != null) {
IRegion range= fRange.getRange();
- offset= TextViewer.this.findAndSelectInRange(offset, findString, searchForward, caseSensitive, wholeWord, range.getOffset(), range.getLength());
+ modelOffset= TextViewer.this.findAndSelectInRange(modelOffset, findString, searchForward, caseSensitive, wholeWord, range.getOffset(), range.getLength());
} else {
- offset= TextViewer.this.findAndSelect(offset, findString, searchForward, caseSensitive, wholeWord);
+ modelOffset= TextViewer.this.findAndSelect(modelOffset, findString, searchForward, caseSensitive, wholeWord);
}
- if (offset != -1)
- offset -= TextViewer.this.getVisibleRegionOffset();
-
+ offset= modelOffset == -1 ? -1 : modelOffset2WidgetOffset(modelOffset);
return offset;
}
@@ -800,8 +798,8 @@ public class TextViewer extends Viewer implements
* @see IFindReplaceTargetExtension#setSelection(int, int)
* @since 2.0
*/
- public void setSelection(int offset, int length) {
- TextViewer.this.setSelectedRange(offset /*+ TextViewer.this.getVisibleRegionOffset()*/, length);
+ public void setSelection(int modelOffset, int modelLength) {
+ TextViewer.this.setSelectedRange(modelOffset, modelLength);
}
/*
@@ -967,8 +965,8 @@ public class TextViewer extends Viewer implements
private IDocument fVisibleDocument;
/** The viewer's document adapter */
private IDocumentAdapter fDocumentAdapter;
- /** The child document manager */
- private ChildDocumentManager fChildDocumentManager;
+ /** The slave document manager */
+ private ISlaveDocumentManager fSlaveDocumentManager;
/** The text viewer's double click strategies connector */
private TextDoubleClickStrategyConnector fDoubleClickStrategyConnector;
/**
@@ -1066,6 +1064,12 @@ public class TextViewer extends Viewer implements
/** Indicates whether the viewer's text presentation should be replaced are modified. */
protected boolean fReplaceTextPresentation= false;
+ /**
+ * The mapping between model and visible document.
+ * @since 2.1
+ */
+ protected IDocumentInformationMapping fInformationMapping;
+
//---- Construction and disposal ------------------
@@ -1243,23 +1247,25 @@ public class TextViewer extends Viewer implements
fTextHoverManager= null;
}
- if (fDocumentListener != null)
+ if (fDocumentListener !=null) {
+ if (fVisibleDocument != null)
+ fVisibleDocument.removeDocumentListener(fDocumentListener);
fDocumentListener= null;
-
- if (fVisibleDocument instanceof ChildDocument) {
- ChildDocument child = (ChildDocument) fVisibleDocument;
- child.removeDocumentListener(fDocumentListener);
- getChildDocumentManager().freeChildDocument(child);
}
-
+
if (fDocumentAdapter != null) {
fDocumentAdapter.setDocument(null);
fDocumentAdapter= null;
}
+ if (fSlaveDocumentManager != null) {
+ if (fVisibleDocument != null)
+ fSlaveDocumentManager.freeSlaveDocument(fVisibleDocument);
+ fSlaveDocumentManager= null;
+ }
+
fVisibleDocument= null;
fDocument= null;
- fChildDocumentManager= null;
fScroller= null;
}
@@ -1541,8 +1547,7 @@ public class TextViewer extends Viewer implements
if (fTextWidget != null) {
Point p= fTextWidget.getSelectionRange();
- int offset= getVisibleRegionOffset();
- return new Point(p.x + offset, p.y);
+ return widgetSelection2ModelSelection(p);
}
return new Point(-1, -1);
@@ -1562,48 +1567,15 @@ public class TextViewer extends Viewer implements
if (fTextWidget == null)
return;
- IDocument document= getVisibleDocument();
- if (document == null)
- return;
-
- int offset= selectionOffset;
- int length= selectionLength;
- if (selectionLength < 0) {
- offset= selectionOffset + selectionLength;
- length= -selectionLength;
- }
-
- int end= offset + length;
-
- if (document instanceof ChildDocument) {
- Position p= ((ChildDocument) document).getParentDocumentRange();
- if (p.overlapsWith(offset, length)) {
-
- if (offset < p.getOffset())
- offset= p.getOffset();
- offset -= p.getOffset();
-
- int e= p.getOffset() + p.getLength();
- if (end > e)
- end= e;
- end -= p.getOffset();
-
- } else
- return;
- }
-
- length= end - offset;
-
- int[] selectionRange= new int[] { offset, length };
- validateSelectionRange(selectionRange);
- if (selectionRange[0] >= 0 && selectionRange[1] >= 0) {
+ IRegion widgetSelection= modelRange2WidgetRange(new Region(selectionOffset, selectionLength));
+ if (widgetSelection != null) {
- if (selectionLength < 0)
- fTextWidget.setSelectionRange(selectionRange[0] + selectionRange[1], -selectionRange[1]);
- else
+ int[] selectionRange= new int[] { widgetSelection.getOffset(), widgetSelection.getLength() };
+ validateSelectionRange(selectionRange);
+ if (selectionRange[0] >= 0) {
fTextWidget.setSelectionRange(selectionRange[0], selectionRange[1]);
-
- selectionChanged(selectionRange[0], selectionRange[1]);
+ selectionChanged(selectionRange[0], selectionRange[1]);
+ }
}
}
@@ -1629,6 +1601,10 @@ public class TextViewer extends Viewer implements
int offset= selectionRange[0];
int length= selectionRange[1];
+ if (length < 0) {
+ length= - length;
+ offset -= length;
+ }
if (offset <0)
offset= 0;
@@ -1670,8 +1646,13 @@ public class TextViewer extends Viewer implements
return;
}
- selectionRange[0]= offset;
- selectionRange[1]= length;
+ if (selectionRange[1] < 0) {
+ selectionRange[0]= offset + length;
+ selectionRange[1]= -length;
+ } else {
+ selectionRange[0]= offset;
+ selectionRange[1]= length;
+ }
}
/*
@@ -1712,7 +1693,8 @@ public class TextViewer extends Viewer implements
*/
protected void selectionChanged(int offset, int length) {
if (redraws()) {
- ISelection selection= new TextSelection(getDocument(), getVisibleRegionOffset() + offset, length);
+ IRegion r= widgetRange2ModelRange(new Region(offset, length));
+ ISelection selection= r != null ? new TextSelection(getDocument(), r.getOffset(), r.getLength()) : TextSelection.emptySelection();
SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
fireSelectionChanged(event);
}
@@ -1727,8 +1709,13 @@ public class TextViewer extends Viewer implements
*/
protected void markChanged(int offset, int length) {
if (redraws()) {
- if (offset != -1)
- offset += getVisibleRegionOffset();
+
+ if (offset != -1) {
+ IRegion r= widgetRange2ModelRange(new Region(offset, length));
+ offset= r.getOffset();
+ length= r.getLength();
+ }
+
ISelection selection= new MarkSelection(getDocument(), offset, length);
SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
fireSelectionChanged(event);
@@ -1771,8 +1758,8 @@ public class TextViewer extends Viewer implements
if (fTextListeners != null) {
DocumentEvent event= cmd.event;
- if (event instanceof ChildDocumentEvent)
- event= ((ChildDocumentEvent) event).getParentEvent();
+ if (event instanceof SlaveDocumentEvent)
+ event= ((SlaveDocumentEvent) event).getMasterEvent();
TextEvent e= new TextEvent(cmd.start, cmd.length, cmd.text, cmd.preservedText, event, redraws());
for (int i= 0; i < fTextListeners.size(); i++) {
@@ -1897,10 +1884,11 @@ public class TextViewer extends Viewer implements
fDocument= document;
try {
- int line= fDocument.getLineOfOffset(visibleRegionOffset);
- int offset= fDocument.getLineOffset(line);
- int length= (visibleRegionOffset - offset) + visibleRegionLength;
- setVisibleDocument(getChildDocumentManager().createChildDocument(fDocument, offset, length));
+
+ IDocument visibleDocument= createSlaveDocument(document);
+ updateVisibleDocument(visibleDocument, visibleRegionOffset, visibleRegionLength);
+ setVisibleDocument(visibleDocument);
+
} catch (BadLocationException x) {
throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_1")); //$NON-NLS-1$
}
@@ -1909,7 +1897,36 @@ public class TextViewer extends Viewer implements
fireInputDocumentChanged(oldDocument, fDocument);
fReplaceTextPresentation= false;
- }
+ }
+
+ protected IDocument createSlaveDocument(IDocument document) {
+ ISlaveDocumentManager manager= getSlaveDocumentManager();
+ if (manager != null) {
+ if (manager.isSlaveDocument(document))
+ return document;
+ return manager.createSlaveDocument(document);
+ }
+ return document;
+ }
+
+ protected boolean updateVisibleDocument(IDocument visibleDocument, int visibleRegionOffset, int visibleRegionLength) throws BadLocationException {
+ if (visibleDocument instanceof ChildDocument) {
+ ChildDocument childDocument= (ChildDocument) visibleDocument;
+
+ IDocument document= childDocument.getParentDocument();
+ int line= document.getLineOfOffset(visibleRegionOffset);
+ int offset= document.getLineOffset(line);
+ int length= (visibleRegionOffset - offset) + visibleRegionLength;
+
+ Position parentRange= childDocument.getParentDocumentRange();
+ if (offset != parentRange.getOffset() || length != parentRange.getLength()) {
+ childDocument.setParentDocumentRange(offset, length);
+ return true;
+ }
+ }
+ return false;
+ }
+
//---- Viewports
@@ -2010,21 +2027,9 @@ public class TextViewer extends Viewer implements
if (fTextWidget != null) {
int top= fTextWidget.getTopIndex();
-
- int offset= getVisibleRegionOffset();
- if (offset > 0) {
- try {
- top += getDocument().getLineOfOffset(offset);
- } catch (BadLocationException x) {
- if (TRACE_ERRORS)
- System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getTopIndex")); //$NON-NLS-1$
- return -1;
+ return widgetlLine2ModelLine(top);
}
- }
- return top;
- }
-
return -1;
}
@@ -2035,31 +2040,13 @@ public class TextViewer extends Viewer implements
if (fTextWidget != null) {
- int offset= getVisibleRegionOffset();
- if (offset > 0) {
- try {
- index -= getDocument().getLineOfOffset(offset);
- } catch (BadLocationException x) {
- if (TRACE_ERRORS)
- System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.setTopIndex_1")); //$NON-NLS-1$
- return;
- }
- }
+ int widgetLine= modelLine2WidgetLine(index);
+ if (widgetLine == -1)
+ widgetLine= getClosestWidgetLineForModelLine(index);
- if (index >= 0) {
-
- int lines= getVisibleLinesInViewport();
- if (lines > -1 ) {
- IDocument d= getVisibleDocument();
- int last= d.getNumberOfLines() - lines;
- if (last > 0 && index > last)
- index= last;
-
- fTextWidget.setTopIndex(index);
+ if (widgetLine > -1) {
+ fTextWidget.setTopIndex(widgetLine);
updateViewportListeners(INTERNAL);
-
- } else
- fTextWidget.setTopIndex(index);
}
}
}
@@ -2087,17 +2074,20 @@ public class TextViewer extends Viewer implements
if (fTextWidget == null)
return -1;
- IRegion r= getVisibleRegion();
+ IRegion coverage= getModelCoverage();
try {
IDocument d= getDocument();
- int startLine= d.getLineOfOffset(r.getOffset());
- int endLine= d.getLineOfOffset(r.getOffset() + r.getLength() - 1);
+ int startLine= d.getLineOfOffset(coverage.getOffset());
+ int endLine= d.getLineOfOffset(coverage.getOffset() + coverage.getLength() - 1);
int lines= getVisibleLinesInViewport();
- if (startLine + lines < endLine)
- return getTopIndex() + lines - 1;
+ if (startLine + lines < endLine) {
+ int widgetTopIndex= fTextWidget.getTopIndex();
+ int widgetBottomIndex= widgetTopIndex + lines -1;
+ return widgetlLine2ModelLine(widgetBottomIndex);
+ }
return endLine;
@@ -2118,7 +2108,7 @@ public class TextViewer extends Viewer implements
int top= fTextWidget.getTopIndex();
try {
top= getVisibleDocument().getLineOffset(top);
- return top + getVisibleRegionOffset();
+ return widgetlLine2ModelLine(top);
} catch (BadLocationException ex) {
if (TRACE_ERRORS)
System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getTopIndexStartOffset")); //$NON-NLS-1$
@@ -2137,9 +2127,9 @@ public class TextViewer extends Viewer implements
IRegion line= getDocument().getLineInformation(getBottomIndex());
int bottomEndOffset= line.getOffset() + line.getLength() - 1;
- IRegion region= getVisibleRegion();
- int visibleRegionEndOffset= region.getOffset() + region.getLength() - 1;
- return visibleRegionEndOffset < bottomEndOffset ? visibleRegionEndOffset : bottomEndOffset;
+ IRegion coverage= getModelCoverage();
+ int coverageEndOffset= coverage.getOffset() + coverage.getLength() - 1;
+ return Math.min(coverageEndOffset, bottomEndOffset);
} catch (BadLocationException ex) {
if (TRACE_ERRORS)
@@ -2156,39 +2146,15 @@ public class TextViewer extends Viewer implements
if (fTextWidget == null || !redraws())
return;
- if (length < 0) {
- start += length;
- length= -length;
- }
-
- int end= start + length;
-
- IDocument document= getVisibleDocument();
- if (document == null)
- return;
-
- Position p= (document instanceof ChildDocument)
- ? ((ChildDocument) document).getParentDocumentRange()
- : new Position(0, document.getLength());
-
- if (p.overlapsWith(start, length)) {
-
- if (start < p.getOffset())
- start= p.getOffset();
- start -= p.getOffset();
-
- int e= p.getOffset() + p.getLength();
- if (end > e)
- end= e;
- end -= p.getOffset();
-
+ IRegion modelRange= new Region(start, length);
+ IRegion widgetRange= modelRange2WidgetRange(modelRange);
+ if (widgetRange != null) {
+ internalRevealRange(widgetRange.getOffset(), widgetRange.getOffset() + widgetRange.getLength());
} else {
- // http://dev.eclipse.org/bugs/show_bug.cgi?id=15159
- start= start < p.getOffset() ? 0 : p.getLength();
- end= start;
+ IRegion coverage= getModelCoverage();
+ int cursor= start < coverage.getOffset() ? 0 : getVisibleDocument().getLength();
+ internalRevealRange(cursor, cursor);
}
-
- internalRevealRange(start, end);
}
/**
@@ -2348,14 +2314,22 @@ public class TextViewer extends Viewer implements
//---- visible range support
/**
- * Returns the child document manager
+ * Returns the slave document manager
*
- * @return the child document manager
+ * @return the slave document manager
*/
- private ChildDocumentManager getChildDocumentManager() {
- if (fChildDocumentManager == null)
- fChildDocumentManager= new ChildDocumentManager();
- return fChildDocumentManager;
+ protected ISlaveDocumentManager getSlaveDocumentManager() {
+ if (fSlaveDocumentManager == null)
+ fSlaveDocumentManager= createSlaveDocumentManager();
+ return fSlaveDocumentManager;
+ }
+
+ /**
+ * Creates a new slave document manager.
+ * @return ISlaveDocumentManager
+ */
+ protected ISlaveDocumentManager createSlaveDocumentManager() {
+ return new ChildDocumentManager();
}
/*
@@ -2374,25 +2348,14 @@ public class TextViewer extends Viewer implements
public final void invalidateTextPresentation(int offset, int length) {
if (fVisibleDocument != null) {
- IRegion visibleRegion= getVisibleRegion();
-
- int delta= visibleRegion.getOffset() - offset;
- if (delta > 0) {
- offset= visibleRegion.getOffset();
- length -= delta;
- }
- offset -= visibleRegion.getOffset();
+ IRegion widgetRange= modelRange2WidgetRange(new Region(offset, length));
- delta= (offset + length) - (visibleRegion.getOffset() + visibleRegion.getLength());
- if (delta > 0)
- length -= delta;
-
fWidgetCommand.event= null;
- fWidgetCommand.start= offset;
- fWidgetCommand.length= length;
+ fWidgetCommand.start= widgetRange.getOffset();
+ fWidgetCommand.length= widgetRange.getLength();
try {
- fWidgetCommand.text= fVisibleDocument.get(offset, length);
+ fWidgetCommand.text= fVisibleDocument.get(widgetRange.getOffset(), widgetRange.getLength());
updateTextListeners(fWidgetCommand);
} catch (BadLocationException x) {
// can not happen because of previous checking
@@ -2426,12 +2389,13 @@ public class TextViewer extends Viewer implements
*
* @param document the visible document
*/
- private void setVisibleDocument(IDocument document) {
+ protected void setVisibleDocument(IDocument document) {
if (fVisibleDocument != null && fDocumentListener != null)
fVisibleDocument.removeDocumentListener(fDocumentListener);
fVisibleDocument= document;
+ initializeDocumentInformationMapping(fVisibleDocument);
initializeWidgetContents();
resetPlugins();
@@ -2440,6 +2404,11 @@ public class TextViewer extends Viewer implements
fVisibleDocument.addDocumentListener(fDocumentListener);
}
+ protected void initializeDocumentInformationMapping(IDocument visibleDocument) {
+ ISlaveDocumentManager manager= getSlaveDocumentManager();
+ fInformationMapping= manager == null ? null : manager.createMasterSlaveMapping(visibleDocument);
+ }
+
/**
* Returns the viewer's visible document.
*
@@ -2454,7 +2423,7 @@ public class TextViewer extends Viewer implements
*
* @return the offset of the visible region
*/
- protected int getVisibleRegionOffset() {
+ protected int _getVisibleRegionOffset() {
IDocument document= getVisibleDocument();
if (document instanceof ChildDocument) {
@@ -2478,7 +2447,22 @@ public class TextViewer extends Viewer implements
return new Region(0, document == null ? 0 : document.getLength());
}
-
+
+ /*
+ * @see ITextViewer#overlapsWithVisibleRegion
+ */
+ public boolean overlapsWithVisibleRegion(int start, int length) {
+ IDocument document= getVisibleDocument();
+ if (document instanceof ChildDocument) {
+ ChildDocument cdoc= (ChildDocument) document;
+ return cdoc.getParentDocumentRange().overlapsWith(start, length);
+ } else if (document != null) {
+ int size= document.getLength();
+ return (start >= 0 && length >= 0 && start + length <= size);
+ }
+ return false;
+ }
+
/*
* @see ITextViewer#setVisibleRegion
*/
@@ -2490,28 +2474,10 @@ public class TextViewer extends Viewer implements
return;
}
- ChildDocument child= null;
- IDocument parent= getVisibleDocument();
-
- if (parent instanceof ChildDocument) {
- child= (ChildDocument) parent;
- parent= child.getParentDocument();
- }
-
try {
-
- int line= parent.getLineOfOffset(start);
- int offset= parent.getLineOffset(line);
- length += (start - offset);
-
- if (child != null) {
- child.setParentDocumentRange(offset, length);
- } else {
- child= getChildDocumentManager().createChildDocument(parent, offset, length);
- }
-
- setVisibleDocument(child);
-
+ IDocument visibleDocument= createSlaveDocument(getVisibleDocument());
+ if (updateVisibleDocument(visibleDocument, start, length))
+ setVisibleDocument(visibleDocument);
} catch (BadLocationException x) {
throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_2")); //$NON-NLS-1$
}
@@ -2521,29 +2487,16 @@ public class TextViewer extends Viewer implements
* @see ITextViewer#resetVisibleRegion
*/
public void resetVisibleRegion() {
- IDocument document= getVisibleDocument();
- if (document instanceof ChildDocument) {
- ChildDocument child = (ChildDocument) document;
- setVisibleDocument(child.getParentDocument());
- getChildDocumentManager().freeChildDocument(child);
- }
- }
-
- /*
- * @see ITextViewer#overlapsWithVisibleRegion
- */
- public boolean overlapsWithVisibleRegion(int start, int length) {
- IDocument document= getVisibleDocument();
- if (document instanceof ChildDocument) {
- ChildDocument cdoc= (ChildDocument) document;
- return cdoc.getParentDocumentRange().overlapsWith(start, length);
- } else if (document != null) {
- int size= document.getLength();
- return (start >= 0 && length >= 0 && start + length <= size);
+ ISlaveDocumentManager manager= getSlaveDocumentManager();
+ if (manager != null) {
+ IDocument slave= getVisibleDocument();
+ IDocument master= manager.getMasterDocument(slave);
+ if (master != null) {
+ setVisibleDocument(master);
+ manager.freeSlaveDocument(slave);
+ }
}
- return false;
}
-
//--------------------------------------
@@ -2639,20 +2592,20 @@ public class TextViewer extends Viewer implements
return;
}
- int offset= getVisibleRegionOffset();
- fDocumentCommand.setEvent(e, offset);
+ IRegion modelRange= event2ModelRange(e);
+ fDocumentCommand.setEvent(e, modelRange);
customizeDocumentCommand(fDocumentCommand);
- if (!fDocumentCommand.fillEvent(e, offset)) {
+ if (!fDocumentCommand.fillEvent(e, modelRange)) {
try {
fVerifyListener.forward(false);
fDocumentCommand.execute(getDocument());
if (fTextWidget != null) {
- int caretOffset= fDocumentCommand.caretOffset;
+ int documentCaret= fDocumentCommand.caretOffset;
// old behaviour of document command
- if (caretOffset == -1)
- caretOffset= fDocumentCommand.offset + (fDocumentCommand.text == null ? 0 : fDocumentCommand.text.length());
- caretOffset -= getVisibleRegionOffset();
- fTextWidget.setCaretOffset(caretOffset);
+ if (documentCaret == -1)
+ documentCaret= fDocumentCommand.offset + (fDocumentCommand.text == null ? 0 : fDocumentCommand.text.length());
+ int widgetCaret= modelOffset2WidgetOffset(documentCaret);
+ fTextWidget.setCaretOffset(widgetCaret);
}
} catch (BadLocationException x) {
if (TRACE_ERRORS)
@@ -2671,19 +2624,11 @@ public class TextViewer extends Viewer implements
* @return <code>true</code> if the marked region of this viewer is empty, otherwise <code>false</code>
*/
private boolean isMarkedRegionEmpty() {
-
- if (fTextWidget == null)
- return true;
-
- IRegion region= getVisibleRegion();
- int offset= region.getOffset();
- int length= region.getLength();
-
return
+ fTextWidget == null ||
fMarkPosition == null ||
fMarkPosition.isDeleted() ||
- fMarkPosition.offset < offset ||
- fMarkPosition.offset > offset + length;
+ modelRange2WidgetRange(fMarkPosition) == null;
}
/*
@@ -2765,9 +2710,10 @@ public class TextViewer extends Viewer implements
case DELETE:
deleteText();
break;
- case SELECT_ALL:
- setSelectedRange(getVisibleRegionOffset(), getVisibleDocument().getLength());
+ case SELECT_ALL: {
+ setSelectedRange(0, getDocument().getLength());
break;
+ }
case SHIFT_RIGHT:
shift(false, true, false);
break;
@@ -2808,21 +2754,15 @@ public class TextViewer extends Viewer implements
if (fTextWidget == null)
return;
- IRegion region= getVisibleRegion();
- int offset= region.getOffset();
- int length= region.getLength();
-
- if (fMarkPosition == null || fMarkPosition.isDeleted() ||
- fMarkPosition.offset < offset || fMarkPosition.offset > offset + length)
+ if (fMarkPosition == null || fMarkPosition.isDeleted() || modelRange2WidgetRange(fMarkPosition) == null)
return;
- int markOffset= fMarkPosition.offset - offset;
-
+ int widgetMarkOffset= modelOffset2WidgetOffset(fMarkPosition.offset);
Point selection= fTextWidget.getSelection();
- if (selection.x <= markOffset)
- fTextWidget.setSelection(selection.x, markOffset);
+ if (selection.x <= widgetMarkOffset)
+ fTextWidget.setSelection(selection.x, widgetMarkOffset);
else
- fTextWidget.setSelection(markOffset, selection.x);
+ fTextWidget.setSelection(widgetMarkOffset, selection.x);
if (delete) {
fTextWidget.cut();
@@ -3207,19 +3147,23 @@ public class TextViewer extends Viewer implements
return -1;
try {
- int offset= (startPosition == -1 ? startPosition : startPosition - getVisibleRegionOffset());
- int pos= getVisibleDocument().search(offset, findString, forwardSearch, caseSensitive, wholeWord);
- if (pos > -1) {
+
+ int widgetOffset= (startPosition == -1 ? startPosition : modelOffset2WidgetOffset(startPosition));
+ int widgetPos= getVisibleDocument().search(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord);
+ if (widgetPos > -1) {
+
int length= findString.length();
if (redraws()) {
- fTextWidget.setSelectionRange(pos, length);
- internalRevealRange(pos, pos + length);
- selectionChanged(pos, length);
+ fTextWidget.setSelectionRange(widgetPos, length);
+ internalRevealRange(widgetPos, widgetPos + length);
+ selectionChanged(widgetPos, length);
} else {
- setSelectedRange(pos + getVisibleRegionOffset(), length);
+ setSelectedRange(widgetOffset2ModelOffset(widgetPos), length);
}
+
+ return widgetOffset2ModelOffset(widgetPos);
}
- return pos + getVisibleRegionOffset();
+
} catch (BadLocationException x) {
if (TRACE_ERRORS)
System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); //$NON-NLS-1$
@@ -3237,32 +3181,41 @@ public class TextViewer extends Viewer implements
return -1;
try {
- int offset;
+
+ int modelOffset;
if (forwardSearch && (startPosition == -1 || startPosition < rangeOffset)) {
- offset= rangeOffset;
+ modelOffset= rangeOffset;
} else if (!forwardSearch && (startPosition == -1 || startPosition > rangeOffset + rangeLength)) {
- offset= rangeOffset + rangeLength;
+ modelOffset= rangeOffset + rangeLength;
} else {
- offset= startPosition;
+ modelOffset= startPosition;
}
- offset -= getVisibleRegionOffset();
- int pos= getVisibleDocument().search(offset, findString, forwardSearch, caseSensitive, wholeWord);
+ int widgetOffset= modelOffset2WidgetOffset(modelOffset);
+ if (widgetOffset == -1)
+ return -1;
+ int widgetPos= getVisibleDocument().search(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord);
+ int modelPos= widgetPos == -1 ? -1 : widgetOffset2ModelOffset(widgetPos);
+
int length = findString.length();
- if (pos != -1 && (pos + getVisibleRegionOffset() < rangeOffset || pos + getVisibleRegionOffset() + length > rangeOffset + rangeLength))
- pos= -1;
+ if (widgetPos != -1 && (modelPos < rangeOffset || modelPos + length > rangeOffset + rangeLength))
+ widgetPos= -1;
- if (pos > -1) {
+ if (widgetPos > -1) {
+
if (redraws()) {
- fTextWidget.setSelectionRange(pos, length);
- internalRevealRange(pos, pos + length);
- selectionChanged(pos, length);
+ fTextWidget.setSelectionRange(widgetPos, length);
+ internalRevealRange(widgetPos, widgetPos + length);
+ selectionChanged(widgetPos, length);
} else {
- setSelectedRange(pos + getVisibleRegionOffset(), length);
+ setSelectedRange(modelPos, length);
}
+
+ return modelPos;
}
- return pos + getVisibleRegionOffset();
+
+
} catch (BadLocationException x) {
if (TRACE_ERRORS)
System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); //$NON-NLS-1$
@@ -3296,10 +3249,17 @@ public class TextViewer extends Viewer implements
s.start= start;
s.length= length;
- fTextWidget.setStyleRange(s);
-
- if (controlRedraw)
- fTextWidget.setRedraw(true);
+ s= modelStyleRange2WidgetStyleRange(s);
+ if (s != null) {
+
+ if (controlRedraw)
+ fTextWidget.setRedraw(false);
+
+ fTextWidget.setStyleRange(s);
+
+ if (controlRedraw)
+ fTextWidget.setRedraw(true);
+ }
}
}
@@ -3313,34 +3273,69 @@ public class TextViewer extends Viewer implements
StyleRange range= presentation.getDefaultStyleRange();
if (range != null) {
- fTextWidget.setStyleRange(range);
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ fTextWidget.setStyleRange(range);
+
Iterator e= presentation.getNonDefaultStyleRangeIterator();
while (e.hasNext()) {
range= (StyleRange) e.next();
- fTextWidget.setStyleRange(range);
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ fTextWidget.setStyleRange(range);
}
} else {
- IRegion coverage= presentation.getCoverage();
- if (coverage != null) {
- Iterator e= presentation.getAllStyleRangeIterator();
- StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()];
- for (int i= 0; i < ranges.length; i++)
- ranges[i]= (StyleRange) e.next();
+ List list= new ArrayList();
+ Iterator e= presentation.getAllStyleRangeIterator();
+ while (e.hasNext()) {
+ range= (StyleRange) e.next();
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ list.add(range);
+ }
- fTextWidget.replaceStyleRanges(coverage.getOffset(), coverage.getLength(), ranges);
+ if (!list.isEmpty()) {
+ StyleRange[] ranges= new StyleRange[list.size()];
+ list.toArray(ranges);
+ IRegion region= modelRange2WidgetRange(presentation.getCoverage());
+ fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges);
}
}
}
/**
+ * Applies the given presentation to the given text widget. Helper method.
+ *
+ * @param presentation the style information
+ * @since 2.1
+ */
+ private void applyTextPresentation(TextPresentation presentation) {
+
+ List list= new ArrayList();
+ Iterator e= presentation.getAllStyleRangeIterator();
+ while (e.hasNext()) {
+ StyleRange range= (StyleRange) e.next();
+ range= modelStyleRange2WidgetStyleRange(range);
+ if (range != null)
+ list.add(range);
+ }
+
+ if (!list.isEmpty()) {
+ StyleRange[] ranges= new StyleRange[list.size()];
+ list.toArray(ranges);
+ fTextWidget.setStyleRanges(ranges);
+ }
+ }
+
+ /**
* Returns the visible region if it is not equal to the whole document.
* Otherwise returns <code>null</code>.
*
* @return the viewer's visible region if smaller than input document, otherwise <code>null</code>
*/
- protected IRegion internalGetVisibleRegion() {
+ protected IRegion _internalGetVisibleRegion() {
IDocument document= getVisibleDocument();
if (document instanceof ChildDocument) {
@@ -3359,7 +3354,6 @@ public class TextViewer extends Viewer implements
if (presentation == null || !redraws())
return;
- presentation.setResultWindow(internalGetVisibleRegion());
if (presentation.isEmpty() || fTextWidget == null)
return;
@@ -3367,7 +3361,7 @@ public class TextViewer extends Viewer implements
fTextWidget.setRedraw(false);
if (fReplaceTextPresentation)
- TextPresentation.applyTextPresentation(presentation, fTextWidget);
+ applyTextPresentation(presentation);
else
addPresentation(presentation);
@@ -3483,7 +3477,7 @@ public class TextViewer extends Viewer implements
fMarkPosition.undelete();
}
- markChanged(fMarkPosition.offset - getVisibleRegionOffset(), 0);
+ markChanged(modelOffset2WidgetOffset(fMarkPosition.offset), 0);
}
}
@@ -3574,11 +3568,6 @@ public class TextViewer extends Viewer implements
if (fTextWidget != null && !fTextWidget.isDisposed())
fTextWidget.setRedraw(false);
-
- /*
- * TODO: should be removed.
- */
- fireRedrawChanged();
}
/*
@@ -3659,4 +3648,192 @@ public class TextViewer extends Viewer implements
return fTextHoverManager.getHoverEventLocation();
}
+
+ // ----------------------------------- conversions -------------------------------------------------------
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#modelLine2WidgetLine(int)
+ */
+ public int modelLine2WidgetLine(int modelLine) {
+ if (fInformationMapping == null)
+ return modelLine;
+
+ try {
+ return fInformationMapping.toImageLine(modelLine);
+ } catch (BadLocationException x) {
+ }
+
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#modelOffset2WidgetOffset(int)
+ */
+ public int modelOffset2WidgetOffset(int modelOffset) {
+ if (fInformationMapping == null)
+ return modelOffset;
+
+ try {
+ return fInformationMapping.toImageOffset(modelOffset);
+ } catch (BadLocationException x) {
+ }
+
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#modelRange2WidgetRange(org.eclipse.jface.text.IRegion)
+ */
+ public IRegion modelRange2WidgetRange(IRegion modelRange) {
+ if (fInformationMapping == null)
+ return modelRange;
+
+ try {
+ return fInformationMapping.toImageRegion(modelRange);
+ } catch (BadLocationException x) {
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#widgetlLine2ModelLine(int)
+ */
+ public int widgetlLine2ModelLine(int widgetLine) {
+ if (fInformationMapping == null)
+ return widgetLine;
+
+ try {
+ return fInformationMapping.toOriginLine(widgetLine);
+ } catch (BadLocationException x) {
+ }
+
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#widgetOffset2ModelOffset(int)
+ */
+ public int widgetOffset2ModelOffset(int widgetOffset) {
+ if (fInformationMapping == null)
+ return widgetOffset;
+
+ try {
+ return fInformationMapping.toOriginOffset(widgetOffset);
+ } catch (BadLocationException x) {
+ if (widgetOffset == getVisibleDocument().getLength()) {
+ IRegion coverage= fInformationMapping.getCoverage();
+ return coverage.getOffset() + coverage.getLength();
+ }
+ }
+
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#widgetRange2ModelRange(org.eclipse.jface.text.IRegion)
+ */
+ public IRegion widgetRange2ModelRange(IRegion widgetRange) {
+ if (fInformationMapping == null)
+ return widgetRange;
+
+ try {
+ return fInformationMapping.toOriginRegion(widgetRange);
+ } catch (BadLocationException x) {
+ int modelOffset= widgetOffset2ModelOffset(widgetRange.getOffset());
+ if (modelOffset > -1) {
+ int modelEndOffset= widgetOffset2ModelOffset(widgetRange.getOffset() + widgetRange.getLength());
+ if (modelEndOffset > -1)
+ return new Region(modelOffset, modelEndOffset - modelOffset);
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#getModelCoverage()
+ */
+ public IRegion getModelCoverage() {
+ if (fInformationMapping == null) {
+ IDocument document= getDocument();
+ if (document == null)
+ return null;
+ return new Region(0, document.getLength());
+ }
+
+ return fInformationMapping.getCoverage();
+ }
+
+ protected int getClosestWidgetLineForModelLine(int modelLine) {
+ if (fInformationMapping == null)
+ return modelLine;
+
+ try {
+ return fInformationMapping.toClosestImageLine(modelLine);
+ } catch (BadLocationException x) {
+ }
+
+ return -1;
+ }
+
+ protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) {
+ IRegion region= modelRange2WidgetRange(new Region(range.start, range.length));
+ if (region != null) {
+ StyleRange result= (StyleRange) range.clone();
+ result.start= region.getOffset();
+ result.length= region.getLength();
+ return result;
+ }
+ return null;
+ }
+
+ protected IRegion modelRange2WidgetRange(Position modelPosition) {
+ return modelRange2WidgetRange(new Region(modelPosition.getOffset(), modelPosition.getLength()));
+ }
+
+ protected IRegion event2ModelRange(VerifyEvent event) {
+
+ Region region= null;
+ if (event.start <= event.end)
+ region= new Region(event.start, event.end - event.start);
+ else
+ region= new Region(event.end, event.start - event.end);
+
+ return widgetRange2ModelRange(region);
+ }
+
+ protected Point widgetSelection2ModelSelection(Point widgetSelection) {
+ IRegion region= new Region(widgetSelection.x, widgetSelection.y);
+ region= widgetRange2ModelRange(region);
+ return region == null ? null : new Point(region.getOffset(), region.getLength());
+ }
+
+ protected Point modelSelection2WidgetSelection(Point modelSelection) {
+ if (fInformationMapping == null)
+ return modelSelection;
+
+ try {
+ IRegion region= new Region(modelSelection.x, modelSelection.y);
+ region= fInformationMapping.toImageRegion(region);
+ return new Point(region.getOffset(), region.getLength());
+ } catch (BadLocationException x) {
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextViewerExtension3#widgetLineOfWidgetOffset(int)
+ */
+ public int widgetLineOfWidgetOffset(int widgetOffset) {
+ IDocument document= getVisibleDocument();
+ if (document != null) {
+ try {
+ return document.getLineOfOffset(widgetOffset);
+ } catch (BadLocationException e) {
+ }
+ }
+ return -1;
+ }
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewerHoverManager.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewerHoverManager.java
index 23a1fbdd002..864a4da69c4 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewerHoverManager.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewerHoverManager.java
@@ -174,14 +174,18 @@ class TextViewerHoverManager extends AbstractHoverInformationControlManager impl
*/
private int computeOffsetAtLocation(int x, int y) {
- StyledText styledText= fTextViewer.getTextWidget();
- IDocument document= fTextViewer.getVisibleDocument();
-
- if (document == null)
- return -1;
-
try {
- return styledText.getOffsetAtLocation(new Point(x, y)) + fTextViewer.getVisibleRegionOffset();
+
+ StyledText styledText= fTextViewer.getTextWidget();
+ int widgetOffset= styledText.getOffsetAtLocation(new Point(x, y));
+
+ if (fTextViewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fTextViewer;
+ return extension.widgetOffset2ModelOffset(widgetOffset);
+ }
+
+ return widgetOffset + fTextViewer._getVisibleRegionOffset();
+
} catch (IllegalArgumentException e) {
return -1;
}
@@ -195,14 +199,11 @@ class TextViewerHoverManager extends AbstractHoverInformationControlManager impl
*/
private Rectangle computeArea(IRegion region) {
+ IRegion widgetRegion= modelRange2WidgetRange(region);
+ int start= widgetRegion.getOffset();
+ int end= widgetRegion.getOffset() + widgetRegion.getLength();
+
StyledText styledText= fTextViewer.getTextWidget();
-
- IRegion visibleRegion= fTextViewer.getVisibleRegion();
- int start= region.getOffset() - visibleRegion.getOffset();
- int end= start + region.getLength();
- if (end > visibleRegion.getLength())
- end= visibleRegion.getLength();
-
Point upperLeft= styledText.getLocationAtOffset(start);
Point lowerRight= new Point(upperLeft.x, upperLeft.y);
@@ -231,6 +232,26 @@ class TextViewerHoverManager extends AbstractHoverInformationControlManager impl
return new Rectangle(upperLeft.x, upperLeft.y, width, height);
}
+ /**
+ * Method modelRange2WidgetRange.
+ * @param region
+ * @return IRegion
+ */
+ private IRegion modelRange2WidgetRange(IRegion region) {
+ if (fTextViewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fTextViewer;
+ return extension.modelRange2WidgetRange(region);
+ }
+
+ IRegion visibleRegion= fTextViewer.getVisibleRegion();
+ int start= region.getOffset() - visibleRegion.getOffset();
+ int end= start + region.getLength();
+ if (end > visibleRegion.getLength())
+ end= visibleRegion.getLength();
+
+ return new Region(start, end - start);
+ }
+
/*
* @see AbstractInformationControlManager#showInformationControl(Rectangle)
*/
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java
index 4360fe922d5..7c7390a056a 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/information/InformationPresenter.java
@@ -37,9 +37,11 @@ import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension3;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.IWidgetTokenKeeper;
import org.eclipse.jface.text.IWidgetTokenOwner;
+import org.eclipse.jface.text.Region;
import org.eclipse.jface.util.Assert;
@@ -308,13 +310,12 @@ public class InformationPresenter extends AbstractInformationControlManager impl
* @return the graphical extend of the given region
*/
private Rectangle computeArea(IRegion region) {
+
+ IRegion widgetRegion= modelRange2WidgetRange(region);
+ int start= widgetRegion.getOffset();
+ int end= widgetRegion.getOffset() + widgetRegion.getLength();
StyledText styledText= fTextViewer.getTextWidget();
-
- IRegion visible= fTextViewer.getVisibleRegion();
- int start= region.getOffset() - visible.getOffset();
- int end= start + region.getLength();
-
Point upperLeft= styledText.getLocationAtOffset(start);
Point lowerRight= new Point(upperLeft.x, upperLeft.y);
@@ -345,6 +346,26 @@ public class InformationPresenter extends AbstractInformationControlManager impl
return new Rectangle(upperLeft.x, upperLeft.y, width, height);
}
+ /**
+ * Method modelRange2WidgetRange.
+ * @param region
+ * @return IRegion
+ */
+ private IRegion modelRange2WidgetRange(IRegion region) {
+ if (fTextViewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fTextViewer;
+ return extension.modelRange2WidgetRange(region);
+ }
+
+ IRegion visibleRegion= fTextViewer.getVisibleRegion();
+ int start= region.getOffset() - visibleRegion.getOffset();
+ int end= start + region.getLength();
+ if (end > visibleRegion.getLength())
+ end= visibleRegion.getLength();
+
+ return new Region(start, end - start);
+ }
+
/*
* @see IInformationPresenter#install(ITextViewer)
*/
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java
index 566be49bc0a..fcce99149e8 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/presentation/PresentationReconciler.java
@@ -28,6 +28,7 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension3;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextEvent;
@@ -175,13 +176,12 @@ public class PresentationReconciler implements IPresentationReconciler {
IDocument d= fViewer.getDocument();
processDamage(new Region(0, d.getLength()), d);
} else {
- IRegion visible= fViewer.getVisibleRegion();
- IRegion region= new Region(e.getOffset() + visible.getOffset(), e.getLength());
+ IRegion region= widgetRegion2ModelRegion(e);
processDamage(region, fViewer.getDocument());
}
} else {
-
+
IRegion damage= getDamage(de);
if (damage != null)
processDamage(damage, de.getDocument());
@@ -190,6 +190,17 @@ public class PresentationReconciler implements IPresentationReconciler {
fDocumentPartitioningChanged= false;
fChangedDocumentPartitions= null;
}
+
+ protected IRegion widgetRegion2ModelRegion(TextEvent e) {
+ if (fViewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fViewer;
+ return extension.widgetRange2ModelRange(new Region(e.getOffset(), e.getLength()));
+ }
+
+ IRegion visible= fViewer.getVisibleRegion();
+ IRegion region= new Region(e.getOffset() + visible.getOffset(), e.getLength());
+ return region;
+ }
};
/** The map of presentation damagers. */
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationBarHoverManager.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationBarHoverManager.java
index fc1d1141efa..33f0a0a75ae 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationBarHoverManager.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationBarHoverManager.java
@@ -20,6 +20,8 @@ import org.eclipse.jface.text.AbstractHoverInformationControlManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewerExtension3;
+
import org.eclipse.jface.util.Assert;
@@ -73,14 +75,18 @@ class AnnotationBarHoverManager extends AbstractHoverInformationControlManager {
}
/**
- * Returns for a given absolute line number the corresponding line
- * number relative to the viewer's visible region.
- *
+ * Returns for the widget line number for the given document line number.
+ *
* @param line the absolute line number
* @return the line number relative to the viewer's visible region
* @throws BadLocationException if <code>line</code> is not valid in the viewer's document
*/
- private int getRelativeLineNumber(int line) throws BadLocationException {
+ private int getWidgetLineNumber(int line) throws BadLocationException {
+ if (fSourceViewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fSourceViewer;
+ return extension.modelLine2WidgetLine(line);
+ }
+
IRegion region= fSourceViewer.getVisibleRegion();
int firstLine= fSourceViewer.getDocument().getLineOfOffset(region.getOffset());
return line - firstLine;
@@ -96,7 +102,7 @@ class AnnotationBarHoverManager extends AbstractHoverInformationControlManager {
try {
StyledText text= fSourceViewer.getTextWidget();
int lineHeight= text.getLineHeight();
- int y= getRelativeLineNumber(line) * lineHeight - text.getTopPixel();
+ int y= getWidgetLineNumber(line) * lineHeight - text.getTopPixel();
Point size= fVerticalRuler.getControl().getSize();
return new Rectangle(0, y, size.x, lineHeight);
} catch (BadLocationException x) {
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
index 8c0959ae1a4..cc1bb18a3a4 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
@@ -37,8 +37,10 @@ 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.ITextViewerExtension3;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextEvent;
@@ -97,6 +99,8 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
private InternalListener fInternalListener= new InternalListener();
/** The width of this vertical ruler */
private int fWidth;
+ /** Switch for enabling/disabling the setModel method. */
+ private boolean fAllowSetModel= true;
/**
@@ -104,6 +108,18 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
*
* @param width the width of the vertical ruler
*/
+ public AnnotationRulerColumn(IAnnotationModel model, int width) {
+ fWidth= width;
+ fAllowSetModel= false;
+ fModel= model;
+ fModel.addAnnotationModelListener(fInternalListener);
+ }
+
+ /**
+ * Constructs this column with the given width.
+ *
+ * @param width the width of the vertical ruler
+ */
public AnnotationRulerColumn(int width) {
fWidth= width;
}
@@ -158,6 +174,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
public void mouseDoubleClick(MouseEvent event) {
fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+ mouseDoubleClicked(fParentRuler.getLineOfLastMouseButtonActivity());
}
});
@@ -169,6 +186,9 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
return fCanvas;
}
+ protected void mouseDoubleClicked(int rulerLine) {
+ }
+
/**
* Disposes the ruler's resources.
*/
@@ -214,7 +234,11 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
try {
gc.setBackground(fCanvas.getBackground());
gc.fillRectangle(0, 0, size.x, size.y);
- doPaint(gc);
+
+ if (fCachedTextViewer instanceof ITextViewerExtension3)
+ doPaint1(gc);
+ else
+ doPaint(gc);
} finally {
gc.dispose();
}
@@ -331,6 +355,64 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
}
}
+ protected void doPaint1(GC gc) {
+
+ if (fModel == null || fCachedTextViewer == null)
+ return;
+
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fCachedTextViewer;
+
+ fScrollPos= fCachedTextWidget.getTopPixel();
+ int lineheight= fCachedTextWidget.getLineHeight();
+ Point dimension= fCanvas.getSize();
+ int shift= fCachedTextViewer.getTopInset();
+
+ // 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;
+
+ IRegion widgetRegion= extension.modelRange2WidgetRange(new Region(position.getOffset(), position.getLength()));
+ if (widgetRegion == null)
+ continue;
+
+ int startLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset());
+ if (startLine == -1)
+ continue;
+
+ int endLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset() + Math.max(widgetRegion.getLength() -1, 0));
+ if (endLine == -1)
+ continue;
+
+ 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);
+ }
+ }
+ }
+
+
/**
* Post a redraw request for thid column into the UI thread.
*/
@@ -362,7 +444,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
* @see IVerticalRulerColumn#setModel
*/
public void setModel(IAnnotationModel model) {
- if (model != fModel) {
+ if (fAllowSetModel && model != fModel) {
if (fModel != null)
fModel.removeAnnotationModelListener(fInternalListener);
@@ -381,4 +463,12 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn {
*/
public void setFont(Font font) {
}
+
+ protected ITextViewer getCachedTextViewer() {
+ return fCachedTextViewer;
+ }
+
+ protected IAnnotationModel getModel() {
+ return fModel;
+ }
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/CompositeRuler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/CompositeRuler.java
index 406e9c23728..6bbd3a228e5 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/CompositeRuler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/CompositeRuler.java
@@ -47,6 +47,7 @@ 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.ITextViewerExtension3;
/**
@@ -693,15 +694,24 @@ public class CompositeRuler implements IVerticalRuler, IVerticalRulerExtension {
return -1;
StyledText text= fTextViewer.getTextWidget();
- int line= ((y_coordinate + text.getTopPixel()) / text.getLineHeight());
+ int line= ((y_coordinate + text.getTopPixel()) / text.getLineHeight());
+ return widgetLine2ModelLine(fTextViewer, line);
+ }
+
+ protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) {
+
+ if (viewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
+ return extension.widgetlLine2ModelLine(widgetLine);
+ }
+
try {
- IRegion r= fTextViewer.getVisibleRegion();
- IDocument d= fTextViewer.getDocument();
- line += d.getLineOfOffset(r.getOffset());
+ IRegion r= viewer.getVisibleRegion();
+ IDocument d= viewer.getDocument();
+ return widgetLine += d.getLineOfOffset(r.getOffset());
} catch (BadLocationException x) {
}
-
- return line;
+ return widgetLine;
}
/**
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
index 23d0a20c7a6..c639ccd2c31 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
@@ -41,6 +41,7 @@ import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITextViewerExtension3;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.TextEvent;
@@ -512,7 +513,12 @@ public final class LineNumberRulerColumn implements IVerticalRulerColumn {
try {
gc.setBackground(getBackground(fCanvas.getDisplay()));
gc.fillRectangle(0, 0, size.x, size.y);
- doPaint(gc);
+
+ if (fCachedTextViewer instanceof ITextViewerExtension3)
+ doPaint1(gc);
+ else
+ doPaint(gc);
+
} finally {
gc.dispose();
}
@@ -584,6 +590,67 @@ public final class LineNumberRulerColumn implements IVerticalRulerColumn {
}
}
+ private void doPaint1(GC gc) {
+
+ if (fCachedTextViewer == null)
+ return;
+
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fCachedTextViewer;
+
+ int firstLine= 0;
+
+
+ int widgetTopLine= fCachedTextWidget.getTopIndex();
+ if (widgetTopLine > 0)
+ -- widgetTopLine;
+
+ int topLine= extension.widgetlLine2ModelLine(widgetTopLine);
+ int bottomLine= fCachedTextViewer.getBottomIndex();
+ if (bottomLine >= 0)
+ ++ bottomLine;
+
+ try {
+
+ IRegion region= extension.getModelCoverage();
+ IDocument doc= fCachedTextViewer.getDocument();
+
+ firstLine= doc.getLineOfOffset(region.getOffset());
+ if (firstLine > topLine || topLine == -1)
+ topLine= firstLine;
+
+ int lastLine= doc.getLineOfOffset(region.getOffset() + region.getLength());
+ if (lastLine < bottomLine || bottomLine == -1)
+ 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= (widgetTopLine * lineheight) - fScrollPos + fCachedTextViewer.getTopInset();
+ for (int modelLine= topLine; modelLine <= bottomLine; modelLine++) {
+
+ if (y >= canvasheight)
+ break;
+
+ int widgetLine= extension.modelLine2WidgetLine(modelLine);
+ if (widgetLine == -1)
+ continue;
+
+ String s= Integer.toString(modelLine + 1);
+ int indentation= fIndentation[s.length()];
+ gc.drawString(nf.format(modelLine + 1), indentation, y);
+ y+= lineheight;
+ }
+ }
+
/*
* @see IVerticalRulerColumn#redraw
*/
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
index dcad1009c21..b4811d1c99e 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java
@@ -423,7 +423,7 @@ public class SourceViewer extends TextViewer implements ISourceViewer {
IDocument document= getDocument();
Position p= new Position(s.x, s.y);
- IRegion r= (s.y == 0) ? getVisibleRegion() : new Region(s.x, s.y);
+ IRegion r= (s.y == 0) ? getModelCoverage() : new Region(s.x, s.y);
try {
setRedraw(false);
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java
index 78ef11c835f..fab8064dcc8 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VerticalRuler.java
@@ -32,8 +32,10 @@ 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.ITextViewerExtension3;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextEvent;
@@ -201,7 +203,12 @@ public final class VerticalRuler implements IVerticalRuler, IVerticalRulerExtens
try {
gc.setBackground(fCanvas.getBackground());
gc.fillRectangle(0, 0, size.x, size.y);
- doPaint(gc);
+
+ if (fTextViewer instanceof ITextViewerExtension3)
+ doPaint1(gc);
+ else
+ doPaint(gc);
+
} finally {
gc.dispose();
}
@@ -238,7 +245,7 @@ public final class VerticalRuler implements IVerticalRuler, IVerticalRulerExtens
*
* @param gc the gc to draw into
*/
- private void doPaint(GC gc) {
+ protected void doPaint(GC gc) {
if (fModel == null || fTextViewer == null)
return;
@@ -320,6 +327,64 @@ public final class VerticalRuler implements IVerticalRuler, IVerticalRulerExtens
}
}
}
+
+ protected void doPaint1(GC gc) {
+
+ if (fModel == null || fTextViewer == null)
+ return;
+
+ ITextViewerExtension3 extension= (ITextViewerExtension3) fTextViewer;
+ StyledText textWidget= fTextViewer.getTextWidget();
+
+ fScrollPos= textWidget.getTopPixel();
+ int lineheight= textWidget.getLineHeight();
+ Point dimension= fCanvas.getSize();
+ int shift= fTextViewer.getTopInset();
+
+ // 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;
+
+ IRegion widgetRegion= extension.modelRange2WidgetRange(new Region(position.getOffset(), position.getLength()));
+ if (widgetRegion == null)
+ continue;
+
+ int startLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset());
+ if (startLine == -1)
+ continue;
+
+ int endLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset() + Math.max(widgetRegion.getLength() -1, 0));
+ if (endLine == -1)
+ continue;
+
+ 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);
+ }
+ }
+ }
/**
* Thread-safe implementation.
@@ -401,15 +466,24 @@ public final class VerticalRuler implements IVerticalRuler, IVerticalRulerExtens
return -1;
StyledText text= fTextViewer.getTextWidget();
- int line= ((y_coordinate + fScrollPos) / text.getLineHeight());
+ int line= ((y_coordinate + fScrollPos) / text.getLineHeight());
+ return widgetLine2ModelLine(fTextViewer, line);
+ }
+
+ protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) {
+
+ if (viewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
+ return extension.widgetlLine2ModelLine(widgetLine);
+ }
+
try {
- IRegion r= fTextViewer.getVisibleRegion();
- IDocument d= fTextViewer.getDocument();
- line += d.getLineOfOffset(r.getOffset());
+ IRegion r= viewer.getVisibleRegion();
+ IDocument d= viewer.getDocument();
+ return widgetLine += d.getLineOfOffset(r.getOffset());
} catch (BadLocationException x) {
}
-
- return line;
+ return widgetLine;
}
/*
diff --git a/org.eclipse.text/.classpath b/org.eclipse.text/.classpath
index d8b3fa0d8f2..16fb22f551c 100644
--- a/org.eclipse.text/.classpath
+++ b/org.eclipse.text/.classpath
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="projection"/>
<classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
+ <classpathentry kind="src" path="/org.junit"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/org.eclipse.text/.project b/org.eclipse.text/.project
index 9e0b25af586..e6a88f34e13 100644
--- a/org.eclipse.text/.project
+++ b/org.eclipse.text/.project
@@ -3,6 +3,7 @@
<name>org.eclipse.text</name>
<comment></comment>
<projects>
+ <project>org.junit</project>
</projects>
<buildSpec>
<buildCommand>
diff --git a/org.eclipse.text/build.properties b/org.eclipse.text/build.properties
index 04e9be9a51b..03e53ece0c8 100644
--- a/org.eclipse.text/build.properties
+++ b/org.eclipse.text/build.properties
@@ -1,4 +1,5 @@
bin.includes = plugin.properties,\
plugin.xml,\
*.jar
-source.text.jar = src/
+source.text.jar = src/,\
+ projection/
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/CoordinatesTranslator.java b/org.eclipse.text/projection/org/eclipse/jface/text/CoordinatesTranslator.java
new file mode 100644
index 00000000000..f4c7c3017f8
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/CoordinatesTranslator.java
@@ -0,0 +1,288 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ *
+ */
+public class CoordinatesTranslator implements IDocumentInformationMapping {
+
+ private IDocument fParentDocument;
+ private String fParentCategory;
+ private ProjectionDocument fProjectionDocument;
+ private String fProjectionCategory;
+
+ public CoordinatesTranslator(IDocument parent, String parentCategory, ProjectionDocument projection, String projectionCategory) {
+ fParentDocument= parent;
+ fParentCategory= parentCategory;
+ fProjectionDocument= projection;
+ fProjectionCategory= projectionCategory;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginOffset(int)
+ */
+ public int toOriginOffset(int imageOffset) throws BadLocationException {
+ Fragment fragment= (Fragment) getPositionOfOffset(fProjectionDocument, ProjectionDocument.FRAGMENT_CATEGORY, imageOffset);
+ if (fragment == null) {
+ if (imageOffset == 0)
+ return 0;
+ throw new BadLocationException();
+ }
+
+ int relative= imageOffset - fragment.offset;
+ return fragment.getOrigin().offset + relative;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginRegion(org.eclipse.jface.text.IRegion)
+ */
+ public IRegion toOriginRegion(IRegion imageRegion) throws BadLocationException {
+
+ int projectionOffset= imageRegion.getOffset();
+ int projectionLength= imageRegion.getLength();
+
+ if (projectionLength == 0) {
+ if (projectionOffset == 0 && projectionLength == fProjectionDocument.getLength())
+ return new Region(0, fParentDocument.getLength());
+ return new Region(toOriginOffset(projectionOffset), 0);
+ }
+
+ int o1= toOriginOffset(projectionOffset);
+ int o2= toOriginOffset(projectionOffset + projectionLength -1);
+ return new Region(o1, o2 - o1 + 1);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginLines(int)
+ */
+ public IRegion toOriginLines(int imageLine) throws BadLocationException {
+
+ IRegion projectionDocumentRegion= fProjectionDocument.getLineInformation(imageLine);
+ IRegion parentDocumentRegion= toOriginRegion(projectionDocumentRegion);
+
+ int startLine= fParentDocument.getLineOfOffset(parentDocumentRegion.getOffset());
+ if (parentDocumentRegion.getLength() == 0)
+ return new Region(startLine, 0);
+
+ int endLine= fParentDocument.getLineOfOffset(parentDocumentRegion.getOffset() + parentDocumentRegion.getLength() -1);
+ return new Region(startLine, endLine - startLine);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginLine(int)
+ */
+ public int toOriginLine(int imageLine) throws BadLocationException {
+ IRegion lines= toOriginLines(imageLine);
+ if (lines.getLength() > 0)
+ throw new IllegalStateException();
+ return lines.getOffset();
+ }
+
+ public int toImageOffset(int originOffset) throws BadLocationException {
+ ProjectionPosition projection= (ProjectionPosition) getPositionOfOffset(fParentDocument, ProjectionDocumentManager.PROJECTION_DOCUMENTS, originOffset);
+ if (projection != null)
+ return translateOffset(projection, originOffset, projection.getFragment());
+ // not included
+ return -1;
+ }
+
+ public IRegion toImageRegion(IRegion originRegion) throws BadLocationException {
+
+ if (originRegion.getLength() == 0) {
+ int projectionOffset= toImageOffset(originRegion.getOffset());
+ return projectionOffset == -1 ? null : new Region(projectionOffset, 0);
+ }
+
+ Position[] positions= getPositionsOfRange(fParentDocument, ProjectionDocumentManager.PROJECTION_DOCUMENTS, originRegion, null);
+ if (positions != null && positions.length > 0) {
+ ProjectionPosition projection= (ProjectionPosition) positions[0];
+
+ int offset= originRegion.getOffset();
+ int length= originRegion.getLength();
+
+ int delta= projection.getOffset() - offset;
+ if (delta > 0) {
+ offset += delta;
+ length -= delta;
+ }
+ int start= translateOffset(projection, offset, projection.getFragment());
+
+ projection= (ProjectionPosition) positions[positions.length -1];
+ int decrease= 0;
+ int endOffset= offset + length;
+ if (length > 0)
+ decrease= 1;
+ endOffset -= decrease;
+
+ delta= endOffset - (projection.getOffset() + Math.max(projection.getLength() -1, 0));
+ if (delta > 0)
+ endOffset -= delta;
+
+ int end= translateOffset(projection, endOffset, projection.getFragment());
+ return new Region(start, end - start + decrease);
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toImageLine(int)
+ */
+ public int toImageLine(int originLine) throws BadLocationException {
+
+ IRegion parentDocumentRegion= fParentDocument.getLineInformation(originLine);
+ IRegion projectionDocumentRegion= toImageRegion(parentDocumentRegion);
+ if (projectionDocumentRegion == null)
+ return -1;
+
+ int startLine= fProjectionDocument.getLineOfOffset(projectionDocumentRegion.getOffset());
+ if (projectionDocumentRegion.getLength() == 0)
+ return startLine;
+
+ int endLine= fProjectionDocument.getLineOfOffset(projectionDocumentRegion.getOffset() + projectionDocumentRegion.getLength() -1);
+ if (endLine != startLine)
+ throw new IllegalStateException();
+
+ return startLine;
+ }
+
+
+ //-----------------------------------------------------------------------------------------------------------------------------------
+
+
+ private int translateOffset(Position origin, int originOffset, Position target) {
+ int relative= originOffset - origin.offset;
+ return target.offset + relative;
+ }
+
+ private Position getPositionOfOffset(IDocument document, String category, int offset) throws BadLocationException {
+ try {
+ int index= getPositionIndexOfOffset(document, category, offset, 0);
+ if (index > -1) {
+ Position[] positions= document.getPositions(category);
+ return positions[index];
+ }
+ } catch (BadPositionCategoryException x) {
+ }
+ return null;
+ }
+
+ private Position[] getPositionsOfRange(IDocument document, String category, IRegion range, Comparator comparator) {
+
+ int offset= range.getOffset();
+ int length= range.getLength();
+
+ try {
+
+ int start= getPositionIndexOfOffset(document, category, offset, length);
+ int end= getPositionIndexOfOffset(document, category, offset + length -1, 1 - length);
+
+ if (start > -1 && end > -1) {
+
+ Position[] positions= document.getPositions(category);
+
+ if (start == end)
+ return new Position[] { positions[start] };
+
+ Position[] result= new Position[end - start + 1];
+ for (int i= start; i <= end; i++)
+ result[i - start]= positions[i];
+
+ if (comparator != null)
+ Arrays.sort(result, comparator);
+
+ return result;
+ }
+
+ } catch (BadPositionCategoryException e) {
+ } catch (BadLocationException e) {
+ }
+
+ return new Position[0];
+ }
+
+ private int getPositionIndexOfOffset(IDocument document, String category, int offset, int direction ) throws BadPositionCategoryException, BadLocationException{
+
+ Position[] positions= document.getPositions(category);
+ if (positions != null && positions.length > 0) {
+
+ // test for inclusion
+ int index= document.computeIndexInCategory(category, offset);
+ if (index < positions.length && positions[index].includes(offset))
+ return index;
+ if (index > 0 && positions[index -1].includes(offset))
+ return index -1;
+
+ // find next accorrding to direction
+ if (direction != 0) {
+ if (direction > 0) {
+ if (index < positions.length && positions[index].overlapsWith(offset, direction))
+ return index;
+ } else {
+ if (index > 0 && positions[index -1].overlapsWith(offset + direction, -direction))
+ return index -1;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#getCoverage()
+ */
+ public IRegion getCoverage() {
+ Position coverage= fProjectionDocument.getParentDocumentCoverage();
+ return new Region(coverage.getOffset(), coverage.getLength());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toClosestImageLine(int)
+ */
+ public int toClosestImageLine(int originLine) throws BadLocationException {
+ try {
+
+ int modelLineOffset= fParentDocument.getLineOffset(originLine);
+ int index= fParentDocument.computeIndexInCategory(ProjectionDocumentManager.PROJECTION_DOCUMENTS, modelLineOffset);
+ Position[] projections= fParentDocument.getPositions(ProjectionDocumentManager.PROJECTION_DOCUMENTS);
+
+ if (index < projections.length) {
+ Position p= projections[index -1];
+ int delta1= modelLineOffset - (p.getOffset() + p.getLength());
+ p= projections[index];
+ int delta2= modelLineOffset - (p.getOffset() + p.getLength());
+ if (delta1 < delta2) {
+ p= projections[index -1];
+ originLine= fParentDocument.getLineOfOffset(p.getOffset() + Math.max(p.getLength() -1, 0));
+ } else {
+ originLine= fParentDocument.getLineOfOffset(p.getOffset());
+ }
+ } else if (projections.length > 0) {
+ Position p= projections[index -1];
+ originLine= fParentDocument.getLineOfOffset(p.getOffset() + Math.max(p.getLength() -1, 0));
+ } else {
+ return 0;
+ }
+
+ return toImageLine(originLine);
+
+ } catch (BadLocationException x) {
+ } catch (BadPositionCategoryException x) {
+ }
+
+ return 0;
+ }
+}
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/Fragment.java b/org.eclipse.text/projection/org/eclipse/jface/text/Fragment.java
new file mode 100644
index 00000000000..22ee665eee6
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/Fragment.java
@@ -0,0 +1,43 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+import org.eclipse.jface.text.Position;
+
+/**
+ * Fragment.java
+ */
+public class Fragment extends Position {
+
+ private Position fOrigin;
+
+ public Fragment(int offset, int length, Position origin) {
+ super(offset, length);
+ fOrigin= origin;
+ }
+
+// public Fragment(int offset, int length) {
+// super(offset, length);
+// }
+
+ /**
+ * Returns the fOrigin.
+ * @return Position
+ */
+ public Position getOrigin() {
+ return fOrigin;
+ }
+
+ public void setOrigin(Position origin) {
+ fOrigin= origin;
+ }
+}
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/FragmentUpdater.java b/org.eclipse.text/projection/org/eclipse/jface/text/FragmentUpdater.java
new file mode 100644
index 00000000000..7233a2ce57d
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/FragmentUpdater.java
@@ -0,0 +1,104 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+
+/**
+ * The position updater used to adapt the fragments of a projection document to
+ * changes of the master document.
+ */
+public class FragmentUpdater extends DefaultPositionUpdater {
+
+ private boolean fShiftMode= false;
+ private boolean fIsLast= false;
+
+ /**
+ * Creates the fragment updater.
+ */
+ protected FragmentUpdater(String fragmentCategory) {
+ super(fragmentCategory);
+ }
+
+ public void enableShiftMode(boolean enable) {
+ fShiftMode= enable;
+ }
+
+ /**
+ * If an insertion happens at a fragment's offset, the fragment is extended
+ * rather than shifted. Also, the last fragment is extended if an inserted
+ * happends at the end of the fragment.
+ */
+ protected void adaptToInsert() {
+
+ if (fShiftMode) {
+ super.adaptToInsert();
+ return;
+ }
+
+ int myStart= fPosition.offset;
+ int myEnd= fPosition.offset + fPosition.length - (fIsLast ? 0 : 1);
+ myEnd= Math.max(myStart, myEnd);
+
+ int yoursStart= fOffset;
+ int yoursEnd= fOffset + fReplaceLength -1;
+ yoursEnd= Math.max(yoursStart, yoursEnd);
+
+ if (myEnd < yoursStart)
+ return;
+
+ if (fLength <= 0) {
+
+ if (myStart <= yoursStart)
+ fPosition.length += fReplaceLength;
+ else
+ fPosition.offset += fReplaceLength;
+
+ } else {
+
+ if (myStart <= yoursStart && fOriginalPosition.offset <= yoursStart)
+ fPosition.length += fReplaceLength;
+ else
+ fPosition.offset += fReplaceLength;
+ }
+ }
+
+ /*
+ * @see IPositionUpdater#update(DocumentEvent event)
+ */
+ public void update(DocumentEvent event) {
+
+ try {
+
+ Position[] category= event.getDocument().getPositions(getCategory());
+
+ fOffset= event.getOffset();
+ fLength= event.getLength();
+ fReplaceLength= (event.getText() == null ? 0 : event.getText().length());
+ fDocument= event.getDocument();
+
+ for (int i= 0; i < category.length; i++) {
+
+ fPosition= category[i];
+ fIsLast= (i == category.length -1);
+
+ fOriginalPosition.offset= fPosition.offset;
+ fOriginalPosition.length= fPosition.length;
+
+ if (notDeleted())
+ adaptToReplace();
+ }
+
+ } catch (BadPositionCategoryException x) {
+ // do nothing
+ }
+ }
+}; \ No newline at end of file
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocument.java b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocument.java
new file mode 100644
index 00000000000..9191c9186d4
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocument.java
@@ -0,0 +1,745 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+
+
+/**
+ * A patch document represent a projection of its parent document.
+ * The patch document is always in sync with its parent document
+ * by utilizing the parent document as its <code>ITextStore</code>.
+ * This class is for internal use only.
+ *
+ * TODO: sorting Fragments on creation/joining
+ *
+ * @see ITextStore
+ */
+public final class ProjectionDocument extends AbstractDocument {
+
+ final public static String FRAGMENT_CATEGORY= "__fragment_category";
+
+ /** The parent document */
+ private IDocument fParentDocument;
+ /** The parent document as document extension */
+ private IDocumentExtension fExtension;
+ /** The position category defining the projection */
+ private String fProjectionCategory;
+ /** The document event issued by the parent document */
+ private DocumentEvent fParentEvent;
+ /** The document event issued and to be issued by the patch document */
+ private SlaveDocumentEvent fEvent;
+ /** Indicates whether the patch document initiated a parent document update or not */
+ private boolean fIsUpdating= false;
+ /** The fragment updater */
+ private FragmentUpdater fFragmentUpdater= new FragmentUpdater(FRAGMENT_CATEGORY);
+
+ /**
+ * Creates a projection document of the given parent document.
+ *
+ * @param parentDocument the parent Document
+ * @param projectionCategory the document position category whose positions define the projection of the parent document
+ */
+ public ProjectionDocument(IDocument parentDocument, String projectionCategory) {
+ super();
+
+ fParentDocument= parentDocument;
+ if (fParentDocument instanceof IDocumentExtension)
+ fExtension= (IDocumentExtension) fParentDocument;
+
+ ITextStore s= new ProjectionTextStore(this);
+ ILineTracker tracker= new DefaultLineTracker();
+
+ setTextStore(s);
+ setLineTracker(tracker);
+
+ completeInitialization();
+
+ initializeProjection(projectionCategory);
+ tracker.set(s.get(0, s.getLength()));
+ }
+
+ /**
+ * Initializes the projection document from the parent document based on the given
+ * projection category.
+ * @param projectionCategory the document position category whose positions define the projection of the parent document
+ */
+ private void initializeProjection(String projectionCategory) {
+
+ fProjectionCategory= projectionCategory;
+
+ try {
+
+ addPositionCategory(FRAGMENT_CATEGORY);
+ addPositionUpdater(fFragmentUpdater);
+
+ int offset= 0;
+ Position[] patch= fParentDocument.getPositions(fProjectionCategory);
+ for (int i= 0; i < patch.length; i++) {
+ Position p= patch[i];
+ addPosition(FRAGMENT_CATEGORY, new Fragment(offset, p.length, p));
+ offset += p.length;
+ }
+
+ } catch (BadPositionCategoryException x) {
+ } catch (BadLocationException x) {
+ }
+ }
+
+ /**
+ * Creates a fragment from a postion of the parent document.
+ * @param parentPosition a position of the parent document
+ * @return the fragment representing the range given by the parent position
+ */
+ public Fragment createFragment(Position parentPosition) {
+ try {
+
+ int index= fParentDocument.computeIndexInCategory(fProjectionCategory, parentPosition.offset);
+ if (index <= 0)
+ return new Fragment(0, parentPosition.length, parentPosition);
+
+ Position[] fragments= getPositions(FRAGMENT_CATEGORY);
+ Position p= fragments[index -1];
+ return new Fragment(p.offset + p.length, parentPosition.length, parentPosition);
+
+ } catch (BadPositionCategoryException e) {
+ } catch (BadLocationException e) {
+ }
+
+ return null;
+ }
+
+ private int getPositionOfOffset(IDocument document, String category, int offset, int direction ) throws BadPositionCategoryException, BadLocationException{
+
+ Position[] positions= document.getPositions(category);
+ if (positions != null && positions.length > 0) {
+
+ // test for inclusion
+ int index= document.computeIndexInCategory(category, offset);
+ if (index < positions.length && positions[index].includes(offset))
+ return index;
+ if (index > 0 && positions[index -1].includes(offset))
+ return index -1;
+
+ // find next accorrding to direction
+ if (direction != 0) {
+ if (direction > 0) {
+ if (index < positions.length && positions[index].overlapsWith(offset, direction))
+ return index;
+ } else {
+ if (index > 0 && positions[index -1].overlapsWith(offset + direction, -direction))
+ return index -1;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Returns the position which is used to manage a parent
+ * document range represented in this projection document and that
+ * includes or is close to the given parent document offset. The distance
+ * is computed based on the given direction hint.
+ *
+ * @param offsetInParent the parent document offset
+ * @param direction the direction hint used for computing the distance
+ * @return position the parent document position including or near to the parent document offset
+ */
+ private Position getParentDocumentPositionOfOffset(int offsetInParent, int direction ) {
+ try {
+
+ int index= getPositionOfOffset(fParentDocument, fProjectionCategory, offsetInParent, direction);
+ if (index > -1) {
+ Position[] positions= fParentDocument.getPositions(fProjectionCategory);
+ return positions[index];
+ }
+
+ } catch (BadPositionCategoryException x) {
+ } catch (BadLocationException x) {
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the offset in the projection document corresponding to the
+ * given parent document offset.
+ *
+ * @param offsetInParent the parent document offset
+ * @return the projection document offset corresponding to the given parent document offset
+ */
+ private int toProjectionDocumentOffset(int offsetInParent, int direction) {
+
+ Position p= getParentDocumentPositionOfOffset(offsetInParent, direction);
+ if (p == null)
+ return -1;
+
+ int relative= offsetInParent - p.offset;
+
+ if (direction > 0) {
+ if (relative < 0)
+ relative= 0;
+ } else if (direction < 0) {
+ if (relative >= p.length)
+ relative= p.length -1;
+ }
+
+ Fragment f= findCorrespondingFragment(p);
+ return f.offset + relative;
+ }
+
+ /**
+ * Creates a position describing the projection document range corresponding to
+ * the given parent document range.
+ *
+ * @param offsetInParent the parent document offset
+ * @param lengthInParent the parent document lengh
+ * @return position describing the projection document range corresponding to the given parent document range
+ */
+ public Position computeProjectionDocumentPosition(int offsetInParent, int lengthInParent) {
+
+ Position p= getParentDocumentCoverage();
+ if (p != null) {
+
+ if (p.overlapsWith(offsetInParent, lengthInParent)) {
+
+ int o1= toProjectionDocumentOffset(offsetInParent, lengthInParent);
+ if (o1 == -1)
+ return null;
+
+ if (lengthInParent == 0)
+ return new Position(o1, 0);
+
+ int o2= toProjectionDocumentOffset(offsetInParent + lengthInParent -1, 1 - lengthInParent);
+ if (o2 == -1)
+ return null;
+
+ return new Position(o1, o2 - o1 + 1);
+
+ } else if (p.getOffset() + p.getLength() == offsetInParent + lengthInParent) {
+
+ Position[] fragments= getFragmentation();
+ if (fragments != null && fragments.length > 0) {
+ Position last= fragments[fragments.length -1];
+ return new Position(last.getOffset() + last.getLength());
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public int toParentDocumentOffset(int offset) throws BadLocationException {
+ Fragment fragment= getFragmentOfOffset(offset);
+
+ if (fragment == null) {
+
+// if (offset == 0)
+// return 0;
+// throw new BadLocationException();
+
+ Position[] fragmentation= getFragmentation();
+ if (fragmentation != null && fragmentation.length > 0) {
+ Fragment last= (Fragment) fragmentation[fragmentation.length -1];
+ if (last.offset + last.length == offset) {
+ Position origin= last.getOrigin();
+ return origin.offset + origin.length;
+ }
+ }
+
+ throw new BadLocationException();
+ }
+
+ int relative= offset - fragment.offset;
+ return fragment.getOrigin().offset + relative;
+ }
+
+ public IRegion computeParentDocumentRegion(int offset, int length) throws BadLocationException {
+
+ if (length == 0) {
+ if (offset == 0 && length == getLength())
+ return new Region(0, fParentDocument.getLength());
+ return new Region(toParentDocumentOffset(offset), 0);
+ }
+
+ int o1= toParentDocumentOffset(offset);
+ int o2= toParentDocumentOffset(offset + length -1);
+ return new Region(o1, o2 - o1 + 1);
+ }
+
+ /**
+ * Removes all fragments and thus empties this projection document.
+ */
+ public void removeAllFragments() {
+ Position[] projection= getProjection();
+ if (projection == null)
+ return;
+
+ for (int i= 0; i < projection.length; i++) {
+ try {
+ removeFragment(projection[i]);
+ } catch (BadLocationException e) {
+ }
+ }
+ }
+
+ /**
+ * Add a new fragment of the parent document to this projection document.
+ *
+ * @param offsetInParent offset of the parent document range
+ * @param lengthInParent length of the parent document range
+ * @return returns the position representing the parent document range in this projection document
+ * @throws BadLocationException
+ */
+ public void addFragment(int offsetInParent, int lengthInParent) throws BadLocationException {
+
+ if (lengthInParent == 0)
+ return;
+
+ try {
+
+ ProjectionPosition p= new ProjectionPosition(this, offsetInParent, lengthInParent);
+ fParentDocument.addPosition(fProjectionCategory, p);
+
+ Fragment fragment= createFragment(p);
+ p.setFragment(fragment);
+ fireDocumentProjectionChanged(new DocumentEvent(this, fragment.offset, 0, fParentDocument.get(offsetInParent, lengthInParent)));
+ addPosition(FRAGMENT_CATEGORY, fragment);
+
+
+ getTracker().set(getStore().get(0, getStore().getLength()));
+
+ } catch (BadPositionCategoryException x) {
+ }
+
+ }
+
+ public void joinFragments() {
+ try {
+ while (joinTwoFragments()) {}
+ } catch (BadPositionCategoryException x) {
+ }
+ }
+
+ private boolean joinTwoFragments() throws BadPositionCategoryException {
+ Position[] projection= getProjection();
+ if (projection != null && projection.length > 0) {
+ Position previous= projection[0];
+ for (int i= 1; i < projection.length; i++) {
+ Position current= projection[i];
+ if (previous.offset + previous.length == current.offset) {
+ join(previous, current);
+ return true;
+ }
+ previous= current;
+ }
+ }
+ return false;
+ }
+
+ private void join(Position p1, Position p2) throws BadPositionCategoryException {
+ // remove p2
+ Fragment fragment= findCorrespondingFragment(p2);
+ removePosition(FRAGMENT_CATEGORY, fragment);
+ fParentDocument.removePosition(fProjectionCategory, p2);
+ // extend p1 by length of p2
+ fragment= findCorrespondingFragment(p1);
+ fragment.length += p2.length;
+ p1.length += p2.length;
+ }
+
+ /**
+ * Removes the given parent document range from this projection document.
+ *
+ * @param parentPosition the position representing the parent document range
+ * @throws BadLocationException
+ */
+ public void removeFragment(Position parentPosition) throws BadLocationException {
+ try {
+
+ Fragment fragment= findCorrespondingFragment(parentPosition);
+ if (fragment != null) {
+ removePosition(FRAGMENT_CATEGORY, fragment);
+ fParentDocument.removePosition(fProjectionCategory, parentPosition);
+ fireDocumentProjectionChanged(new DocumentEvent(this, fragment.offset, fragment.length, null));
+ getTracker().set(getStore().get(0, getStore().getLength()));
+ }
+
+ } catch (BadPositionCategoryException x) {
+ }
+ }
+
+ public Position[] getAffectedFragments(int offsetInParent, int lengthInParent) {
+
+ Position p= computeProjectionDocumentPosition(offsetInParent, lengthInParent);
+ if (p == null)
+ return null;
+
+ Fragment[] f= getFragmentsOfRange(p.offset, p.length);
+ if (f == null)
+ return null;
+
+ Position[] result= new Position[f.length];
+ for (int i= 0; i < f.length; i++)
+ result[i]= f[i].getOrigin();
+ return result;
+ }
+
+ /**
+ * Finds the fragment that represents the given parent document range in this projection document.
+ *
+ * @param parentPosition the parent document range
+ * @return the fragment representing the given parent document range
+ */
+ private Fragment findCorrespondingFragment(Position parentPosition) {
+ try {
+ Position[] fragments= getPositions(FRAGMENT_CATEGORY);
+ for (int i= 0; i < fragments.length; i++) {
+ Fragment f= (Fragment) fragments[i];
+ if (parentPosition.equals(f.getOrigin()))
+ return f;
+ }
+ } catch (BadPositionCategoryException x) {
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the fragment that contains the given offset.
+ *
+ * @param offset the offset
+ * @return the fragment that contains the given offset
+ */
+ protected Fragment getFragmentOfOffset(int offset) throws BadLocationException {
+ try {
+ int index= getPositionOfOffset(this, FRAGMENT_CATEGORY, offset, 0);
+ if (index > -1) {
+ Position[] fragments= getPositions(FRAGMENT_CATEGORY);
+ return (Fragment) fragments[index];
+ }
+ } catch (BadPositionCategoryException x) {
+ }
+ return null;
+ }
+
+ /**
+ * Returns the minimal consecutive list of fragments that completely covers the given range.
+ *
+ * @param offset the offset of the range
+ * @param length the length of the range
+ * @return the minimal consecutive list of fragments convering the given range
+ */
+ protected Fragment[] getFragmentsOfRange(int offset, int length) {
+
+ try {
+
+ int start= getPositionOfOffset(this, FRAGMENT_CATEGORY, offset, length);
+ int end= getPositionOfOffset(this, FRAGMENT_CATEGORY, offset + length -1, 1 - length);
+
+ if (start > -1 && end > -1) {
+
+ Position[] positions= getPositions(FRAGMENT_CATEGORY);
+
+ if (start == end)
+ return new Fragment[] { (Fragment) positions[start] };
+
+ Fragment[] result= new Fragment[end - start + 1];
+ for (int i= start; i <= end; i++)
+ result[i - start]= (Fragment) positions[i];
+ sortFragments(result);
+ return result;
+ }
+
+ } catch (BadPositionCategoryException e) {
+ } catch (BadLocationException e) {
+ }
+
+ return new Fragment[0];
+ }
+
+ /**
+ * Sorts a list of fragments based on the sequence of their origins in the parent document.
+ * @param result
+ */
+ private void sortFragments(Object[] result) {
+
+ Comparator comparator= new Comparator() {
+
+ public int compare(Object o1, Object o2) {
+ Fragment f1= (Fragment) o1;
+ Fragment f2= (Fragment) o2;
+ return f1.getOrigin().getOffset() - f2.getOrigin().getOffset();
+ }
+
+ public boolean equals(Object obj) {
+ return false;
+ }
+ };
+
+ Arrays.sort(result, comparator);
+ }
+
+ /**
+ * Returns the minimal range of the parent document that covers all fragments.
+ *
+ * @return a position describing the minimal parent document range covering all fragments
+ */
+ public Position getParentDocumentCoverage() {
+ Position[] projection= getProjection();
+ if (projection != null && projection.length > 0) {
+ Position first=projection[0];
+ Position last= projection[projection.length -1];
+ return new Position(first.offset, last.offset - first.offset + last.length);
+ }
+ return new Position(0, 0);
+ }
+
+ private void fireDocumentProjectionChanged(DocumentEvent event) {
+ fFragmentUpdater.enableShiftMode(true);
+ try {
+ updatePositions(event);
+ } finally {
+ fFragmentUpdater.enableShiftMode(false);
+ }
+ }
+
+ /**
+ * Returns parent document
+ *
+ * @return the parent document
+ */
+ public IDocument getParentDocument() {
+ return fParentDocument;
+ }
+
+ /**
+ * Returns the ranges of the parent document covered by this patch document.
+ *
+ * @return the child document's parent document range
+ */
+ public Position[] getProjection() {
+ try {
+ return fParentDocument.getPositions(fProjectionCategory);
+ } catch (BadPositionCategoryException x) {
+ }
+ return null;
+ }
+
+ public Position[] getFragmentation() {
+ try {
+
+ Position[] fragmentation= getPositions(FRAGMENT_CATEGORY);
+ sortFragments(fragmentation);
+ return fragmentation;
+
+ } catch (BadPositionCategoryException x) {
+ }
+ return null;
+ }
+
+ /**
+ * Transforms a document event of the parent document into a patch document
+ * based document event.
+ *
+ * @param e the parent document event
+ * @return the child document event
+ */
+ private SlaveDocumentEvent normalize(DocumentEvent e) {
+
+ Position c= computeProjectionDocumentPosition(e.getOffset(), e.getLength());
+
+ if (c != null) {
+ if (c.length == 0) {
+ int insertLength= e.getText() == null ? 0 : e.getText().length();
+ if (insertLength == 0)
+ return null;
+ }
+ return new SlaveDocumentEvent(this, c.offset, c.length, e.getText(), e);
+ }
+
+ return null;
+ }
+
+ /**
+ * When called this patch document is informed about a forthcoming change
+ * of its parent document. This child document checks whether the parent
+ * document change affects it and if so informs all document listeners.
+ *
+ * @param event the parent document event
+ */
+ public void parentDocumentAboutToBeChanged(DocumentEvent event) {
+ fParentEvent= event;
+ fEvent= normalize(event);
+ if (fEvent != null)
+ delayedFireDocumentAboutToBeChanged();
+ }
+
+ /**
+ * When called this child document is informed about a change of its parent document.
+ * If this child document is affected it informs all of its document listeners.
+ *
+ * @param event the parent document event
+ */
+ public void parentDocumentChanged(DocumentEvent event) {
+ if ( !fIsUpdating && event == fParentEvent && fEvent != null) {
+ try {
+ getTracker().replace(fEvent.getOffset(), fEvent.getLength(), fEvent.getText());
+ fireDocumentChanged(fEvent);
+ } catch (BadLocationException x) {
+ Assert.isLegal(false);
+ }
+ }
+ }
+
+ /*
+ * @see AbstractDocument#fireDocumentAboutToBeChanged
+ */
+ protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
+ // delay it until there is a notification from the parent document
+ // otherwise there it is expensive to construct the parent document information
+ }
+
+ /**
+ * Fires the child document event as about-to-be-changed event to all registed listeners.
+ */
+ private void delayedFireDocumentAboutToBeChanged() {
+ super.fireDocumentAboutToBeChanged(fEvent);
+ }
+
+ /**
+ * Ignores the given event and sends the similar child document event instead.
+ *
+ * @param event the event to be ignored
+ */
+ protected void fireDocumentChanged(DocumentEvent event) {
+ super.fireDocumentChanged(fEvent);
+ }
+
+ /*
+ * @see IDocument#replace(int, int, String)
+ * @since 2.0
+ */
+ public void replace(int offset, int length, String text) throws BadLocationException {
+ try {
+ fIsUpdating= true;
+ if (fExtension != null)
+ fExtension.stopPostNotificationProcessing();
+
+ super.replace(offset, length, text);
+
+ } finally {
+ fIsUpdating= false;
+ if (fExtension != null)
+ fExtension.resumePostNotificationProcessing();
+ }
+ }
+
+ /*
+ * @see IDocument#set(String)
+ * @since 2.0
+ */
+ public void set(String text) {
+ try {
+ fIsUpdating= true;
+ if (fExtension != null)
+ fExtension.stopPostNotificationProcessing();
+
+ super.set(text);
+
+ } finally {
+ fIsUpdating= false;
+ if (fExtension != null)
+ fExtension.resumePostNotificationProcessing();
+ }
+ }
+
+ /*
+ * @see IDocumentExtension#registerPostNotificationReplace(IDocumentListener, IDocumentExtension.IReplace)
+ * @since 2.0
+ */
+ public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) {
+ if (!fIsUpdating)
+ throw new UnsupportedOperationException();
+ super.registerPostNotificationReplace(owner, replace);
+ }
+
+
+ /**
+ * Convenience method for hiding the specified region of the document.
+ * * @param document * @param offsetInParent * @param lengthInParent */
+ public void hide(int offsetInParent, int lengthInParent) {
+
+ IDocument parent= getParentDocument();
+ Position[] effected= getAffectedFragments(offsetInParent, lengthInParent);
+
+ try {
+
+ if (effected == null) {
+ // populate new document with two new fragments, the left and the right of the hidden region
+ int end= offsetInParent + lengthInParent;
+ addFragment(0, offsetInParent);
+ addFragment(end, parent.getLength() - end);
+ } else if (effected.length == 1) {
+ // the only affected fragment must be splitted into two
+ Position fragment= effected[0];
+ removeFragment(fragment);
+ addFragment(fragment.offset, offsetInParent - fragment.offset);
+ int secondOffset= offsetInParent + lengthInParent;
+ addFragment(secondOffset, fragment.offset + fragment.length - secondOffset);
+ } else {
+ // first expand and than collapse
+ internalShow(offsetInParent, lengthInParent, effected);
+ hide(offsetInParent, lengthInParent);
+ }
+
+ joinFragments();
+
+ } catch (BadLocationException x) {
+ }
+ }
+
+ public void show(int offsetInParent, int lengthInParent) {
+
+ Position[] effected= getAffectedFragments(offsetInParent, lengthInParent);
+ if (effected == null || effected.length == 0) {
+ try {
+ addFragment(offsetInParent, lengthInParent);
+ joinFragments();
+ } catch (BadLocationException x) {
+ }
+ return;
+ }
+
+ internalShow(offsetInParent, lengthInParent, effected);
+ joinFragments();
+
+ }
+
+ private void internalShow(int offsetInParent, int lengthInParent, Position[] effected) {
+ try {
+
+ int size= effected.length;
+ for (int i= 0; i < size; i++)
+ removeFragment(effected[i]);
+
+ int offset= Math.min(offsetInParent, effected[0].offset);
+ int end= Math.max(offsetInParent + lengthInParent, effected[size -1].offset + effected[size -1].length);
+ addFragment(offset, end - offset);
+
+ } catch (BadLocationException x) {
+ }
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocumentManager.java b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocumentManager.java
new file mode 100644
index 00000000000..a039af8c598
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionDocumentManager.java
@@ -0,0 +1,287 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+
+/**
+ * Manages a set of child documents for given parent documents.
+ * A child document represents a particular range of the parent
+ * document and is accordingly adapted to changes of the parent document.
+ * Vice versa, the parent document is accordingly adapted to changes of
+ * its child documents. The manager does not maintain any particular management
+ * structure but utilizes mechanisms given by <code>IDocument</code> such
+ * as position categories and position updaters. <p>
+ *
+ * For internal use only.
+ */
+public final class ProjectionDocumentManager implements IDocumentListener, ISlaveDocumentManager {
+
+
+ /**
+ * Name of the position categories used to keep track of the child
+ * documents offset ranges into the parent document.
+ */
+ public final static String PROJECTION_DOCUMENTS= "__projectiondocuments"; //$NON-NLS-1$
+
+
+// /**
+// * The child document partitioner uses the parent document to answer all questions.
+// */
+// static class ChildPartitioner implements IDocumentPartitioner {
+//
+// protected ProjectionDocument fChildDocument;
+// protected IDocument fParentDocument;
+//
+// protected ChildPartitioner() {
+// }
+//
+// /*
+// * @see IDocumentPartitioner#getPartition(int)
+// */
+// public ITypedRegion getPartition(int offset) {
+// try {
+// offset += fChildDocument.getParentDocumentRange().getOffset();
+// return fParentDocument.getPartition(offset);
+// } catch (BadLocationException x) {
+// }
+//
+// return null;
+// }
+//
+// /*
+// * @see IDocumentPartitioner#computePartitioning(int, int)
+// */
+// public ITypedRegion[] computePartitioning(int offset, int length) {
+// try {
+// offset += fChildDocument.getParentDocumentRange().getOffset();
+// return fParentDocument.computePartitioning(offset, length);
+// } catch (BadLocationException x) {
+// }
+//
+// return null;
+// }
+//
+// /*
+// * @see IDocumentPartitioner#getContentType(int)
+// */
+// public String getContentType(int offset) {
+// try {
+// offset += fChildDocument.getParentDocumentRange().getOffset();
+// return fParentDocument.getContentType(offset);
+// } catch (BadLocationException x) {
+// }
+//
+// return null;
+// }
+//
+// /*
+// * @see IDocumentPartitioner#getLegalContentTypes()
+// */
+// public String[] getLegalContentTypes() {
+// return fParentDocument.getLegalContentTypes();
+// }
+//
+// /*
+// * @see IDocumentPartitioner#documentChanged(DocumentEvent)
+// */
+// public boolean documentChanged(DocumentEvent event) {
+// // ignore as the parent does this for us
+// return false;
+// }
+//
+// /*
+// * @see IDocumentPartitioner#documentAboutToBeChanged(DocumentEvent)
+// */
+// public void documentAboutToBeChanged(DocumentEvent event) {
+// // ignore as the parent does this for us
+// }
+//
+// /*
+// * @see IDocumentPartitioner#disconnect()
+// */
+// public void disconnect() {
+// fChildDocument= null;
+// fParentDocument= null;
+// }
+//
+// /*
+// * @see IDocumentPartitioner#connect(IDocument)
+// */
+// public void connect(IDocument childDocument) {
+// Assert.isTrue(childDocument instanceof ProjectionDocument);
+// fChildDocument= (ProjectionDocument) childDocument;
+// fParentDocument= fChildDocument.getParentDocument();
+// }
+// };
+
+
+
+ /** The position updater shared by all documents which have projection documents */
+ private IPositionUpdater fProjectionPositionUpdater;
+
+ private Map fRegistar= new HashMap();
+
+
+ /**
+ * Returns the projection position updater. If necessary, it is dynamically created.
+ *
+ * @return the child position updater
+ */
+ protected IPositionUpdater getProjectionPositionUpdater() {
+ if (fProjectionPositionUpdater == null)
+ fProjectionPositionUpdater= new FragmentUpdater(PROJECTION_DOCUMENTS);
+ return fProjectionPositionUpdater;
+ }
+
+ private void add(IDocument parent, ProjectionDocument projection) {
+ List list= (List) fRegistar.get(parent);
+ if (list == null) {
+ list= new ArrayList(1);
+ fRegistar.put(parent, list);
+ }
+ list.add(projection);
+ }
+
+ private void remove(IDocument parent, ProjectionDocument projection) {
+ List list= (List) fRegistar.get(parent);
+ if (list != null) {
+ list.remove(projection);
+ if (list.size() == 0)
+ fRegistar.remove(parent);
+ }
+ }
+
+ private boolean hasProjection(IDocument parent) {
+ return (fRegistar.get(parent) instanceof List);
+ }
+
+ private Iterator getProjectionsIterator(IDocument parent) {
+ List list= (List) fRegistar.get(parent);
+ if (list != null)
+ return list.iterator();
+ return null;
+ }
+
+ /**
+ * Informs all child documents of the document which issued this document event.
+ *
+ * @param about indicates whether the change is about to happen or alread happend
+ * @param event the document event which will be processed to inform child documents
+ */
+ protected void fireDocumentEvent(boolean about, DocumentEvent event) {
+ IDocument parent= event.getDocument();
+ Iterator e= getProjectionsIterator(parent);
+ if (e == null)
+ return;
+
+ while (e.hasNext()) {
+ ProjectionDocument document= (ProjectionDocument) e.next();
+ if (about)
+ document.parentDocumentAboutToBeChanged(event);
+ else
+ document.parentDocumentChanged(event);
+ }
+ }
+
+ /*
+ * @see IDocumentListener#documentChanged(DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent event) {
+ fireDocumentEvent(false, event);
+ }
+
+ /*
+ * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ fireDocumentEvent(true, event);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#createMasterSlaveMapping(org.eclipse.jface.text.IDocument)
+ */
+ public IDocumentInformationMapping createMasterSlaveMapping(IDocument slave) {
+ if (slave instanceof ProjectionDocument) {
+ ProjectionDocument projectionDocument= (ProjectionDocument) slave;
+ return new CoordinatesTranslator(projectionDocument.getParentDocument(), PROJECTION_DOCUMENTS, projectionDocument, ProjectionDocument.FRAGMENT_CATEGORY);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#createSlaveDocument(org.eclipse.jface.text.IDocument)
+ */
+ public IDocument createSlaveDocument(IDocument master) {
+ if (!master.containsPositionCategory(PROJECTION_DOCUMENTS)) {
+ master.addPositionCategory(PROJECTION_DOCUMENTS);
+ master.addPositionUpdater(getProjectionPositionUpdater());
+ master.addDocumentListener(this);
+ }
+
+ ProjectionDocument slave= new ProjectionDocument(master, PROJECTION_DOCUMENTS);
+// IDocumentPartitioner partitioner= new ChildPartitioner();
+// child.setDocumentPartitioner(partitioner);
+// partitioner.connect(child);
+
+ add(master, slave);
+ return slave;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#freeSlaveDocument(org.eclipse.jface.text.IDocument)
+ */
+ public void freeSlaveDocument(IDocument slave) {
+
+ if ( !(slave instanceof ProjectionDocument))
+ return;
+
+ ProjectionDocument projectionDocument= (ProjectionDocument) slave;
+
+// childDocument.getDocumentPartitioner().disconnect();
+
+ IDocument parent= projectionDocument.getParentDocument();
+ remove(parent, projectionDocument);
+
+ try {
+ if (!hasProjection(parent)) {
+ parent.removeDocumentListener(this);
+ parent.removePositionUpdater(getProjectionPositionUpdater());
+ parent.removePositionCategory(PROJECTION_DOCUMENTS);
+ }
+ } catch (BadPositionCategoryException x) {
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#getMasterDocument(org.eclipse.jface.text.IDocument)
+ */
+ public IDocument getMasterDocument(IDocument slave) {
+ if (slave instanceof ProjectionDocument)
+ return ((ProjectionDocument) slave).getParentDocument();
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#isSlaveDocument(org.eclipse.jface.text.IDocument)
+ */
+ public boolean isSlaveDocument(IDocument document) {
+ return (document instanceof ProjectionDocument);
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPosition.java b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPosition.java
new file mode 100644
index 00000000000..14b0eacdcf1
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPosition.java
@@ -0,0 +1,42 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+package org.eclipse.jface.text;
+
+/**
+ * ProjectionPosition.java
+ */
+public class ProjectionPosition extends Position {
+
+ private IDocument fProjectionDocument;
+ private Fragment fFragment;
+
+ public ProjectionPosition(IDocument projectionDocument, int offset, int length) {
+ super(offset, length);
+ fProjectionDocument= projectionDocument;
+ }
+
+ public void setFragment(Fragment fragment) {
+ fFragment= fragment;
+ }
+
+ public Fragment getFragment() {
+ return fFragment;
+ }
+
+// /**
+// * Changed to be compatible to the position updater behavior
+// * @see Position#overlapsWith(int, int)
+// */
+// public boolean overlapsWith(int offset, int length) {
+// boolean append= (offset == this.offset + this.length) && length == 0;
+// return append || super.overlapsWith(offset, length);
+// }
+}
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPositionUpdater.java b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPositionUpdater.java
new file mode 100644
index 00000000000..a82cf4ce5d3
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionPositionUpdater.java
@@ -0,0 +1,51 @@
+package org.eclipse.jface.text;
+
+import org.eclipse.jface.text.DefaultPositionUpdater;
+
+/**
+ * The position updater used to adapt the positions representing
+ * the child document ranges to changes of the parent document.
+ */
+
+public class ProjectionPositionUpdater extends DefaultPositionUpdater {
+
+ /**
+ * Creates the position updated.
+ */
+ protected ProjectionPositionUpdater(String category) {
+ super(category);
+ }
+
+ /**
+ * Child document ranges cannot be deleted other then by calling
+ * freeChildDocument.
+ */
+ protected boolean notDeleted() {
+ return true;
+ }
+
+ /**
+ * If an insertion happens at a child document's start offset, the
+ * position is extended rather than shifted. Also, if something is added
+ * right behind the end of the position, the position is extended rather
+ * than kept stable.
+ */
+ protected void adaptToInsert() {
+
+ int myStart= fPosition.offset;
+ int myEnd= fPosition.offset + fPosition.length;
+ myEnd= Math.max(myStart, myEnd);
+
+ int yoursStart= fOffset;
+ int yoursEnd= fOffset + fReplaceLength -1;
+ yoursEnd= Math.max(yoursStart, yoursEnd);
+
+ if (myEnd < yoursStart)
+ return;
+
+ if (myStart <= yoursStart)
+ fPosition.length += fReplaceLength;
+ else
+ fPosition.offset += fReplaceLength;
+ }
+}
diff --git a/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionTextStore.java b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionTextStore.java
new file mode 100644
index 00000000000..467578330fc
--- /dev/null
+++ b/org.eclipse.text/projection/org/eclipse/jface/text/ProjectionTextStore.java
@@ -0,0 +1,132 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+
+/**
+ * ProjectionTextStore.java
+ */
+public class ProjectionTextStore implements ITextStore {
+
+ private ProjectionDocument fProjectionDocument;
+
+ public ProjectionTextStore(ProjectionDocument projectionDocument) {
+ fProjectionDocument= projectionDocument;
+ }
+
+ private int computeParentDocumentOffset(int offset) {
+ try {
+ return fProjectionDocument.toParentDocumentOffset(offset);
+ } catch (BadLocationException x) {
+ throw new RuntimeException();
+ }
+ }
+
+ /*
+ * @see ITextStore#set
+ */
+ public void set(String contents) {
+
+ try {
+
+ Position[] projection= fProjectionDocument.getProjection();
+ if (projection != null && projection.length > 0) {
+ Position first=projection[0];
+ Position last= projection[projection.length -1];
+ int length= last.offset - first.offset + last.length;
+ getParentDocument().replace(first.getOffset(), length, contents);
+ } else {
+ getParentDocument().set(contents);
+ }
+
+ } catch (BadLocationException x) {
+ }
+ }
+
+ /*
+ * @see ITextStore#replace
+ */
+ public void replace(int offset, int length, String text) {
+
+ try {
+
+ int endoffset= length > 0 ? offset + length -1 : offset;
+ int o2= computeParentDocumentOffset(endoffset);
+ if (length > 0)
+ ++ o2;
+
+ offset= computeParentDocumentOffset(offset);
+ length= o2 - offset;
+
+ getParentDocument().replace(offset, length, text);
+
+ } catch (BadLocationException x) {
+ // ignored as surrounding document should have handled this
+ }
+ }
+
+ /*
+ * @see ITextStore#getLength
+ */
+ public int getLength() {
+ Position[] projection= fProjectionDocument.getProjection();
+ if (projection == null || projection.length == 0)
+ return 0;
+
+ int length= 0;
+ for (int i= 0; i < projection.length; i++)
+ length += projection[i].length;
+ return length;
+ }
+
+ /*
+ * @see ITextStore#get
+ */
+ public String get(int offset, int length) {
+ try {
+
+ Fragment[] fragments= fProjectionDocument.getFragmentsOfRange(offset, length);
+ if (fragments == null || fragments.length == 0)
+ return "";
+
+ StringBuffer buffer= new StringBuffer();
+ for (int i= 0; i < fragments.length; i++) {
+ Position p= fragments[i].getOrigin();
+ buffer.append(getParentDocument().get(p.offset, p.length));
+ }
+
+ offset -= fragments[0].offset;
+ return buffer.substring(offset, offset + length);
+
+ } catch (BadLocationException x) {
+ }
+
+ return null;
+ }
+
+ private IDocument getParentDocument() {
+ return fProjectionDocument.getParentDocument();
+ }
+
+ /*
+ * @see ITextStore#get
+ */
+ public char get(int offset) {
+ try {
+ int o= computeParentDocumentOffset(offset);
+ return getParentDocument().getChar(o);
+ } catch (BadLocationException x) {
+ }
+
+ return (char) 0;
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.text/scripts/exportplugin.xml b/org.eclipse.text/scripts/exportplugin.xml
index 870cc45dc6b..ba29a6de216 100644
--- a/org.eclipse.text/scripts/exportplugin.xml
+++ b/org.eclipse.text/scripts/exportplugin.xml
@@ -23,6 +23,7 @@
<copy file="plugin.properties" todir="${dest}"/>
<zip zipfile="${dest}/textsrc.zip">
<fileset dir="src" />
+ <fileset dir="projection"/>
</zip>
</target>
</project>
diff --git a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java b/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java
index 7d2185c3302..c534dd30d96 100644
--- a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java
+++ b/org.eclipse.text/src/org/eclipse/jface/text/ChildDocument.java
@@ -177,7 +177,7 @@ public final class ChildDocument extends AbstractDocument {
if (offset + length > fRange.getLength())
length= fRange.getLength() - offset;
- return new ChildDocumentEvent(this, offset, length, e.fText, e);
+ return new SlaveDocumentEvent(this, offset, length, e.fText, e);
}
/**
diff --git a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentEvent.java b/org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentEvent.java
deleted file mode 100644
index cc5e52976b5..00000000000
--- a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentEvent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.eclipse.jface.text;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-
-/**
- * A child document event represents a parent document event as a
- * child-relative document event. It also carries the original event.
- */
-public class ChildDocumentEvent extends DocumentEvent {
-
- /** The parent document event */
- private DocumentEvent fParentEvent;
-
- /**
- * Creates a new child document event.
- *
- * @param doc the child document
- * @param offset the offset in the child document
- * @param length the length in the child document
- * @param text the substitution text
- * @param parentEvent the parent Event
- */
- public ChildDocumentEvent(IDocument doc, int offset, int length, String text, DocumentEvent parentEvent) {
- super(doc, offset, length, text);
- fParentEvent= parentEvent;
- }
-
- /**
- * Returns this event's parent event.
- *
- * @return this event's parent event
- */
- public DocumentEvent getParentEvent() {
- return fParentEvent;
- }
-} \ No newline at end of file
diff --git a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentManager.java b/org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentManager.java
index 2b9ed9a4b19..ecf02967892 100644
--- a/org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentManager.java
+++ b/org.eclipse.text/src/org/eclipse/jface/text/ChildDocumentManager.java
@@ -1,10 +1,15 @@
-package org.eclipse.jface.text;
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+package org.eclipse.jface.text;
@@ -19,7 +24,7 @@ package org.eclipse.jface.text;
*
* For internal use only.
*/
-public final class ChildDocumentManager implements IDocumentListener {
+public final class ChildDocumentManager implements IDocumentListener, ISlaveDocumentManager {
/**
@@ -210,47 +215,45 @@ public final class ChildDocumentManager implements IDocumentListener {
return fChildPositionUpdater;
}
- /**
- * Creates and returns a new child document for the specified range of the given parent document.
- * The created child document is initialized with a child document partitioner.
- *
- * @param parent the parent document
- * @param offset the offset of the parent document range
- * @param length the length of the parent document range
- * @exception BadLocationException if the specified range is invalid in the parent document
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#createSlaveDocument(org.eclipse.jface.text.IDocument)
*/
- public ChildDocument createChildDocument(IDocument parent, int offset, int length) throws BadLocationException {
-
- if (!parent.containsPositionCategory(CHILDDOCUMENTS)) {
- parent.addPositionCategory(CHILDDOCUMENTS);
- parent.addPositionUpdater(getChildPositionUpdater());
- parent.addDocumentListener(this);
+ public IDocument createSlaveDocument(IDocument master) {
+
+ if (!master.containsPositionCategory(CHILDDOCUMENTS)) {
+ master.addPositionCategory(CHILDDOCUMENTS);
+ master.addPositionUpdater(getChildPositionUpdater());
+ master.addDocumentListener(this);
}
-
- ChildPosition pos= new ChildPosition(parent, offset, length);
+
+ ChildPosition pos= new ChildPosition(master, 0, 0);
try {
- parent.addPosition(CHILDDOCUMENTS, pos);
+ master.addPosition(CHILDDOCUMENTS, pos);
} catch (BadPositionCategoryException x) {
// cannot happen
+ } catch (BadLocationException x) {
+ // (0, 0) is OK
}
-
- ChildDocument child= new ChildDocument(parent, pos);
+
+ ChildDocument child= new ChildDocument(master, pos);
IDocumentPartitioner partitioner= new ChildPartitioner();
child.setDocumentPartitioner(partitioner);
partitioner.connect(child);
-
+
pos.fChildDocument= child;
return child;
}
- /**
- * Disconnects the given child document from it's parent document and frees
- * all resources which are no longer needed.
- *
- * @param childDocument the child document to be freed
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#freeSlaveDocument(org.eclipse.jface.text.IDocument)
*/
- public void freeChildDocument(ChildDocument childDocument) {
+ public void freeSlaveDocument(IDocument slave) {
+
+ if (! (slave instanceof ChildDocument))
+ return;
+
+ ChildDocument childDocument= (ChildDocument) slave;
childDocument.getDocumentPartitioner().disconnect();
@@ -270,6 +273,31 @@ public final class ChildDocumentManager implements IDocumentListener {
}
}
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#createMasterSlaveMapping(org.eclipse.jface.text.IDocument)
+ */
+ public IDocumentInformationMapping createMasterSlaveMapping(IDocument slave) {
+ if (slave instanceof ChildDocument)
+ return new ParentChildMapping((ChildDocument) slave);
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#getMasterDocument(org.eclipse.jface.text.IDocument)
+ */
+ public IDocument getMasterDocument(IDocument slave) {
+ if (slave instanceof ChildDocument)
+ return ((ChildDocument) slave).getParentDocument();
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ISlaveDocumentManager#isSlaveDocument(org.eclipse.jface.text.IDocument)
+ */
+ public boolean isSlaveDocument(IDocument document) {
+ return (document instanceof ChildDocument);
+ }
+
/**
* Informs all child documents of the document which issued this document event.
*
diff --git a/org.eclipse.text/src/org/eclipse/jface/text/IDocumentInformationMapping.java b/org.eclipse.text/src/org/eclipse/jface/text/IDocumentInformationMapping.java
new file mode 100644
index 00000000000..6fead880e86
--- /dev/null
+++ b/org.eclipse.text/src/org/eclipse/jface/text/IDocumentInformationMapping.java
@@ -0,0 +1,27 @@
+package org.eclipse.jface.text;
+
+
+
+public interface IDocumentInformationMapping {
+
+ IRegion getCoverage();
+
+
+ int toOriginOffset(int imageOffset) throws BadLocationException;
+
+ IRegion toOriginRegion(IRegion imageRegion) throws BadLocationException;
+
+ IRegion toOriginLines(int imageLine) throws BadLocationException;
+
+ int toOriginLine(int imageLine) throws BadLocationException;
+
+
+
+ int toImageOffset(int originOffset) throws BadLocationException;
+
+ IRegion toImageRegion(IRegion originRegion) throws BadLocationException;
+
+ int toImageLine(int originLine) throws BadLocationException;
+
+ int toClosestImageLine(int originLine) throws BadLocationException;
+} \ No newline at end of file
diff --git a/org.eclipse.text/src/org/eclipse/jface/text/ISlaveDocumentManager.java b/org.eclipse.text/src/org/eclipse/jface/text/ISlaveDocumentManager.java
new file mode 100644
index 00000000000..d74731d20af
--- /dev/null
+++ b/org.eclipse.text/src/org/eclipse/jface/text/ISlaveDocumentManager.java
@@ -0,0 +1,57 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+/**
+ * Slave documents are documents that use a text store which is based on a
+ * master document.
+ */
+public interface ISlaveDocumentManager {
+
+ /**
+ * Creates a new slave document for the given master document.
+ *
+ * @param master
+ * @return IDocument
+ */
+ IDocument createSlaveDocument(IDocument master);
+
+ /**
+ * Frees the given slave document.
+ *
+ * @param slave
+ */
+ void freeSlaveDocument(IDocument slave);
+
+ /**
+ * Creates a new mapping between the given slave document and its master.
+ *
+ * @param slaveDocument
+ * @return IDocumentInformationMapping
+ */
+ IDocumentInformationMapping createMasterSlaveMapping(IDocument slave);
+
+ /**
+ * Returns the master of the given slave document.
+ *
+ * @param slave
+ * @return IDocument
+ */
+ IDocument getMasterDocument(IDocument slave);
+
+ /**
+ * Method isSlaveDocument.
+ * @param document
+ * @return boolean
+ */
+ boolean isSlaveDocument(IDocument document);
+} \ No newline at end of file
diff --git a/org.eclipse.text/src/org/eclipse/jface/text/ParentChildMapping.java b/org.eclipse.text/src/org/eclipse/jface/text/ParentChildMapping.java
new file mode 100644
index 00000000000..d47e2c9c796
--- /dev/null
+++ b/org.eclipse.text/src/org/eclipse/jface/text/ParentChildMapping.java
@@ -0,0 +1,139 @@
+package org.eclipse.jface.text;
+
+/**
+ * ParentChildMapping.java
+ */
+public class ParentChildMapping implements IDocumentInformationMapping {
+
+ private IDocument fParentDocument;
+ private ChildDocument fChildDocument;
+
+
+ public ParentChildMapping(ChildDocument childDocument) {
+ fParentDocument= childDocument.getParentDocument();
+ fChildDocument= childDocument;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#getCoverage()
+ */
+ public IRegion getCoverage() {
+ Position p= fChildDocument.getParentDocumentRange();
+ return new Region(p.getOffset(), p.getLength());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginOffset(int)
+ */
+ public int toOriginOffset(int imageOffset) throws BadLocationException {
+ int anchorOffset= fChildDocument.getParentDocumentRange().getOffset();
+ return anchorOffset + imageOffset;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginRegion(org.eclipse.jface.text.IRegion)
+ */
+ public IRegion toOriginRegion(IRegion imageRegion) throws BadLocationException {
+ int anchorOffset= fChildDocument.getParentDocumentRange().getOffset();
+ return new Region(anchorOffset + imageRegion.getOffset(), imageRegion.getLength());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginLines(int)
+ */
+ public IRegion toOriginLines(int imageLine) throws BadLocationException {
+ IRegion imageDocumentRegion= fChildDocument.getLineInformation(imageLine);
+ IRegion originDocumentRegion= toOriginRegion(imageDocumentRegion);
+
+ int startLine= fParentDocument.getLineOfOffset(originDocumentRegion.getOffset());
+ if (originDocumentRegion.getLength() == 0)
+ return new Region(startLine, 0);
+
+ int endLine= fParentDocument.getLineOfOffset(originDocumentRegion.getOffset() + originDocumentRegion.getLength() -1);
+ return new Region(startLine, endLine - startLine);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toOriginLine(int)
+ */
+ public int toOriginLine(int imageLine) throws BadLocationException {
+ int anchorOffset= fChildDocument.getParentDocumentRange().getOffset();
+ return fParentDocument.getLineOfOffset(anchorOffset) + imageLine;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toImageOffset(int)
+ */
+ public int toImageOffset(int originOffset) throws BadLocationException {
+ Position p= fChildDocument.getParentDocumentRange();
+ if (p.includes(originOffset))
+ return originOffset - p.getOffset();
+ return -1;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toImageRegion(org.eclipse.jface.text.IRegion)
+ */
+ public IRegion toImageRegion(IRegion originRegion) throws BadLocationException {
+
+ int offset= originRegion.getOffset();
+ int length= originRegion.getLength();
+
+ if (length < 0) {
+ length= -length;
+ offset -= length;
+ }
+
+ Position p= fChildDocument.getParentDocumentRange();
+ if (p.overlapsWith(offset, length)) {
+
+ if (offset < p.getOffset())
+ offset= p.getOffset();
+
+ int end= offset + length;
+ int e= p.getOffset() + p.getLength();
+ if (end > e)
+ end= e;
+
+ offset -= p.getOffset();
+ end -= p.getOffset();
+
+ if (originRegion.getLength() < 0)
+ return new Region(end, offset - end);
+ return new Region(offset, end - offset);
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toImageLine(int)
+ */
+ public int toImageLine(int originLine) throws BadLocationException {
+ int anchorOffset= fChildDocument.getParentDocumentRange().getOffset();
+ int startLine= fParentDocument.getLineOfOffset(anchorOffset);
+
+ int imageLine= originLine - startLine;
+ if (imageLine < 0 || imageLine > fChildDocument.getNumberOfLines())
+ return -1;
+ return imageLine;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.IDocumentInformationMapping#toClosestImageLine(int)
+ */
+ public int toClosestImageLine(int originLine) throws BadLocationException {
+ int anchorOffset= fChildDocument.getParentDocumentRange().getOffset();
+ int startLine= fParentDocument.getLineOfOffset(anchorOffset);
+
+ int imageLine= originLine - startLine;
+ if (imageLine < 0)
+ return 0;
+
+ int maxLine= fChildDocument.getNumberOfLines();
+ if (imageLine > maxLine)
+ return maxLine;
+
+ return imageLine;
+ }
+}
diff --git a/org.eclipse.text/src/org/eclipse/jface/text/SlaveDocumentEvent.java b/org.eclipse.text/src/org/eclipse/jface/text/SlaveDocumentEvent.java
new file mode 100644
index 00000000000..6563524707f
--- /dev/null
+++ b/org.eclipse.text/src/org/eclipse/jface/text/SlaveDocumentEvent.java
@@ -0,0 +1,45 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.jface.text;
+
+/**
+ * A slave document event represents a master document event as a slave-relative
+ * document event. It also carries the master document event.
+ */
+public class SlaveDocumentEvent extends DocumentEvent {
+
+ /** The master document event */
+ private DocumentEvent fMasterEvent;
+
+ /**
+ * Creates a new slave document event.
+ *
+ * @param doc the slave document
+ * @param offset the offset in the slave document
+ * @param length the length in the slave document
+ * @param text the substitution text
+ * @param masterEvent the master document event
+ */
+ public SlaveDocumentEvent(IDocument doc, int offset, int length, String text, DocumentEvent masterEvent) {
+ super(doc, offset, length, text);
+ fMasterEvent= masterEvent;
+ }
+
+ /**
+ * Returns this event's master event.
+ *
+ * @return this event's master event
+ */
+ public DocumentEvent getMasterEvent() {
+ return fMasterEvent;
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.ui.editors/.classpath b/org.eclipse.ui.editors/.classpath
index 843ecb0dc07..736b0952d17 100644
--- a/org.eclipse.ui.editors/.classpath
+++ b/org.eclipse.ui.editors/.classpath
@@ -2,6 +2,7 @@
<classpath>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="src" path="extensions"/>
+ <classpathentry kind="src" path="projection"/>
<classpathentry kind="src" path="/org.eclipse.text"/>
<classpathentry kind="src" path="/org.eclipse.jface"/>
<classpathentry kind="src" path="/org.eclipse.core.resources"/>
diff --git a/org.eclipse.ui.editors/build.properties b/org.eclipse.ui.editors/build.properties
index 62e61b8210f..7aef06c7c65 100644
--- a/org.eclipse.ui.editors/build.properties
+++ b/org.eclipse.ui.editors/build.properties
@@ -1,5 +1,6 @@
source.editors.jar = src/,\
- extensions/
+ extensions/,\
+ projection/
bin.includes = *.jar,\
plugin.xml,\
plugin.properties
diff --git a/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/DefineProjectionAction.java b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/DefineProjectionAction.java
new file mode 100644
index 00000000000..93811a78c9c
--- /dev/null
+++ b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/DefineProjectionAction.java
@@ -0,0 +1,65 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.ui.editors.text;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+/**
+ * CollapseAction.java
+ */
+public class DefineProjectionAction extends TextEditorAction {
+
+ /**
+ * Constructor for CollapseAction.
+ * @param bundle
+ * @param prefix
+ * @param editor
+ */
+ public DefineProjectionAction(ResourceBundle bundle, String prefix, ITextEditor editor) {
+ super(bundle, prefix, editor);
+ }
+
+ /*
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ public void run() {
+ ProjectionTextEditor editor= (ProjectionTextEditor) getTextEditor();
+ ITextSelection s= (ITextSelection) editor.getSelectionProvider().getSelection();
+
+ IDocumentProvider provider= editor.getDocumentProvider();
+ IDocument document= provider.getDocument(editor.getEditorInput());
+
+ try {
+
+ int line1= document.getLineOfOffset(s.getOffset());
+ int start= document.getLineOffset(line1);
+
+ int line2= document.getLineOfOffset(s.getOffset() + s.getLength());
+ int lineStart= document.getLineOffset(line2);
+ int end= lineStart + document.getLineLength(line2);
+
+ if (line2 > line1) {
+ System.out.println("lines " + line1 + " and " + line2 + " are defined as collapsable.");
+ editor.defineProjection(start, end - start);
+ }
+
+ } catch (BadLocationException x) {
+ }
+ }
+}
diff --git a/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.java b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.java
new file mode 100644
index 00000000000..f71827f0b69
--- /dev/null
+++ b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.java
@@ -0,0 +1,30 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package org.eclipse.ui.editors.text;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+class EditorMessages {
+
+ private static final String RESOURCE_BUNDLE= "org.eclipse.ui.editors.text.EditorMessages";//$NON-NLS-1$
+
+ private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+ private EditorMessages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return fgResourceBundle.getString(key);
+ } catch (MissingResourceException e) {
+ return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+
+ public static ResourceBundle getResourceBundle() {
+ return fgResourceBundle;
+ }
+}
diff --git a/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.properties b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.properties
new file mode 100644
index 00000000000..4d118ddf14c
--- /dev/null
+++ b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/EditorMessages.properties
@@ -0,0 +1,3 @@
+Editor.Collapse.label=Collapse
+Editor.Expand.label=Expand
+Editor.DefineProjection.label=Define Projection
diff --git a/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionPainter.java b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionPainter.java
new file mode 100644
index 00000000000..f48b9eb3304
--- /dev/null
+++ b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionPainter.java
@@ -0,0 +1,124 @@
+package org.eclipse.ui.editors.text;
+
+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.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ProjectionAnnotation;
+import org.eclipse.jface.text.source.ProjectionSourceViewer;
+
+/**
+ * ProjectionPainter.java
+ */
+public class ProjectionPainter implements PaintListener{
+
+ private ProjectionSourceViewer fSourceViewer;
+
+
+ public ProjectionPainter(ProjectionSourceViewer sourceViewer) {
+ fSourceViewer= sourceViewer;
+ }
+
+ private IAnnotationModel getAnnotationModel() {
+ return fSourceViewer.getProjectionAnnotationModel();
+ }
+
+ private IDocument getDocument() {
+ return fSourceViewer.getDocument();
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
+ */
+ public void paintControl(PaintEvent e) {
+ IRegion lineRange= computeLineRange(e);
+ IRegion characterRange= computeCharacterRange(lineRange);
+ List annotations= findAnnotations(characterRange);
+ if (annotations != null) {
+
+ IAnnotationModel model= getAnnotationModel();
+ IDocument document= getDocument();
+ StyledText text= fSourceViewer.getTextWidget();
+
+ Iterator iter= annotations.iterator();
+ while (iter.hasNext()) {
+ ProjectionAnnotation a= (ProjectionAnnotation) iter.next();
+ Position p= model.getPosition(a);
+
+ try {
+ IRegion lineInfo= document.getLineInformationOfOffset(p.getOffset());
+ int modelOffset= lineInfo.getOffset() + lineInfo.getLength();
+ int widgetOffset= fSourceViewer.modelOffset2WidgetOffset(modelOffset);
+ doPaint(text, e.gc, text.getLocationAtOffset(widgetOffset));
+ } catch (BadLocationException x) {
+ }
+ }
+ }
+ }
+
+ private void doPaint(StyledText styledText, GC gc, Point point) {
+ gc.setForeground(styledText.getDisplay().getSystemColor(SWT.COLOR_BLUE));
+ FontMetrics metrics= gc.getFontMetrics();
+ gc.drawRectangle(point.x +3, point.y, metrics.getAverageCharWidth() * 2, metrics.getHeight() - 1);
+ }
+
+ private IRegion computeLineRange(PaintEvent e) {
+ StyledText text= fSourceViewer.getTextWidget();
+ int widgetLine= ((e.y + text.getTopPixel()) / text.getLineHeight());
+ int startLine= fSourceViewer.widgetlLine2ModelLine(widgetLine);
+
+ widgetLine= ((e.y + e.height + text.getTopPixel()) / text.getLineHeight());
+ IDocument visible= fSourceViewer.getVisibleDocument();
+ widgetLine= Math.min(widgetLine, visible.getNumberOfLines() -1);
+ int endLine= fSourceViewer.widgetlLine2ModelLine(widgetLine);
+
+ return new Region(startLine, Math.max(0, endLine - startLine));
+ }
+
+ private IRegion computeCharacterRange(IRegion lineRange) {
+ IDocument document= fSourceViewer.getDocument();
+ try {
+ int startOffset= document.getLineOffset(lineRange.getOffset());
+ int endLine= lineRange.getOffset() + lineRange.getLength();
+ int endOffset= document.getLineOffset(endLine) + document.getLineLength(endLine);
+ return new Region(startOffset, endOffset - startOffset);
+ } catch (BadLocationException x) {
+ }
+ return null;
+ }
+
+ private List findAnnotations(IRegion characterRange) {
+ List result= new ArrayList();
+ IAnnotationModel model= getAnnotationModel();
+ if (model != null) {
+ Iterator e= model.getAnnotationIterator();
+ while (e.hasNext()) {
+ Object next= e.next();
+ if (next instanceof ProjectionAnnotation) {
+ ProjectionAnnotation annotation= (ProjectionAnnotation) next;
+ if (annotation.isFolded()) {
+ Position p= model.getPosition(annotation);
+ if (p.overlapsWith(characterRange.getOffset(), characterRange.getLength()))
+ result.add(annotation);
+ }
+ }
+ }
+ }
+ return result;
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionTextEditor.java b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionTextEditor.java
new file mode 100644
index 00000000000..e4b91cab9b8
--- /dev/null
+++ b/org.eclipse.ui.editors/projection/org/eclipse/ui/editors/text/ProjectionTextEditor.java
@@ -0,0 +1,119 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
+package org.eclipse.ui.editors.text;
+
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.AnnotationRulerColumn;
+import org.eclipse.jface.text.source.CompositeRuler;
+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.IVerticalRulerColumn;
+import org.eclipse.jface.text.source.LineNumberRulerColumn;
+import org.eclipse.jface.text.source.OutlinerRulerColumn;
+import org.eclipse.jface.text.source.ProjectionAnnotation;
+import org.eclipse.jface.text.source.ProjectionSourceViewer;
+
+import org.eclipse.jface.action.IMenuManager;
+
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+
+
+/**
+ * ProjectionTextEditor.java
+ */
+public class ProjectionTextEditor extends TextEditor {
+
+ private IAnnotationModel fProjectionAnnotationModel;
+
+ public void collapse(int offset, int length) {
+ ProjectionSourceViewer viewer= (ProjectionSourceViewer) getSourceViewer();
+ viewer.collapse(offset, length);
+ }
+
+ public void expand(int offset, int length) {
+ ProjectionSourceViewer viewer= (ProjectionSourceViewer) getSourceViewer();;
+ viewer.expand(offset, length);
+ }
+
+ public void defineProjection(int offset, int length) {
+ Position p= new Position(offset, length);
+ fProjectionAnnotationModel.addAnnotation(new ProjectionAnnotation(p), p);
+ }
+
+ protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
+ ProjectionSourceViewer viewer= new ProjectionSourceViewer(parent, ruler, styles);
+ if (fProjectionAnnotationModel != null) {
+ viewer.setProjectionAnnotationModel(fProjectionAnnotationModel);
+ StyledText text= viewer.getTextWidget();
+ text.addPaintListener(new ProjectionPainter(viewer));
+ }
+ return viewer;
+ }
+
+ /*
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
+ */
+ protected void createActions() {
+ super.createActions();
+ setAction("DefineProjection", new DefineProjectionAction(EditorMessages.getResourceBundle(), "Editor.DefineProjection.", this));
+ }
+
+ /*
+ * @see AbstractTextEditor#editorContextMenuAboutToShow(IMenuManager)
+ */
+ protected void editorContextMenuAboutToShow(IMenuManager menu) {
+ super.editorContextMenuAboutToShow(menu);
+ addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "DefineProjection");
+ }
+
+ /*
+ * @see AbstractTextEditor#createVerticalRuler()
+ */
+ protected IVerticalRuler createVerticalRuler() {
+ CompositeRuler ruler= new CompositeRuler(2);
+ ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH));
+ ruler.addDecorator(1, new LineNumberRulerColumn());
+ fProjectionAnnotationModel= new AnnotationModel();
+ IVerticalRulerColumn column= new OutlinerRulerColumn(fProjectionAnnotationModel, VERTICAL_RULER_WIDTH);
+ ruler.addDecorator(2, column);
+ return ruler;
+ }
+
+ /*
+ * @see ITextEditor#setHighlightRange
+ */
+ public void setHighlightRange(int start, int length, boolean moveCursor) {
+ ISourceViewer sourceViewer= getSourceViewer();
+ if (sourceViewer != null) {
+ IRegion rangeIndication= sourceViewer.getRangeIndication();
+ if (rangeIndication == null || start != rangeIndication.getOffset() || length != rangeIndication.getLength())
+ sourceViewer.setRangeIndication(start, length, moveCursor);
+ }
+ }
+
+ /*
+ * @see ITextEditor#getHighlightRange
+ */
+ public IRegion getHighlightRange() {
+ ISourceViewer sourceViewer= getSourceViewer();
+ if (sourceViewer != null)
+ return sourceViewer.getRangeIndication();
+ return null;
+ }
+}
diff --git a/org.eclipse.ui.editors/scripts/exportplugin.xml b/org.eclipse.ui.editors/scripts/exportplugin.xml
index 6106df01a88..bb8dcd8ed0b 100644
--- a/org.eclipse.ui.editors/scripts/exportplugin.xml
+++ b/org.eclipse.ui.editors/scripts/exportplugin.xml
@@ -24,6 +24,7 @@
<zip zipfile="${dest}/editorssrc.zip">
<fileset dir="src" />
<fileset dir="extensions" />
+ <fileset dir="projection"/>
</zip>
</target>
</project>
diff --git a/org.eclipse.ui.examples.javaeditor/.classpath b/org.eclipse.ui.examples.javaeditor/.classpath
index 973aed0d7ef..828ce7c2fdb 100644
--- a/org.eclipse.ui.examples.javaeditor/.classpath
+++ b/org.eclipse.ui.examples.javaeditor/.classpath
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="Eclipse Java Editor Example"/>
- <classpathentry kind="src" path="/org.eclipse.ui"/>
- <classpathentry kind="src" path="/org.eclipse.swt"/>
- <classpathentry kind="src" path="/org.eclipse.core.resources"/>
- <classpathentry kind="src" path="/org.eclipse.core.runtime"/>
- <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="Eclipse Java Editor Example/"/>
+ <classpathentry kind="src" path="/org.eclipse.ui"/>
+ <classpathentry kind="src" path="/org.eclipse.core.resources"/>
+ <classpathentry kind="src" path="/org.eclipse.core.runtime"/>
+ <classpathentry kind="src" path="/org.eclipse.core.boot"/>
+ <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.ui.examples.javaeditor/.project b/org.eclipse.ui.examples.javaeditor/.project
index afe248a3b87..50be6132535 100644
--- a/org.eclipse.ui.examples.javaeditor/.project
+++ b/org.eclipse.ui.examples.javaeditor/.project
@@ -3,10 +3,10 @@
<name>org.eclipse.ui.examples.javaeditor</name>
<comment></comment>
<projects>
- <project>org.eclipse.ui</project>
- <project>org.eclipse.core.runtime</project>
- <project>org.eclipse.swt</project>
+ <project>org.eclipse.core.boot</project>
<project>org.eclipse.core.resources</project>
+ <project>org.eclipse.core.runtime</project>
+ <project>org.eclipse.ui</project>
</projects>
<buildSpec>
<buildCommand>
diff --git a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaActionContributor.java b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaActionContributor.java
index 234cb02c9e7..ecf3178b7f6 100644
--- a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaActionContributor.java
+++ b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaActionContributor.java
@@ -1,14 +1,28 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
package org.eclipse.ui.examples.javaeditor;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jface.action.*;
-import org.eclipse.ui.*;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.editors.text.TextEditorActionContributor;
-import org.eclipse.ui.texteditor.*;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.RetargetTextEditorAction;
+import org.eclipse.ui.texteditor.TextEditorAction;
/**
* Contributes interesting Java actions to the desktop's Edit menu and the toolbar.
diff --git a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaDocumentProvider.java b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaDocumentProvider.java
index a78662ffcc4..22ab20735d4 100644
--- a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaDocumentProvider.java
+++ b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaDocumentProvider.java
@@ -1,14 +1,23 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
package org.eclipse.ui.examples.javaeditor;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
import org.eclipse.core.runtime.CoreException;
+
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.rules.DefaultPartitioner;
+
import org.eclipse.ui.editors.text.FileDocumentProvider;
import org.eclipse.ui.examples.javaeditor.java.JavaPartitionScanner;
diff --git a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaEditor.java b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaEditor.java
index c097bcd8085..00b0cf7dc30 100644
--- a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaEditor.java
+++ b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaEditor.java
@@ -1,16 +1,25 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
package org.eclipse.ui.examples.javaeditor;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.text.source.ISourceViewer;
+
import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.editors.text.ProjectionTextEditor;
import org.eclipse.ui.texteditor.DefaultRangeIndicator;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
@@ -18,7 +27,7 @@ import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
/**
* Java specific text editor.
*/
-public class JavaEditor extends TextEditor {
+public class JavaEditor extends ProjectionTextEditor {
/** The outline page */
private JavaContentOutlinePage fOutlinePage;
diff --git a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaSourceViewerConfiguration.java b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaSourceViewerConfiguration.java
index 5d770501fb5..4b65f87ae33 100644
--- a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaSourceViewerConfiguration.java
+++ b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/JavaSourceViewerConfiguration.java
@@ -1,19 +1,40 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
package org.eclipse.ui.examples.javaeditor;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-import org.eclipse.jface.text.*;
+import org.eclipse.swt.graphics.RGB;
+
+import org.eclipse.jface.text.DefaultAutoIndentStrategy;
+import org.eclipse.jface.text.IAutoIndentStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
-import org.eclipse.jface.text.rules.*;
-import org.eclipse.jface.text.source.*;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.ui.examples.javaeditor.java.*;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+import org.eclipse.ui.examples.javaeditor.java.JavaAutoIndentStrategy;
+import org.eclipse.ui.examples.javaeditor.java.JavaCompletionProcessor;
+import org.eclipse.ui.examples.javaeditor.java.JavaDoubleClickSelector;
+import org.eclipse.ui.examples.javaeditor.java.JavaPartitionScanner;
import org.eclipse.ui.examples.javaeditor.javadoc.JavaDocCompletionProcessor;
import org.eclipse.ui.examples.javaeditor.util.JavaColorProvider;
@@ -71,8 +92,8 @@ public class JavaSourceViewerConfiguration extends SourceViewerConfiguration {
assistant.enableAutoActivation(true);
assistant.setAutoActivationDelay(500);
- assistant.setProposalPopupOrientation(assistant.PROPOSAL_OVERLAY);
- assistant.setContextInformationPopupOrientation(assistant.CONTEXT_INFO_ABOVE);
+ assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
+ assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
assistant.setContextInformationPopupBackground(JavaEditorEnvironment.getJavaColorProvider().getColor(new RGB(150, 150, 0)));
return assistant;
@@ -111,11 +132,11 @@ public class JavaSourceViewerConfiguration extends SourceViewerConfiguration {
reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
- dr= new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(provider.getColor(provider.JAVADOC_DEFAULT))));
+ dr= new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(provider.getColor(JavaColorProvider.JAVADOC_DEFAULT))));
reconciler.setDamager(dr, JavaPartitionScanner.JAVA_DOC);
reconciler.setRepairer(dr, JavaPartitionScanner.JAVA_DOC);
- dr= new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(provider.getColor(provider.MULTI_LINE_COMMENT))));
+ dr= new DefaultDamagerRepairer(new SingleTokenScanner(new TextAttribute(provider.getColor(JavaColorProvider.MULTI_LINE_COMMENT))));
reconciler.setDamager(dr, JavaPartitionScanner.JAVA_MULTILINE_COMMENT);
reconciler.setRepairer(dr, JavaPartitionScanner.JAVA_MULTILINE_COMMENT);
diff --git a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/PresentationAction.java b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/PresentationAction.java
index 9f9e6b003b4..cc1ad334625 100644
--- a/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/PresentationAction.java
+++ b/org.eclipse.ui.examples.javaeditor/Eclipse Java Editor Example/org/eclipse/ui/examples/javaeditor/PresentationAction.java
@@ -1,9 +1,16 @@
+/**********************************************************************
+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 v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+
+Contributors:
+ IBM Corporation - Initial implementation
+**********************************************************************/
+
package org.eclipse.ui.examples.javaeditor;
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.TextEditorAction;
diff --git a/org.eclipse.ui.workbench.texteditor/scripts/exportplugin.xml b/org.eclipse.ui.workbench.texteditor/scripts/exportplugin.xml
index 755041d0318..4a100642047 100644
--- a/org.eclipse.ui.workbench.texteditor/scripts/exportplugin.xml
+++ b/org.eclipse.ui.workbench.texteditor/scripts/exportplugin.xml
@@ -23,6 +23,7 @@
<copy file="plugin.properties" todir="${dest}"/>
<zip zipfile="${dest}/texteditorsrc.jar">
<fileset dir="src" />
+ <fileset dir="icons"/>
</zip>
</target>
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java
index b9c31ef5603..0e0a83e0284 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java
@@ -23,6 +23,31 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ST;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.ShellAdapter;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+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;
@@ -37,19 +62,6 @@ 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;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.action.Separator;
-import org.eclipse.jface.dialogs.ErrorDialog;
-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;
@@ -62,7 +74,9 @@ import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITextViewerExtension3;
import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.source.Annotation;
@@ -74,6 +88,20 @@ 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.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.ErrorDialog;
+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.util.Assert;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
@@ -82,31 +110,6 @@ import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ST;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.custom.VerifyKeyListener;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.ShellAdapter;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Shell;
-
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorDescriptor;
@@ -205,8 +208,8 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
*/
public void verifyText(VerifyEvent e) {
if (! validateEditorInputState())
- e.doit= false;
- }
+ e.doit= false;
+ }
};
/**
@@ -520,8 +523,6 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
}
}
}
- if (fKeyBindingService.processKey(event))
- event.doit= false;
}
/**
@@ -540,7 +541,6 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
}
fKeyBindingService= getEditorSite().getKeyBindingService();
- fKeyBindingService.enable(true);
fIsInstalled= true;
}
}
@@ -823,7 +823,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
int lineLength;
try {
- int caretOffsetInDocument= caretOffset + getSourceViewer().getVisibleRegion().getOffset();
+ int caretOffsetInDocument= widgetOffset2ModelOffset(getSourceViewer(), caretOffset);
lineLength= getSourceViewer().getDocument().getLineInformationOfOffset(caretOffsetInDocument).getLength();
} catch (BadLocationException ex) {
return;
@@ -838,7 +838,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
i--;
}
i++;
-
+
// Remember current selection
Point oldSelection= st.getSelection();
@@ -911,7 +911,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
int lineLength;
try {
- int caretOffsetInDocument= caretOffset + getSourceViewer().getVisibleRegion().getOffset();
+ int caretOffsetInDocument= widgetOffset2ModelOffset(getSourceViewer(), caretOffset);
lineLength= getSourceViewer().getDocument().getLineInformationOfOffset(caretOffsetInDocument).getLength();
} catch (BadLocationException ex) {
return;
@@ -923,7 +923,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
int i= 0;
while (i < lineLength && Character.isWhitespace(line.charAt(i)))
i++;
-
+
// Remember current selection
Point oldSelection= st.getSelection();
@@ -2254,7 +2254,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
fSourceViewer.removeTextListener(fTextListener);
fTextListener= null;
}
-
+
fTextInputListener= null;
fSelectionProvider= null;
fSourceViewer= null;
@@ -2579,25 +2579,25 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
if (! (provider instanceof IDocumentProviderExtension))
return;
- IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;
-
- boolean wasReadOnly= isEditorInputReadOnly();
-
+ IDocumentProviderExtension extension= (IDocumentProviderExtension) provider;
+
+ boolean wasReadOnly= isEditorInputReadOnly();
+
try {
- extension.validateState(input, getSite().getShell());
-
+ extension.validateState(input, getSite().getShell());
+
} catch (CoreException exception) {
// for backward compatibility only
if (exception instanceof ValidateStateException) {
if (fSourceViewer != null)
fSourceViewer.setEditable(isEditable());
-
+
if (wasReadOnly != isEditorInputReadOnly())
- updateStateDependentActions();
+ updateStateDependentActions();
}
-
- ILog log= Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog();
+
+ ILog log= Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog();
log.log(exception.getStatus());
Shell shell= getSite().getShell();
@@ -2606,14 +2606,14 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
ErrorDialog.openError(shell, title, msg, exception.getStatus());
return;
- }
+ }
if (fSourceViewer != null)
fSourceViewer.setEditable(isEditable());
if (wasReadOnly != isEditorInputReadOnly())
updateStateDependentActions();
- }
+ }
/*
* @see org.eclipse.ui.texteditor.ITextEditorExtension2.validateEditorInputState()
@@ -2630,7 +2630,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
} finally {
viewer.removeTextInputListener(fTextInputListener);
- }
+ }
}
/**
@@ -3574,11 +3574,8 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
return;
if (fShowHighlightRangeOnly) {
- if (moveCursor) {
- IRegion visibleRegion= fSourceViewer.getVisibleRegion();
- if (start != visibleRegion.getOffset() || length != visibleRegion.getLength())
- fSourceViewer.setVisibleRegion(start, length);
- }
+ if (moveCursor)
+ fSourceViewer.setVisibleRegion(start, length);
} else {
IRegion rangeIndication= fSourceViewer.getRangeIndication();
if (rangeIndication == null || start != rangeIndication.getOffset() || length != rangeIndication.getLength())
@@ -3594,7 +3591,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
return null;
if (fShowHighlightRangeOnly)
- return fSourceViewer.getVisibleRegion();
+ return getCoverage(fSourceViewer);
return fSourceViewer.getRangeIndication();
}
@@ -3624,7 +3621,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
if (fSourceViewer == null)
return;
- if (!fSourceViewer.overlapsWithVisibleRegion(offset, length))
+ if (!isVisible(fSourceViewer, offset, length))
fSourceViewer.resetVisibleRegion();
}
@@ -3812,9 +3809,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
return fErrorLabel;
StyledText styledText= fSourceViewer.getTextWidget();
-
- int offset= fSourceViewer.getVisibleRegion().getOffset();
- int caret= offset + styledText.getCaretOffset();
+ int caret= widgetOffset2ModelOffset(fSourceViewer, styledText.getCaretOffset());
IDocument document= fSourceViewer.getDocument();
if (document == null)
@@ -3854,7 +3849,7 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
}
return true;
}
-
+
/*
* @see ITextEditorExtension2#isEditorInputModifiable()
* @since 2.1
@@ -3895,5 +3890,29 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
protected boolean canHandleMove(IEditorInput originalElement, IEditorInput movedElement) {
return true;
}
-
+
+ protected final static int widgetOffset2ModelOffset(ISourceViewer viewer, int widgetOffset) {
+ if (viewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
+ return extension.widgetOffset2ModelOffset(widgetOffset);
+ }
+ return widgetOffset + viewer.getVisibleRegion().getOffset();
+ }
+
+ protected final static IRegion getCoverage(ISourceViewer viewer) {
+ if (viewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
+ return extension.getModelCoverage();
+ }
+ return viewer.getVisibleRegion();
+ }
+
+ protected final static boolean isVisible(ISourceViewer viewer, int offset, int length) {
+ if (viewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
+ IRegion overlap= extension.modelRange2WidgetRange(new Region(offset, length));
+ return overlap != null;
+ }
+ return viewer.overlapsWithVisibleRegion(offset, length);
+ }
} \ No newline at end of file
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IncrementalFindTarget.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IncrementalFindTarget.java
index bb1bd10abfa..39bb497c63b 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IncrementalFindTarget.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IncrementalFindTarget.java
@@ -102,7 +102,6 @@ class IncrementalFindTarget implements IFindReplaceTarget, IFindReplaceTargetExt
return;
}
- // TODO: reverse searches should put the caret at the start of the selection, instead of the end
text.setSelectionRange(searchResult.selection, searchResult.length);
text.showSelection();
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/MarkRegionTarget.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/MarkRegionTarget.java
index 369f54184b7..9f04b1cf59e 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/MarkRegionTarget.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/MarkRegionTarget.java
@@ -19,6 +19,7 @@ import org.eclipse.jface.text.IMarkRegionTarget;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
+import org.eclipse.jface.text.ITextViewerExtension3;
/**
* Default implementation of <code>IMarkRegionTarget</code> using <code>ITextViewer</code>
@@ -85,11 +86,7 @@ public class MarkRegionTarget implements IMarkRegionTarget {
return;
}
- IRegion region= fViewer.getVisibleRegion();
- int offset= region.getOffset();
- int length= region.getLength();
-
- if (markPosition < offset || markPosition > offset + length) {
+ if (!isVisible(fViewer, markPosition)) {
fStatusLine.setErrorMessage("mark not in visible region");
fStatusLine.setMessage(""); //$NON-NLS-1$
return;
@@ -104,4 +101,15 @@ public class MarkRegionTarget implements IMarkRegionTarget {
fStatusLine.setErrorMessage(""); //$NON-NLS-1$
fStatusLine.setMessage(EditorMessages.getString("Editor.mark.status.message.mark.swapped")); //$NON-NLS-1$
}
-}
+
+ protected final static boolean isVisible(ITextViewer viewer, int offset) {
+ if (viewer instanceof ITextViewerExtension3) {
+ ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
+ return extension.modelOffset2WidgetOffset(offset) >= 0;
+ } else {
+ IRegion region= viewer.getVisibleRegion();
+ int vOffset= region.getOffset();
+ return (vOffset <= offset && offset <= vOffset + region.getLength());
+ }
+ }
+}

Back to the top