Jump to: navigation, search

Difference between revisions of "Word Wrap for Text Viewer and Editor"

m
m
Line 9: Line 9:
 
First "micro/alpha"-release is available at http://ahtik.com/blog/2006/06/18/first-alpha-of-eclipse-word-wrap-released/
 
First "micro/alpha"-release is available at http://ahtik.com/blog/2006/06/18/first-alpha-of-eclipse-word-wrap-released/
  
'''Implementation notes -- developer-only reference'''
+
==Implementation notes -- developer-only reference==
 
SUMMARY
 
SUMMARY
  
TextEditor
+
''ITextEditor''
 +
Interface to a text editor. This interface defines functional extensions to IEditorPart as well as the configuration capabilities of a text editor.
  
IDocument Represents text providing support for
+
Text editors are configured with an IDocumentProvider which
- text manipulation,
+
delivers a textual presentation (IDocument) of the editor's
- positions,
+
input. The editor works on the document and forwards all input element
- partitions,
+
related calls, such as save, to the document provider. The
- line information,
+
provider also delivers the input's annotation model which is used to control
- document change listeners,
+
the editor's vertical ruler.
- document partition change listeners
+
  
 +
''IDocument''
 +
Represents text providing support for
 +
* text manipulation,
 +
* positions,
 +
* partitions,
 +
* line information,
 +
* document change listeners,
 +
* document partition change listeners
  
IDocumentInformationMapping
 
A <code>IDocumentInformationMapping</code>  represents a mapping between the coordinates of two
 
<code>IDocument</code> objects: the original and the image. The document information mapping
 
can translate document information such as line numbers or character ranges given for the original into
 
the corresponding information of the image and vice versa.
 
  
ITextStore Storing and managing text.
+
''IDocumentInformationMapping''
 +
A IDocumentInformationMapping represents a mapping between the coordinates of two IDocument objects: the original and the image. The document information mapping can translate document information such as line numbers or character ranges given for the original into the corresponding information of the image and vice versa.
  
ILineTracker Maps character positions to line numbers and vice versa.
+
''ITextStore''
 +
Storing and managing text.
  
IDocumentAdapter Adapts an org.eclipse.jface.text.IDocument to the
+
''ILineTracker''
org.eclipse.swt.custom.StyledTextContent interface.
+
Maps character positions to line numbers and vice versa.
The document adapter is used by org.eclipse.jface.text.TextViewer to translate
+
document changes into styled text content changes and vice versa.
+
  
 +
''IDocumentAdapter''
 +
Adapts an org.eclipse.jface.text.IDocument to the org.eclipse.swt.custom.StyledTextContent interface.
 +
The document adapter is used by org.eclipse.jface.text.TextViewer to translate document changes into styled text content changes and vice versa.
  
*** How to store wrapped and unwrapped line number information about the same document? ***
 
  
 +
=== Open Issues ===
 +
* How to store wrapped and unwrapped line number information about the same document?
 
Both of these are required:
 
Both of these are required:
 
Wrapped line information is for the text viewer, code navigation, vertical column annotations.
 
Wrapped line information is for the text viewer, code navigation, vertical column annotations.
Unwrapped line information is required for functionalities like goto line, line numbering ruler column, current line  
+
Unwrapped line information is required for functionalities like goto line, line numbering ruler column, current line highlight.
 
+
highlight.
+
 
+
  
 
Creating IDocumentAdapter that supports word wrap would fix TextViewer to support wrapping.
 
Creating IDocumentAdapter that supports word wrap would fix TextViewer to support wrapping.
 
But as wrapping is only visual then all related ruler columns like annotations, line numberings etc fall apart.
 
But as wrapping is only visual then all related ruler columns like annotations, line numberings etc fall apart.
 
  
 
LineNumberRulerColumn is currently using following to paint line numbers
 
LineNumberRulerColumn is currently using following to paint line numbers
for (int line= visibleLines.getStartLine(); line < lastLine; line++) {
 
int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);
 
  
if (widgetLine == -1)
+
for (int line= visibleLines.getStartLine(); line < lastLine; line++) {
continue;
+
int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);
 
+
int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine));
+
if (widgetLine == -1)
paintLine(line, y, lineHeight, gc, display);
+
continue;
y += lineHeight;
+
}
+
int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine));
 +
paintLine(line, y, lineHeight, gc, display);
 +
y += lineHeight;
 +
}
  
 
This logic could be patched by following to support word wrap:
 
This logic could be patched by following to support word wrap:
  
int lastWidgetLine=-1;
+
int lastWidgetLine=-1;
int lastLineNumber = -1;
+
int lastLineNumber = -1;
for (int line= visibleLines.getStartLine(); line < lastLine; line++) {
+
for (int line= visibleLines.getStartLine(); line < lastLine; line++) {
int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);
+
int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);
 
+
if (widgetLine == -1)
+
if (widgetLine == -1)
continue;
+
continue;
 
+
int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine));
+
int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine));
 
+
if (lastWidgetLine==widgetLine) {
+
if (lastWidgetLine==widgetLine) {
paintLine(lastLineNumber, y, lineHeight, gc, display);
+
paintLine(lastLineNumber, y, lineHeight, gc, display);
} else {
+
} else {
paintLine(line, y, lineHeight, gc, display);
+
paintLine(line, y, lineHeight, gc, display);
lastLineNumber=line;
+
lastLineNumber=line;
}
+
}
y += lineHeight;
+
y += lineHeight;
}
+
}
  
 
JFaceTextUtil.modelLineToWidgetLine(...) is becoming responsible for returning same line number for multiple lines  
 
JFaceTextUtil.modelLineToWidgetLine(...) is becoming responsible for returning same line number for multiple lines  
Line 116: Line 120:
  
  
!!! StatusBar is showing cursor position correctly (2:34) even after patching DocumentAdapter to support word-wrap!
+
StatusBar is showing cursor position correctly (2:34) even after patching DocumentAdapter to support word-wrap.
 
Also Goto Line works correctly!
 
Also Goto Line works correctly!
  
Patching DocumentAdapter seems to be not enough to keep editing functionality. Keyboard navigation seems to be
+
Patching DocumentAdapter seems to be not enough to keep editing functionality.
 
+
Keyboard navigation is not fully functional (Del key does not work and some of the navigation has unexpected behaviour).
tracked somewhere else (inserts usually work but do not redraw all affected areas).
+

Revision as of 07:40, 2 August 2006

Project is part of Google_Summer_of_Code_2006

Student: Ahti Kitsik (ahti.kitsik@gmail.com)

Blog: http://ahtik.com/blog/

Mentor: Philippe Ombredanne

First "micro/alpha"-release is available at http://ahtik.com/blog/2006/06/18/first-alpha-of-eclipse-word-wrap-released/

Implementation notes -- developer-only reference

SUMMARY

ITextEditor Interface to a text editor. This interface defines functional extensions to IEditorPart as well as the configuration capabilities of a text editor.

Text editors are configured with an IDocumentProvider which delivers a textual presentation (IDocument) of the editor's input. The editor works on the document and forwards all input element related calls, such as save, to the document provider. The provider also delivers the input's annotation model which is used to control the editor's vertical ruler.

IDocument Represents text providing support for

  • text manipulation,
  • positions,
  • partitions,
  • line information,
  • document change listeners,
  • document partition change listeners


IDocumentInformationMapping A IDocumentInformationMapping represents a mapping between the coordinates of two IDocument objects: the original and the image. The document information mapping can translate document information such as line numbers or character ranges given for the original into the corresponding information of the image and vice versa.

ITextStore Storing and managing text.

ILineTracker Maps character positions to line numbers and vice versa.

IDocumentAdapter Adapts an org.eclipse.jface.text.IDocument to the org.eclipse.swt.custom.StyledTextContent interface. The document adapter is used by org.eclipse.jface.text.TextViewer to translate document changes into styled text content changes and vice versa.


Open Issues

  • How to store wrapped and unwrapped line number information about the same document?

Both of these are required: Wrapped line information is for the text viewer, code navigation, vertical column annotations. Unwrapped line information is required for functionalities like goto line, line numbering ruler column, current line highlight.

Creating IDocumentAdapter that supports word wrap would fix TextViewer to support wrapping. But as wrapping is only visual then all related ruler columns like annotations, line numberings etc fall apart.

LineNumberRulerColumn is currently using following to paint line numbers

for (int line= visibleLines.getStartLine(); line < lastLine; line++) {
	int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);

	if (widgetLine == -1)
		continue;

	int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine));
	paintLine(line, y, lineHeight, gc, display);
	y += lineHeight;
}

This logic could be patched by following to support word wrap:

int lastWidgetLine=-1;
int lastLineNumber = -1;
for (int line= visibleLines.getStartLine(); line < lastLine; line++) {
	int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);

	if (widgetLine == -1)
		continue;

	int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine));

	if (lastWidgetLine==widgetLine) {
		paintLine(lastLineNumber, y, lineHeight, gc, display);
	} else {
		paintLine(line, y, lineHeight, gc, display);
		lastLineNumber=line;
	}
	y += lineHeight;
}

JFaceTextUtil.modelLineToWidgetLine(...) is becoming responsible for returning same line number for multiple lines

that form one wrapped line.

JFaceTextUtil.modelLineToWidgetLine(...):

public static int modelLineToWidgetLine(ITextViewer viewer, final int modelLine) { int widgetLine; if (viewer instanceof ITextViewerExtension5) { ITextViewerExtension5 extension= (ITextViewerExtension5) viewer; widgetLine= extension.modelLine2WidgetLine(modelLine); } else { IRegion region= viewer.getVisibleRegion(); IDocument document= viewer.getDocument(); try { int visibleStartLine= document.getLineOfOffset(region.getOffset()); int visibleEndLine= document.getLineOfOffset(region.getOffset() + region.getLength()); if (modelLine < visibleStartLine || modelLine > visibleEndLine) widgetLine= -1; else widgetLine= modelLine - visibleStartLine; } catch (BadLocationException x) { // ignore and return -1 widgetLine= -1; } } return widgetLine; }


StatusBar is showing cursor position correctly (2:34) even after patching DocumentAdapter to support word-wrap. Also Goto Line works correctly!

Patching DocumentAdapter seems to be not enough to keep editing functionality. Keyboard navigation is not fully functional (Del key does not work and some of the navigation has unexpected behaviour).