Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Pazderski2019-02-20 16:44:26 -0500
committerPaul Pazderski2019-09-12 17:53:49 -0400
commit1ddf37c93b738dd018118935b7b762dae28db788 (patch)
tree28b4a985f8bb4559fba54c499e52f360eac378b2
parent10afa0452509c63806769551cbdf1767d91dea8e (diff)
downloadeclipse.platform.debug-1ddf37c93b738dd018118935b7b762dae28db788.tar.gz
eclipse.platform.debug-1ddf37c93b738dd018118935b7b762dae28db788.tar.xz
eclipse.platform.debug-1ddf37c93b738dd018118935b7b762dae28db788.zip
Bug 550620, 197958 - Fix style range override in TextConsoleViewer
Current implementation of override works most of the time since the usual combinations of existing style ranges and link range are quite limited. New implementation yields correct results for any combination. This also supersedes fix of Bug 111256. Change-Id: Idcc94f4be0d7ca815e854a2d2a271a32494a2412 Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
-rw-r--r--org.eclipse.debug.tests/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.debug.tests/pom.xml2
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java2
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/TextConsoleViewerTest.java326
-rw-r--r--org.eclipse.ui.console/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.ui.console/pom.xml2
-rw-r--r--org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsole.java7
-rw-r--r--org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsoleViewer.java124
8 files changed, 417 insertions, 50 deletions
diff --git a/org.eclipse.debug.tests/META-INF/MANIFEST.MF b/org.eclipse.debug.tests/META-INF/MANIFEST.MF
index 180427110..3b3c6bff9 100644
--- a/org.eclipse.debug.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.debug.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.debug.tests;singleton:=true
-Bundle-Version: 3.11.400.qualifier
+Bundle-Version: 3.11.500.qualifier
Bundle-Activator: org.eclipse.debug.tests.TestsPlugin
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui;bundle-version="[3.6.0,4.0.0)",
diff --git a/org.eclipse.debug.tests/pom.xml b/org.eclipse.debug.tests/pom.xml
index 8f410afe5..47ef925e7 100644
--- a/org.eclipse.debug.tests/pom.xml
+++ b/org.eclipse.debug.tests/pom.xml
@@ -18,7 +18,7 @@
</parent>
<groupId>org.eclipse.debug</groupId>
<artifactId>org.eclipse.debug.tests</artifactId>
- <version>3.11.400-SNAPSHOT</version>
+ <version>3.11.500-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
<code.ignoredWarnings>${tests.ignoredWarnings}</code.ignoredWarnings>
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java
index 317599be1..d659beea9 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/AutomatedSuite.java
@@ -23,6 +23,7 @@ import org.eclipse.debug.tests.console.IOConsoleTests;
import org.eclipse.debug.tests.console.ProcessConsoleManagerTests;
import org.eclipse.debug.tests.console.ProcessConsoleTests;
import org.eclipse.debug.tests.console.StreamsProxyTests;
+import org.eclipse.debug.tests.console.TextConsoleViewerTest;
import org.eclipse.debug.tests.launching.AcceleratorSubstitutionTests;
import org.eclipse.debug.tests.launching.ArgumentParsingTests;
import org.eclipse.debug.tests.launching.LaunchConfigurationTests;
@@ -119,6 +120,7 @@ public class AutomatedSuite extends TestSuite {
addTest(new TestSuite(ProcessConsoleManagerTests.class));
addTest(new TestSuite(ProcessConsoleTests.class));
addTest(new TestSuite(StreamsProxyTests.class));
+ addTest(new TestSuite(TextConsoleViewerTest.class));
// Launch Groups
addTest(new TestSuite(LaunchGroupTests.class));
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/TextConsoleViewerTest.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/TextConsoleViewerTest.java
new file mode 100644
index 000000000..ed260ba48
--- /dev/null
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/TextConsoleViewerTest.java
@@ -0,0 +1,326 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Paul Pazderski and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Paul Pazderski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.tests.console;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.tests.AbstractDebugTest;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.ui.console.TextConsoleViewer;
+
+/**
+ * Not really a test for {@link TextConsoleViewer} yet since it only test one
+ * private method of it.
+ */
+public class TextConsoleViewerTest extends AbstractDebugTest {
+
+ public TextConsoleViewerTest() {
+ super(TextConsoleViewerTest.class.getSimpleName());
+ }
+
+ public TextConsoleViewerTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Test override of existing styles with a new style. Typically used to
+ * apply link styling on already styled console document.
+ */
+ public void testStyleOverride() throws Throwable {
+ Color colorR = null;
+ Color colorG = null;
+ Color colorB = null;
+ Color colorK = null;
+ Color colorW = null;
+ try {
+ final Method method = TextConsoleViewer.class.getDeclaredMethod("overrideStyleRange", List.class, StyleRange.class);
+ method.setAccessible(true);
+ assertTrue("Required method <" + method + "> is not static.", Modifier.isStatic(method.getModifiers()));
+
+ final List<StyleRange> styles = new ArrayList<>();
+ colorR = new Color(null, 255, 0, 0);
+ colorG = new Color(null, 0, 255, 0);
+ colorB = new Color(null, 0, 0, 255);
+ colorK = new Color(null, 0, 0, 0);
+ colorW = new Color(null, 255, 255, 255);
+
+ // overwrite in empty list
+ method.invoke(null, styles, new StyleRange(5, 5, colorR, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 2, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 13, null);
+
+ // overwrite unstyled part before
+ method.invoke(null, styles, new StyleRange(0, 3, colorG, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 3, colorG);
+ assertStyle(styles, 3, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 13, null);
+
+ // overwrite unstyled part after
+ method.invoke(null, styles, new StyleRange(15, 5, colorB, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 3, colorG);
+ assertStyle(styles, 3, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 15, null);
+ assertStyle(styles, 15, 20, colorB);
+ assertStyle(styles, 20, 23, null);
+
+ // overwrite existing: start exact, end exact
+ method.invoke(null, styles, new StyleRange(0, 3, colorK, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 3, colorK);
+ assertStyle(styles, 3, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 15, null);
+ assertStyle(styles, 15, 20, colorB);
+ assertStyle(styles, 20, 23, null);
+
+ // overwrite existing: start exact, end after
+ method.invoke(null, styles, new StyleRange(0, 4, colorW, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 4, colorW);
+ assertStyle(styles, 4, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 15, null);
+ assertStyle(styles, 15, 20, colorB);
+ assertStyle(styles, 20, 23, null);
+
+ // overwrite existing: start exact, end inside
+ method.invoke(null, styles, new StyleRange(0, 2, colorK, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 2, colorK);
+ assertStyle(styles, 2, 4, colorW);
+ assertStyle(styles, 4, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 15, null);
+ assertStyle(styles, 15, 20, colorB);
+ assertStyle(styles, 20, 23, null);
+
+ // overwrite existing: start before, end exact
+ method.invoke(null, styles, new StyleRange(13, 7, colorW, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 2, colorK);
+ assertStyle(styles, 2, 4, colorW);
+ assertStyle(styles, 4, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 13, null);
+ assertStyle(styles, 13, 20, colorW);
+ assertStyle(styles, 20, 23, null);
+
+ // overwrite existing: start inside, end exact
+ method.invoke(null, styles, new StyleRange(15, 5, colorK, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 2, colorK);
+ assertStyle(styles, 2, 4, colorW);
+ assertStyle(styles, 4, 5, null);
+ assertStyle(styles, 5, 10, colorR);
+ assertStyle(styles, 10, 13, null);
+ assertStyle(styles, 13, 15, colorW);
+ assertStyle(styles, 15, 20, colorK);
+ assertStyle(styles, 20, 23, null);
+
+ // prepare new existing style
+ styles.clear();
+ method.invoke(null, styles, new StyleRange(10, 10, colorW, null));
+ assertStyle(styles, 10, 20, colorW);
+ method.invoke(null, styles, new StyleRange(10, 10, colorK, null));
+ assertStyle(styles, 10, 20, colorK);
+ assertEquals("Wrong number of styles.", 1, styles.size());
+
+ // overwrite existing: start before, end after
+ method.invoke(null, styles, new StyleRange(5, 15, colorR, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 5, 20, colorR);
+
+ // overwrite existing: start before, end inside
+ method.invoke(null, styles, new StyleRange(0, 10, colorG, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 10, colorG);
+ assertStyle(styles, 10, 20, colorR);
+
+ // overwrite existing: start inside, end after
+ method.invoke(null, styles, new StyleRange(15, 10, colorB, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 10, colorG);
+ assertStyle(styles, 10, 15, colorR);
+ assertStyle(styles, 15, 20, colorB);
+
+ // overwrite existing: start inside, end inside
+ method.invoke(null, styles, new StyleRange(6, 1, colorW, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 6, colorG);
+ assertStyle(styles, 6, 7, colorW);
+ assertStyle(styles, 7, 10, colorG);
+ assertStyle(styles, 10, 15, colorR);
+ assertStyle(styles, 15, 20, colorB);
+
+ // overwrite many styles
+ method.invoke(null, styles, new StyleRange(0, 25, colorK, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 25, colorK);
+ assertStyle(styles, 25, 30, null);
+
+ // prepare new existing style
+ styles.clear();
+ styles.add(new StyleRange(0, 10, colorR, null));
+ styles.add(new StyleRange(15, 5, colorG, null));
+
+ // overwrite: start in one style, end in other
+ method.invoke(null, styles, new StyleRange(7, 11, colorB, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 7, colorR);
+ assertStyle(styles, 7, 18, colorB);
+ assertStyle(styles, 18, 20, colorG);
+ assertStyle(styles, 20, 25, null);
+
+ // prepare new existing style
+ styles.clear();
+ styles.add(new StyleRange(0, 10, colorR, null));
+ styles.add(new StyleRange(15, 5, colorG, null));
+
+ // overwrite: start in one style, end after other
+ method.invoke(null, styles, new StyleRange(7, 15, colorB, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 7, colorR);
+ assertStyle(styles, 7, 22, colorB);
+ assertStyle(styles, 22, 25, null);
+
+ // prepare new existing style
+ styles.clear();
+ styles.add(new StyleRange(5, 5, colorR, null));
+ styles.add(new StyleRange(15, 5, colorG, null));
+
+ // overwrite: start before one style, end in other
+ method.invoke(null, styles, new StyleRange(2, 15, colorB, null));
+ checkOverlapping(styles);
+ assertStyle(styles, 0, 2, null);
+ assertStyle(styles, 2, 17, colorB);
+ assertStyle(styles, 17, 20, colorG);
+ assertStyle(styles, 20, 25, null);
+
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() != null) {
+ throw e.getTargetException();
+ }
+ throw e;
+ } catch (Exception e) {
+ // if this happened the method may have be renamed or moved
+ throw e;
+ }
+ finally {
+ if (colorR != null) {
+ colorR.dispose();
+ }
+ if (colorG != null) {
+ colorG.dispose();
+ }
+ if (colorB != null) {
+ colorB.dispose();
+ }
+ if (colorK != null) {
+ colorK.dispose();
+ }
+ if (colorW != null) {
+ colorW.dispose();
+ }
+ }
+ }
+
+ /**
+ * Assert any offset in given range is styled with given foreground color.
+ * <p>
+ * Note: this test class only uses foreground color and assumes all other
+ * style attributes are set to there default values.
+ * </p>
+ *
+ * @param styles list of known style ranges
+ * @param offset inclusive start offset of range to check
+ * @param end exclusive end offset of range to check
+ * @param foregroundColor the expected foreground color for styles in given
+ * range. May be <code>null</code> to check for unstyled ranges.
+ */
+ private static void assertStyle(List<StyleRange> styles, int offset, int end, Color foregroundColor) {
+ int o = offset;
+ while (o < end) {
+ final StyleRange expected = foregroundColor != null ? new StyleRange(0, 0, foregroundColor, null) : null;
+ final StyleRange actual = getStyleAtOffset(styles, o);
+ assertEquals("Got wrong style at offset " + o, generalizeStyle(expected), generalizeStyle(actual));
+ final int step = actual != null ? actual.length : 1;
+ o += Math.min(step, 1);
+ }
+ }
+
+ /**
+ * Get style from list at given offset or <code>null</code>. If offset has
+ * more then one style it is undefined which one is returned. Does not
+ * return zero-length styles.
+ *
+ * @param styles list of styles
+ * @param offset offset of interest
+ * @return style at given offset or <code>null</code> if offset is not
+ * styled
+ */
+ private static StyleRange getStyleAtOffset(List<StyleRange> styles, int offset) {
+ if (styles != null) {
+ for (StyleRange style : styles) {
+ if (style.start <= offset && style.start + style.length >= offset + 1) {
+ return style;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Set styles start and length to <code>0</code> to compare only the styling
+ * parts using <code>equals</code>.
+ *
+ * @param style the original style. Not modified by this method.
+ * @return the style without position information.
+ */
+ private static StyleRange generalizeStyle(StyleRange style) {
+ if (style == null) {
+ return new StyleRange();
+ }
+ final StyleRange copy = (StyleRange) style.clone();
+ copy.start = copy.length = 0;
+ return copy;
+ }
+
+ /**
+ * Check if styles are disjoint and sorted ascending by offset.
+ *
+ * @param styles the styles to check
+ */
+ private static void checkOverlapping(List<StyleRange> styles) {
+ if (styles == null || styles.size() <= 1) {
+ return;
+ }
+ int lastEnd = Integer.MIN_VALUE;
+ for (StyleRange s : styles) {
+ assertTrue("Styles overlap or not sorted.", lastEnd <= s.start);
+ assertTrue("Empty style.", s.length > 0);
+ lastEnd = s.start + s.length;
+ }
+ }
+}
diff --git a/org.eclipse.ui.console/META-INF/MANIFEST.MF b/org.eclipse.ui.console/META-INF/MANIFEST.MF
index 2e5be95a9..e84c1e558 100644
--- a/org.eclipse.ui.console/META-INF/MANIFEST.MF
+++ b/org.eclipse.ui.console/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ui.console; singleton:=true
-Bundle-Version: 3.8.600.qualifier
+Bundle-Version: 3.8.700.qualifier
Bundle-Activator: org.eclipse.ui.console.ConsolePlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/org.eclipse.ui.console/pom.xml b/org.eclipse.ui.console/pom.xml
index 164593c55..7b76a4f3d 100644
--- a/org.eclipse.ui.console/pom.xml
+++ b/org.eclipse.ui.console/pom.xml
@@ -18,6 +18,6 @@
</parent>
<groupId>org.eclipse.ui</groupId>
<artifactId>org.eclipse.ui.console</artifactId>
- <version>3.8.600-SNAPSHOT</version>
+ <version>3.8.700-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsole.java b/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsole.java
index e847c23fa..e0cf26783 100644
--- a/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsole.java
+++ b/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsole.java
@@ -376,10 +376,10 @@ public abstract class TextConsole extends AbstractConsole {
}
/**
- * Returns the hyperlink at the given offset of <code>null</code> if none.
+ * Returns the hyperlink at the given offset or <code>null</code> if none.
*
* @param offset offset for which a hyperlink is requested
- * @return the hyperlink at the given offset of <code>null</code> if none
+ * @return the hyperlink at the given offset or <code>null</code> if none
*/
public IHyperlink getHyperlink(int offset) {
try {
@@ -399,7 +399,8 @@ public abstract class TextConsole extends AbstractConsole {
/**
* Binary search for the position at a given offset.
*
- * @param offset the offset whose position should be found
+ * @param offset the offset whose position should be found
+ * @param positions the positions list to search in
* @return the position containing the offset, or <code>null</code>
*/
private Position findPosition(int offset, Position[] positions) {
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsoleViewer.java b/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsoleViewer.java
index 6a94c00bb..c5ffa14bd 100644
--- a/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsoleViewer.java
+++ b/org.eclipse.ui.console/src/org/eclipse/ui/console/TextConsoleViewer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Paul Pazderski - Bug 550620: reimplementation of style override (to fix existing and future problems with link styling)
*******************************************************************************/
package org.eclipse.ui.console;
@@ -377,11 +378,9 @@ public class TextConsoleViewer extends SourceViewer implements LineStyleListener
int offset = event.lineOffset;
int length = event.lineText.length();
- StyleRange[] partitionerStyles = ((IConsoleDocumentPartitioner) document.getDocumentPartitioner()).getStyleRanges(event.lineOffset, event.lineText.length());
+ StyleRange[] partitionerStyles = ((IConsoleDocumentPartitioner) document.getDocumentPartitioner()).getStyleRanges(offset, length);
if (partitionerStyles != null) {
Collections.addAll(ranges, partitionerStyles);
- } else {
- ranges.add(new StyleRange(offset, length, null, null));
}
try {
@@ -393,7 +392,7 @@ public class TextConsoleViewer extends SourceViewer implements LineStyleListener
Position position = overlap[i];
StyleRange linkRange = new StyleRange(position.offset, position.length, color, null);
linkRange.underline = true;
- override(ranges, linkRange);
+ overrideStyleRange(ranges, linkRange);
}
}
} catch (BadPositionCategoryException e) {
@@ -405,52 +404,92 @@ public class TextConsoleViewer extends SourceViewer implements LineStyleListener
}
}
- private void override(List<StyleRange> ranges, StyleRange newRange) {
- if (ranges.isEmpty()) {
- ranges.add(newRange);
- return;
- }
-
- int start = newRange.start;
- int end = start + newRange.length;
- for (int i = 0; i < ranges.size(); i++) {
- StyleRange existingRange = ranges.get(i);
- int rEnd = existingRange.start + existingRange.length;
- if (end <= existingRange.start || start >= rEnd) {
- continue;
- }
-
- if (start < existingRange.start && end > existingRange.start) {
- start = existingRange.start;
+ /**
+ * Apply new style range to list of existing style ranges. If the new style
+ * range overlaps with any of the existing style ranges the new style overrides
+ * the existing one in the affected range by splitting/adjusting the existing
+ * ones.
+ *
+ * @param ranges list of existing style ranges (will contain the new style
+ * range when finished)
+ * @param newRange new style range which should be combined with the existing
+ * ranges
+ */
+ private static void overrideStyleRange(List<StyleRange> ranges, StyleRange newRange) {
+ final int overrideStart = newRange.start;
+ final int overrideEnd = overrideStart + newRange.length;
+ int insertIndex = ranges.size();
+ for (int i = ranges.size() - 1; i >= 0; i--) {
+ final StyleRange existingRange = ranges.get(i);
+ final int existingStart = existingRange.start;
+ final int existingEnd = existingStart + existingRange.length;
+
+ // Find first position to insert where offset of new range is smaller then all
+ // offsets before. This way the list is still sorted by offset after insert if
+ // it was sorted before and it will not fail if list was not sorted.
+ if (overrideStart <= existingStart) {
+ insertIndex = i;
}
- if (start >= existingRange.start && end <= rEnd) {
- existingRange.length = start - existingRange.start;
- ranges.add(++i, newRange);
- if (end != rEnd) {
- ranges.add(++i, new StyleRange(end, rEnd - end - 1, existingRange.foreground, existingRange.background));
+ // adjust the existing range if required
+ if (overrideStart <= existingStart) { // new range starts before or with existing
+ if (overrideEnd < existingStart) {
+ // new range lies before existing range. No overlapping.
+ // new range: ++++_________
+ // existing : ________=====
+ // . result : ++++____=====
+ // nothing to do
+ } else if (overrideEnd < existingEnd) {
+ // new range overlaps start of existing.
+ // new range: ++++++++_____
+ // existing : _____========
+ // . result : ++++++++=====
+ final int overlap = overrideEnd - existingStart;
+ existingRange.start += overlap;
+ existingRange.length -= overlap;
+ } else {
+ // new range completely overlaps existing.
+ // new range: ___++++++++++
+ // existing : ___======____
+ // . result : ___++++++++++
+ ranges.remove(i);
+ }
+ } else { // new range starts inside or after existing
+ if (existingEnd < overrideStart) {
+ // new range lies after existing range. No overlapping.
+ // new range: _________++++
+ // existing : =====________
+ // . result : =====____++++
+ // nothing to do
+ } else if (overrideEnd >= existingEnd) {
+ // new range overlaps end of existing.
+ // new range: _____++++++++
+ // existing : ========_____
+ // . result : =====++++++++
+ existingRange.length -= existingEnd - overrideStart;
+ } else {
+ // new range lies inside existing range but not overrides all of it
+ // (and does not touch first or last offset of existing)
+ // new range: ____+++++____
+ // existing : =============
+ // . result : ====+++++====
+ final StyleRange clonedRange = (StyleRange) existingRange.clone();
+ existingRange.length = overrideStart - existingStart;
+ clonedRange.start = overrideEnd;
+ clonedRange.length = existingEnd - overrideEnd;
+ ranges.add(i + 1, clonedRange);
}
- return;
- } else if (start >= existingRange.start && start < rEnd) {
- existingRange.length = start - existingRange.start;
- ranges.add(++i, newRange);
- } else if (end >= rEnd) {
- ranges.remove(i);
- } else {
- ranges.add(++i, new StyleRange(end + 1, rEnd - end + 1, existingRange.foreground, existingRange.background));
}
}
+ ranges.add(insertIndex, newRange);
}
/**
* Binary search for the positions overlapping the given range
*
- * @param offset
- * the offset of the range
- * @param length
- * the length of the range
- * @param positions
- * the positions to search
+ * @param offset the offset of the range
+ * @param length the length of the range
+ * @param positions the positions to search
* @return the positions overlapping the given range, or <code>null</code>
*/
private Position[] findPosition(int offset, int length, Position[] positions) {
@@ -635,8 +674,7 @@ public class TextConsoleViewer extends SourceViewer implements LineStyleListener
* Returns the hyperlink at the specified offset, or <code>null</code> if
* none.
*
- * @param offset
- * offset at which a hyperlink has been requested
+ * @param offset offset at which a hyperlink has been requested
* @return hyperlink at the specified offset, or <code>null</code> if none
*/
public IHyperlink getHyperlink(int offset) {

Back to the top