Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorteicher2009-04-21 19:06:05 +0000
committerteicher2009-04-21 19:06:05 +0000
commitdf91ec416e52e1eb6c2bb2a72356570ff62da20e (patch)
treed0ce21deb025d9d2f8fe8d406d91965ae0f72b17 /org.eclipse.jface.text/src/org/eclipse/jface
parent665107ef6114a1f4bb743210c60c4fa72387ec96 (diff)
downloadeclipse.platform.text-df91ec416e52e1eb6c2bb2a72356570ff62da20e.tar.gz
eclipse.platform.text-df91ec416e52e1eb6c2bb2a72356570ff62da20e.tar.xz
eclipse.platform.text-df91ec416e52e1eb6c2bb2a72356570ff62da20e.zip
bug 267804: [block selection][projection] copy paste does not work for unequal length selected text
Diffstat (limited to 'org.eclipse.jface.text/src/org/eclipse/jface')
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/internal/text/SelectionProcessor.java6
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java147
2 files changed, 120 insertions, 33 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/SelectionProcessor.java b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/SelectionProcessor.java
index 7cc9d23ab81..8ffb7b77f00 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/SelectionProcessor.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/internal/text/SelectionProcessor.java
@@ -18,7 +18,6 @@ import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
-import org.eclipse.text.edits.RangeMarker;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
@@ -227,7 +226,6 @@ public final class SelectionProcessor {
int endColumn= cts.getEndColumn();
int visualStartColumn= computeVisualColumn(startLine, startColumn);
int visualEndColumn= computeVisualColumn(endLine, endColumn);
- visualEndColumn= Math.max(visualStartColumn, visualEndColumn); // HACK - TextViewer::getSelection does not know about virtual selections
root= new MultiTextEdit();
String[] delimiters= fDocument.getLegalLineDelimiters();
@@ -248,8 +246,6 @@ public final class SelectionProcessor {
}
TextEdit replace= createReplaceEdit(line, visualStartColumn, visualEndColumn, string);
root.addChild(replace);
- if (line == startLine)
- root.addChild(new RangeMarker(replace.getOffset() + replace.getLength(), 0));
}
while (lastDelim != -1) {
// more stuff to insert
@@ -427,6 +423,8 @@ public final class SelectionProcessor {
}
if (endColumn == -1)
endColumn= lineLength;
+ if (replacement.length() == 0)
+ return new DeleteEdit(info.getOffset() + startColumn, endColumn - startColumn);
return new ReplaceEdit(info.getOffset() + startColumn, endColumn - startColumn, replacement);
}
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 878607a84b5..aa289f419dc 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
@@ -72,6 +72,7 @@ import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.internal.text.NonDeletingPositionUpdater;
import org.eclipse.jface.internal.text.SelectionProcessor;
import org.eclipse.jface.internal.text.StickyHoverManager;
+import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -1117,6 +1118,20 @@ public class TextViewer extends Viewer implements
fStateMask= stateMask;
}
}
+
+ /**
+ * Position storing block selection information in order to maintain a column selection.
+ *
+ * @since 3.5
+ */
+ private static final class ColumnPosition extends Position {
+ int fStartColumn, fEndColumn;
+ ColumnPosition(int offset, int length, int startColumn, int endColumn) {
+ super(offset, length);
+ fStartColumn= startColumn;
+ fEndColumn= endColumn;
+ }
+ }
/**
* Captures and remembers the viewer state (selection and visual position). {@link TextViewer.ViewerState}
@@ -1193,13 +1208,32 @@ public class TextViewer extends Viewer implements
if (isConnected())
disconnect();
if (fSelection != null) {
- int offset= fSelection.getOffset();
- int length= fSelection.getLength();
- if (fReverseSelection) {
- offset-= length;
- length= -length;
+ if (fSelection instanceof ColumnPosition) {
+ ColumnPosition cp= (ColumnPosition)fSelection;
+ IDocument document= fDocument;
+ try {
+ int startLine= document.getLineOfOffset(fSelection.getOffset());
+ int startLineOffset= document.getLineOffset(startLine);
+ int selectionEnd= fSelection.getOffset() + fSelection.getLength();
+ int endLine= document.getLineOfOffset(selectionEnd);
+ int endLineOffset= document.getLineOffset(endLine);
+ int tabs= getTextWidget().getTabs();
+ int startColumn= fSelection.getOffset() - startLineOffset + cp.fStartColumn;
+ int endColumn= selectionEnd - endLineOffset + cp.fEndColumn;
+ setSelection(new BlockTextSelection(document, startLine, startColumn, endLine, endColumn, tabs));
+ } catch (BadLocationException e) {
+ // fall back to linear mode
+ setSelectedRange(cp.getOffset(), cp.getLength());
+ }
+ } else {
+ int offset= fSelection.getOffset();
+ int length= fSelection.getLength();
+ if (fReverseSelection) {
+ offset-= length;
+ length= -length;
+ }
+ setSelectedRange(offset, length);
}
- setSelectedRange(offset, length);
if (restoreViewport)
updateViewport();
}
@@ -1246,18 +1280,26 @@ public class TextViewer extends Viewer implements
fUpdaterDocument.addPositionCategory(fUpdaterCategory);
fUpdaterDocument.addPositionUpdater(fUpdater);
- Point selectionRange= getSelectedRange();
- fReverseSelection= selectionRange.y < 0;
- int offset, length;
- if (fReverseSelection) {
- offset= selectionRange.x + selectionRange.y;
- length= -selectionRange.y;
+ ISelection selection= TextViewer.this.getSelection();
+ if (selection instanceof IBlockTextSelection) {
+ IBlockTextSelection bts= (IBlockTextSelection) selection;
+ int startVirtual= Math.max(0, bts.getStartColumn() - document.getLineInformationOfOffset(bts.getOffset()).getLength());
+ int endVirtual= Math.max(0, bts.getEndColumn() - document.getLineInformationOfOffset(bts.getOffset() + bts.getLength()).getLength());
+ fSelection= new ColumnPosition(bts.getOffset(), bts.getLength(), startVirtual, endVirtual);
} else {
- offset= selectionRange.x;
- length= selectionRange.y;
+ Point selectionRange= getSelectedRange();
+ fReverseSelection= selectionRange.y < 0;
+ int offset, length;
+ if (fReverseSelection) {
+ offset= selectionRange.x + selectionRange.y;
+ length= -selectionRange.y;
+ } else {
+ offset= selectionRange.x;
+ length= selectionRange.y;
+ }
+ fSelection= new Position(offset, length);
}
- fSelection= new Position(offset, length);
fSelectionSet= false;
fUpdaterDocument.addPosition(fUpdaterCategory, fSelection);
@@ -2427,17 +2469,39 @@ public class TextViewer extends Viewer implements
* @see Viewer#setSelection(ISelection)
*/
public void setSelection(ISelection selection, boolean reveal) {
-// // FIXME ViewerState should also support column selections
-// if (selection instanceof IColumnTextSelection && getTextWidget().getBlockSelection()) {
-// IColumnTextSelection s= (IColumnTextSelection) selection;
-// StyledText styledText= getTextWidget();
-// int startLine= modelLine2WidgetLine(s.getStartLine());
-// int endLine= modelLine2WidgetLine(s.getEndLine());
-// styledText.setBlColumnSelection(s.getStartColumn(), startLine, s.getEndColumn(), endLine);
-// if (reveal)
-// revealRange(s.getOffset(), s.getLength());
-// } else if (selection instanceof ITextSelection) {
- if (selection instanceof ITextSelection) {
+ if (selection instanceof IBlockTextSelection && getTextWidget().getBlockSelection()) {
+ IBlockTextSelection s= (IBlockTextSelection) selection;
+
+ try {
+ int startLine= s.getStartLine();
+ int endLine= s.getEndLine();
+ IRegion startLineInfo= fDocument.getLineInformation(startLine);
+ int startLineLength= startLineInfo.getLength();
+ int startVirtuals= Math.max(0, s.getStartColumn() - startLineLength);
+
+ IRegion endLineInfo= fDocument.getLineInformation(endLine);
+ int endLineLength= endLineInfo.getLength();
+ int endVirtuals= Math.max(0, s.getEndColumn() - endLineLength);
+
+ int startOffset= modelOffset2WidgetOffset(startLineInfo.getOffset() + s.getStartColumn() - startVirtuals);
+ int endOffset= modelOffset2WidgetOffset(endLineInfo.getOffset() + s.getEndColumn() - endVirtuals);
+ Point clientAreaOrigin= new Point(fTextWidget.getHorizontalPixel(), fTextWidget.getTopPixel());
+ Point startLocation= Geometry.add(clientAreaOrigin, fTextWidget.getLocationAtOffset(startOffset));
+ int averageCharWidth= getAverageCharWidth();
+ startLocation.x += startVirtuals * averageCharWidth;
+ Point endLocation= Geometry.add(clientAreaOrigin, fTextWidget.getLocationAtOffset(endOffset));
+ endLocation.x += endVirtuals * averageCharWidth;
+ endLocation.y += fTextWidget.getLineHeight(endOffset);
+
+ fTextWidget.setBlockSelectionBounds(Geometry.createRectangle(startLocation, Geometry.subtract(endLocation, startLocation)));
+ // TODO fire selection change, validate etc - see setSelectedRange
+ } catch (BadLocationException e) {
+ // fall back to linear selection mode
+ setSelectedRange(s.getOffset(), s.getLength());
+ }
+ if (reveal)
+ revealRange(s.getOffset(), s.getLength());
+ } else if (selection instanceof ITextSelection) {
ITextSelection s= (ITextSelection) selection;
setSelectedRange(s.getOffset(), s.getLength());
if (reveal)
@@ -2449,11 +2513,20 @@ public class TextViewer extends Viewer implements
* @see Viewer#getSelection()
*/
public ISelection getSelection() {
- if (redraws() && fTextWidget != null && fTextWidget.getBlockSelection()) {
+ if (fTextWidget != null && fTextWidget.getBlockSelection()) {
int[] ranges= fTextWidget.getSelectionRanges();
int startOffset= ranges[0];
int endOffset= ranges[ranges.length - 2] + ranges[ranges.length - 1];
+ // getBlockSelectionBounds returns pixel coordinates relative to document
+ Rectangle bounds= fTextWidget.getBlockSelectionBounds();
+ int clientAreaX= fTextWidget.getHorizontalPixel();
+ int startX= bounds.x - clientAreaX;
+ int endX= bounds.x + bounds.width - clientAreaX;
+ int avgCharWidth= getAverageCharWidth();
+ int startVirtuals= computeVirtualChars(startOffset, startX, avgCharWidth);
+ int endVirtuals= computeVirtualChars(endOffset, endX, avgCharWidth);
+
IDocument document= getDocument();
startOffset= widgetOffset2ModelOffset(startOffset);
endOffset= widgetOffset2ModelOffset(endOffset);
@@ -2461,8 +2534,8 @@ public class TextViewer extends Viewer implements
int startLine= document.getLineOfOffset(startOffset);
int endLine= document.getLineOfOffset(endOffset);
- int startColumn= startOffset - document.getLineOffset(startLine);
- int endColumn= endOffset - document.getLineOffset(endLine);
+ int startColumn= startOffset - document.getLineOffset(startLine) + startVirtuals;
+ int endColumn= endOffset - document.getLineOffset(endLine) + endVirtuals;
if (startLine == -1 || endLine == -1)
return TextSelection.emptySelection();
return new BlockTextSelection(document, startLine, startColumn, endLine, endColumn, fTextWidget.getTabs());
@@ -2478,6 +2551,22 @@ public class TextViewer extends Viewer implements
return new TextSelection(getDocument(), p.x, p.y);
}
+ /**
+ * Returns the number of virtual characters that exist beyond the end-of-line at offset
+ * <code>offset</code> for an x-coordinate <code>x</code>.
+ *
+ * @param offset the non-virtual offset to consider
+ * @param x the x-coordinate (relative to the client area) of the possibly virtual offset
+ * @param avgCharWidth the average character width to assume for virtual spaces
+ * @return the number of virtual spaces needed to reach <code>x</code> from the location of
+ * <code>offset</code>, <code>0</code> if <code>x</code> points inside the text
+ * @since 3.5
+ */
+ private int computeVirtualChars(int offset, int x, int avgCharWidth) {
+ int diff= x - fTextWidget.getLocationAtOffset(offset).x;
+ return diff > 0 ? diff / avgCharWidth : 0;
+ }
+
/*
* @see ITextViewer#getSelectionProvider()
*/

Back to the top