Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 118701 Details for
Bug 19771
[typing] Add column based editing capabilities to textual editors
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
block_selection.patch
block_selection.patch (text/plain), 94.16 KB, created by
Tom Hofmann
on 2008-11-25 16:29:53 EST
(
hide
)
Description:
block_selection.patch
Filename:
MIME Type:
Creator:
Tom Hofmann
Created:
2008-11-25 16:29:53 EST
Size:
94.16 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.ui.workbench.texteditor >Index: src/org/eclipse/ui/texteditor/BasicTextEditorActionContributor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/BasicTextEditorActionContributor.java,v >retrieving revision 1.34 >diff -u -r1.34 BasicTextEditorActionContributor.java >--- src/org/eclipse/ui/texteditor/BasicTextEditorActionContributor.java 11 Sep 2008 11:58:02 -0000 1.34 >+++ src/org/eclipse/ui/texteditor/BasicTextEditorActionContributor.java 25 Nov 2008 21:13:16 -0000 >@@ -212,6 +212,7 @@ > for (int i= 0; i < ACTIONS.length; i++) > actionBars.setGlobalActionHandler(ACTIONS[i], getAction(editor, ACTIONS[i])); > actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.SHOW_WHITESPACE_CHARACTERS, getAction(editor, ITextEditorActionConstants.SHOW_WHITESPACE_CHARACTERS)); >+ actionBars.setGlobalActionHandler(ITextEditorActionDefinitionIds.COLUMN_MODE, getAction(editor, ITextEditorActionConstants.COLUMN_MODE)); > > fFindNext.setAction(getAction(editor, ITextEditorActionConstants.FIND_NEXT)); > fFindPrevious.setAction(getAction(editor, ITextEditorActionConstants.FIND_PREVIOUS)); >Index: src/org/eclipse/ui/texteditor/TextViewerDeleteLineTarget.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/TextViewerDeleteLineTarget.java,v >retrieving revision 1.3 >diff -u -r1.3 TextViewerDeleteLineTarget.java >--- src/org/eclipse/ui/texteditor/TextViewerDeleteLineTarget.java 11 Sep 2008 11:58:02 -0000 1.3 >+++ src/org/eclipse/ui/texteditor/TextViewerDeleteLineTarget.java 25 Nov 2008 21:13:18 -0000 >@@ -34,10 +34,12 @@ > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.IRegion; > import org.eclipse.jface.text.ITextListener; >+import org.eclipse.jface.text.ITextSelection; > import org.eclipse.jface.text.ITextViewer; > import org.eclipse.jface.text.ITextViewerExtension5; > import org.eclipse.jface.text.Region; > import org.eclipse.jface.text.TextEvent; >+import org.eclipse.jface.text.TextSelection; > > import org.eclipse.ui.internal.texteditor.TextEditorPlugin; > >@@ -47,7 +49,7 @@ > * > * @since 3.4 > */ >-public class TextViewerDeleteLineTarget implements IDeleteLineTarget { >+public class TextViewerDeleteLineTarget implements IDeleteLineTarget, IDeleteLineTargetExtension { > > /** > * A clipboard which concatenates subsequent delete line actions. >@@ -258,29 +260,25 @@ > * Returns the document's delete region specified by position and type. > * > * @param document the document >- * @param offset the offset >- * @param length the length >+ * @param selection the selection > * @param type the line deletion type, must be one of <code>WHOLE_LINE</code>, > * <code>TO_BEGINNING</code> or <code>TO_END</code> > * @return the document's delete region > * @throws BadLocationException if the document is accessed with invalid offset or line > */ >- private IRegion getDeleteRegion(IDocument document, int offset, int length, int type) throws BadLocationException { >+ private IRegion getDeleteRegion(IDocument document, ITextSelection selection, int type) throws BadLocationException { > >- int line= document.getLineOfOffset(offset); >+ int offset= selection.getOffset(); >+ int line= selection.getStartLine(); > int resultOffset= 0; > int resultLength= 0; > > switch (type) { >- case DeleteLineAction.WHOLE: >- resultOffset= document.getLineOffset(line); >- int endOffset= offset + length; >- IRegion endLineInfo= document.getLineInformationOfOffset(endOffset); >- int endLine= document.getLineOfOffset(endLineInfo.getOffset()); >- if (endLineInfo.getOffset() == endOffset && endLine > 0 && length > 0) >- endLine= endLine - 1; >- resultLength= document.getLineOffset(endLine) + document.getLineLength(endLine) - resultOffset; >- break; >+ case DeleteLineAction.WHOLE: >+ resultOffset= document.getLineOffset(line); >+ int endLine= selection.getEndLine(); >+ resultLength= document.getLineOffset(endLine) + document.getLineLength(endLine) - resultOffset; >+ break; > > case DeleteLineAction.TO_BEGINNING: > resultOffset= document.getLineOffset(line); >@@ -338,8 +336,16 @@ > * @since 3.4 > */ > public void deleteLine(IDocument document, int offset, int length, int type, boolean copyToClipboard) throws BadLocationException { >+ deleteLine(document, new TextSelection(offset, length), type, copyToClipboard); >+ } >+ >+ /* >+ * @see org.eclipse.ui.texteditor.IDeleteLineTargetExtension#deleteLine(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.ITextSelection, int, boolean) >+ * @since 3.5 >+ */ >+ public void deleteLine(IDocument document, ITextSelection selection, int type, boolean copyToClipboard) throws BadLocationException { > >- IRegion deleteRegion= getDeleteRegion(document, offset, length, type); >+ IRegion deleteRegion= getDeleteRegion(document, selection, type); > int deleteOffset= deleteRegion.getOffset(); > int deleteLength= deleteRegion.getLength(); > >Index: src/org/eclipse/ui/texteditor/DeleteLineAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/DeleteLineAction.java,v >retrieving revision 1.16 >diff -u -r1.16 DeleteLineAction.java >--- src/org/eclipse/ui/texteditor/DeleteLineAction.java 22 Oct 2008 12:39:59 -0000 1.16 >+++ src/org/eclipse/ui/texteditor/DeleteLineAction.java 25 Nov 2008 21:13:17 -0000 >@@ -189,7 +189,10 @@ > return; > > try { >- fTarget.deleteLine(document, selection.getOffset(), selection.getLength(), fType, fCopyToClipboard); >+ if (fTarget instanceof IDeleteLineTargetExtension) >+ ((IDeleteLineTargetExtension) fTarget).deleteLine(document, selection, fType, fCopyToClipboard); >+ else >+ fTarget.deleteLine(document, selection.getOffset(), selection.getLength(), fType, fCopyToClipboard); > } catch (BadLocationException e) { > // should not happen > } >Index: src/org/eclipse/ui/texteditor/IDeleteLineTarget.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IDeleteLineTarget.java,v >retrieving revision 1.2 >diff -u -r1.2 IDeleteLineTarget.java >--- src/org/eclipse/ui/texteditor/IDeleteLineTarget.java 11 Sep 2008 11:58:03 -0000 1.2 >+++ src/org/eclipse/ui/texteditor/IDeleteLineTarget.java 25 Nov 2008 21:13:17 -0000 >@@ -22,6 +22,7 @@ > * </p> > * > * @since 3.4 >+ * @see IDeleteLineTargetExtension > */ > interface IDeleteLineTarget { > >Index: src/org/eclipse/ui/texteditor/ConstructedEditorMessages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ConstructedEditorMessages.properties,v >retrieving revision 1.13 >diff -u -r1.13 ConstructedEditorMessages.properties >--- src/org/eclipse/ui/texteditor/ConstructedEditorMessages.properties 24 Nov 2008 16:15:52 -0000 1.13 >+++ src/org/eclipse/ui/texteditor/ConstructedEditorMessages.properties 25 Nov 2008 21:13:16 -0000 >@@ -238,3 +238,8 @@ > Editor.ShowInformation.tooltip= Shows the Tooltip Description > Editor.ShowInformation.image= > Editor.ShowInformation.description= Displays information for the current caret location in a sticky hover >+ >+Editor.ToggleColumnMode.label= Toggle Column Mode >+Editor.ToggleColumnMode.description= Enable rectangular / column selection in the current text editor >+Editor.ToggleColumnMode.image= >+Editor.ToggleColumnMode.tooltip= Toggle Column Selection Mode >Index: src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java,v >retrieving revision 1.37 >diff -u -r1.37 ITextEditorActionDefinitionIds.java >--- src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java 24 Nov 2008 10:28:59 -0000 1.37 >+++ src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java 25 Nov 2008 21:13:17 -0000 >@@ -569,4 +569,10 @@ > */ > String SHOW_INFORMATION= "org.eclipse.ui.edit.text.showInformation"; //$NON-NLS-1$ > >+ /** >+ * Command ID of the command to toggle column selection mode. >+ * Value: <code>"org.eclipse.ui.edit.text.toggleColumnMode"</code>). >+ * @since 3.5 >+ */ >+ String COLUMN_MODE = "org.eclipse.ui.edit.text.toggleColumnMode"; //$NON-NLS-1$ > } >Index: src/org/eclipse/ui/texteditor/AbstractTextEditor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java,v >retrieving revision 1.291 >diff -u -r1.291 AbstractTextEditor.java >--- src/org/eclipse/ui/texteditor/AbstractTextEditor.java 25 Nov 2008 13:42:36 -0000 1.291 >+++ src/org/eclipse/ui/texteditor/AbstractTextEditor.java 25 Nov 2008 21:13:16 -0000 >@@ -96,6 +96,7 @@ > import org.eclipse.jface.preference.PreferenceConverter; > import org.eclipse.jface.resource.ImageDescriptor; > import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.jface.util.Geometry; > import org.eclipse.jface.util.IPropertyChangeListener; > import org.eclipse.jface.util.PropertyChangeEvent; > import org.eclipse.jface.util.SafeRunnable; >@@ -248,7 +249,7 @@ > * {@link #COMMON_RULER_CONTEXT_MENU_ID}. > * </p> > */ >-public abstract class AbstractTextEditor extends EditorPart implements ITextEditor, IReusableEditor, ITextEditorExtension, ITextEditorExtension2, ITextEditorExtension3, ITextEditorExtension4, INavigationLocationProvider, ISaveablesSource, IPersistableEditor { >+public abstract class AbstractTextEditor extends EditorPart implements ITextEditor, IReusableEditor, ITextEditorExtension, ITextEditorExtension2, ITextEditorExtension3, ITextEditorExtension4, ITextEditorExtension5, INavigationLocationProvider, ISaveablesSource, IPersistableEditor { > > /** > * Tag used in xml configuration files to specify editor action contributions. >@@ -286,6 +287,12 @@ > private static final int SINGLE_CARET_WIDTH= 1; > > /** >+ * The symbolic name of the column mode font. >+ * @since 3.3 >+ */ >+ protected static final String COLUMN_MODE_FONT= "org.eclipse.ui.workbench.texteditor.columnModeFont"; //$NON-NLS-1$ >+ >+ /** > * The text input listener. > * > * @see ITextInputListener >@@ -685,8 +692,17 @@ > return; > > String property= event.getProperty(); >- >- if (getFontPropertyPreferenceKey().equals(property)) { >+ >+ StyledText widget= fSourceViewer.getTextWidget(); >+ boolean columnMode= widget != null && widget.getBlockSelection(); >+ >+ if (columnMode) { >+ if (COLUMN_MODE_FONT.equals(property)) { >+ Font columnFont= JFaceResources.getFont(COLUMN_MODE_FONT); >+ disposeFont(); >+ setFont(fSourceViewer, columnFont); >+ } >+ } else if (getFontPropertyPreferenceKey().equals(property)) { > initializeViewerFont(fSourceViewer); > updateCaret(); > } >@@ -2021,6 +2037,15 @@ > } > } > >+// private Point fTextDNDColumnSelection; >+ >+ /** >+ * Column selection mode enablement. Per default, column selection is disabled for >+ * compatibility. >+ * @since 3.5 >+ */ >+ private boolean fEnableColumnMode= true; >+ > > /** > * Key used to look up font preference. >@@ -3462,11 +3487,9 @@ > fTextDragAndDropToken= null; > try { > fSelection= st.getSelection(); >- int offset= st.getOffsetAtLocation(new Point(event.x, event.y)); >- Point p= st.getLocationAtOffset(offset); >- if (p.x > event.x) >- offset--; >- event.doit= offset >= fSelection.x && offset < fSelection.y; >+// if (st.getBlockSelection()) >+// fTextDNDColumnSelection= st.getSelectionRange(); >+ event.doit= isLocationSelected(st, new Point(event.x, event.y)); > > ISelection selection= selectionProvider.getSelection(); > if (selection instanceof ITextSelection) >@@ -3477,6 +3500,14 @@ > event.doit= false; > } > } >+ >+ private boolean isLocationSelected(StyledText widget, Point point) { >+ Point selection= widget.getSelection(); >+ Point upperLeft= widget.getLocationAtOffset(selection.x); >+ Point lowerRight= widget.getLocationAtOffset(selection.y); >+ lowerRight.y += widget.getLineHeight(selection.y); >+ return Geometry.createRectangle(upperLeft, Geometry.subtract(lowerRight, upperLeft)).contains(point); >+ } > > public void dragSetData(DragSourceEvent event) { > event.data= fSelectedText; >@@ -3564,16 +3595,37 @@ > } > > String text= (String)event.data; >- Point newSelection= st.getSelection(); >- try { >- int modelOffset= widgetOffset2ModelOffset(viewer, newSelection.x); >- viewer.getDocument().replace(modelOffset, 0, text); >- } catch (BadLocationException e) { >- return; >+ if (st.getBlockSelection()) { >+ // FIXME fix block selection and DND >+// if (fTextDNDColumnSelection != null && fTextDragAndDropToken != null && event.detail == DND.DROP_MOVE) { >+// // DND_MOVE within same editor - remove origin before inserting >+// Rectangle newSelection= st.getColumnSelection(); >+// st.replaceColumnSelection(fTextDNDColumnSelection, ""); //$NON-NLS-1$ >+// st.replaceColumnSelection(newSelection, text); >+// st.setColumnSelection(newSelection.x, newSelection.y, newSelection.x + fTextDNDColumnSelection.width - fTextDNDColumnSelection.x, newSelection.y + fTextDNDColumnSelection.height - fTextDNDColumnSelection.y); >+// } else { >+// Point newSelection= st.getSelection(); >+// st.insert(text); >+// IDocument document= getDocumentProvider().getDocument(getEditorInput()); >+// int startLine= st.getLineAtOffset(newSelection.x); >+// int startColumn= newSelection.x - st.getOffsetAtLine(startLine); >+// int endLine= startLine + document.computeNumberOfLines(text); >+// int endColumn= startColumn + TextUtilities.indexOf(document.getLegalLineDelimiters(), text, 0)[0]; >+// st.setColumnSelection(startColumn, startLine, endColumn, endLine); >+// } >+ } else { >+ Point newSelection= st.getSelection(); >+ try { >+ int modelOffset= widgetOffset2ModelOffset(viewer, newSelection.x); >+ viewer.getDocument().replace(modelOffset, 0, text); >+ } catch (BadLocationException e) { >+ return; >+ } >+ st.setSelectionRange(newSelection.x, text.length()); > } >- st.setSelectionRange(newSelection.x, text.length()); > } finally { > fTextDragAndDropToken= null; >+// fTextDNDColumnSelection= null; > } > } > }; >@@ -3660,15 +3712,27 @@ > if (font == null) > font= JFaceResources.getTextFont(); > >- setFont(viewer, font); >+ if (!font.equals(fSourceViewer.getTextWidget().getFont())) { >+ setFont(viewer, font); >+ >+ disposeFont(); >+ if (!isSharedFont) >+ fFont= font; >+ } else if (!isSharedFont) { >+ font.dispose(); >+ } >+ } > >+ /** >+ * Disposes of the non-shared font. >+ * >+ * @since 3.5 >+ */ >+ private void disposeFont() { > if (fFont != null) { > fFont.dispose(); > fFont= null; > } >- >- if (!isSharedFont) >- fFont= font; > } > > /** >@@ -3681,7 +3745,8 @@ > private void setFont(ISourceViewer sourceViewer, Font font) { > if (sourceViewer.getDocument() != null) { > >- Point selection= sourceViewer.getSelectedRange(); >+ ISelectionProvider provider= sourceViewer.getSelectionProvider(); >+ ISelection selection= provider.getSelection(); > int topIndex= sourceViewer.getTopIndex(); > > StyledText styledText= sourceViewer.getTextWidget(); >@@ -3700,7 +3765,7 @@ > e.setFont(font); > } > >- sourceViewer.setSelectedRange(selection.x , selection.y); >+ provider.setSelection(selection); > sourceViewer.setTopIndex(topIndex); > > if (parent instanceof Composite) { >@@ -4160,10 +4225,7 @@ > fTitleImage= null; > } > >- if (fFont != null) { >- fFont.dispose(); >- fFont= null; >- } >+ disposeFont(); > > disposeNonDefaultCaret(); > fInitialCaret= null; >@@ -4365,8 +4427,7 @@ > } > > /** >- * Returns the property preference key for the editor font. Subclasses may >- * replace this method. >+ * Returns the property preference key for the editor font. > * > * @return a String with the key > * @since 2.1 >@@ -5706,6 +5767,10 @@ > action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_INFORMATION); > setAction(ITextEditorActionConstants.SHOW_INFORMATION, action); > >+ action= new ColumnModeToggleAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ToggleColumnMode.", this); //$NON-NLS-1$ >+ action.setHelpContextId(IAbstractTextEditorHelpContextIds.COLUMN_MODE_ACTION); >+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.COLUMN_MODE); >+ setAction(ITextEditorActionConstants.COLUMN_MODE, action); > > PropertyDialogAction openProperties= new PropertyDialogAction( > new IShellProvider() { >@@ -7004,6 +7069,18 @@ > } > } > >+ /** >+ * Enables column (aka rectangular) selection mode in the editor. Column selection mode is >+ * disabled by default for compatibility, but editor implementors may enable it. >+ * >+ * @param enable the new column mode state >+ * @see #supportsColumnSelection() >+ * @since 3.5 >+ */ >+ protected final void enableColumnSelectionMode(boolean enable) { >+ fEnableColumnMode= enable; >+ } >+ > //---- Tabs to spaces conversion support ------------------ > > /** >@@ -7069,4 +7146,75 @@ > } > } > >+ /* >+ * @see org.eclipse.ui.texteditor.ITextEditorExtension5#supportsColumnSelection() >+ * @since 3.3 >+ */ >+ public final boolean supportsColumnSelection() { >+ return fEnableColumnMode; >+ } >+ >+ /* >+ * @see org.eclipse.ui.texteditor.ITextEditorExtension5#isColumnMode() >+ * @since 3.3 >+ */ >+ public final boolean isColumnMode() { >+ if (supportsColumnSelection()) { >+ ISourceViewer viewer= getSourceViewer(); >+ if (viewer != null) { >+ StyledText styledText= viewer.getTextWidget(); >+ if (styledText != null) >+ return styledText.getBlockSelection(); >+ } >+ } >+ return false; >+ } >+ >+ /* >+ * @see org.eclipse.ui.texteditor.ITextEditorExtension5#setColumnMode(boolean) >+ * @since 3.3 >+ */ >+ public void setColumnMode(boolean enable) { >+ if (supportsColumnSelection()) { >+ ISourceViewer viewer= getSourceViewer(); >+ if (viewer != null) { >+ StyledText styledText= viewer.getTextWidget(); >+ if (styledText != null) { >+ /* >+ * Font switching. Column mode needs a monospace font. We try to adapt the >+ * column font size to the current (normal) font size. >+ * - set the font _before enabling_ column mode in order to maintain the >+ * selection >+ * - revert the font _after disabling_ column mode in order to maintain the >+ * selection >+ */ >+ if (enable) { >+ Font columnFont= JFaceResources.getFont(COLUMN_MODE_FONT); >+ Font normalFont= styledText.getFont(); >+ if (!columnFont.equals(normalFont) && !normalFont.getFontData()[0].equals(columnFont.getFontData()[0])) { >+ int size= normalFont.getFontData()[0].getHeight(); >+ FontData[] fontData= columnFont.getFontData(); >+ boolean created= false; >+ if (fontData[0].getHeight() != size) { >+ for (int i= 0; i < fontData.length; i++) { >+ fontData[i].setHeight(size); >+ } >+ columnFont= new Font(columnFont.getDevice(), fontData); >+ created= true; >+ } >+ setFont(viewer, columnFont); >+ disposeFont(); >+ if (created) >+ fFont= columnFont; >+ } >+ } >+ >+ styledText.setBlockSelection(enable); >+ >+ if (!enable) >+ initializeViewerFont(viewer); >+ } >+ } >+ } >+ } > } >Index: src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java,v >retrieving revision 1.44 >diff -u -r1.44 ITextEditorActionConstants.java >--- src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java 24 Nov 2008 16:15:52 -0000 1.44 >+++ src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java 25 Nov 2008 21:13:17 -0000 >@@ -664,4 +664,11 @@ > * @since 3.3 > */ > String SHOW_INFORMATION= "ShowInformation"; //$NON-NLS-1$ >+ >+ /** >+ * Name of the action for toggling column mode. >+ * Value: <code>"ColumnMode"</code> >+ * @since 3.5 >+ */ >+ String COLUMN_MODE = "ColumnMode"; //$NON-NLS-1$ > } >Index: src/org/eclipse/ui/texteditor/CaseAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/CaseAction.java,v >retrieving revision 1.12 >diff -u -r1.12 CaseAction.java >--- src/org/eclipse/ui/texteditor/CaseAction.java 16 Jul 2008 12:03:42 -0000 1.12 >+++ src/org/eclipse/ui/texteditor/CaseAction.java 25 Nov 2008 21:13:16 -0000 >@@ -14,10 +14,15 @@ > import java.util.ResourceBundle; > > import org.eclipse.swt.custom.StyledText; >-import org.eclipse.swt.graphics.Point; >+ > > import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.IColumnTextSelection; > import org.eclipse.jface.text.IDocument; >+import org.eclipse.jface.text.IRegion; >+import org.eclipse.jface.text.ITextSelection; >+import org.eclipse.jface.text.ITextViewerExtension; >+import org.eclipse.jface.text.SelectionProcessor; > import org.eclipse.jface.text.source.ISourceViewer; > > /** >@@ -71,45 +76,39 @@ > if (st == null) > return; > >- Point sel= viewer.getSelectedRange(); >- if (sel == null) >- return; >+ ITextSelection selection= (ITextSelection) viewer.getSelectionProvider().getSelection(); >+ SelectionProcessor processor= new SelectionProcessor(viewer); > >+ int adjustment= 0; > try { >- // if the selection is empty, we select the word / string using the viewer's >- // double-click strategy >- if (sel.y == 0) { >- >- // TODO find a better way to do this although there are multiple partitionings on a single document >- >-// String partition= getContentType(viewer, document, sel.x); >-// SourceViewerConfiguration svc= fEditor.getSourceViewerConfiguration(); // never null when viewer instantiated >-// ITextDoubleClickStrategy dcs= svc.getDoubleClickStrategy(viewer, partition); >-// if (dcs != null) { >-// dcs.doubleClicked(viewer); >-// sel= viewer.getSelectedRange(); >-// } >- >- if (sel.y == 0) >- return; // if the selection is still empty, we're done >+ if (processor.isEmpty(selection)) >+ return; >+ >+ IRegion[] ranges= processor.getRanges(selection); >+ if (ranges.length > 1 && viewer instanceof ITextViewerExtension) >+ ((ITextViewerExtension) viewer).getRewriteTarget().beginCompoundChange(); >+ for (int i= 0; i < ranges.length; i++) { >+ IRegion region= ranges[i]; >+ String target= document.get(region.getOffset(), region.getLength()); >+ String replacement= (fToUpper ? target.toUpperCase() : target.toLowerCase()); >+ if (!target.equals(replacement)) { >+ document.replace(region.getOffset(), region.getLength(), replacement); >+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=145326: replacement might be larger than the original >+ adjustment= replacement.length() - target.length(); >+ } > } >- >- String target= document.get(sel.x, sel.y); >- String replacement= (fToUpper ? target.toUpperCase() : target.toLowerCase()); >- if (!target.equals(replacement)) { >- document.replace(sel.x, target.length(), replacement); >- // https://bugs.eclipse.org/bugs/show_bug.cgi?id=145326: replacement might be larger than the original >- int adjustment= replacement.length() - target.length(); >- if (adjustment > 0) >- sel.y += adjustment; >- } >+ if (ranges.length > 1 && viewer instanceof ITextViewerExtension) >+ ((ITextViewerExtension) viewer).getRewriteTarget().endCompoundChange(); > } catch (BadLocationException x) { > // ignore and return > return; > } > > // reinstall selection and move it into view >- viewer.setSelectedRange(sel.x, sel.y); >+ if (!(selection instanceof IColumnTextSelection)) >+ viewer.setSelectedRange(selection.getOffset(), selection.getLength() + adjustment); >+ else >+ viewer.getSelectionProvider().setSelection(selection); > // don't use the viewer's reveal feature in order to avoid jumping around > st.showSelection(); > } >Index: src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java,v >retrieving revision 1.35 >diff -u -r1.35 IAbstractTextEditorHelpContextIds.java >--- src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java 24 Nov 2008 16:15:52 -0000 1.35 >+++ src/org/eclipse/ui/texteditor/IAbstractTextEditorHelpContextIds.java 25 Nov 2008 21:13:17 -0000 >@@ -10,6 +10,7 @@ > * Genady Beryozkin, me@genady.org - https://bugs.eclipse.org/bugs/show_bug.cgi?id=11668 > * Benjamin Muskalla <b.muskalla@gmx.net> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=41573 > * Dakshinamurthy Karra (Jalian Systems) - Templates View - https://bugs.eclipse.org/bugs/show_bug.cgi?id=69581 >+ * Tom Eicher (Avaloq Evolution AG) - column mode > *******************************************************************************/ > package org.eclipse.ui.texteditor; > >@@ -387,4 +388,11 @@ > * @since 3.4 > */ > String TEMPLATES_VIEW= PREFIX + "templates_view_context";//$NON-NLS-1$ >+ >+ /** >+ * Help context id for the column mode toggle action. >+ * Value: <code>"column_mode_context_action_context"</code> >+ * @since 3.5 >+ */ >+ String COLUMN_MODE_ACTION=PREFIX + "column_mode" + ACTION_POSTFIX; //$NON-NLS-1$ > } >Index: src/org/eclipse/ui/texteditor/MoveLinesAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/MoveLinesAction.java,v >retrieving revision 1.21 >diff -u -r1.21 MoveLinesAction.java >--- src/org/eclipse/ui/texteditor/MoveLinesAction.java 11 Sep 2008 11:58:02 -0000 1.21 >+++ src/org/eclipse/ui/texteditor/MoveLinesAction.java 25 Nov 2008 21:13:18 -0000 >@@ -13,7 +13,6 @@ > import java.util.ResourceBundle; > > import org.eclipse.swt.custom.StyledText; >-import org.eclipse.swt.graphics.Point; > import org.eclipse.swt.widgets.Event; > > import org.eclipse.core.runtime.Assert; >@@ -291,12 +290,10 @@ > return; > > // get selection >- Point p= fTextViewer.getSelectedRange(); >- if (p == null) >+ ITextSelection sel= (ITextSelection) fTextViewer.getSelectionProvider().getSelection(); >+ if (sel.isEmpty()) > return; > >- ITextSelection sel= new TextSelection(document, p.x, p.y); >- > ITextSelection skippedLine= getSkippedLine(document, sel); > if (skippedLine == null) > return; >Index: plugin.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/plugin.properties,v >retrieving revision 1.47 >diff -u -r1.47 plugin.properties >--- plugin.properties 15 Mar 2007 10:25:00 -0000 1.47 >+++ plugin.properties 25 Nov 2008 21:13:12 -0000 >@@ -32,6 +32,10 @@ > showInformation.name= Show Tooltip Description > showInformation.description= Displays information for the current caret location in a sticky hover > >+toggleColumnMode.label= Toggle Column Mode >+toggleColumnMode.tooltip= Toggle Column Selection Mode >+toggleColumnMode.description= Enable rectangular / column selection in the current text editor >+ > smartEnter.label= Insert Line Below Current Line > smartEnter.description= Adds a new line below the current line > smartEnterInverse.label= Insert Line Above Current Line >@@ -169,3 +173,5 @@ > > SpellingEngine= Spelling Engine > >+columnModeFont.label= Column Mode Editor Font >+columnModeFont.description= The column mode font is used by text editors in column mode. A monospace font should be used. >Index: plugin.xml >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench.texteditor/plugin.xml,v >retrieving revision 1.91 >diff -u -r1.91 plugin.xml >--- plugin.xml 2 May 2007 20:23:35 -0000 1.91 >+++ plugin.xml 25 Nov 2008 21:13:12 -0000 >@@ -399,6 +399,12 @@ > categoryId="org.eclipse.ui.category.window" > id="org.eclipse.ui.edit.text.toggleShowSelectedElementOnly"> > </command> >+ <command >+ name="%toggleColumnMode.label" >+ description="%toggleColumnMode.description" >+ categoryId="org.eclipse.ui.category.window" >+ id="org.eclipse.ui.edit.text.toggleColumnMode"> >+ </command> > <command > name="%command.toggleInsertMode.name" > description="%command.toggleInsertMode.description" >@@ -763,6 +769,11 @@ > commandId="org.eclipse.ui.edit.text.showInformation" > schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/> > <key >+ commandId="org.eclipse.ui.edit.text.toggleColumnMode" >+ contextId="org.eclipse.ui.textEditorScope" >+ sequence="M3+C" >+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/> >+ <key > commandId="org.eclipse.ui.edit.text.hippieCompletion" > contextId="org.eclipse.ui.textEditorScope" > sequence="M3+/" >@@ -1100,6 +1111,47 @@ > toolbarPath="Normal/Presentation" > tooltip="%showWhitespaceCharacters.tooltip"> > </action> >+ <action >+ allowLabelUpdate="true" >+ definitionId="org.eclipse.ui.edit.text.toggleColumnMode" >+ disabledIcon="$nl$/icons/full/dtool16/column_mode.gif" >+ helpContextId="column_mode_action_context" >+ hoverIcon="$nl$/icons/full/ctool16/column_mode.gif" >+ icon="$nl$/icons/full/etool16/column_mode.gif" >+ id="org.eclipse.ui.edit.text.toggleColumnMode" >+ label="%toggleColumnMode.label" >+ retarget="true" >+ style="toggle" >+ toolbarPath="Normal/Presentation" >+ tooltip="%toggleColumnMode.tooltip"> >+ </action> > </actionSet> > </extension> >+ <extension >+ point="org.eclipse.ui.themes"> >+ <fontDefinition >+ categoryId="org.eclipse.ui.workbenchMisc" >+ id="org.eclipse.ui.workbench.texteditor.columnModeFont" >+ isEditable="true" >+ label="%columnModeFont.label" >+ value="Courier New-regular-10"> >+ <description> >+ %columnModeFont.description >+ </description> >+ <fontValue >+ os="linux" >+ value="Monospace-regular-10" >+ ws="gtk"> >+ </fontValue> >+ <fontValue >+ os="win32" >+ value="Courier New-regular-10" >+ > >+ </fontValue> >+ <fontValue >+ os="macosx" >+ value="Monaco-regular-11"> >+ </fontValue> >+ </fontDefinition> >+ </extension> > </plugin> >Index: src/org/eclipse/ui/texteditor/IDeleteLineTargetExtension.java >=================================================================== >RCS file: src/org/eclipse/ui/texteditor/IDeleteLineTargetExtension.java >diff -N src/org/eclipse/ui/texteditor/IDeleteLineTargetExtension.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/texteditor/IDeleteLineTargetExtension.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,38 @@ >+/******************************************************************************* >+ * Copyright (c) 2008 Tom Eicher 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: >+ * Tom Eicher - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.texteditor; >+ >+import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.IDocument; >+import org.eclipse.jface.text.ITextSelection; >+ >+/** >+ * Defines the target for finding and replacing strings. >+ * <p> >+ * Clients can implements that interface or use the provided default >+ * implementation {@link TextViewerDeleteLineTarget}. >+ * </p> >+ * >+ * @since 3.5 >+ */ >+public interface IDeleteLineTargetExtension { >+ /** >+ * Deletes the specified fraction of the line of the given offset. >+ * >+ * @param document the document >+ * @param selection the selection >+ * @param type the line deletion type, must be one of >+ * <code>WHOLE_LINE</code>, <code>TO_BEGINNING</code> or <code>TO_END</code> >+ * @param copyToClipboard <code>true</code> if the deleted line should be copied to the clipboard >+ * @throws BadLocationException if position is not valid in the given document >+ */ >+ void deleteLine(IDocument document, ITextSelection selection, int type, boolean copyToClipboard) throws BadLocationException; >+} >Index: src/org/eclipse/ui/texteditor/ITextEditorExtension5.java >=================================================================== >RCS file: src/org/eclipse/ui/texteditor/ITextEditorExtension5.java >diff -N src/org/eclipse/ui/texteditor/ITextEditorExtension5.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/texteditor/ITextEditorExtension5.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,55 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Tom Eicher (Avaloq Evolution AG) - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.ui.texteditor; >+ >+ >+/** >+ * Extension interface for {@link org.eclipse.ui.texteditor.ITextEditor}. Adds the following >+ * functions: >+ * <ul> >+ * <li>column mode</li> >+ * </ul> >+ * <p> >+ * This interface may be implemented by clients. >+ * </p> >+ * >+ * @since 3.5 >+ */ >+public interface ITextEditorExtension5 { >+ >+ /** >+ * Returns <code>true</code> if the receiver supports column (aka rectangular) selections, >+ * <code>false</code> otherwise. >+ * >+ * @return <code>true</code> if the receiver supports column mode >+ */ >+ boolean supportsColumnSelection(); >+ >+ /** >+ * Returns <code>true</code> if the receiver is in column (aka rectangular) selection mode, >+ * <code>false</code> otherwise. If the receiver does not >+ * {@linkplain #supportsColumnSelection() support} column mode at all, <code>false</code> is >+ * returned. >+ * >+ * @return the receiver's column selection state >+ */ >+ boolean isColumnMode(); >+ >+ /** >+ * Sets the column mode state of the receiver to <code>enable</code>. Nothing happens if the >+ * receiver does not {@linkplain #supportsColumnSelection() support} column mode or already is >+ * in the requested state. >+ * >+ * @param enable the new column selection state >+ */ >+ void setColumnMode(boolean enable); >+} >Index: src/org/eclipse/ui/texteditor/ColumnModeToggleAction.java >=================================================================== >RCS file: src/org/eclipse/ui/texteditor/ColumnModeToggleAction.java >diff -N src/org/eclipse/ui/texteditor/ColumnModeToggleAction.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/texteditor/ColumnModeToggleAction.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,69 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Tom Eicher (Avaloq Evolution AG) - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.ui.texteditor; >+ >+import java.util.ResourceBundle; >+ >+import org.eclipse.jface.action.IAction; >+ >+ >+/** >+ * This action toggles the column (aka rectangular) selection mode. >+ * <p> >+ * <em>This API is provisional and may change any time before the 3.3 API freeze.</em> >+ * </p> >+ * >+ * @since 3.5 >+ */ >+final class ColumnModeToggleAction extends TextEditorAction { >+ >+ /** >+ * Construct the action and initialize its state. >+ * >+ * @param resourceBundle the resource bundle to construct label and tooltip from >+ * @param prefix the prefix to use for constructing resource bundle keys >+ * @param editor the editor this action is associated with >+ */ >+ public ColumnModeToggleAction(ResourceBundle resourceBundle, String prefix, ITextEditor editor) { >+ super(resourceBundle, prefix, editor, IAction.AS_CHECK_BOX); >+ } >+ >+ /* >+ * @see org.eclipse.jface.action.Action#run() >+ */ >+ public void run() { >+ ITextEditor editor= getTextEditor(); >+ if (editor instanceof ITextEditorExtension5) { >+ ITextEditorExtension5 ext5= (ITextEditorExtension5) editor; >+ if (ext5.supportsColumnSelection()) { >+ ext5.setColumnMode(!ext5.isColumnMode()); >+ } >+ } >+ update(); // update in case anyone else has directly accessed the widget >+ } >+ >+ /* >+ * @see org.eclipse.ui.texteditor.TextEditorAction#update() >+ */ >+ public void update() { >+ ITextEditor editor= getTextEditor(); >+ if (editor instanceof ITextEditorExtension5) { >+ ITextEditorExtension5 ext5= (ITextEditorExtension5) editor; >+ if (ext5.supportsColumnSelection()) { >+ setEnabled(true); >+ setChecked(ext5.isColumnMode()); >+ return; >+ } >+ } >+ setEnabled(false); >+ setChecked(false); >+ } >+} >#P org.eclipse.ui.editors >Index: src/org/eclipse/ui/editors/text/TextEditor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/TextEditor.java,v >retrieving revision 1.61 >diff -u -r1.61 TextEditor.java >--- src/org/eclipse/ui/editors/text/TextEditor.java 11 Sep 2008 12:00:15 -0000 1.61 >+++ src/org/eclipse/ui/editors/text/TextEditor.java 25 Nov 2008 21:13:20 -0000 >@@ -75,6 +75,7 @@ > setHelpContextId(ITextEditorHelpContextIds.TEXT_EDITOR); > configureInsertMode(SMART_INSERT, false); > setInsertMode(INSERT); >+ enableColumnSelectionMode(true); > } > > /* >#P org.eclipse.jface.text >Index: src/org/eclipse/jface/text/source/SourceViewer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java,v >retrieving revision 1.84 >diff -u -r1.84 SourceViewer.java >--- src/org/eclipse/jface/text/source/SourceViewer.java 11 Sep 2008 11:58:24 -0000 1.84 >+++ src/org/eclipse/jface/text/source/SourceViewer.java 25 Nov 2008 21:13:25 -0000 >@@ -27,8 +27,10 @@ > import org.eclipse.jface.text.AbstractHoverInformationControlManager; > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.BadPositionCategoryException; >+import org.eclipse.jface.text.ColumnTextSelection; > import org.eclipse.jface.text.DocumentRewriteSession; > import org.eclipse.jface.text.DocumentRewriteSessionType; >+import org.eclipse.jface.text.IColumnTextSelection; > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.IDocumentExtension4; > import org.eclipse.jface.text.IPositionUpdater; >@@ -36,6 +38,7 @@ > import org.eclipse.jface.text.IRewriteTarget; > import org.eclipse.jface.text.ISlaveDocumentManager; > import org.eclipse.jface.text.ISlaveDocumentManagerExtension; >+import org.eclipse.jface.text.ITextSelection; > import org.eclipse.jface.text.ITextViewerExtension2; > import org.eclipse.jface.text.Position; > import org.eclipse.jface.text.Region; >@@ -715,6 +718,20 @@ > } > > /** >+ * Position storing column 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; >+ } >+ } >+ >+ /** > * Remembers and returns the current selection. The saved selection can be restored > * by calling <code>restoreSelection()</code>. > * >@@ -724,7 +741,7 @@ > */ > protected Point rememberSelection() { > >- final Point selection= getSelectedRange(); >+ final ITextSelection selection= (ITextSelection) getSelection(); > final IDocument document= getDocument(); > > if (fSelections.isEmpty()) { >@@ -735,8 +752,11 @@ > } > > try { >- >- final Position position= new Position(selection.x, selection.y); >+ final Position position; >+ if (selection instanceof IColumnTextSelection) >+ position= new ColumnPosition(selection.getOffset(), selection.getLength(), ((IColumnTextSelection) selection).getStartColumn(), ((IColumnTextSelection) selection).getEndColumn()); >+ else >+ position= new Position(selection.getOffset(), selection.getLength()); > document.addPosition(fSelectionCategory, position); > fSelections.push(position); > >@@ -746,7 +766,7 @@ > // Should not happen > } > >- return selection; >+ return new Point(selection.getOffset(), selection.getLength()); > } > > /** >@@ -766,13 +786,20 @@ > try { > document.removePosition(fSelectionCategory, position); > Point currentSelection= getSelectedRange(); >- if (currentSelection == null || currentSelection.x != position.getOffset() || currentSelection.y != position.getLength()) >- setSelectedRange(position.getOffset(), position.getLength()); >+ if (currentSelection == null || currentSelection.x != position.getOffset() || currentSelection.y != position.getLength()) { >+ if (position instanceof ColumnPosition && getTextWidget().getBlockSelection()) { >+ setSelection(new ColumnTextSelection(document, document.getLineOfOffset(position.getOffset()), ((ColumnPosition) position).fStartColumn, document.getLineOfOffset(position.getOffset() + position.getLength()), ((ColumnPosition) position).fEndColumn, getTextWidget().getTabs())); >+ } else { >+ setSelectedRange(position.getOffset(), position.getLength()); >+ } >+ } > > if (fSelections.isEmpty()) > clearRememberedSelection(); > } catch (BadPositionCategoryException exception) { > // Should not happen >+ } catch (BadLocationException x) { >+ // Should not happen > } > } > } >Index: src/org/eclipse/jface/text/TextViewer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java,v >retrieving revision 1.202 >diff -u -r1.202 TextViewer.java >--- src/org/eclipse/jface/text/TextViewer.java 15 Oct 2008 08:18:05 -0000 1.202 >+++ src/org/eclipse/jface/text/TextViewer.java 25 Nov 2008 21:13:24 -0000 >@@ -2409,6 +2409,16 @@ > * @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) { > ITextSelection s= (ITextSelection) selection; > setSelectedRange(s.getOffset(), s.getLength()); >@@ -2421,6 +2431,28 @@ > * @see Viewer#getSelection() > */ > public ISelection getSelection() { >+ if (redraws() && fTextWidget != null && fTextWidget.getBlockSelection()) { >+ int[] ranges= fTextWidget.getSelectionRanges(); >+ int startOffset= ranges[0]; >+ int endOffset= ranges[ranges.length - 2] + ranges[ranges.length - 1]; >+ >+ IDocument document= getDocument(); >+ startOffset= widgetOffset2ModelOffset(startOffset); >+ endOffset= widgetOffset2ModelOffset(endOffset); >+ try { >+ int startLine= document.getLineOfOffset(startOffset); >+ int endLine= document.getLineOfOffset(endOffset); >+ >+ int startColumn= startOffset - document.getLineOffset(startLine); >+ int endColumn= endOffset - document.getLineOffset(endLine); >+ if (startLine == -1 || endLine == -1) >+ return TextSelection.emptySelection(); >+ return new ColumnTextSelection(document, startLine, startColumn, endLine, endColumn, fTextWidget.getTabs()); >+ } catch (BadLocationException e) { >+ return TextSelection.emptySelection(); >+ } >+ } >+ > Point p= getSelectedRange(); > if (p.x == -1 || p.y == -1) > return TextSelection.emptySelection(); >@@ -3956,13 +3988,15 @@ > * @return the region describing the text block comprising the given selection > * @since 2.0 > */ >- private IRegion getTextBlockFromSelection(Point selection) { >+ private IRegion getTextBlockFromSelection(ITextSelection selection) { > > try { > IDocument document= getDocument(); >- IRegion line= document.getLineInformationOfOffset(selection.x); >- int length= selection.y == 0 ? line.getLength() : selection.y + (selection.x - line.getOffset()); >- return new Region(line.getOffset(), length); >+ int start= document.getLineOffset(selection.getStartLine()); >+ int endLine= selection.getEndLine(); >+ IRegion endLineInfo= document.getLineInformation(endLine); >+ int end= endLineInfo.getOffset() + endLineInfo.getLength(); >+ return new Region(start, end - start); > > } catch (BadLocationException x) { > } >@@ -4001,7 +4035,7 @@ > Map partitioners= null; > DocumentRewriteSession rewriteSession= null; > try { >- Point selection= getSelectedRange(); >+ ITextSelection selection= (ITextSelection) getSelection(); > IRegion block= getTextBlockFromSelection(selection); > ITypedRegion[] regions= TextUtilities.computePartitioning(d, getDocumentPartitioning(), block.getOffset(), block.getLength(), false); > >Index: src/org/eclipse/jface/text/CursorLinePainter.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/CursorLinePainter.java,v >retrieving revision 1.21 >diff -u -r1.21 CursorLinePainter.java >--- src/org/eclipse/jface/text/CursorLinePainter.java 11 Sep 2008 11:58:23 -0000 1.21 >+++ src/org/eclipse/jface/text/CursorLinePainter.java 25 Nov 2008 21:13:22 -0000 >@@ -77,7 +77,7 @@ > int caret= textWidget.getCaretOffset(); > int length= event.lineText.length(); > >- if (event.lineOffset <= caret && caret <= event.lineOffset + length) >+ if (event.lineOffset <= caret && caret <= event.lineOffset + length && !hasMultiLineSelection(textWidget)) > event.lineBackground= fHighlightColor; > else > event.lineBackground= textWidget.getBackground(); >@@ -223,10 +223,7 @@ > StyledText textWidget= fViewer.getTextWidget(); > > // check selection >- Point selection= textWidget.getSelection(); >- int startLine= textWidget.getLineAtOffset(selection.x); >- int endLine= textWidget.getLineAtOffset(selection.y); >- if (startLine != endLine) { >+ if (hasMultiLineSelection(textWidget)) { > deactivate(true); > return; > } >@@ -247,6 +244,22 @@ > } > } > >+ /** >+ * Returns <code>true</code> if the widget has a selection spanning multiple lines, >+ * <code>false</code> otherwise. >+ * >+ * @param textWidget the text widget to check >+ * @return <code>true</code> if <code>textWidget</code> has a multiline selection, >+ * <code>false</code> otherwise >+ * @since 3.5 >+ */ >+ private boolean hasMultiLineSelection(StyledText textWidget) { >+ Point selection= textWidget.getSelection(); >+ int startLine= textWidget.getLineAtOffset(selection.x); >+ int endLine= textWidget.getLineAtOffset(selection.y); >+ return startLine != endLine; >+ } >+ > /* > * @see IPainter#setPositionManager(IPaintPositionManager) > */ >Index: src/org/eclipse/jface/text/WhitespaceCharacterPainter.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/WhitespaceCharacterPainter.java,v >retrieving revision 1.11 >diff -u -r1.11 WhitespaceCharacterPainter.java >--- src/org/eclipse/jface/text/WhitespaceCharacterPainter.java 11 Sep 2008 11:58:23 -0000 1.11 >+++ src/org/eclipse/jface/text/WhitespaceCharacterPainter.java 25 Nov 2008 21:13:25 -0000 >@@ -229,7 +229,6 @@ > String text= content.getTextRange(startOffset, length); > StyleRange styleRange= null; > Color fg= null; >- Point selection= fTextWidget.getSelection(); > StringBuffer visibleChar= new StringBuffer(10); > for (int textOffset= 0; textOffset <= length; ++textOffset) { > int delta= 0; >@@ -270,7 +269,7 @@ > if (visibleChar.length() > 0) { > int widgetOffset= startOffset + textOffset - visibleChar.length() + delta; > if (!eol || !isFoldedLine(content.getLineAtOffset(widgetOffset))) { >- if (widgetOffset >= selection.x && widgetOffset < selection.y) { >+ if (isOffsetSelected(fTextWidget, widgetOffset)) { > fg= fTextWidget.getSelectionForeground(); > } else if (styleRange == null || styleRange.start + styleRange.length <= widgetOffset) { > styleRange= fTextWidget.getStyleRangeAtOffset(widgetOffset); >@@ -286,6 +285,15 @@ > } > } > } >+ >+ private static final boolean isOffsetSelected(StyledText widget, int offset) { >+ int[] ranges= widget.getSelectionRanges(); >+ for (int i= 0; i < ranges.length; i+=2) { >+ if (ranges[i] <= offset && offset <= ranges[i+1]) >+ return true; >+ } >+ return false; >+ } > > /** > * Check if the given widget line is a folded line. >Index: projection/org/eclipse/jface/text/source/projection/ProjectionViewer.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/projection/org/eclipse/jface/text/source/projection/ProjectionViewer.java,v >retrieving revision 1.103 >diff -u -r1.103 ProjectionViewer.java >--- projection/org/eclipse/jface/text/source/projection/ProjectionViewer.java 2 Oct 2008 15:40:41 -0000 1.103 >+++ projection/org/eclipse/jface/text/source/projection/ProjectionViewer.java 25 Nov 2008 21:13:22 -0000 >@@ -14,6 +14,8 @@ > import java.util.Iterator; > import java.util.List; > >+import org.eclipse.core.runtime.Assert; >+ > import org.eclipse.swt.SWTError; > import org.eclipse.swt.custom.ST; > import org.eclipse.swt.custom.StyledText; >@@ -26,7 +28,6 @@ > import org.eclipse.swt.widgets.Composite; > import org.eclipse.swt.widgets.Display; > >-import org.eclipse.core.runtime.Assert; > > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.DocumentEvent; >@@ -36,9 +37,12 @@ > import org.eclipse.jface.text.IDocumentListener; > import org.eclipse.jface.text.IRegion; > import org.eclipse.jface.text.ISlaveDocumentManager; >+import org.eclipse.jface.text.ITextSelection; > import org.eclipse.jface.text.ITextViewerExtension5; > import org.eclipse.jface.text.Position; > import org.eclipse.jface.text.Region; >+import org.eclipse.jface.text.SelectionProcessor; >+import org.eclipse.jface.text.TextSelection; > import org.eclipse.jface.text.TextUtilities; > import org.eclipse.jface.text.projection.ProjectionDocument; > import org.eclipse.jface.text.projection.ProjectionDocumentEvent; >@@ -1443,34 +1447,31 @@ > if (textWidget == null) > return; > >- Point selection= null; >+ ITextSelection selection= null; > switch (operation) { > > case CUT: > > if (redraws()) { >- selection= getSelectedRange(); >- if (exposeModelRange(new Region(selection.x, selection.y))) >- return; >- >- if (selection.y == 0) >+ selection= (ITextSelection) getSelection(); >+ if (selection.getLength() == 0) > copyMarkedRegion(true); > else >- copyToClipboard(selection.x, selection.y, true, textWidget); >+ copyToClipboard(selection, true, textWidget); > >- selection= textWidget.getSelectionRange(); >- fireSelectionChanged(selection.x, selection.y); >+ Point range= textWidget.getSelectionRange(); >+ fireSelectionChanged(range.x, range.y); > } > break; > > case COPY: > > if (redraws()) { >- selection= getSelectedRange(); >- if (selection.y == 0) >+ selection= (ITextSelection) getSelection(); >+ if (selection.getLength() == 0) > copyMarkedRegion(false); > else >- copyToClipboard(selection.x, selection.y, false, textWidget); >+ copyToClipboard(selection, false, textWidget); > } > break; > >@@ -1478,15 +1479,15 @@ > > if (redraws()) { > try { >- selection= getSelectedRange(); >+ selection= (ITextSelection) getSelection(); > Point widgetSelection= textWidget.getSelectionRange(); >- if (selection.y == 0 || selection.y == widgetSelection.y) >+ if (selection.getLength() == widgetSelection.y) > getTextWidget().invokeAction(ST.DELETE_NEXT); > else >- deleteTextRange(selection.x, selection.y, textWidget); >+ deleteSelection(selection, textWidget); > >- selection= textWidget.getSelectionRange(); >- fireSelectionChanged(selection.x, selection.y); >+ Point range= textWidget.getSelectionRange(); >+ fireSelectionChanged(range.x, range.y); > > } catch (BadLocationException x) { > // ignore >@@ -1567,21 +1568,14 @@ > protected void copyMarkedRegion(boolean delete) { > IRegion markedRegion= getMarkedRegion(); > if (markedRegion != null) >- copyToClipboard(markedRegion.getOffset(), markedRegion.getLength(), delete, getTextWidget()); >+ copyToClipboard(new TextSelection(getDocument(), markedRegion.getOffset(), markedRegion.getLength()), delete, getTextWidget()); > } > >- private void copyToClipboard(int offset, int length, boolean delete, StyledText textWidget) { >- >- String copyText= null; >+ private void copyToClipboard(ITextSelection selection, boolean delete, StyledText textWidget) { > >- try { >- IDocument document= getDocument(); >- copyText= document.get(offset, length); >- } catch (BadLocationException ex) { >- // XXX: should log here, but JFace Text has no Log >- // As a fallback solution let the widget handle this >+ String copyText= selection.getText(); >+ if (copyText == null) // selection.getText failed - backup using widget > textWidget.copy(); >- } > > if (copyText != null && copyText.equals(textWidget.getSelectionText())) { > /* >@@ -1616,18 +1610,23 @@ > > if (delete) { > try { >- deleteTextRange(offset, length, textWidget); >+ deleteSelection(selection, textWidget); > } catch (BadLocationException x) { > // XXX: should log here, but JFace Text has no Log > } > } > } > >- private void deleteTextRange(int offset, int length, StyledText textWidget) throws BadLocationException { >- getDocument().replace(offset, length, ""); //$NON-NLS-1$ >- int widgetCaret= modelOffset2WidgetOffset(offset); >- if (widgetCaret > -1) >- textWidget.setSelection(widgetCaret); >+ /** >+ * Deletes the selection and sets the caret before the deleted range. >+ * >+ * @param selection the selection to delete >+ * @param textWidget the widget >+ * @throws BadLocationException on document access failure >+ * @since 3.5 >+ */ >+ private void deleteSelection(ITextSelection selection, StyledText textWidget) throws BadLocationException { >+ new SelectionProcessor(this).doDelete(selection); > } > > /** >Index: src/org/eclipse/jface/text/IColumnTextSelection.java >=================================================================== >RCS file: src/org/eclipse/jface/text/IColumnTextSelection.java >diff -N src/org/eclipse/jface/text/IColumnTextSelection.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/text/IColumnTextSelection.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,76 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Tom Eicher (Avaloq Evolution AG) - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jface.text; >+ >+/** >+ * A rectangular selection in a text document. A column selection spans the visually identical range >+ * of columns on a contiguous range of lines. The character count of the same visually perceived >+ * column may not be equal for two different lines, therefore computing the set of disjunct >+ * character ranges covered by a column selection is influenced by the used font and tabulator >+ * width. Using column selections with proportional fonts may render unexpected results. >+ * <h5><a name="virtual">Virtual Spaces</a></h5> >+ * The {@linkplain #getStartColumn() start column} and {@linkplain #getEndColumn() end column} may >+ * refer to "virtual offsets" in the white space beyond the end of the line. Such an >+ * offset can be realized by inserting a space for each missing character. >+ * <p> >+ * The {@linkplain ITextSelection#getOffset() offset} and >+ * {@linkplain ITextSelection#getLength() length} of an {@link IColumnTextSelection} refer to the >+ * smallest non-virtual range that comprises the entire rectangular selection. >+ * </p> >+ * <p> >+ * Clients may implement this interface or use the default implementation provided by >+ * {@link org.eclipse.jface.text.ColumnTextSelection}. >+ * </p> >+ * >+ * @see org.eclipse.jface.text.ColumnTextSelection >+ * @since 3.5 >+ */ >+public interface IColumnTextSelection extends ITextSelection { >+ /** >+ * Returns the column on the {@linkplain ITextSelection#getStartLine() start line} at which the >+ * selection starts. The returned column is a character count measured from the start of the >+ * line. It may be larger than the length of the line, in which case it is a <a >+ * href="#virtual">virtual</a> offset. >+ * >+ * @return the start column measured from the line start >+ */ >+ int getStartColumn(); >+ /** >+ * Returns the exclusive column on the {@linkplain ITextSelection#getEndLine() end line} at which the >+ * selection ends. The returned column is a character count measured from the start of the >+ * line. It may be larger than the length of the line, in which case it is a <a >+ * href="#virtual">virtual</a> offset. >+ * >+ * @return the end column measured from the line start >+ */ >+ int getEndColumn(); >+ /** >+ * {@inheritDoc} >+ * <p> >+ * The returned text does not necessarily correspond to the total >+ * {@linkplain ITextSelection#getOffset() offset} and {@link ITextSelection#getLength() length}, >+ * as only the text within the selected columns is returned. >+ * <p> >+ * Any <a href="#virtual">virtual</a> spaces beyond the end of the selected lines are >+ * materialized and returned as text. >+ * </p> >+ * >+ * @see org.eclipse.jface.text.ITextSelection#getText() >+ */ >+ String getText(); >+ /** >+ * Returns a non-empty array containing the selected text range for each line covered by the >+ * selection. >+ * >+ * @return an array containing a the covered text range for each line covered by the receiver >+ */ >+ IRegion[] getRegions(); >+} >Index: src/org/eclipse/jface/text/SelectionProcessor.java >=================================================================== >RCS file: src/org/eclipse/jface/text/SelectionProcessor.java >diff -N src/org/eclipse/jface/text/SelectionProcessor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/text/SelectionProcessor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,442 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Tom Eicher (Avaloq Evolution AG) - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jface.text; >+ >+import java.util.Arrays; >+ >+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.ReplaceEdit; >+import org.eclipse.text.edits.TextEdit; >+ >+import org.eclipse.core.runtime.Assert; >+ >+import org.eclipse.jface.viewers.ISelection; >+import org.eclipse.jface.viewers.ISelectionProvider; >+ >+import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.IDocument; >+import org.eclipse.jface.text.IRegion; >+import org.eclipse.jface.text.Region; >+import org.eclipse.jface.text.TextUtilities; >+ >+/** >+ * Processes {@link ITextSelection}s. >+ * >+ * @since 3.5 >+ * FIXME document >+ */ >+public final class SelectionProcessor { >+ private static class Implementation { >+ TextEdit replace(ISelection selection, String replacement) throws BadLocationException { >+ return new MultiTextEdit(); >+ } >+ >+ String getText(ISelection selection) throws BadLocationException { >+ return ""; //$NON-NLS-1$ >+ } >+ >+ boolean isEmpty(ISelection selection) throws BadLocationException { >+ return selection.isEmpty(); >+ } >+ >+ boolean isMultiline(ISelection selection) { >+ return false; >+ } >+ >+ TextEdit delete(ISelection selection) throws BadLocationException { >+ return replace(selection, ""); //$NON-NLS-1$ >+ } >+ >+ TextEdit backspace(ISelection selection) throws BadLocationException { >+ return replace(selection, ""); //$NON-NLS-1$ >+ } >+ >+ ISelection makeEmpty(ISelection selection) throws BadLocationException { >+ return selection; >+ } >+ >+ IRegion[] getRanges(ISelection selection) throws BadLocationException { >+ return new IRegion[0]; >+ } >+ } >+ >+ private final Implementation NULL_IMPLEMENTATION= new Implementation(); >+ >+ private final Implementation RANGE_IMPLEMENTATION= new Implementation() { >+ TextEdit replace(ISelection selection, String replacement) { >+ ITextSelection ts= (ITextSelection) selection; >+ return new ReplaceEdit(ts.getOffset(), ts.getLength(), replacement); >+ } >+ >+ String getText(ISelection selection) { >+ ITextSelection ts= (ITextSelection) selection; >+ return ts.getText(); >+ } >+ >+ boolean isEmpty(ISelection selection) { >+ ITextSelection ts= (ITextSelection) selection; >+ return ts.getLength() == 0; >+ } >+ >+ boolean isMultiline(ISelection selection) { >+ ITextSelection ts= (ITextSelection) selection; >+ return ts.getEndLine() > ts.getStartLine(); >+ } >+ >+ TextEdit delete(ISelection selection) throws BadLocationException { >+ ITextSelection ts= (ITextSelection) selection; >+ if (isEmpty(selection)) >+ return new DeleteEdit(ts.getOffset(), 1); >+ return new DeleteEdit(ts.getOffset(), ts.getLength()); >+ } >+ >+ TextEdit backspace(ISelection selection) throws BadLocationException { >+ ITextSelection ts= (ITextSelection) selection; >+ if (isEmpty(selection)) >+ return new DeleteEdit(ts.getOffset() - 1, 1); >+ return new DeleteEdit(ts.getOffset(), ts.getLength()); >+ } >+ >+ ISelection makeEmpty(ISelection selection) { >+ ITextSelection ts= (ITextSelection) selection; >+ return new TextSelection(fDocument, ts.getOffset(), 0); >+ } >+ >+ IRegion[] getRanges(ISelection selection) { >+ ITextSelection ts= (ITextSelection) selection; >+ return new IRegion[] { new Region(ts.getOffset(), ts.getLength()) }; >+ } >+ }; >+ >+ private final Implementation COLUMN_IMPLEMENTATION= new Implementation() { >+ TextEdit replace(ISelection selection, String replacement) throws BadLocationException { >+ try { >+ MultiTextEdit root; >+ IColumnTextSelection cts= (IColumnTextSelection) selection; >+ int startLine= cts.getStartLine(); >+ int endLine= cts.getEndLine(); >+ int startColumn= cts.getStartColumn(); >+ int endColumn= cts.getEndColumn(); >+ int visualStartColumn= computeVisualColumn(startLine, startColumn); >+ int visualEndColumn= computeVisualColumn(endLine, endColumn); >+ root= new MultiTextEdit(); >+ String[] delimiters= fDocument.getLegalLineDelimiters(); >+ >+ int lastDelim= 0; >+ for (int line= startLine; line <= endLine; line++) { >+ String string; >+ if (lastDelim == -1) { >+ string= ""; //$NON-NLS-1$ >+ } else { >+ int[] index= TextUtilities.indexOf(delimiters, replacement, lastDelim); >+ if (index[0] == -1) { >+ string= replacement.substring(lastDelim); >+ lastDelim= -1; >+ } else { >+ string= replacement.substring(lastDelim, index[0]); >+ lastDelim= index[0] + delimiters[index[1]].length(); >+ } >+ } >+ TextEdit replace= createReplaceEdit(cts, line, visualStartColumn, visualEndColumn, string); >+ root.addChild(replace); >+ } >+ while (lastDelim != -1) { >+ // more stuff to insert >+ String string; >+ int[] index= TextUtilities.indexOf(delimiters, replacement, lastDelim); >+ if (index[0] == -1) { >+ string= replacement.substring(lastDelim); >+ lastDelim= -1; >+ } else { >+ string= replacement.substring(lastDelim, index[0]); >+ lastDelim= index[0] + delimiters[index[1]].length(); >+ } >+ endLine++; >+ TextEdit edit; >+ if (endLine < fDocument.getNumberOfLines()) { >+ edit= createReplaceEdit(cts, endLine, visualStartColumn, visualEndColumn, string); >+ } else { >+ // insertion reaches beyond the last line >+ int insertLocation= root.getExclusiveEnd(); >+ int spaces= visualStartColumn; >+ char[] array= new char[spaces]; >+ Arrays.fill(array, ' '); >+ string= fDocument.getLegalLineDelimiters()[0] + String.valueOf(array) + string; >+ edit= new InsertEdit(insertLocation, string); >+ insertLocation += string.length(); >+ } >+ root.addChild(edit); >+ } >+ return root; >+ } catch (MalformedTreeException x) { >+ Assert.isTrue(false); >+ return null; >+ } >+ } >+ >+ String getText(ISelection selection) throws BadLocationException { >+ IColumnTextSelection cts= (IColumnTextSelection) selection; >+ StringBuffer buf= new StringBuffer(cts.getLength()); >+ int startLine= cts.getStartLine(); >+ int endLine= cts.getEndLine(); >+ int startColumn= cts.getStartColumn(); >+ int endColumn= cts.getEndColumn(); >+ int visualStartColumn= computeVisualColumn(startLine, startColumn); >+ int visualEndColumn= computeVisualColumn(endLine, endColumn); >+ >+ for (int line= startLine; line <= endLine; line++) { >+ appendColumnRange(buf, line, visualStartColumn, visualEndColumn); >+ if (line != endLine) >+ buf.append(fDocument.getLineDelimiter(line)); >+ } >+ >+ return buf.toString(); >+ } >+ >+ boolean isEmpty(ISelection selection) throws BadLocationException { >+ IColumnTextSelection cts= (IColumnTextSelection) selection; >+ int startLine= cts.getStartLine(); >+ int endLine= cts.getEndLine(); >+ int startColumn= cts.getStartColumn(); >+ int endColumn= cts.getEndColumn(); >+ int visualStartColumn= computeVisualColumn(startLine, startColumn); >+ int visualEndColumn= computeVisualColumn(endLine, endColumn); >+ return visualEndColumn == visualStartColumn; >+ } >+ >+ boolean isMultiline(ISelection selection) { >+ ITextSelection ts= (ITextSelection) selection; >+ return ts.getEndLine() > ts.getStartLine(); >+ } >+ >+ TextEdit delete(ISelection selection) throws BadLocationException { >+ if (isEmpty(selection)) { >+ IColumnTextSelection cts= (IColumnTextSelection) selection; >+ selection= new ColumnTextSelection(fDocument, cts.getStartLine(), cts.getStartColumn(), cts.getEndLine(), cts.getEndColumn() + 1, fTabWidth); >+ } >+ return replace(selection, ""); //$NON-NLS-1$ >+ } >+ >+ TextEdit backspace(ISelection selection) throws BadLocationException { >+ IColumnTextSelection cts= (IColumnTextSelection) selection; >+ if (isEmpty(selection) && cts.getStartColumn() > 0) { >+ selection= new ColumnTextSelection(fDocument, cts.getStartLine(), cts.getStartColumn() - 1, cts.getEndLine(), cts.getEndColumn(), fTabWidth); >+ } >+ return replace(selection, ""); //$NON-NLS-1$ >+ } >+ >+ ISelection makeEmpty(ISelection selection) throws BadLocationException { >+ IColumnTextSelection cts= (IColumnTextSelection) selection; >+ int startLine= cts.getStartLine(); >+ int startColumn= cts.getStartColumn(); >+ int endLine= cts.getEndLine(); >+ int endColumn= computeCharacterColumn(cts.getEndLine(), computeVisualColumn(startLine, startColumn)); >+ return new ColumnTextSelection(fDocument, startLine, startColumn, endLine, endColumn, fTabWidth); >+ } >+ >+ IRegion[] getRanges(ISelection selection) throws BadLocationException { >+ IColumnTextSelection cts= (IColumnTextSelection) selection; >+ final int startLine= cts.getStartLine(); >+ final int endLine= cts.getEndLine(); >+ int visualStartColumn= computeVisualColumn(startLine, cts.getStartColumn()); >+ int visualEndColumn= computeVisualColumn(endLine, cts.getEndColumn()); >+ IRegion[] ranges= new IRegion[endLine - startLine + 1]; >+ >+ for (int line= startLine; line <= endLine; line++) { >+ int startColumn= computeCharacterColumn(line, visualStartColumn); >+ int endColumn= computeCharacterColumn(line, visualEndColumn); >+ IRegion lineInfo= fDocument.getLineInformation(line); >+ int lineEnd= lineInfo.getLength(); >+ startColumn= Math.min(startColumn, lineEnd); >+ endColumn= Math.min(endColumn, lineEnd); >+ ranges[line - startLine] = new Region(lineInfo.getOffset() + startColumn, endColumn - startColumn); >+ } >+ >+ return ranges; >+ } >+ >+ private TextEdit createReplaceEdit(IColumnTextSelection cts, int line, int visualStartColumn, int visualEndColumn, String replacement) throws BadLocationException { >+ IRegion info= fDocument.getLineInformation(line); >+ int lineLength= info.getLength(); >+ String content= fDocument.get(info.getOffset(), lineLength); >+ int startColumn= -1; >+ int endColumn= -1; >+ int visual= 0; >+ for (int offset= 0; offset < lineLength; offset++) { >+ if (startColumn == -1 && visual >= visualStartColumn) >+ startColumn= offset; >+ if (visual == visualEndColumn) { >+ endColumn= offset; >+ break; >+ } >+ if (content.charAt(offset) == '\t') >+ visual+= fTabWidth - visual % fTabWidth; >+ else >+ visual++; >+ } >+ if (startColumn == -1) { >+ boolean materializeVirtualSpace= replacement.length() != 0; >+ if (materializeVirtualSpace) { >+ int spaces= visualStartColumn - visual; >+ char[] array= new char[spaces]; >+ Arrays.fill(array, ' '); >+ return new InsertEdit(info.getOffset() + lineLength, String.valueOf(array) + replacement); >+ } >+ return new MultiTextEdit(); >+ } >+ if (endColumn == -1) >+ endColumn= lineLength; >+ return new ReplaceEdit(info.getOffset() + startColumn, endColumn - startColumn, replacement); >+ } >+ >+ private void appendColumnRange(StringBuffer buf, int line, int visualStartColumn, int visualEndColumn) throws BadLocationException { >+ IRegion info= fDocument.getLineInformation(line); >+ int lineLength= info.getLength(); >+ String content= fDocument.get(info.getOffset(), lineLength); >+ int startColumn= -1; >+ int endColumn= -1; >+ int visual= 0; >+ for (int offset= 0; offset < lineLength; offset++) { >+ if (startColumn == -1 && visual >= visualStartColumn) >+ startColumn= offset; >+ if (visual == visualEndColumn) { >+ endColumn= offset; >+ break; >+ } >+ if (content.charAt(offset) == '\t') >+ visual+= fTabWidth - visual % fTabWidth; >+ else >+ visual++; >+ } >+ if (startColumn != -1) >+ buf.append(content.substring(startColumn, endColumn == -1 ? lineLength : endColumn)); >+ if (endColumn == -1) { >+ int spaces= visualEndColumn - Math.max(visual, visualStartColumn); >+ for (int i= 0; i < spaces; i++) >+ buf.append(' '); >+ } >+ } >+ >+ private int computeVisualColumn(final int line, final int column) throws BadLocationException { >+ int visualColumn= 0; >+ IRegion info= fDocument.getLineInformation(line); >+ int lineEnd= info.getLength(); >+ int to= Math.min(lineEnd, column); >+ String content= fDocument.get(info.getOffset(), info.getLength()); >+ for (int offset= 0; offset < to; offset++) { >+ if (content.charAt(offset) == '\t') >+ visualColumn+= fTabWidth - visualColumn % fTabWidth; >+ else >+ visualColumn++; >+ } >+ if (column > lineEnd) { >+ visualColumn+= column - lineEnd; // virtual spaces >+ } >+ return visualColumn; >+ } >+ >+ private int computeCharacterColumn(int line, int visualColumn) throws BadLocationException { >+ IRegion info= fDocument.getLineInformation(line); >+ int lineLength= info.getLength(); >+ String content= fDocument.get(info.getOffset(), lineLength); >+ int column= -1; >+ int visual= 0; >+ for (int offset= 0; offset < lineLength; offset++) { >+ if (column == -1 && visual >= visualColumn) >+ return offset; >+ if (content.charAt(offset) == '\t') >+ visual+= fTabWidth - visual % fTabWidth; >+ else >+ visual++; >+ } >+ return lineLength + visualColumn - visual; >+ } >+ }; >+ >+ private final IDocument fDocument; >+ private final int fTabWidth; >+ private IRewriteTarget fRewriteTarget; >+ private ISelectionProvider fSelectionProvider; >+ >+ public SelectionProcessor(ITextViewer viewer) { >+ this(viewer.getDocument(), viewer.getTextWidget().getTabs()); >+ if (viewer instanceof ITextViewerExtension) { >+ ITextViewerExtension ext= (ITextViewerExtension) viewer; >+ fRewriteTarget= ext.getRewriteTarget(); >+ } >+ fSelectionProvider= viewer.getSelectionProvider(); >+ } >+ >+ public SelectionProcessor(IDocument document, int tabWidth) { >+ Assert.isNotNull(document); >+ Assert.isTrue(tabWidth > 0); >+ fDocument= document; >+ fTabWidth= tabWidth; >+ } >+ >+ public TextEdit delete(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).delete(selection); >+ } >+ >+ public TextEdit backspace(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).backspace(selection); >+ } >+ >+ public TextEdit replace(ISelection selection, String replacement) throws BadLocationException { >+ return getImplementation(selection).replace(selection, replacement); >+ } >+ >+ public String getText(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).getText(selection); >+ } >+ >+ public boolean isEmpty(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).isEmpty(selection); >+ } >+ >+ public boolean isMultiline(ISelection selection) { >+ return getImplementation(selection).isMultiline(selection); >+ } >+ >+ public ISelection makeEmpty(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).makeEmpty(selection); >+ } >+ >+ public void doDelete(ISelection selection) throws BadLocationException { >+ TextEdit edit= delete(selection); >+ ISelection empty= makeEmpty(selection); >+ boolean complex= edit.hasChildren(); >+ if (complex && fRewriteTarget != null) >+ fRewriteTarget.beginCompoundChange(); >+ edit.apply(fDocument, TextEdit.UPDATE_REGIONS); >+ if (fSelectionProvider != null) >+ fSelectionProvider.setSelection(empty); >+ if (complex && fRewriteTarget != null) >+ fRewriteTarget.endCompoundChange(); >+ >+ } >+ >+ private Implementation getImplementation(ISelection selection) { >+ if (selection instanceof IColumnTextSelection) >+ return COLUMN_IMPLEMENTATION; >+ else if (selection instanceof ITextSelection) >+ return RANGE_IMPLEMENTATION; >+ else >+ return NULL_IMPLEMENTATION; >+ } >+ >+ public IRegion[] getRanges(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).getRanges(selection); >+ } >+} >Index: src/org/eclipse/jface/text/ColumnTextSelection.java >=================================================================== >RCS file: src/org/eclipse/jface/text/ColumnTextSelection.java >diff -N src/org/eclipse/jface/text/ColumnTextSelection.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/text/ColumnTextSelection.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,172 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 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 >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Tom Eicher (Avaloq Evolution AG) - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jface.text; >+ >+import org.eclipse.core.runtime.Assert; >+ >+ >+/** >+ * Standard implementation of {@link org.eclipse.jface.text.IColumnTextSelection}. >+ * >+ * @since 3.5 >+ */ >+public class ColumnTextSelection extends TextSelection implements IColumnTextSelection { >+ >+ /** The start line. */ >+ private final int fStartLine; >+ /** The start column. */ >+ private final int fStartColumn; >+ /** The end line. */ >+ private final int fEndLine; >+ /** The end column. */ >+ private final int fEndColumn; >+ /** The tabulator width used to compute visual columns from character offsets. */ >+ private final int fTabWidth; >+ /** The document. XXX should TextSelection open its document to subclasses? */ >+ private final IDocument fDocument; >+ >+ /** >+ * Creates a column selection for the given lines and columns. >+ * >+ * @param document the document that this selection refers to >+ * @param startLine the start line >+ * @param startColumn the possibly virtual start column, measured in characters from the start >+ * of <code>startLine</code> >+ * @param endLine the inclusive end line >+ * @param endColumn the exclusive and possibly virtual end column, measured in characters from >+ * the start of <code>endLine</code> >+ * @param tabWidth the tabulator width used to compute the visual offsets from character offsets >+ */ >+ public ColumnTextSelection(IDocument document, int startLine, int startColumn, int endLine, int endColumn, int tabWidth) { >+ super(document, computeOffset(document, startLine, startColumn), computeOffset(document, endLine, endColumn) - computeOffset(document, startLine, startColumn)); >+ Assert.isLegal(startLine >= 0); >+ Assert.isLegal(startColumn >= 0); >+ Assert.isLegal(endLine >= startLine); >+ Assert.isLegal(endColumn >= 0); >+ Assert.isLegal(tabWidth >= 0); >+ fStartLine= startLine; >+ fStartColumn= startColumn; >+ fEndLine= endLine; >+ fEndColumn= endColumn; >+ fTabWidth= tabWidth > 0 ? tabWidth : 8; // seems to be the default when StyledText.getTabs returns 0 >+ fDocument= document; >+ } >+ >+ /** >+ * Returns the document offset for a given tuple of line and column count. If the column count >+ * points beyond the end of the line, the end of the line is returned (virtual location). If the >+ * line points beyond the number of lines, the end of the document is returned; if the line is >+ * < zero, 0 is returned. >+ * >+ * @param document the document to get line information from >+ * @param line the line in the document, may be greater than the line count >+ * @param column the offset in the given line, may be greater than the line length >+ * @return the document offset corresponding to the line and column counts >+ */ >+ private static int computeOffset(IDocument document, int line, int column) { >+ try { >+ IRegion lineInfo= document.getLineInformation(line); >+ int offsetInLine= Math.min(column, lineInfo.getLength()); >+ return lineInfo.getOffset() + offsetInLine; >+ } catch (BadLocationException x) { >+ if (line < 0) >+ return 0; >+ return document.getLength(); >+ } >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.TextSelection#getStartLine() >+ */ >+ public int getStartLine() { >+ return fStartLine; >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.IColumnTextSelection#getStartColumn() >+ */ >+ public int getStartColumn() { >+ return fStartColumn; >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.TextSelection#getEndLine() >+ */ >+ public int getEndLine() { >+ return fEndLine; >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.IColumnTextSelection#getEndColumn() >+ */ >+ public int getEndColumn() { >+ return fEndColumn; >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.TextSelection#getText() >+ */ >+ public String getText() { >+ try { >+ return new SelectionProcessor(fDocument, fTabWidth).getText(this); >+ } catch (BadLocationException x) { >+ // TODO Auto-generated catch block >+ x.printStackTrace(); >+ return super.getText(); >+ } >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.TextSelection#hashCode() >+ */ >+ public int hashCode() { >+ final int prime= 31; >+ int result= super.hashCode(); >+ result= prime * result + fEndColumn; >+ result= prime * result + fEndLine; >+ result= prime * result + fStartColumn; >+ result= prime * result + fStartLine; >+ return result; >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.TextSelection#equals(java.lang.Object) >+ */ >+ public boolean equals(Object obj) { >+ if (this == obj) >+ return true; >+ if (!super.equals(obj)) >+ return false; >+ final ColumnTextSelection other= (ColumnTextSelection) obj; >+ if (fEndColumn != other.fEndColumn) >+ return false; >+ if (fEndLine != other.fEndLine) >+ return false; >+ if (fStartColumn != other.fStartColumn) >+ return false; >+ if (fStartLine != other.fStartLine) >+ return false; >+ return true; >+ } >+ >+ /* >+ * @see org.eclipse.jface.text.IColumnTextSelection#getRegions() >+ */ >+ public IRegion[] getRegions() { >+ try { >+ return new SelectionProcessor(fDocument, fTabWidth).getRanges(this); >+ } catch (BadLocationException x) { >+ // TODO Auto-generated catch block >+ x.printStackTrace(); >+ return new IRegion[] {new Region(getOffset(), getLength())}; >+ } >+ } >+} >#P org.eclipse.jdt.ui >Index: ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java,v >retrieving revision 1.159 >diff -u -r1.159 JavaSourceViewerConfiguration.java >--- ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java 15 Sep 2008 14:16:47 -0000 1.159 >+++ ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java 25 Nov 2008 21:13:31 -0000 >@@ -459,9 +459,9 @@ > else if (IJavaPartitions.JAVA_STRING.equals(contentType)) > return new IAutoEditStrategy[] { new SmartSemicolonAutoEditStrategy(partitioning), new JavaStringAutoIndentStrategy(partitioning) }; > else if (IJavaPartitions.JAVA_CHARACTER.equals(contentType) || IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) >- return new IAutoEditStrategy[] { new SmartSemicolonAutoEditStrategy(partitioning), new JavaAutoIndentStrategy(partitioning, getProject()) }; >+ return new IAutoEditStrategy[] { new SmartSemicolonAutoEditStrategy(partitioning), new JavaAutoIndentStrategy(partitioning, getProject(), sourceViewer) }; > else >- return new IAutoEditStrategy[] { new JavaAutoIndentStrategy(partitioning, getProject()) }; >+ return new IAutoEditStrategy[] { new JavaAutoIndentStrategy(partitioning, getProject(), sourceViewer) }; > } > > /* >Index: ui/org/eclipse/jdt/internal/ui/javaeditor/JavaMoveLinesAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaMoveLinesAction.java,v >retrieving revision 1.12 >diff -u -r1.12 JavaMoveLinesAction.java >--- ui/org/eclipse/jdt/internal/ui/javaeditor/JavaMoveLinesAction.java 11 Sep 2008 11:59:24 -0000 1.12 >+++ ui/org/eclipse/jdt/internal/ui/javaeditor/JavaMoveLinesAction.java 25 Nov 2008 21:13:30 -0000 >@@ -13,7 +13,6 @@ > import java.util.ResourceBundle; > > import org.eclipse.swt.custom.StyledText; >-import org.eclipse.swt.graphics.Point; > import org.eclipse.swt.widgets.Event; > > import org.eclipse.core.runtime.Assert; >@@ -320,12 +319,10 @@ > return; > > // get selection >- Point p= viewer.getSelectedRange(); >- if (p == null) >+ ITextSelection sel= (ITextSelection) viewer.getSelectionProvider().getSelection(); >+ if (sel.isEmpty()) > return; > >- ITextSelection sel= new TextSelection(document, p.x, p.y); >- > ITextSelection skippedLine= getSkippedLine(document, sel); > if (skippedLine == null) > return; >@@ -436,7 +433,14 @@ > if (numberOfLines < 1) > return new Region(offset, 0); > int endLine= startLine + numberOfLines - 1; >- int endOffset= document.getLineOffset(endLine) + document.getLineLength(endLine); >+ int endOffset; >+ if (fSharedState.fEditor.getViewer().getTextWidget().getBlockSelection()) { >+ // in column mode, don't select the last delimiter as we count an empty selected line >+ IRegion endLineInfo= document.getLineInformation(endLine); >+ endOffset= endLineInfo.getOffset() + endLineInfo.getLength(); >+ } else { >+ endOffset= document.getLineOffset(endLine) + document.getLineLength(endLine); >+ } > return new Region(offset, endOffset - offset); > } > >Index: ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java,v >retrieving revision 1.471 >diff -u -r1.471 JavaEditor.java >--- ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java 17 Nov 2008 16:49:35 -0000 1.471 >+++ ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditor.java 25 Nov 2008 21:13:29 -0000 >@@ -761,12 +761,17 @@ > return; > > int next= findNextPosition(position); >- if (next != BreakIterator.DONE) { >- setCaretPosition(next); >- getTextWidget().showSelection(); >- fireSelectionChanged(); >+ try { >+ if (getTextWidget().getBlockSelection() && document.getLineOfOffset(next) != document.getLineOfOffset(position)) { >+ super.run(); // may navigate into virtual white space >+ } else if (next != BreakIterator.DONE) { >+ setCaretPosition(next); >+ getTextWidget().showSelection(); >+ fireSelectionChanged(); >+ } >+ } catch (BadLocationException x) { >+ // ignore > } >- > } > > /** >@@ -858,20 +863,33 @@ > return; > > final ISourceViewer viewer= getSourceViewer(); >- final int caret, length; >- Point selection= viewer.getSelectedRange(); >- if (selection.y != 0) { >- caret= selection.x; >- length= selection.y; >+ StyledText text= viewer.getTextWidget(); >+ Point widgetSelection= text.getSelection(); >+ if (text.getBlockSelection() && widgetSelection.y != widgetSelection.x) { >+ final int caret= text.getCaretOffset(); >+ final int offset= modelOffset2WidgetOffset(viewer, position); >+ >+ if (caret == widgetSelection.x) >+ text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y); >+ else >+ text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x); >+ text.invokeAction(ST.DELETE_NEXT); > } else { >- caret= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()); >- length= position - caret; >- } >+ Point selection= viewer.getSelectedRange(); >+ final int caret, length; >+ if (selection.y != 0) { >+ caret= selection.x; >+ length= selection.y; >+ } else { >+ caret= widgetOffset2ModelOffset(viewer, text.getCaretOffset()); >+ length= position - caret; >+ } > >- try { >- viewer.getDocument().replace(caret, length, ""); //$NON-NLS-1$ >- } catch (BadLocationException exception) { >- // Should not happen >+ try { >+ viewer.getDocument().replace(caret, length, ""); //$NON-NLS-1$ >+ } catch (BadLocationException exception) { >+ // Should not happen >+ } > } > } > >@@ -955,10 +973,16 @@ > return; > > int previous= findPreviousPosition(position); >- if (previous != BreakIterator.DONE) { >- setCaretPosition(previous); >- getTextWidget().showSelection(); >- fireSelectionChanged(); >+ try { >+ if (getTextWidget().getBlockSelection() && document.getLineOfOffset(previous) != document.getLineOfOffset(position)) { >+ super.run(); // may navigate into virtual white space >+ } else if (previous != BreakIterator.DONE) { >+ setCaretPosition(previous); >+ getTextWidget().showSelection(); >+ fireSelectionChanged(); >+ } >+ } catch (BadLocationException x) { >+ // ignore - getLineOfOffset failed > } > > } >@@ -1053,18 +1077,31 @@ > > final int length; > final ISourceViewer viewer= getSourceViewer(); >- Point selection= viewer.getSelectedRange(); >- if (selection.y != 0) { >- position= selection.x; >- length= selection.y; >+ StyledText text= viewer.getTextWidget(); >+ Point widgetSelection= text.getSelection(); >+ if (text.getBlockSelection() && widgetSelection.y != widgetSelection.x) { >+ final int caret= text.getCaretOffset(); >+ final int offset= modelOffset2WidgetOffset(viewer, position); >+ >+ if (caret == widgetSelection.x) >+ text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y); >+ else >+ text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x); >+ text.invokeAction(ST.DELETE_PREVIOUS); > } else { >- length= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()) - position; >- } >+ Point selection= viewer.getSelectedRange(); >+ if (selection.y != 0) { >+ position= selection.x; >+ length= selection.y; >+ } else { >+ length= widgetOffset2ModelOffset(viewer, text.getCaretOffset()) - position; >+ } > >- try { >- viewer.getDocument().replace(position, length, ""); //$NON-NLS-1$ >- } catch (BadLocationException exception) { >- // Should not happen >+ try { >+ viewer.getDocument().replace(position, length, ""); //$NON-NLS-1$ >+ } catch (BadLocationException exception) { >+ // Should not happen >+ } > } > } > >@@ -1745,6 +1782,7 @@ > * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor() > */ > protected void initializeEditor() { >+ enableColumnSelectionMode(true); > } > > /** >Index: ui/org/eclipse/jdt/internal/ui/actions/IndentAction.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/IndentAction.java,v >retrieving revision 1.48 >diff -u -r1.48 IndentAction.java >--- ui/org/eclipse/jdt/internal/ui/actions/IndentAction.java 11 Sep 2008 11:59:06 -0000 1.48 >+++ ui/org/eclipse/jdt/internal/ui/actions/IndentAction.java 25 Nov 2008 21:13:27 -0000 >@@ -148,10 +148,8 @@ > > try { > document.addPosition(end); >- firstLine= document.getLineOfOffset(offset); >- // check for marginal (zero-length) lines >- int minusOne= length == 0 ? 0 : 1; >- nLines= document.getLineOfOffset(offset + length - minusOne) - firstLine + 1; >+ firstLine= selection.getStartLine(); >+ nLines= selection.getEndLine() - firstLine + 1; > } catch (BadLocationException e) { > // will only happen on concurrent modification > JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, "", e)); //$NON-NLS-1$ >Index: ui/org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.java,v >retrieving revision 1.115 >diff -u -r1.115 JavaAutoIndentStrategy.java >--- ui/org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.java 24 Nov 2008 12:55:16 -0000 1.115 >+++ ui/org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.java 25 Nov 2008 21:13:30 -0000 >@@ -27,6 +27,7 @@ > import org.eclipse.jface.text.Region; > import org.eclipse.jface.text.TextUtilities; > import org.eclipse.jface.text.rules.FastPartitioner; >+import org.eclipse.jface.text.source.ISourceViewer; > > import org.eclipse.ui.IEditorPart; > import org.eclipse.ui.IWorkbenchPage; >@@ -92,16 +93,23 @@ > private String fPartitioning; > private final IJavaProject fProject; > private static IScanner fgScanner= ToolFactory.createScanner(false, false, false, false); >+ /** >+ * The viewer. >+ * @since 3.3 >+ */ >+ private final ISourceViewer fViewer; > > /** > * Creates a new Java auto indent strategy for the given document partitioning. > * > * @param partitioning the document partitioning > * @param project the project to get formatting preferences from, or null to use default preferences >+ * @param viewer the source viewer that this strategy is attached to > */ >- public JavaAutoIndentStrategy(String partitioning, IJavaProject project) { >+ public JavaAutoIndentStrategy(String partitioning, IJavaProject project, ISourceViewer viewer) { > fPartitioning= partitioning; > fProject= project; >+ fViewer= viewer; > } > > private int getBracketCount(IDocument d, int startOffset, int endOffset, boolean ignoreCloseBrackets) throws BadLocationException { >@@ -1211,7 +1219,8 @@ > else if (c.text.length() == 1) > smartIndentOnKeypress(d, c); > else if (c.text.length() > 1 && getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_PASTE)) >- smartPaste(d, c); // no smart backspace for paste >+ if (fViewer == null || fViewer.getTextWidget() == null || !fViewer.getTextWidget().getBlockSelection()) >+ smartPaste(d, c); // no smart backspace for paste > > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
eclipse
:
review+
Actions:
View
|
Diff
Attachments on
bug 19771
:
57686
|
57687
|
65347
|
118701
|
121140