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 121140 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), 106.28 KB, created by
Tom Hofmann
on 2008-12-23 09:44:18 EST
(
hide
)
Description:
block_selection.patch
Filename:
MIME Type:
Creator:
Tom Hofmann
Created:
2008-12-23 09:44:18 EST
Size:
106.28 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.ui.workbench.texteditor >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.293 >diff -u -r1.293 AbstractTextEditor.java >--- src/org/eclipse/ui/texteditor/AbstractTextEditor.java 27 Nov 2008 14:43:32 -0000 1.293 >+++ src/org/eclipse/ui/texteditor/AbstractTextEditor.java 23 Dec 2008 14:39:49 -0000 >@@ -12,6 +12,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 > * Stephan Wahlbrink <stephan.wahlbrink@walware.de> - Wrong operations mode/feedback for text drag over/drop in text editors - https://bugs.eclipse.org/bugs/show_bug.cgi?id=206043 >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.ui.texteditor; > >@@ -96,6 +97,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 +250,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 +288,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 >@@ -568,7 +576,7 @@ > class TextListener implements ITextListener, ITextInputListener { > > /** The posted updater code. */ >- private Runnable fRunnable= new Runnable() { >+ private final Runnable fRunnable= new Runnable() { > public void run() { > fIsRunnablePosted= false; > >@@ -685,8 +693,16 @@ > return; > > String property= event.getProperty(); >+ >+ boolean columnMode= isBlockSelectionEnabled(); > >- if (getFontPropertyPreferenceKey().equals(property)) { >+ 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(); > } >@@ -995,9 +1011,9 @@ > protected static final class IdMapEntry { > > /** The action id. */ >- private String fActionId; >+ private final String fActionId; > /** The StyledText action. */ >- private int fAction; >+ private final int fAction; > > /** > * Creates a new mapping. >@@ -1033,7 +1049,7 @@ > class ScrollLinesAction extends Action { > > /** Number of lines to scroll. */ >- private int fScrollIncrement; >+ private final int fScrollIncrement; > > /** > * Creates a new scroll action that scroll the given number of lines. If the >@@ -1120,7 +1136,7 @@ > protected class LineEndAction extends TextNavigationAction { > > /** boolean flag which tells if the text up to the line end should be selected. */ >- private boolean fDoSelect; >+ private final boolean fDoSelect; > > /** > * Create a new line end action. >@@ -1797,9 +1813,9 @@ > */ > private static final class InformationProvider implements IInformationProvider, IInformationProviderExtension, IInformationProviderExtension2 { > >- private IRegion fHoverRegion; >- private Object fHoverInfo; >- private IInformationControlCreator fControlCreator; >+ private final IRegion fHoverRegion; >+ private final Object fHoverInfo; >+ private final IInformationControlCreator fControlCreator; > > InformationProvider(IRegion hoverRegion, Object hoverInfo, IInformationControlCreator controlCreator) { > fHoverRegion= hoverRegion; >@@ -2021,6 +2037,7 @@ > } > } > >+// private Point fTextDNDColumnSelection; > > /** > * Key used to look up font preference. >@@ -2447,7 +2464,7 @@ > * Ruler context menu listeners. > * @since 2.0 > */ >- private List fRulerContextMenuListeners= new ArrayList(); >+ private final List fRulerContextMenuListeners= new ArrayList(); > /** > * Indicates whether sanity checking in enabled. > * @since 2.0 >@@ -2975,7 +2992,7 @@ > if (fSelectionChangedListener == null) { > fSelectionChangedListener= new ISelectionChangedListener() { > >- private Runnable fRunnable= new Runnable() { >+ private final Runnable fRunnable= new Runnable() { > public void run() { > // check whether editor has not been disposed yet > if (fSourceViewer != null && fSourceViewer.getDocument() != null) { >@@ -3462,11 +3479,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 +3492,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 +3587,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 (isBlockSelectionEnabled()) { >+ // 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 +3704,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 +3737,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 +3757,7 @@ > e.setFont(font); > } > >- sourceViewer.setSelectedRange(selection.x , selection.y); >+ provider.setSelection(selection); > sourceViewer.setTopIndex(topIndex); > > if (parent instanceof Composite) { >@@ -4160,10 +4217,7 @@ > fTitleImage= null; > } > >- if (fFont != null) { >- fFont.dispose(); >- fFont= null; >- } >+ disposeFont(); > > disposeNonDefaultCaret(); > fInitialCaret= null; >@@ -4365,8 +4419,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 >@@ -5707,6 +5760,10 @@ > action.setActionDefinitionId(ITextEditorActionDefinitionIds.SHOW_INFORMATION); > setAction(ITextEditorActionConstants.SHOW_INFORMATION, action); > >+ action= new BlockModeToggleAction(EditorMessages.getBundleForConstructedKeys(), "Editor.ToggleColumnMode.", this); //$NON-NLS-1$ >+ action.setHelpContextId(IAbstractTextEditorHelpContextIds.COLUMN_MODE_ACTION); >+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.BLOCK_MODE); >+ setAction(ITextEditorActionConstants.BLOCK_MODE, action); > > PropertyDialogAction openProperties= new PropertyDialogAction( > new IShellProvider() { >@@ -6893,7 +6950,7 @@ > /** The cached editor. */ > private ITextEditor fTextEditor; > /** The cached editor input. */ >- private IEditorInput fEditorInput; >+ private final IEditorInput fEditorInput; > /** The cached document. */ > private IDocument fDocument; > >@@ -7070,4 +7127,63 @@ > } > } > >+ /* >+ * @see org.eclipse.ui.texteditor.ITextEditorExtension5#isColumnMode() >+ * @since 3.5 >+ */ >+ public final boolean isBlockSelectionEnabled() { >+ 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.5 >+ */ >+ public void setBlockSelectionMode(boolean enable) { >+ 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 23 Dec 2008 14:39:50 -0000 >@@ -9,6 +9,7 @@ > * IBM Corporation - initial API and implementation > * 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 >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.ui.texteditor; > >@@ -664,4 +665,11 @@ > * @since 3.3 > */ > String SHOW_INFORMATION= "ShowInformation"; //$NON-NLS-1$ >+ >+ /** >+ * Name of the action for toggling block selection mode. >+ * Value: <code>"ColumnMode"</code> >+ * @since 3.5 >+ */ >+ String BLOCK_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 23 Dec 2008 14:39:49 -0000 >@@ -8,16 +8,21 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Sebastian Davids <sdavids@gmx.de> - bug 145326 [typing] toUpperCase incorrect selection >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.ui.texteditor; > > 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.IBlockTextSelection; > 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.JFaceTextUtil; > import org.eclipse.jface.text.source.ISourceViewer; > > /** >@@ -71,45 +76,38 @@ > if (st == null) > return; > >- Point sel= viewer.getSelectedRange(); >- if (sel == null) >- return; >+ ITextSelection selection= (ITextSelection) viewer.getSelectionProvider().getSelection(); > >+ 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 (JFaceTextUtil.isEmpty(viewer, selection)) >+ return; >+ >+ IRegion[] ranges= JFaceTextUtil.getCoveredRanges(viewer, 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 IBlockTextSelection)) >+ 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/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 23 Dec 2008 14:39:49 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > > package org.eclipse.ui.texteditor; >@@ -212,6 +213,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.BLOCK_MODE, getAction(editor, ITextEditorActionConstants.BLOCK_MODE)); > > fFindNext.setAction(getAction(editor, ITextEditorActionConstants.FIND_NEXT)); > fFindPrevious.setAction(getAction(editor, ITextEditorActionConstants.FIND_PREVIOUS)); >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 23 Dec 2008 14:39:49 -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) - block selection 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/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 23 Dec 2008 14:39:49 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > > package org.eclipse.ui.texteditor; >@@ -189,7 +190,10 @@ > return; > > try { >- fTarget.deleteLine(document, selection.getOffset(), selection.getLength(), fType, fCopyToClipboard); >+ if (fTarget instanceof TextViewerDeleteLineTarget) >+ ((TextViewerDeleteLineTarget) 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/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 23 Dec 2008 14:39:50 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.ui.texteditor; > >@@ -34,10 +35,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; > >@@ -255,32 +258,28 @@ > } > > /** >- * Returns the document's delete region specified by position and type. >+ * Returns the document's delete region according to <code>selection</code> and <code>type</code>. > * > * @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 +337,22 @@ > * @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); >+ } > >- IRegion deleteRegion= getDeleteRegion(document, offset, length, type); >+ /** >+ * Deletes the lines that intersect with the given <code>selection</code>. >+ * >+ * @param document the document >+ * @param selection the selection to use to determine the document range to delete >+ * @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 >+ * @since 3.5 >+ */ >+ public void deleteLine(IDocument document, ITextSelection selection, int type, boolean copyToClipboard) throws BadLocationException { >+ IRegion deleteRegion= getDeleteRegion(document, selection, type); > int deleteOffset= deleteRegion.getOffset(); > int deleteLength= deleteRegion.getLength(); > >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 23 Dec 2008 14:39:50 -0000 >@@ -7,13 +7,13 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.ui.texteditor; > > 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 +291,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: 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 23 Dec 2008 14:39:49 -0000 >@@ -7,6 +7,7 @@ > # > # Contributors: > # IBM Corporation - initial API and implementation >+# Tom Eicher (Avaloq Evolution AG) - block selection mode > ############################################################################### > > Editor.Undo.label=&Undo >@@ -238,3 +239,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 23 Dec 2008 14:39:50 -0000 >@@ -10,6 +10,7 @@ > * Chris.Dennis@invidi.com - http://bugs.eclipse.org/bugs/show_bug.cgi?id=29027 > * 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 >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.ui.texteditor; > >@@ -569,4 +570,10 @@ > */ > String SHOW_INFORMATION= "org.eclipse.ui.edit.text.showInformation"; //$NON-NLS-1$ > >+ /** >+ * Command ID of the command to toggle block selection mode. >+ * Value: <code>"org.eclipse.ui.edit.text.toggleColumnMode"</code>). >+ * @since 3.5 >+ */ >+ String BLOCK_MODE = "org.eclipse.ui.edit.text.toggleColumnMode"; //$NON-NLS-1$ > } >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 23 Dec 2008 14:39:44 -0000 >@@ -7,6 +7,7 @@ > # > # Contributors: > # IBM Corporation - initial API and implementation >+# Tom Eicher (Avaloq Evolution AG) - block selection mode > ############################################################################### > pluginName= Text Editor Framework > providerName= Eclipse.org >@@ -32,6 +33,10 @@ > showInformation.name= Show Tooltip Description > showInformation.description= Displays information for the current caret location in a sticky hover > >+toggleColumnMode.label= Enable Block Selection >+toggleColumnMode.tooltip= Enables block selection mode >+toggleColumnMode.description= Enable block / 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 +174,5 @@ > > SpellingEngine= Spelling Engine > >+columnModeFont.label= Text Editor Block Selection Font >+columnModeFont.description= The block selection mode font is used by text editors in block (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 23 Dec 2008 14:39:45 -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,46 @@ > 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" >+ 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/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,43 @@ >+/******************************************************************************* >+ * 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>block selection 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 is in block (aka rectangular or column) selection >+ * mode, <code>false</code> otherwise. >+ * >+ * @return the receiver's block selection state >+ */ >+ boolean isBlockSelectionEnabled(); >+ >+ /** >+ * Sets the block selection mode state of the receiver to <code>enable</code>. Nothing happens >+ * if the receiver already is in the requested state. >+ * >+ * @param enable the new block selection state >+ */ >+ void setBlockSelectionMode(boolean enable); >+} >Index: src/org/eclipse/ui/texteditor/BlockModeToggleAction.java >=================================================================== >RCS file: src/org/eclipse/ui/texteditor/BlockModeToggleAction.java >diff -N src/org/eclipse/ui/texteditor/BlockModeToggleAction.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/texteditor/BlockModeToggleAction.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,65 @@ >+/******************************************************************************* >+ * 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 block (aka rectangular) selection mode. >+ * <p> >+ * <em>This API is provisional and may change any time before the 3.5 API freeze.</em> >+ * </p> >+ * >+ * @since 3.5 >+ */ >+final class BlockModeToggleAction 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 BlockModeToggleAction(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; >+ ext5.setBlockSelectionMode(!ext5.isBlockSelectionEnabled()); >+ } >+ 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; >+ setEnabled(true); >+ setChecked(ext5.isBlockSelectionEnabled()); >+ return; >+ } >+ setEnabled(false); >+ setChecked(false); >+ } >+} >#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 23 Dec 2008 14:39:56 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jdt.ui.text; > >@@ -459,9 +460,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 23 Dec 2008 14:39:55 -0000 >@@ -7,13 +7,13 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.javaeditor; > > 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 +320,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 +434,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.isBlockSelectionEnabled()) { >+ // 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 23 Dec 2008 14:39:54 -0000 >@@ -8,6 +8,7 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Tom Eicher <eclipse@tom.eicher.name> - [formatting] 'Format Element' in JavaDoc does also format method body - https://bugs.eclipse.org/bugs/show_bug.cgi?id=238746 >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.javaeditor; > >@@ -761,12 +762,17 @@ > return; > > int next= findNextPosition(position); >- if (next != BreakIterator.DONE) { >- setCaretPosition(next); >- getTextWidget().showSelection(); >- fireSelectionChanged(); >+ try { >+ if (isBlockSelectionEnabled() && 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 +864,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 (isBlockSelectionEnabled() && 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 +974,16 @@ > return; > > int previous= findPreviousPosition(position); >- if (previous != BreakIterator.DONE) { >- setCaretPosition(previous); >- getTextWidget().showSelection(); >- fireSelectionChanged(); >+ try { >+ if (isBlockSelectionEnabled() && 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 +1078,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 (isBlockSelectionEnabled() && 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 >+ } > } > } > >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 23 Dec 2008 14:39:52 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.actions; > >@@ -148,10 +149,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 23 Dec 2008 14:39:55 -0000 >@@ -8,6 +8,7 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Nikolay Metchev - Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=29909 >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.text.java; > >@@ -27,6 +28,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 +94,23 @@ > private String fPartitioning; > private final IJavaProject fProject; > private static IScanner fgScanner= ToolFactory.createScanner(false, false, false, false); >+ /** >+ * The viewer. >+ * @since 3.5 >+ */ >+ 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 +1220,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 > > } > >#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 23 Dec 2008 14:40:02 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jface.text.source; > >@@ -27,8 +28,10 @@ > import org.eclipse.jface.text.AbstractHoverInformationControlManager; > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.BadPositionCategoryException; >+import org.eclipse.jface.text.BlockTextSelection; > import org.eclipse.jface.text.DocumentRewriteSession; > import org.eclipse.jface.text.DocumentRewriteSessionType; >+import org.eclipse.jface.text.IBlockTextSelection; > import org.eclipse.jface.text.IDocument; > import org.eclipse.jface.text.IDocumentExtension4; > import org.eclipse.jface.text.IPositionUpdater; >@@ -36,6 +39,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 +719,20 @@ > } > > /** >+ * Position storing block selection information in order to maintain a column selection. >+ * >+ * @since 3.5 >+ */ >+ private static final class ColumnPosition extends Position { >+ int fStartColumn, fEndColumn; >+ ColumnPosition(int offset, int length, int startColumn, int endColumn) { >+ super(offset, length); >+ fStartColumn= startColumn; >+ fEndColumn= endColumn; >+ } >+ } >+ >+ /** > * Remembers and returns the current selection. The saved selection can be restored > * by calling <code>restoreSelection()</code>. > * >@@ -724,7 +742,7 @@ > */ > protected Point rememberSelection() { > >- final Point selection= getSelectedRange(); >+ final ITextSelection selection= (ITextSelection) getSelection(); > final IDocument document= getDocument(); > > if (fSelections.isEmpty()) { >@@ -735,8 +753,11 @@ > } > > try { >- >- final Position position= new Position(selection.x, selection.y); >+ final Position position; >+ if (selection instanceof IBlockTextSelection) >+ position= new ColumnPosition(selection.getOffset(), selection.getLength(), ((IBlockTextSelection) selection).getStartColumn(), ((IBlockTextSelection) selection).getEndColumn()); >+ else >+ position= new Position(selection.getOffset(), selection.getLength()); > document.addPosition(fSelectionCategory, position); > fSelections.push(position); > >@@ -746,7 +767,7 @@ > // Should not happen > } > >- return selection; >+ return new Point(selection.getOffset(), selection.getLength()); > } > > /** >@@ -766,13 +787,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 BlockTextSelection(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.204 >diff -u -r1.204 TextViewer.java >--- src/org/eclipse/jface/text/TextViewer.java 19 Dec 2008 09:45:36 -0000 1.204 >+++ src/org/eclipse/jface/text/TextViewer.java 23 Dec 2008 14:40:01 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jface.text; > >@@ -2415,6 +2416,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()); >@@ -2427,6 +2438,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 BlockTextSelection(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(); >@@ -3965,13 +3998,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) { > } >@@ -4010,7 +4045,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/TextSelection.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/TextSelection.java,v >retrieving revision 1.13 >diff -u -r1.13 TextSelection.java >--- src/org/eclipse/jface/text/TextSelection.java 12 Sep 2008 14:44:18 -0000 1.13 >+++ src/org/eclipse/jface/text/TextSelection.java 23 Dec 2008 14:39:59 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jface.text; > >@@ -17,7 +18,7 @@ > /** > * Standard implementation of {@link org.eclipse.jface.text.ITextSelection}. > * <p> >- * Makes advantage of the weak contract of correctness of its interface. If >+ * Takes advantage of the weak contract of correctness of its interface. If > * generated from a selection provider, it only remembers its offset and length > * and computes the remaining information on request.</p> > */ >@@ -42,8 +43,8 @@ > return NULL; > } > >- /** Document which delivers the data of the selection */ >- private IDocument fDocument; >+ /** Document which delivers the data of the selection, possibly <code>null</code>. */ >+ protected final IDocument fDocument; > /** Offset of the selection */ > private int fOffset; > /** Length of the selection */ >@@ -56,6 +57,7 @@ > private TextSelection() { > fOffset= -1; > fLength= -1; >+ fDocument= null; > } > > /** >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 23 Dec 2008 14:39:59 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > > package org.eclipse.jface.text; >@@ -77,7 +78,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 +224,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 +245,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 23 Dec 2008 14:40:01 -0000 >@@ -9,6 +9,7 @@ > * Anton Leherbauer (Wind River Systems) - initial API and implementation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=22712 > * Anton Leherbauer (Wind River Systems) - [painting] Long lines take too long to display when "Show Whitespace Characters" is enabled - https://bugs.eclipse.org/bugs/show_bug.cgi?id=196116 > * Anton Leherbauer (Wind River Systems) - [painting] Whitespace characters not drawn when scrolling to right slowly - https://bugs.eclipse.org/bugs/show_bug.cgi?id=206633 >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jface.text; > >@@ -229,7 +230,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 +270,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 +286,23 @@ > } > } > } >+ >+ /** >+ * Returns <code>true</code> if <code>offset</code> is selection in <code>widget</code>, >+ * <code>false</code> otherwise. >+ * >+ * @param widget the widget >+ * @param offset the offset >+ * @return <code>true</code> if <code>offset</code> is selection, <code>false</code> otherwise >+ * @since 3.5 >+ */ >+ 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: src/org/eclipse/jface/text/JFaceTextUtil.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jface.text/src/org/eclipse/jface/text/JFaceTextUtil.java,v >retrieving revision 1.8 >diff -u -r1.8 JFaceTextUtil.java >--- src/org/eclipse/jface/text/JFaceTextUtil.java 27 Nov 2008 14:43:08 -0000 1.8 >+++ src/org/eclipse/jface/text/JFaceTextUtil.java 23 Dec 2008 14:39:59 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jface.text; > >@@ -16,6 +17,8 @@ > import org.eclipse.swt.graphics.Rectangle; > import org.eclipse.swt.widgets.Control; > >+import org.eclipse.jface.internal.text.SelectionProcessor; >+ > import org.eclipse.jface.text.source.ILineRange; > import org.eclipse.jface.text.source.LineRange; > >@@ -353,4 +356,33 @@ > return increment; > } > >+ /** >+ * Returns <code>true</code> if the text covered by <code>selection</code> does not contain any >+ * characters in the given viewer. Note the difference to {@link ITextSelection#isEmpty()}, >+ * which returns <code>true</code> only for invalid selections. >+ * >+ * @param viewer the viewer >+ * @param selection the selection >+ * @return <code>true</code> if <code>selection</code> does not contain any text, >+ * <code>false</code> otherwise >+ * @throws BadLocationException if accessing the document failed >+ * @since 3.5 >+ */ >+ public static boolean isEmpty(ITextViewer viewer, ITextSelection selection) throws BadLocationException { >+ return new SelectionProcessor(viewer).isEmpty(selection); >+ } >+ >+ /** >+ * Returns the text regions covered by the given selection in the given viewer. >+ * >+ * @param viewer the viewer >+ * @param selection the selection >+ * @return the text regions corresponding to <code>selection</code> >+ * @throws BadLocationException if accessing the document failed >+ * @since 3.5 >+ */ >+ public static IRegion[] getCoveredRanges(ITextViewer viewer, ITextSelection selection) throws BadLocationException { >+ return new SelectionProcessor(viewer).getRanges(selection); >+ } >+ > } >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 23 Dec 2008 14:39:58 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Tom Eicher (Avaloq Evolution AG) - block selection mode > *******************************************************************************/ > package org.eclipse.jface.text.source.projection; > >@@ -28,6 +29,8 @@ > > import org.eclipse.core.runtime.Assert; > >+import org.eclipse.jface.internal.text.SelectionProcessor; >+ > import org.eclipse.jface.text.BadLocationException; > import org.eclipse.jface.text.DocumentEvent; > import org.eclipse.jface.text.FindReplaceDocumentAdapter; >@@ -36,9 +39,11 @@ > 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.TextSelection; > import org.eclipse.jface.text.TextUtilities; > import org.eclipse.jface.text.projection.ProjectionDocument; > import org.eclipse.jface.text.projection.ProjectionDocumentEvent; >@@ -1443,34 +1448,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 +1480,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 +1569,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) { >+ private void copyToClipboard(ITextSelection selection, boolean delete, StyledText textWidget) { > >- String copyText= null; >- >- 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 +1611,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/internal/text/SelectionProcessor.java >=================================================================== >RCS file: src/org/eclipse/jface/internal/text/SelectionProcessor.java >diff -N src/org/eclipse/jface/internal/text/SelectionProcessor.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/internal/text/SelectionProcessor.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,540 @@ >+/******************************************************************************* >+ * 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.internal.text; >+ >+import java.util.Arrays; >+ >+import org.eclipse.core.runtime.Assert; >+ >+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.jface.viewers.ISelection; >+import org.eclipse.jface.viewers.ISelectionProvider; >+ >+import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.BlockTextSelection; >+import org.eclipse.jface.text.IBlockTextSelection; >+import org.eclipse.jface.text.IDocument; >+import org.eclipse.jface.text.IRegion; >+import org.eclipse.jface.text.IRewriteTarget; >+import org.eclipse.jface.text.ITextSelection; >+import org.eclipse.jface.text.ITextViewer; >+import org.eclipse.jface.text.ITextViewerExtension; >+import org.eclipse.jface.text.Region; >+import org.eclipse.jface.text.TextSelection; >+import org.eclipse.jface.text.TextUtilities; >+ >+/** >+ * Processes {@link ITextSelection}s. >+ * >+ * @since 3.5 >+ */ >+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) { >+ 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; >+ IBlockTextSelection cts= (IBlockTextSelection)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 { >+ IBlockTextSelection cts= (IBlockTextSelection)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 { >+ IBlockTextSelection cts= (IBlockTextSelection)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)) { >+ IBlockTextSelection cts= (IBlockTextSelection)selection; >+ selection= new BlockTextSelection(fDocument, cts.getStartLine(), cts.getStartColumn(), cts.getEndLine(), cts.getEndColumn() + 1, fTabWidth); >+ } >+ return replace(selection, ""); //$NON-NLS-1$ >+ } >+ >+ TextEdit backspace(ISelection selection) throws BadLocationException { >+ IBlockTextSelection cts= (IBlockTextSelection)selection; >+ if (isEmpty(selection) && cts.getStartColumn() > 0) { >+ selection= new BlockTextSelection(fDocument, cts.getStartLine(), cts.getStartColumn() - 1, cts.getEndLine(), cts.getEndColumn(), fTabWidth); >+ } >+ return replace(selection, ""); //$NON-NLS-1$ >+ } >+ >+ ISelection makeEmpty(ISelection selection) throws BadLocationException { >+ IBlockTextSelection cts= (IBlockTextSelection)selection; >+ int startLine= cts.getStartLine(); >+ int startColumn= cts.getStartColumn(); >+ int endLine= cts.getEndLine(); >+ int endColumn= computeCharacterColumn(cts.getEndLine(), computeVisualColumn(startLine, startColumn)); >+ return new BlockTextSelection(fDocument, startLine, startColumn, endLine, endColumn, fTabWidth); >+ } >+ >+ IRegion[] getRanges(ISelection selection) throws BadLocationException { >+ IBlockTextSelection cts= (IBlockTextSelection)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(IBlockTextSelection 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; >+ >+ /** >+ * Creates a new processor on the given viewer. >+ * >+ * @param viewer the viewer >+ */ >+ public SelectionProcessor(ITextViewer viewer) { >+ this(viewer.getDocument(), viewer.getTextWidget().getTabs()); >+ if (viewer instanceof ITextViewerExtension) { >+ ITextViewerExtension ext= (ITextViewerExtension)viewer; >+ fRewriteTarget= ext.getRewriteTarget(); >+ } >+ fSelectionProvider= viewer.getSelectionProvider(); >+ } >+ >+ /** >+ * Creates a new processor on the given document and using the given tab width. >+ * >+ * @param document the document >+ * @param tabWidth the tabulator width in space equivalents >+ */ >+ public SelectionProcessor(IDocument document, int tabWidth) { >+ Assert.isNotNull(document); >+ Assert.isTrue(tabWidth > 0); >+ fDocument= document; >+ fTabWidth= tabWidth; >+ } >+ >+ /** >+ * Returns a text edit describing the text modification that would be executed if the delete key >+ * was pressed on the given selection. >+ * >+ * @param selection the selection to delete >+ * @return a text edit describing the operation needed to delete <code>selection</code> >+ * @throws BadLocationException if computing the edit failed >+ */ >+ public TextEdit delete(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).delete(selection); >+ } >+ >+ /** >+ * Returns a text edit describing the text modification that would be executed if the backspace >+ * key was pressed on the given selection. >+ * >+ * @param selection the selection to delete >+ * @return a text edit describing the operation needed to delete <code>selection</code> >+ * @throws BadLocationException if computing the edit failed >+ */ >+ public TextEdit backspace(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).backspace(selection); >+ } >+ >+ /** >+ * Returns a text edit describing the text modification that would be executed if the given >+ * selection was replaced by <code>replacement</code>. >+ * >+ * @param selection the selection to replace >+ * @param replacement the replacement text >+ * @return a text edit describing the operation needed to replace <code>selection</code> >+ * @throws BadLocationException if computing the edit failed >+ */ >+ public TextEdit replace(ISelection selection, String replacement) throws BadLocationException { >+ return getImplementation(selection).replace(selection, replacement); >+ } >+ >+ /** >+ * Returns the text covered by <code>selection</code> >+ * >+ * @param selection the selection >+ * @return the text covered by <code>selection</code> >+ * @throws BadLocationException if computing the edit failed >+ */ >+ public String getText(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).getText(selection); >+ } >+ >+ /** >+ * Returns <code>true</code> if the text covered by <code>selection</code> does not contain any >+ * characters. Note the difference to {@link ITextSelection#isEmpty()}, which returns >+ * <code>true</code> only for invalid selections. >+ * >+ * @param selection the selection >+ * @return <code>true</code> if <code>selection</code> does not contain any text, >+ * <code>false</code> otherwise >+ * @throws BadLocationException if accessing the document failed >+ */ >+ public boolean isEmpty(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).isEmpty(selection); >+ } >+ >+ /** >+ * Returns <code>true</code> if <code>selection</code> covers text on two or more lines, >+ * <code>false</code> otherwise. >+ * >+ * @param selection the selection >+ * @return <code>true</code> if <code>selection</code> covers text on two or more lines, >+ * <code>false</code> otherwise >+ */ >+ public boolean isMultiline(ISelection selection) { >+ return getImplementation(selection).isMultiline(selection); >+ } >+ >+ /** >+ * Returns a selection similar to <code>selection</code> but {@linkplain #isEmpty(ISelection) >+ * empty}. Typically, the selection is reduced to its left-most offset. >+ * >+ * @param selection the selection >+ * @return an empty variant of <code>selection</code> >+ * @throws BadLocationException if accessing the document failed >+ */ >+ public ISelection makeEmpty(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).makeEmpty(selection); >+ } >+ >+ /** >+ * Convenience method that applies the edit returned from {@link #delete(ISelection)} to the >+ * underlying document. >+ * >+ * @param selection the selection to delete >+ * @throws BadLocationException if accessing the document failed >+ */ >+ 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(); >+ >+ } >+ >+ /** >+ * Returns the text regions covered by the given selection. >+ * >+ * @param selection the selection >+ * @return the text regions corresponding to <code>selection</code> >+ * @throws BadLocationException if accessing the document failed >+ */ >+ public IRegion[] getRanges(ISelection selection) throws BadLocationException { >+ return getImplementation(selection).getRanges(selection); >+ } >+ >+ /** >+ * Returns the implementation. >+ * >+ * @param selection the selection >+ * @return the corresponding processor implementation >+ */ >+ private Implementation getImplementation(ISelection selection) { >+ if (selection instanceof IBlockTextSelection) >+ return COLUMN_IMPLEMENTATION; >+ else if (selection instanceof ITextSelection) >+ return RANGE_IMPLEMENTATION; >+ else >+ return NULL_IMPLEMENTATION; >+ } >+} >Index: src/org/eclipse/jface/text/BlockTextSelection.java >=================================================================== >RCS file: src/org/eclipse/jface/text/BlockTextSelection.java >diff -N src/org/eclipse/jface/text/BlockTextSelection.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/text/BlockTextSelection.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,167 @@ >+/******************************************************************************* >+ * 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; >+ >+import org.eclipse.jface.internal.text.SelectionProcessor; >+ >+ >+/** >+ * Standard implementation of {@link org.eclipse.jface.text.IBlockTextSelection}. >+ * >+ * @since 3.5 >+ */ >+public class BlockTextSelection extends TextSelection implements IBlockTextSelection { >+ >+ /** 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; >+ >+ /** >+ * 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 BlockTextSelection(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 >+ } >+ >+ /** >+ * 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) { >+ 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 BlockTextSelection other= (BlockTextSelection) 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) { >+ return new IRegion[] {new Region(getOffset(), getLength())}; >+ } >+ } >+} >Index: src/org/eclipse/jface/text/IBlockTextSelection.java >=================================================================== >RCS file: src/org/eclipse/jface/text/IBlockTextSelection.java >diff -N src/org/eclipse/jface/text/IBlockTextSelection.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/text/IBlockTextSelection.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 IBlockTextSelection} 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.BlockTextSelection}. >+ * </p> >+ * >+ * @see org.eclipse.jface.text.BlockTextSelection >+ * @since 3.5 >+ */ >+public interface IBlockTextSelection 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(); >+}
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
Actions:
View
|
Diff
Attachments on
bug 19771
:
57686
|
57687
|
65347
|
118701
| 121140