Skip to content

Commit a2ffc06

Browse files
authored
Merge branch 'master' into fontregistry-multiple-display
2 parents bf1b8b1 + ea68ca2 commit a2ffc06

File tree

14 files changed

+245
-115
lines changed

14 files changed

+245
-115
lines changed

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ public void documentAboutToBeChanged(DocumentEvent event) {
163163

164164
@Override
165165
public void documentChanged(DocumentEvent event) {
166-
// Do nothing
166+
if (endOffset != null && event != null && event.fDocument != null && event.fDocument.getLength() > endOffset) {
167+
endOffset= null;
168+
}
167169
}
168170

169171
@Override

bundles/org.eclipse.ui.editors/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.ui.editors; singleton:=true
5-
Bundle-Version: 3.19.0.qualifier
5+
Bundle-Version: 3.19.100.qualifier
66
Bundle-Activator: org.eclipse.ui.internal.editors.text.EditorsPlugin
77
Bundle-ActivationPolicy: lazy
88
Bundle-Vendor: %providerName

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProvider.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
import org.eclipse.swt.custom.StyledText;
2121

22+
import org.eclipse.jface.text.ITextViewerExtension5;
23+
import org.eclipse.jface.text.source.ISourceViewer;
24+
2225
/**
2326
* This class provides sticky lines for the given source code in the source viewer. The
2427
* implementation is completely based on indentation and therefore works by default for several
@@ -33,14 +36,16 @@ public class DefaultStickyLinesProvider implements IStickyLinesProvider {
3336
private StickyLinesProperties fProperties;
3437

3538
@Override
36-
public List<IStickyLine> getStickyLines(StyledText textWidget, int lineNumber, StickyLinesProperties properties) {
39+
public List<IStickyLine> getStickyLines(ISourceViewer sourceViewer, int lineNumber, StickyLinesProperties properties) {
3740
this.fProperties= properties;
3841
LinkedList<IStickyLine> stickyLines= new LinkedList<>();
3942

43+
StyledText textWidget= sourceViewer.getTextWidget();
44+
int textWidgetLineNumber= mapLineNumberToWidget(sourceViewer, lineNumber);
4045
try {
41-
int startIndetation= getStartIndentation(lineNumber, textWidget);
46+
int startIndetation= getStartIndentation(textWidgetLineNumber, textWidget);
4247

43-
for (int i= lineNumber, previousIndetation= startIndetation; i >= 0; i--) {
48+
for (int i= textWidgetLineNumber, previousIndetation= startIndetation; i >= 0; i--) {
4449
String line= textWidget.getLine(i);
4550
int indentation= getIndentation(line);
4651

@@ -50,7 +55,7 @@ public List<IStickyLine> getStickyLines(StyledText textWidget, int lineNumber, S
5055

5156
if (indentation < previousIndetation) {
5257
previousIndetation= indentation;
53-
stickyLines.addFirst(new StickyLine(i, textWidget));
58+
stickyLines.addFirst(new StickyLine(mapLineNumberToViewer(sourceViewer, i), textWidget));
5459
}
5560
}
5661
} catch (IllegalArgumentException e) {
@@ -101,4 +106,18 @@ private int getIndentation(String line) {
101106
return line.length() - line.stripLeading().length();
102107
}
103108

109+
private int mapLineNumberToWidget(ISourceViewer sourceViewer, int line) {
110+
if (sourceViewer instanceof ITextViewerExtension5 extension) {
111+
return extension.modelLine2WidgetLine(line);
112+
}
113+
return line;
114+
}
115+
116+
private int mapLineNumberToViewer(ISourceViewer sourceViewer, int line) {
117+
if (sourceViewer instanceof ITextViewerExtension5 extension) {
118+
return extension.widgetLine2ModelLine(line);
119+
}
120+
return line;
121+
}
122+
104123
}

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,35 @@
1515

1616
import java.util.List;
1717

18-
import org.eclipse.swt.custom.StyledText;
19-
2018
import org.eclipse.jface.text.source.ISourceViewer;
2119

2220
/**
23-
* A sticky lines provider calculates the sticky lines for a given text widget. The sticky lines
21+
* A sticky lines provider calculates the sticky lines for a given source viewer. The sticky lines
2422
* will be displayed in the top area of the editor.
2523
*
2624
* TODO move to public package and add since 3.19
2725
*/
2826
public interface IStickyLinesProvider {
2927

3028
/**
31-
* Calculate the sticky lines for the source code of the given textWidget. Specific properties,
32-
* such as the <code>tabWidht</code> and the source viewer, can be retrieved from the
29+
* Calculate the sticky lines for the source code of the given sourceViewer. Specific
30+
* properties, such as the <code>tabWidht</code>, can be retrieved from the
3331
* <code>properties</code>.
3432
*
35-
* @param textWidget The text widget containing the source code
33+
* @param sourceViewer The source viewer containing the source code and gives access to the text
34+
* widget
3635
* @param lineNumber The line number to calculate the sticky lines for
3736
* @param properties Properties for additional information
3837
* @return The list of sticky lines to show
3938
*/
40-
public List<IStickyLine> getStickyLines(StyledText textWidget, int lineNumber, StickyLinesProperties properties);
39+
public List<IStickyLine> getStickyLines(ISourceViewer sourceViewer, int lineNumber, StickyLinesProperties properties);
4140

4241
/**
4342
* Additional properties and access in order to calculate the sticky lines.
4443
*
4544
* @param tabWith The with of a tab
46-
* @param sourceViewer The sourceViewer to access additional information
4745
*/
48-
record StickyLinesProperties(int tabWith, ISourceViewer sourceViewer) {
46+
record StickyLinesProperties(int tabWith) {
4947
}
5048

5149
}

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ private void updateStickyScrollingControls() {
206206
for (int i= 0; i < getNumberStickyLines(); i++) {
207207
IStickyLine stickyLine= stickyLines.get(i);
208208
stickyLineTextJoiner.add(stickyLine.getText());
209-
int lineNumber= getSourceViewerLineNumber(stickyLine.getLineNumber());
209+
int lineNumber= stickyLine.getLineNumber();
210210
stickyLineNumberJoiner.add(fillLineNumberWithLeadingSpaces(lineNumber + 1));
211211
}
212212

@@ -222,13 +222,6 @@ private void updateStickyScrollingControls() {
222222
}
223223
}
224224

225-
private int getSourceViewerLineNumber(int i) {
226-
if (sourceViewer instanceof ITextViewerExtension5 extension) {
227-
return extension.widgetLine2ModelLine(i);
228-
}
229-
return i;
230-
}
231-
232225
private String fillLineNumberWithLeadingSpaces(int lineNumber) {
233226
int lineCount= sourceViewer.getDocument().getNumberOfLines();
234227
int lineNumberLength= String.valueOf(lineCount).length();
@@ -399,6 +392,8 @@ private int getNumberStickyLines() {
399392
* resized/moved.<br>
400393
*/
401394
private void addSourceViewerListeners() {
395+
StyledText textWidget= sourceViewer.getTextWidget();
396+
402397
if (sourceViewer instanceof ITextViewerExtension4 extension) {
403398
textPresentationListener= e -> {
404399
Job.create("Update sticky lines styling", (ICoreRunnable) monitor -> { //$NON-NLS-1$
@@ -411,13 +406,12 @@ private void addSourceViewerListeners() {
411406
}
412407

413408
caretListener= new StickyScollingCaretListener();
414-
sourceViewer.getTextWidget().addCaretListener(caretListener);
415-
sourceViewer.getTextWidget().addKeyListener(caretListener);
409+
textWidget.addCaretListener(caretListener);
410+
textWidget.addKeyListener(caretListener);
416411

417412
controlListener= new ControlListener() {
418413
@Override
419414
public void controlResized(ControlEvent e) {
420-
StyledText textWidget= sourceViewer.getTextWidget();
421415
limitVisibleStickyLinesToTextWidgetHeight(textWidget);
422416
layoutStickyLines();
423417
if (stickyScrollingHandler != null) {
@@ -430,7 +424,7 @@ public void controlMoved(ControlEvent e) {
430424
layoutStickyLines();
431425
}
432426
};
433-
sourceViewer.getTextWidget().addControlListener(controlListener);
427+
textWidget.addControlListener(controlListener);
434428
}
435429

436430
private void limitVisibleStickyLinesToTextWidgetHeight(StyledText textWidget) {

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.util.LinkedList;
2626
import java.util.List;
2727

28-
import org.eclipse.swt.custom.StyledText;
2928
import org.eclipse.swt.graphics.Color;
3029
import org.eclipse.swt.graphics.RGB;
3130

@@ -140,7 +139,7 @@ private StickyScrollingControlSettings loadControlSettings(IPreferenceStore stor
140139

141140
private StickyLinesProperties loadStickyLinesProperties(IPreferenceStore store) {
142141
int tabWidth= store.getInt(EDITOR_TAB_WIDTH);
143-
return new StickyLinesProperties(tabWidth, sourceViewer);
142+
return new StickyLinesProperties(tabWidth);
144143
}
145144

146145
@Override
@@ -155,11 +154,10 @@ public void viewportChanged(int newVerticalOffset) {
155154
private void calculateAndShowStickyLines() {
156155
List<IStickyLine> stickyLines= Collections.emptyList();
157156

158-
StyledText textWidget= sourceViewer.getTextWidget();
159-
int startLine= textWidget.getTopIndex();
157+
int startLine= sourceViewer.getTopIndex();
160158

161159
if (startLine > 0) {
162-
stickyLines= stickyLinesProvider.getStickyLines(textWidget, startLine, stickyLinesProperties);
160+
stickyLines= stickyLinesProvider.getStickyLines(sourceViewer, sourceViewer.getTopIndex(), stickyLinesProperties);
163161
}
164162

165163
if (stickyLines == null) {
@@ -179,11 +177,10 @@ private List<IStickyLine> adaptStickyLinesToVisibleArea(List<IStickyLine> sticky
179177
LinkedList<IStickyLine> adaptedStickyLines= new LinkedList<>(stickyLines);
180178

181179
int firstVisibleLine= startLine + adaptedStickyLines.size();
182-
StyledText textWidget= sourceViewer.getTextWidget();
183-
int maximumLines= textWidget.getLineCount();
180+
int numberOfLines= sourceViewer.getDocument().getNumberOfLines();
184181

185-
for (int i= startLine + 1; i <= firstVisibleLine && i < maximumLines; i++) {
186-
List<IStickyLine> stickyLinesInLineI= stickyLinesProvider.getStickyLines(textWidget, i, stickyLinesProperties);
182+
for (int i= startLine + 1; i <= firstVisibleLine && i < numberOfLines; i++) {
183+
List<IStickyLine> stickyLinesInLineI= stickyLinesProvider.getStickyLines(sourceViewer, i, stickyLinesProperties);
187184

188185
if (stickyLinesInLineI.size() > adaptedStickyLines.size()) {
189186
adaptedStickyLines= new LinkedList<>(stickyLinesInLineI);

tests/org.eclipse.ui.editors.tests/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %Plugin.name
44
Bundle-SymbolicName: org.eclipse.ui.editors.tests;singleton:=true
5-
Bundle-Version: 3.13.600.qualifier
5+
Bundle-Version: 3.13.700.qualifier
66
Bundle-Vendor: %Plugin.providerName
77
Bundle-Localization: plugin
88
Export-Package: org.eclipse.jface.text.tests.codemining,

tests/org.eclipse.ui.editors.tests/plugin.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,14 @@
2222
id="org.eclipse.jface.text.tests.codemining.CodeMiningTestProvider">
2323
</codeMiningProvider>
2424
</extension>
25-
</plugin>
25+
<extension
26+
point="org.eclipse.ui.editors">
27+
<editor
28+
class="org.eclipse.jface.text.tests.codemining.TextProjectionTextEditor"
29+
default="false"
30+
extensions="testprojectionviewer"
31+
id="org.eclipse.jface.text.tests.codemining.TestProjectionTextEditor"
32+
name="TestProjectionTextEditor">
33+
</editor>
34+
</extension>
35+
</plugin>

tests/org.eclipse.ui.editors.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningTest.java

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.io.ByteArrayInputStream;
1414
import java.text.SimpleDateFormat;
1515
import java.util.Date;
16+
import java.util.HashMap;
1617
import java.util.concurrent.Callable;
1718

1819
import org.junit.After;
@@ -41,8 +42,12 @@
4142
import org.eclipse.jface.text.BadLocationException;
4243
import org.eclipse.jface.text.IDocument;
4344
import org.eclipse.jface.text.ITextViewer;
45+
import org.eclipse.jface.text.Position;
46+
import org.eclipse.jface.text.source.Annotation;
4447
import org.eclipse.jface.text.source.ISourceViewer;
4548
import org.eclipse.jface.text.source.ISourceViewerExtension5;
49+
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
50+
import org.eclipse.jface.text.source.projection.ProjectionViewer;
4651

4752
import org.eclipse.ui.IEditorPart;
4853
import org.eclipse.ui.IWorkbenchPage;
@@ -100,6 +105,60 @@ public void run(IProgressMonitor monitor) throws CoreException {
100105
}, new NullProgressMonitor());
101106
}
102107

108+
@Test
109+
public void testInlinedAnnotationSupportIsInLinesReturnsValidResultAfterDocumentChange() throws Exception {
110+
IFile file = project.getFile("test.testprojectionviewer");
111+
if (file.exists()) {
112+
file.delete(true, new NullProgressMonitor());
113+
}
114+
String source = "first\nsecond\nthird\n";
115+
file.create(new ByteArrayInputStream(source.getBytes("UTF-8")), true, new NullProgressMonitor());
116+
CodeMiningTestProvider.provideHeaderMiningAtLine = 2;
117+
CodeMiningTestProvider.lineHeaderMiningText = " first line header\n secone line header\n third line header";
118+
int offset = source.indexOf("second") + "second".length();
119+
IEditorPart editor = IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), file);
120+
drainEventQueue();
121+
ISourceViewer viewer = (ISourceViewer) editor.getAdapter(ITextViewer.class);
122+
StyledText widget = viewer.getTextWidget();
123+
124+
var annotationModel = ((ProjectionViewer) viewer).getProjectionAnnotationModel();
125+
var deletionsArray = new Annotation[] {};
126+
var additions = new HashMap<Annotation, Position>();
127+
ProjectionAnnotation annot = new ProjectionAnnotation();
128+
additions.put(annot, new Position(0, source.length()));
129+
annotationModel.modifyAnnotations(deletionsArray, additions, null);
130+
131+
Assert.assertTrue("Line header code mining above 3rd line not drawn",
132+
waitForCondition(widget.getDisplay(), 2000, new Callable<Boolean>() {
133+
@Override
134+
public Boolean call() throws Exception {
135+
try {
136+
return existsPixelWithNonBackgroundColorAtLine(viewer, 2);
137+
} catch (BadLocationException e) {
138+
e.printStackTrace();
139+
return false;
140+
}
141+
}
142+
}));
143+
144+
IDocument doc = viewer.getDocument();
145+
widget.setCaretOffset(offset);
146+
doc.replace(offset, 0, "\n insert text");
147+
drainEventQueue();
148+
Assert.assertTrue("Line header code mining above 4th line after inserting text not drawn",
149+
waitForCondition(widget.getDisplay(), 2000, new Callable<Boolean>() {
150+
@Override
151+
public Boolean call() throws Exception {
152+
try {
153+
return existsPixelWithNonBackgroundColorAtLine(viewer, 3);
154+
} catch (BadLocationException e) {
155+
e.printStackTrace();
156+
return false;
157+
}
158+
}
159+
}));
160+
}
161+
103162
@Test
104163
public void testCodeMiningOnEmptyLine() throws Exception {
105164
IFile file = project.getFile("test.txt");
@@ -208,12 +267,17 @@ private static boolean existsPixelWithNonBackgroundColorAtLine(ITextViewer viewe
208267
lineLength = 0;
209268
}
210269
int verticalScroolBarWidth = viewer.getTextWidget().getVerticalBar().getThumbBounds().width;
211-
Rectangle lineBounds = widget.getTextBounds(document.getLineOffset(line),
212-
document.getLineOffset(line) + lineLength);
270+
int lineOffset = document.getLineOffset(line);
271+
Rectangle lineBounds = widget.getTextBounds(lineOffset, lineOffset + lineLength);
272+
String lineStr = document.get(lineOffset, lineLength);
213273
Image image = new Image(widget.getDisplay(), widget.getSize().x, widget.getSize().y);
214274
try {
215275
GC gc = new GC(widget);
216276
gc.copyArea(image, 0, 0);
277+
Point textExtent = gc.textExtent(lineStr);
278+
if (lineBounds.height - textExtent.y > textExtent.y) {
279+
lineBounds.height -= textExtent.y;
280+
}
217281
gc.dispose();
218282
ImageData imageData = image.getImageData();
219283
for (int x = lineBounds.x + 1; x < image.getBounds().width - verticalScroolBarWidth

tests/org.eclipse.ui.editors.tests/src/org/eclipse/jface/text/tests/codemining/CodeMiningTestProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
public class CodeMiningTestProvider extends AbstractCodeMiningProvider {
3030
public static int provideHeaderMiningAtLine = -1;
3131
public static int provideContentMiningAtOffset = -1;
32-
32+
public static String lineHeaderMiningText;
3333
@Override
3434
public CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextViewer viewer,
3535
IProgressMonitor monitor) {
@@ -42,6 +42,9 @@ public CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextVi
4242
minings.add(new LineHeaderCodeMining(provideHeaderMiningAtLine, viewer.getDocument(), this) {
4343
@Override
4444
public String getLabel() {
45+
if (lineHeaderMiningText != null) {
46+
return lineHeaderMiningText;
47+
}
4548
return "line header mining";
4649
}
4750
});

0 commit comments

Comments
 (0)