[Pydev-cvs] org.python.pydev/src/org/python/pydev/editor Hyperlink.java,NONE,1.1 PyEdit.java,1.10,1.
Brought to you by:
fabioz
From: Aleksandar T. <at...@us...> - 2004-04-10 02:01:41
|
Update of /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv649/src/org/python/pydev/editor Modified Files: PyEdit.java package.html Added Files: Hyperlink.java Log Message: Huge code rewrite. I've implemented a Python model. Model is based in AST tree, but should be simpler to use. No more visitor pattern. OutlineView and Navigation actions have been reworked to use new model, instead of traversing AST. Added Hyperlinking capability, but goto is not implemetned yet. Index: package.html =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/package.html,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** package.html 30 Mar 2004 01:03:37 -0000 1.2 --- package.html 10 Apr 2004 01:48:14 -0000 1.3 *************** *** 37,43 **** Find an innermost vocabulary containing current selection. Then quiz it for whatever is needed - - Questions: - can vocabularies be overlapping? That would make things hard. </pre> --- 37,40 ---- Index: PyEdit.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev/src/org/python/pydev/editor/PyEdit.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** PyEdit.java 2 Apr 2004 18:17:44 -0000 1.10 --- PyEdit.java 10 Apr 2004 01:48:14 -0000 1.11 *************** *** 6,9 **** --- 6,12 ---- package org.python.pydev.editor; + import java.util.ArrayList; + import java.util.Iterator; + import org.eclipse.core.internal.resources.MarkerAttributeMap; import org.eclipse.core.resources.IFile; *************** *** 12,15 **** --- 15,19 ---- import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; + import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; *************** *** 24,28 **** import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.texteditor.DefaultRangeIndicator; - import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IEditorStatusLine; import org.eclipse.ui.texteditor.MarkerUtilities; --- 28,31 ---- *************** *** 33,41 **** import org.python.parser.Token; import org.python.parser.TokenMgrError; ! import org.python.pydev.plugin.PydevPlugin; ! import org.python.pydev.plugin.PydevPrefs; ! import org.python.pydev.editor.dictionary.PyDEditorItem; import org.python.pydev.outline.PyOutlinePage; - import org.python.pydev.outline.SelectionPosition; import org.python.pydev.parser.IParserListener; import org.python.pydev.parser.PyParser; --- 36,45 ---- import org.python.parser.Token; import org.python.parser.TokenMgrError; ! import org.python.pydev.plugin.*; ! import org.python.pydev.editor.model.AbstractNode; ! import org.python.pydev.editor.model.IModelListener; ! import org.python.pydev.editor.model.Location; ! import org.python.pydev.editor.model.ModelMaker; import org.python.pydev.outline.PyOutlinePage; import org.python.pydev.parser.IParserListener; import org.python.pydev.parser.PyParser; *************** *** 71,79 **** /** need to hold onto it to support indentPrefix change through preferences */ PyEditConfiguration editConfiguration; ! /** top-level dictionary */ ! PyDEditorItem dictionaryRoot; ! public PyEdit() { super(); colorCache = new ColorCache(PydevPrefs.getPreferences()); if (getDocumentProvider() == null) { --- 75,88 ---- /** need to hold onto it to support indentPrefix change through preferences */ PyEditConfiguration editConfiguration; ! /** Python model */ ! AbstractNode pythonModel; ! /** Hyperlinking listener */ ! Hyperlink fMouseListener; ! /** listeners that get notified of model changes */ ! ArrayList modelListeners; ! public PyEdit() { super(); + modelListeners = new ArrayList(); colorCache = new ColorCache(PydevPrefs.getPreferences()); if (getDocumentProvider() == null) { *************** *** 147,152 **** parser.setDocument(getDocumentProvider().getDocument(input)); - dictionaryRoot = new PyDEditorItem(parser); - // listen to changes in TAB_WIDTH preference prefListener = new Preferences.IPropertyChangeListener() { --- 156,159 ---- *************** *** 194,197 **** --- 201,206 ---- // when Ctrl+Spacebar is pressed setActionActivationCode(CONTENTASSIST_PROPOSAL_ID,' ', -1, SWT.CTRL); + + enableBrowserLikeLinks(); } *************** *** 205,208 **** --- 214,221 ---- } + public AbstractNode getPythonModel() { + return pythonModel; + } + /** * @return an outline view *************** *** 217,221 **** /** * implementation copied from ! * @see org.eclipse.ui.externaltools.internal.ant.editor.PlantyEditor#setSelection */ public void setSelection(int offset, int length) { --- 230,234 ---- /** * implementation copied from ! * org.eclipse.ui.externaltools.internal.ant.editor.PlantyEditor#setSelection */ public void setSelection(int offset, int length) { *************** *** 226,251 **** /** ! * Reveals the selection */ ! public void setSelection(SelectionPosition newSel) { ! if (newSel.r != null) { ! setSelection(newSel.r.getOffset(), newSel.r.getLength()); ! } ! else { ! IDocumentProvider provider = getDocumentProvider(); ! IDocument document = provider.getDocument(getEditorInput()); ! try { ! IRegion r = document.getLineInformation(newSel.line - 1); ! // if selecting the whole line, just use the information ! if (newSel.column == SelectionPosition.WHOLE_LINE) { ! newSel.column = 0; ! newSel.length = r.getLength(); ! } ! setSelection(r.getOffset() + newSel.column, newSel.length); ! } catch (BadLocationException e) { ! e.printStackTrace(); } } } /** --- 239,271 ---- /** ! * Selects & reveals the model node */ ! public void revealModelNode(AbstractNode node) { ! if (node == null) ! return; // nothing to see here ! boolean wholeLine = false; ! // if (node instanceof ImportNode) ! // wholeLine = true; ! Location start = node.getStart(); ! Location end = node.getEnd(); ! IDocument document = getDocumentProvider().getDocument(getEditorInput()); ! int offset, length; ! try { ! if (wholeLine) { ! IRegion r; ! r = document.getLineInformation(start.line); ! offset = r.getOffset(); ! length = r.getLength(); ! } else { ! offset = start.toOffset(document); ! length = end.toOffset(document) - offset; } + } catch (BadLocationException e) { + PydevPlugin.log(IStatus.WARNING, "error trying to revealModelItem" + node.toString(), e); + return; } + setSelection(offset, length); } + /** *************** *** 263,267 **** } catch (CoreException e) { // What bad can come from removing markers? Ignore this exception ! e.printStackTrace(); } } --- 283,297 ---- } catch (CoreException e) { // What bad can come from removing markers? Ignore this exception ! PydevPlugin.log(IStatus.WARNING, "Unexpected error removing markers", e); ! } ! IDocument document = getDocumentProvider().getDocument(getEditorInput()); ! int lastLine = document.getNumberOfLines(); ! IRegion r; ! try { ! r = document.getLineInformation(lastLine-1); ! pythonModel = ModelMaker.createModel(root, lastLine , r.getLength()); ! fireModelChanged(pythonModel); ! } catch (BadLocationException e1) { ! PydevPlugin.log(IStatus.WARNING, "Unexpected error getting document length. No model!", e1); } } *************** *** 333,337 **** --- 363,411 ---- } } + + private void enableBrowserLikeLinks() { + if (fMouseListener == null) { + fMouseListener= new Hyperlink(getSourceViewer(), this); + fMouseListener.install(); + } + } + + /** + * Disables browser like links. + */ + private void disableBrowserLikeLinks() { + if (fMouseListener != null) { + fMouseListener.uninstall(); + fMouseListener= null; + } + } + /** stock listener implementation */ + public void addModelListener(IModelListener listener) { + Assert.isNotNull(listener); + if (! modelListeners.contains(listener)) + modelListeners.add(listener); + } + + /** stock listener implementation */ + public void removeModelListener(IModelListener listener) { + Assert.isNotNull(listener); + modelListeners.remove(listener); + } + + /** + * stock listener implementation + * event is fired whenever we get a new root + */ + protected void fireModelChanged(AbstractNode root) { + if (modelListeners.size() > 0) { + ArrayList list= new ArrayList(modelListeners); + Iterator e= list.iterator(); + while (e.hasNext()) { + IModelListener l= (IModelListener) e.next(); + l.modelChanged(root); + } + } + } --- NEW FILE: Hyperlink.java --- /* * Author: atotic * Created on Mar 31, 2004 * License: Common Public License v1.0 */ package org.python.pydev.editor; import java.util.StringTokenizer; import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.ui.PreferenceConstants; import org.eclipse.jface.action.Action; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextInputListener; import org.eclipse.jface.text.ITextViewerExtension2; import org.eclipse.jface.text.ITextViewerExtension3; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.python.pydev.editor.model.AbstractNode; import org.python.pydev.editor.model.ModelUtils; import org.python.pydev.plugin.PydevPlugin; /** * Hyperlink is a "Mouse highlight on ctrl". * The code here has been copied from JavaEditor::MouseClick. * I've just modified Python-specific code. */ public class Hyperlink implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener, IPropertyChangeListener, IDocumentListener, ITextInputListener { /** The session is active. */ private boolean fActive; /** The currently active style range. */ private IRegion fActiveRegion; /** The currently active style range as position. */ private Position fRememberedPosition; /** The hand cursor. */ private Cursor fCursor; /** The link color. */ private Color fColor; /** The key modifier mask. */ private int fKeyModifierMask; /************ * ALEKS ADDITIONS */ private ISourceViewer fSourceViewer; private PyEdit fEditor; public Hyperlink(ISourceViewer sourceViewer, PyEdit editor) { fSourceViewer = sourceViewer; fEditor = editor; } private ISourceViewer getSourceViewer() { return fSourceViewer; } IPreferenceStore fPrefStore = null; public IPreferenceStore getPreferenceStore() { if (fPrefStore == null) fPrefStore = JavaPlugin.getDefault().getPreferenceStore(); return fPrefStore; } public void deactivate() { deactivate(false); } public void deactivate(boolean redrawAll) { if (!fActive) return; repairRepresentation(redrawAll); fActive= false; } public void install() { ISourceViewer sourceViewer= getSourceViewer(); if (sourceViewer == null) return; StyledText text= sourceViewer.getTextWidget(); if (text == null || text.isDisposed()) return; updateColor(sourceViewer); sourceViewer.addTextInputListener(this); IDocument document= sourceViewer.getDocument(); if (document != null) document.addDocumentListener(this); text.addKeyListener(this); text.addMouseListener(this); text.addMouseMoveListener(this); text.addFocusListener(this); text.addPaintListener(this); updateKeyModifierMask(); IPreferenceStore preferenceStore= getPreferenceStore(); preferenceStore.addPropertyChangeListener(this); } private void updateKeyModifierMask() { String modifiers= getPreferenceStore().getString(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); fKeyModifierMask= computeStateMask(modifiers); if (fKeyModifierMask == -1) { // Fallback to stored state mask fKeyModifierMask= getPreferenceStore().getInt(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); }; } private int computeStateMask(String modifiers) { if (modifiers == null) return -1; if (modifiers.length() == 0) return SWT.NONE; int stateMask= 0; StringTokenizer modifierTokenizer= new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$ while (modifierTokenizer.hasMoreTokens()) { int modifier= EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken()); if (modifier == 0 || (stateMask & modifier) == modifier) return -1; stateMask= stateMask | modifier; } return stateMask; } public void uninstall() { if (fColor != null) { fColor.dispose(); fColor= null; } if (fCursor != null) { fCursor.dispose(); fCursor= null; } ISourceViewer sourceViewer= getSourceViewer(); if (sourceViewer == null) return; sourceViewer.removeTextInputListener(this); IDocument document= sourceViewer.getDocument(); if (document != null) document.removeDocumentListener(this); IPreferenceStore preferenceStore= getPreferenceStore(); if (preferenceStore != null) preferenceStore.removePropertyChangeListener(this); StyledText text= sourceViewer.getTextWidget(); if (text == null || text.isDisposed()) return; text.removeKeyListener(this); text.removeMouseListener(this); text.removeMouseMoveListener(this); text.removeFocusListener(this); text.removePaintListener(this); } /* * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { if (event.getProperty().equals(PreferenceConstants.EDITOR_LINK_COLOR)) { ISourceViewer viewer= getSourceViewer(); if (viewer != null) updateColor(viewer); } else if (event.getProperty().equals(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER)) { updateKeyModifierMask(); } } private void updateColor(ISourceViewer viewer) { if (fColor != null) fColor.dispose(); StyledText text= viewer.getTextWidget(); if (text == null || text.isDisposed()) return; Display display= text.getDisplay(); fColor= createColor(getPreferenceStore(), PreferenceConstants.EDITOR_LINK_COLOR, display); } /** * Creates a color from the information stored in the given preference store. * Returns <code>null</code> if there is no such information available. */ private Color createColor(IPreferenceStore store, String key, Display display) { RGB rgb= null; if (store.contains(key)) { if (store.isDefault(key)) rgb= PreferenceConverter.getDefaultColor(store, key); else rgb= PreferenceConverter.getColor(store, key); if (rgb != null) return new Color(display, rgb); } return null; } private void repairRepresentation() { repairRepresentation(false); } private void repairRepresentation(boolean redrawAll) { if (fActiveRegion == null) return; ISourceViewer viewer= getSourceViewer(); if (viewer != null) { resetCursor(viewer); int offset= fActiveRegion.getOffset(); int length= fActiveRegion.getLength(); // remove style if (!redrawAll && viewer instanceof ITextViewerExtension2) ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length); else viewer.invalidateTextPresentation(); // remove underline if (viewer instanceof ITextViewerExtension3) { ITextViewerExtension3 extension= (ITextViewerExtension3) viewer; offset= extension.modelOffset2WidgetOffset(offset); } else { offset -= viewer.getVisibleRegion().getOffset(); } StyledText text= viewer.getTextWidget(); try { text.redrawRange(offset, length, true); } catch (IllegalArgumentException x) { PydevPlugin.log(IStatus.ERROR, "Unexpected error in Hyperlink code", x); } } fActiveRegion= null; } // will eventually be replaced by a method provided by jdt.core private IRegion selectWord(IDocument document, int anchor) { try { int offset= anchor; char c; while (offset >= 0) { c= document.getChar(offset); if (!Character.isJavaIdentifierPart(c)) break; --offset; } int start= offset; offset= anchor; int length= document.getLength(); while (offset < length) { c= document.getChar(offset); if (!Character.isJavaIdentifierPart(c)) break; ++offset; } int end= offset; if (start == end) return new Region(start, 0); else return new Region(start + 1, end - start - 1); } catch (BadLocationException x) { return null; } } IRegion getCurrentTextRegion(ISourceViewer viewer) { int offset= getCurrentTextOffset(viewer); if (offset == -1) return null; AbstractNode node = ModelUtils.getElement(fEditor.getPythonModel(), offset, viewer.getDocument(), AbstractNode.PROP_CLICKABLE); if (node == null) return null; // try { // // IJavaElement[] elements= null; // synchronized (input) { // elements= ((ICodeAssist) input).codeSelect(offset, 0); // } // // if (elements == null || elements.length == 0) // return null; // return selectWord(viewer.getDocument(), offset); return selectWord(viewer.getDocument(), offset); // } catch (JavaModelException e) { // return null; // } } private int getCurrentTextOffset(ISourceViewer viewer) { try { StyledText text= viewer.getTextWidget(); if (text == null || text.isDisposed()) return -1; Display display= text.getDisplay(); Point absolutePosition= display.getCursorLocation(); Point relativePosition= text.toControl(absolutePosition); int widgetOffset= text.getOffsetAtLocation(relativePosition); if (viewer instanceof ITextViewerExtension3) { ITextViewerExtension3 extension= (ITextViewerExtension3) viewer; return extension.widgetOffset2ModelOffset(widgetOffset); } else { return widgetOffset + viewer.getVisibleRegion().getOffset(); } } catch (IllegalArgumentException e) { return -1; } } private void highlightRegion(ISourceViewer viewer, IRegion region) { if (region.equals(fActiveRegion)) return; repairRepresentation(); StyledText text= viewer.getTextWidget(); if (text == null || text.isDisposed()) return; // highlight region int offset= 0; int length= 0; if (viewer instanceof ITextViewerExtension3) { ITextViewerExtension3 extension= (ITextViewerExtension3) viewer; IRegion widgetRange= extension.modelRange2WidgetRange(region); if (widgetRange == null) return; offset= widgetRange.getOffset(); length= widgetRange.getLength(); } else { offset= region.getOffset() - viewer.getVisibleRegion().getOffset(); length= region.getLength(); } StyleRange oldStyleRange= text.getStyleRangeAtOffset(offset); Color foregroundColor= fColor; Color backgroundColor= oldStyleRange == null ? text.getBackground() : oldStyleRange.background; StyleRange styleRange= new StyleRange(offset, length, foregroundColor, backgroundColor); text.setStyleRange(styleRange); // underline text.redrawRange(offset, length, true); fActiveRegion= region; } private void activateCursor(ISourceViewer viewer) { StyledText text= viewer.getTextWidget(); if (text == null || text.isDisposed()) return; Display display= text.getDisplay(); if (fCursor == null) fCursor= new Cursor(display, SWT.CURSOR_HAND); text.setCursor(fCursor); } private void resetCursor(ISourceViewer viewer) { StyledText text= viewer.getTextWidget(); if (text != null && !text.isDisposed()) text.setCursor(null); if (fCursor != null) { fCursor.dispose(); fCursor= null; } } /* * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) */ public void keyPressed(KeyEvent event) { if (fActive) { deactivate(); return; } if (event.keyCode != fKeyModifierMask) { deactivate(); return; } fActive= true; // removed for #25871 // // ISourceViewer viewer= getSourceViewer(); // if (viewer == null) // return; // // IRegion region= getCurrentTextRegion(viewer); // if (region == null) // return; // // highlightRegion(viewer, region); // activateCursor(viewer); } /* * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) */ public void keyReleased(KeyEvent event) { if (!fActive) return; deactivate(); } /* * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) */ public void mouseDoubleClick(MouseEvent e) {} /* * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) */ public void mouseDown(MouseEvent event) { if (!fActive) return; if (event.stateMask != fKeyModifierMask) { deactivate(); return; } if (event.button != 1) { deactivate(); return; } } /* * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) */ public void mouseUp(MouseEvent e) { if (!fActive) return; if (e.button != 1) { deactivate(); return; } boolean wasActive= fCursor != null; deactivate(); if (wasActive) { System.out.println("Clicked for action"); // IAction action= getAction("OpenEditor"); //$NON-NLS-1$ // if (action != null) // action.run(); } } /* * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) */ public void mouseMove(MouseEvent event) { if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) { deactivate(); return; } if (!fActive) { if (event.stateMask != fKeyModifierMask) return; // modifier was already pressed fActive= true; } ISourceViewer viewer= getSourceViewer(); if (viewer == null) { deactivate(); return; } StyledText text= viewer.getTextWidget(); if (text == null || text.isDisposed()) { deactivate(); return; } if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) { deactivate(); return; } IRegion region= getCurrentTextRegion(viewer); if (region == null || region.getLength() == 0) { repairRepresentation(); return; } highlightRegion(viewer, region); activateCursor(viewer); } /* * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent) */ public void focusGained(FocusEvent e) {} /* * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) */ public void focusLost(FocusEvent event) { deactivate(); } /* * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) */ public void documentAboutToBeChanged(DocumentEvent event) { if (fActive && fActiveRegion != null) { fRememberedPosition= new Position(fActiveRegion.getOffset(), fActiveRegion.getLength()); try { event.getDocument().addPosition(fRememberedPosition); } catch (BadLocationException x) { fRememberedPosition= null; } } } /* * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) */ public void documentChanged(DocumentEvent event) { if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) { event.getDocument().removePosition(fRememberedPosition); fActiveRegion= new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength()); } fRememberedPosition= null; ISourceViewer viewer= getSourceViewer(); if (viewer != null) { StyledText widget= viewer.getTextWidget(); if (widget != null && !widget.isDisposed()) { widget.getDisplay().asyncExec(new Runnable() { public void run() { deactivate(); } }); } } } /* * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) */ public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { if (oldInput == null) return; deactivate(); oldInput.removeDocumentListener(this); } /* * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) */ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { if (newInput == null) return; newInput.addDocumentListener(this); } /* * @see PaintListener#paintControl(PaintEvent) */ public void paintControl(PaintEvent event) { if (fActiveRegion == null) return; ISourceViewer viewer= getSourceViewer(); if (viewer == null) return; StyledText text= viewer.getTextWidget(); if (text == null || text.isDisposed()) return; int offset= 0; int length= 0; if (viewer instanceof ITextViewerExtension3) { ITextViewerExtension3 extension= (ITextViewerExtension3) viewer; IRegion widgetRange= extension.modelRange2WidgetRange(new Region(offset, length)); if (widgetRange == null) return; offset= widgetRange.getOffset(); length= widgetRange.getLength(); } else { IRegion region= viewer.getVisibleRegion(); if (!includes(region, fActiveRegion)) return; offset= fActiveRegion.getOffset() - region.getOffset(); length= fActiveRegion.getLength(); } // support for bidi Point minLocation= getMinimumLocation(text, offset, length); Point maxLocation= getMaximumLocation(text, offset, length); int x1= minLocation.x; int x2= minLocation.x + maxLocation.x - minLocation.x - 1; int y= minLocation.y + text.getLineHeight() - 1; GC gc= event.gc; if (fColor != null && !fColor.isDisposed()) gc.setForeground(fColor); gc.drawLine(x1, y, x2, y); } private boolean includes(IRegion region, IRegion position) { return position.getOffset() >= region.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength(); } private Point getMinimumLocation(StyledText text, int offset, int length) { Point minLocation= new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); for (int i= 0; i <= length; i++) { Point location= text.getLocationAtOffset(offset + i); if (location.x < minLocation.x) minLocation.x= location.x; if (location.y < minLocation.y) minLocation.y= location.y; } return minLocation; } private Point getMaximumLocation(StyledText text, int offset, int length) { Point maxLocation= new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); for (int i= 0; i <= length; i++) { Point location= text.getLocationAtOffset(offset + i); if (location.x > maxLocation.x) maxLocation.x= location.x; if (location.y > maxLocation.y) maxLocation.y= location.y; } return maxLocation; } } class EditorUtility { /** * Maps the localized modifier name to a code in the same * manner as #findModifier. * * @return the SWT modifier bit, or <code>0</code> if no match was found * @see findModifier * @since 2.1.1 */ public static int findLocalizedModifier(String token) { if (token == null) return 0; if (token.equalsIgnoreCase(Action.findModifierString(SWT.CTRL))) return SWT.CTRL; if (token.equalsIgnoreCase(Action.findModifierString(SWT.SHIFT))) return SWT.SHIFT; if (token.equalsIgnoreCase(Action.findModifierString(SWT.ALT))) return SWT.ALT; if (token.equalsIgnoreCase(Action.findModifierString(SWT.COMMAND))) return SWT.COMMAND; return 0; } } |