Bug 577122 - Javadoc first line is not copied
Usage of widgetSelection2ModelSelection is mandatory to handle complex
ProjectionAnnotation/ProjectionPositions cases
Change-Id: I71271fcd22f0b9ae8464a8ffef5690bc17f8fb81
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/190679
Tested-by: Mickael Istria <mistria@redhat.com>
Reviewed-by: Mickael Istria <mistria@redhat.com>
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
index 5ea29e8..6ff49e9 100644
--- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java
@@ -77,7 +77,8 @@
TabsToSpacesConverterTest.class,
DefaultTextDoubleClickStrategyTest.class,
MultiSelectionTest.class,
- FindReplaceDocumentAdapterContentProposalProviderTest.class
+ FindReplaceDocumentAdapterContentProposalProviderTest.class,
+ ProjectionViewerTest.class
})
public class JFaceTextTestSuite {
// see @SuiteClasses
diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/ProjectionViewerTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/ProjectionViewerTest.java
new file mode 100644
index 0000000..03c3773
--- /dev/null
+++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/ProjectionViewerTest.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Red Hat, Inc. 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
+ *******************************************************************************/
+package org.eclipse.jface.text.tests;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.AnnotationModel;
+import org.eclipse.jface.text.source.projection.IProjectionPosition;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+
+public class ProjectionViewerTest {
+
+ private static final class ProjectionPosition extends Position implements IProjectionPosition {
+
+ public ProjectionPosition(IDocument document) {
+ super(0, document.getLength());
+ }
+
+ @Override
+ public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException {
+ int firstNewLine= document.get().indexOf('\n');
+ int secondNewLine= document.get().indexOf('\n', firstNewLine + 1);
+ return new IRegion[] { new Region(0, firstNewLine + 1), new Region(secondNewLine + 1, document.getLength() - secondNewLine - 1) };
+ }
+
+ @Override
+ public int computeCaptionOffset(IDocument document) throws BadLocationException {
+ return document.get().indexOf('\n') + 1;
+ }
+
+ }
+
+ @Test
+ public void testCopyPaste() {
+ Shell shell = new Shell();
+ shell.setLayout(new FillLayout());
+ ProjectionViewer viewer = new ProjectionViewer(shell, null, null, false, SWT.NONE);
+ Document document= new Document("/*\n * content\n */");
+ viewer.setDocument(document, new AnnotationModel());
+ viewer.enableProjection();
+ viewer.getProjectionAnnotationModel().addAnnotation(new ProjectionAnnotation(false), new ProjectionPosition(document));
+ shell.setVisible(true);
+ viewer.getTextOperationTarget().doOperation(ProjectionViewer.COLLAPSE_ALL);
+ viewer.getTextOperationTarget().doOperation(ITextOperationTarget.SELECT_ALL);
+ try {
+ assertEquals(document.get(), ((ITextSelection) viewer.getSelection()).getText());
+ viewer.getTextOperationTarget().doOperation(ITextOperationTarget.COPY);
+ assertEquals(document.get(), new Clipboard(viewer.getTextWidget().getDisplay()).getContents(TextTransfer.getInstance()));
+ } finally {
+ shell.dispose();
+ }
+ }
+}
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 6107756..60c174a 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
@@ -2525,9 +2525,9 @@
int[] ranges= fTextWidget.getSelectionRanges();
IRegion[] selectedRanges= new IRegion[ranges.length / 2];
for (int i= 0; i < selectedRanges.length; i++) {
- int start= widgetOffset2ModelOffset(ranges[2 * i]);
- int end= widgetOffset2ModelOffset(ranges[2 * i] + ranges[2 * i + 1]);
- selectedRanges[i]= new Region(start, end - start);
+ Point widgetSelection= new Point(ranges[2 * i], ranges[2 * i + 1]);
+ Point modelSelection= widgetSelection2ModelSelection(widgetSelection);
+ selectedRanges[i]= new Region(modelSelection.x, modelSelection.y);
}
return toSelection(selectedRanges);
}