Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Loskutov2015-09-11 08:13:03 +0000
committerAndrey Loskutov2015-11-10 08:33:01 +0000
commitb212745ce6ea0079e5876fe77658b174a124c1ae (patch)
tree696e73b789743e7eac8c31b71cbba25715e8e0c2
parenta6baa3f82147bb0751b5050bf2eb6c0c23891e78 (diff)
downloadeclipse.platform.text-b212745ce6ea0079e5876fe77658b174a124c1ae.tar.gz
eclipse.platform.text-b212745ce6ea0079e5876fe77658b174a124c1ae.tar.xz
eclipse.platform.text-b212745ce6ea0079e5876fe77658b174a124c1ae.zip
Bug 35779 - [misc] Text Viewer and Editor needs to support word wrap
Added ITextEditorExtension6 API and implementation to control word wrap in AbstractTextEditor. The new word wrap mode is mutually exclusive with the block selection mode of the ITextEditorExtension5. Change-Id: I1102a25b111840f07627c28db1731d6efd16782c Also-by: Holger Voormann <eclipse@voormann.de> Also-by: Florian Weßling <flo@cdhq.de> Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/CursorLinePainter.java27
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java16
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java37
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java17
-rw-r--r--org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.ui.workbench.texteditor/pom.xml2
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java72
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension5.java12
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension6.java47
9 files changed, 211 insertions, 21 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/CursorLinePainter.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/CursorLinePainter.java
index 2f2d39d29..639abd6f4 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/CursorLinePainter.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/CursorLinePainter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,8 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Eicher (Avaloq Evolution AG) - block selection mode
+ * Holger Voormann - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
+ * Florian Weßling <flo@cdhq.de> - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
*******************************************************************************/
package org.eclipse.jface.text;
@@ -172,12 +174,25 @@ public class CursorLinePainter implements IPainter, LineBackgroundListener {
StyledText textWidget= fViewer.getTextWidget();
// check for https://bugs.eclipse.org/bugs/show_bug.cgi?id=64898
// this is a guard against the symptoms but not the actual solution
- if (0 <= widgetOffset && widgetOffset <= textWidget.getCharCount()) {
- Point upperLeft= textWidget.getLocationAtOffset(widgetOffset);
- int width= textWidget.getClientArea().width + textWidget.getHorizontalPixel();
- int height= textWidget.getLineHeight(widgetOffset);
- textWidget.redraw(0, upperLeft.y, width, height, false);
+ int charCount= textWidget.getCharCount();
+ if (widgetOffset > charCount) {
+ return;
+ }
+ Point upperLeft= textWidget.getLocationAtOffset(widgetOffset);
+ int width= textWidget.getClientArea().width + textWidget.getHorizontalPixel();
+
+ // different height if word wrap is activated and line is not empty
+ int height;
+ if (position.length == 0 || !textWidget.getWordWrap()) {
+ height= textWidget.getLineHeight(widgetOffset);
+ } else {
+ int offsetEnd= widgetOffset + position.length - 1;
+ if(offsetEnd >= charCount){
+ offsetEnd = charCount - 1;
+ }
+ height= textWidget.getTextBounds(widgetOffset, offsetEnd).height;
}
+ textWidget.redraw(0, upperLeft.y, width, height, false);
}
/*
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 70e31b981..6d603a499 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
@@ -23,6 +23,8 @@ import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
@@ -338,7 +340,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
handleMouseMove(e);
}
});
-
+
fCanvas.addMouseWheelListener(new MouseWheelListener() {
public void mouseScrolled(MouseEvent e) {
handleMouseScrolled(e);
@@ -348,6 +350,14 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
if (fCachedTextViewer != null) {
fCachedTextViewer.addViewportListener(fInternalListener);
fCachedTextViewer.addTextListener(fInternalListener);
+ // on word wrap toggle a "resized" ControlEvent is fired: suggest a redraw of the ruler
+ fCachedTextWidget.addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ if(fCachedTextWidget != null && fCachedTextWidget.getWordWrap()) {
+ redraw();
+ }
+ }
+ });
}
return fCanvas;
@@ -385,7 +395,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
/**
* Hook method for a mouse down event on the given ruler line.
- *
+ *
* @param rulerLine the ruler line
* @since 3.5
*/
@@ -405,7 +415,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
* <p>
* <strong>Note:</strong> The event is sent on mouse up.
* </p>
- *
+ *
* @param rulerLine the ruler line
* @since 3.0
*/
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 bc043cd4e..6894070df 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
@@ -9,6 +9,7 @@
* IBM Corporation - initial API and implementation
* Nikolay Botev <bono8106@hotmail.com> - [rulers] Shift clicking in line number column doesn't select range - https://bugs.eclipse.org/bugs/show_bug.cgi?id=32166
* Nikolay Botev <bono8106@hotmail.com> - [rulers] Clicking in line number ruler should not trigger annotation ruler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=40889
+ * Florian Weßling <flo@cdhq.de> - [rulers] Line numbering was wrong when word wrap was active - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
*******************************************************************************/
package org.eclipse.jface.text.source;
@@ -16,6 +17,8 @@ import java.util.Arrays;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
@@ -587,6 +590,15 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
fCachedTextViewer= parentRuler.getTextViewer();
fCachedTextWidget= fCachedTextViewer.getTextWidget();
+ // on word wrap toggle a "resized" ControlEvent is fired: suggest a redraw of the line ruler
+ fCachedTextWidget.addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ if(fCachedTextWidget != null && fCachedTextWidget.getWordWrap()) {
+ postRedraw();
+ }
+ }
+ });
+
fCanvas= new Canvas(parentControl, SWT.NO_FOCUS ) {
/*
* @see org.eclipse.swt.widgets.Control#addMouseListener(org.eclipse.swt.events.MouseListener)
@@ -741,15 +753,36 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
// draw diff info
int y= -JFaceTextUtil.getHiddenTopLinePixels(fCachedTextWidget);
+ // add empty lines if line is wrapped
+ boolean isWrapActive= fCachedTextWidget.getWordWrap();
+
int lastLine= end(visibleLines);
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));
+ final int offsetAtLine= fCachedTextWidget.getOffsetAtLine(widgetLine);
+ int lineHeight= fCachedTextWidget.getLineHeight(offsetAtLine);
paintLine(line, y, lineHeight, gc, display);
- y += lineHeight;
+
+ // increment y position
+ if (!isWrapActive) {
+ y+= lineHeight;
+ } else {
+ int charCount= fCachedTextWidget.getCharCount();
+ if (offsetAtLine == charCount)
+ continue;
+
+ // end of wrapped line
+ final int offsetEnd= offsetAtLine + fCachedTextWidget.getLine(widgetLine).length();
+
+ if (offsetEnd == charCount)
+ continue;
+
+ // use height of text bounding because bounds.width changes on word wrap
+ y+= fCachedTextWidget.getTextBounds(offsetAtLine, offsetEnd).height;
+ }
}
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java
index 890040523..567eb1bf5 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/OverviewRuler.java
@@ -20,6 +20,8 @@ import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
@@ -613,8 +615,21 @@ public class OverviewRuler implements IOverviewRulerExtension, IOverviewRuler {
}
});
- if (fTextViewer != null)
+ if (fTextViewer != null) {
fTextViewer.addTextListener(fInternalListener);
+ // on word wrap toggle a "resized" ControlEvent is fired: suggest a redraw of the ruler
+ fTextViewer.getTextWidget().addControlListener(new ControlAdapter() {
+ public void controlResized(ControlEvent e) {
+ if(fTextViewer == null){
+ return;
+ }
+ StyledText textWidget= fTextViewer.getTextWidget();
+ if(textWidget != null && textWidget.getWordWrap()) {
+ redraw();
+ }
+ }
+ });
+ }
return fCanvas;
}
diff --git a/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF b/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF
index 743b36765..d910d805e 100644
--- a/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF
+++ b/org.eclipse.ui.workbench.texteditor/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ui.workbench.texteditor; singleton:=true
-Bundle-Version: 3.9.200.qualifier
+Bundle-Version: 3.10.0.qualifier
Bundle-Activator: org.eclipse.ui.internal.texteditor.TextEditorPlugin
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
diff --git a/org.eclipse.ui.workbench.texteditor/pom.xml b/org.eclipse.ui.workbench.texteditor/pom.xml
index 03cc91555..e9c001075 100644
--- a/org.eclipse.ui.workbench.texteditor/pom.xml
+++ b/org.eclipse.ui.workbench.texteditor/pom.xml
@@ -18,6 +18,6 @@
</parent>
<groupId>org.eclipse.ui</groupId>
<artifactId>org.eclipse.ui.workbench.texteditor</artifactId>
- <version>3.9.200-SNAPSHOT</version>
+ <version>3.10.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
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 cf334b0be..c83295f9f 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,6 +14,8 @@
* Stephan Wahlbrink <stephan.wahlbrink@walware.de> - Wrong operations mode/feedback for text drag over/drop in text editors - https://bugs.eclipse.org/bugs/show_bug.cgi?id=206043
* Tom Eicher (Avaloq Evolution AG) - block selection mode
* Nick Sandonato <nsandona@us.ibm.com> - [implementation] AbstractTextEditor does not prompt when out of sync in MultiPageEditorPart - http://bugs.eclipse.org/337719
+ * Holger Voormann - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
+ * Florian Weßling <flo@cdhq.de> - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
*******************************************************************************/
package org.eclipse.ui.texteditor;
@@ -251,7 +253,7 @@ import org.eclipse.ui.texteditor.rulers.RulerColumnRegistry;
* {@link #COMMON_RULER_CONTEXT_MENU_ID}.
* </p>
*/
-public abstract class AbstractTextEditor extends EditorPart implements ITextEditor, IReusableEditor, ITextEditorExtension, ITextEditorExtension2, ITextEditorExtension3, ITextEditorExtension4, ITextEditorExtension5, INavigationLocationProvider, ISaveablesSource, IPersistableEditor {
+public abstract class AbstractTextEditor extends EditorPart implements ITextEditor, IReusableEditor, ITextEditorExtension, ITextEditorExtension2, ITextEditorExtension3, ITextEditorExtension4, ITextEditorExtension5, ITextEditorExtension6, INavigationLocationProvider, ISaveablesSource, IPersistableEditor {
/**
* Tag used in xml configuration files to specify editor action contributions.
@@ -7388,10 +7390,15 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
disposeFont();
updateCaret();
}
+
+ // we must unset word wrap before we can set block selection
+ if (isWordWrapEnabled()) {
+ setWordWrap(false);
+ }
}
styledText.setBlockSelection(enable);
-
+
if (!enable) {
initializeViewerFont(viewer);
updateCaret();
@@ -7399,4 +7406,63 @@ public abstract class AbstractTextEditor extends EditorPart implements ITextEdit
}
}
}
+
+ /**
+ * Tells whether word wrap is supported.
+ * <p>
+ * By default word wrap is supported. Subclasses may override this method to disable
+ * it.
+ * </p>
+ *
+ * @return <code>true</code> if word wrap is supported, <code>false</code> otherwise
+ * @since 3.10
+ */
+ protected boolean isWordWrapSupported() {
+ return true;
+ }
+
+ /**
+ * <code>true</code> if word wrap is supported and enabled, <code>false</code> otherwise
+ * @return the receiver's word wrap state if word wrap is supported
+ * @since 3.10
+ * @see AbstractTextEditor#isWordWrapSupported()
+ */
+ public final boolean isWordWrapEnabled() {
+ if(!isWordWrapSupported()){
+ return false;
+ }
+ ISourceViewer viewer= getSourceViewer();
+ if (viewer != null) {
+ StyledText styledText= viewer.getTextWidget();
+ if (styledText != null) {
+ return styledText.getWordWrap();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.ui.texteditor.ITextEditorExtension6#setWordWrap(boolean)
+ * @since 3.10
+ */
+ public void setWordWrap(boolean enable) {
+ if (!isWordWrapSupported() || isWordWrapEnabled() == enable) {
+ return;
+ }
+
+ ISourceViewer viewer= getSourceViewer();
+ if (viewer != null) {
+ StyledText styledText= viewer.getTextWidget();
+ if (styledText != null) {
+ if(isBlockSelectionModeEnabled()){
+ setBlockSelectionMode(false);
+ }
+ styledText.setWordWrap(enable);
+ if (fVerticalRuler != null) {
+ fVerticalRuler.update();
+ }
+ }
+ }
+ }
+
}
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension5.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension5.java
index c747f8094..ffe638be7 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension5.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension5.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009 Avaloq Evolution AG and others.
+ * Copyright (c) 2009, 2015 Avaloq Evolution AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -34,10 +34,14 @@ public interface ITextEditorExtension5 {
boolean isBlockSelectionModeEnabled();
/**
- * Sets the block selection mode state of the receiver to <code>state</code>. Nothing happens
- * if the receiver already is in the requested state.
- *
+ * Sets the block selection mode state of the receiver to <code>state</code>. Nothing happens if
+ * the receiver already is in the requested state.
+ * <p>
+ * Note: enabling block selection mode disables word wrap {@link ITextEditorExtension6}),
+ * enabling word wrap will disable block selection mode.
+ *
* @param state the new block selection state
+ * @see ITextEditorExtension6#setWordWrap(boolean)
*/
void setBlockSelectionMode(boolean state);
}
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension6.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension6.java
new file mode 100644
index 000000000..8ad7c0a1d
--- /dev/null
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorExtension6.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Holger Voormann and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Holger Voormann - initial API and implementation
+ * Florian Weßling <flo@cdhq.de> - Word Wrap - https://bugs.eclipse.org/bugs/show_bug.cgi?id=35779
+ *******************************************************************************/
+package org.eclipse.ui.texteditor;
+
+/**
+ * Extension interface for {@link org.eclipse.ui.texteditor.ITextEditor}. Adds the following
+ * functions:
+ * <ul>
+ * <li>word wrap</li>
+ * </ul>
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @since 3.10
+ */
+public interface ITextEditorExtension6 {
+
+ /**
+ * Returns <code>true</code> if word wrap is currently enabled, <code>false</code> otherwise.
+ *
+ * @return the receiver's word wrap state
+ */
+ boolean isWordWrapEnabled();
+
+ /**
+ * Sets whether the text editor wraps lines. Nothing happens if the receiver already is in the
+ * requested state.
+ * <p>
+ * Note: enabling word wrap disables block selection mode (see {@link ITextEditorExtension5}),
+ * enabling block selection mode will disable word wrap.
+ *
+ * @param enable <code>true</code> to enable word wrap, <code>false</code> to turn it off.
+ *
+ * @see ITextEditorExtension5#setBlockSelectionMode(boolean)
+ */
+ public void setWordWrap(boolean enable);
+}

Back to the top