blob: 9e98b792c3e0cfd45fcbba2e8863d100d96700f1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package test0501;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.CollationElementIterator;
import java.text.Collator;
import java.text.RuleBasedCollator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BidiSegmentEvent;
import org.eclipse.swt.custom.BidiSegmentListener;
import org.eclipse.swt.custom.ST;
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.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension3;
import org.eclipse.jface.text.ITextViewerExtension4;
import org.eclipse.jface.text.ITypedRegion;
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.information.IInformationProvider;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.information.InformationPresenter;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.LineChangeHover;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.ui.editors.text.DefaultEncodingSupport;
import org.eclipse.ui.editors.text.IEncodingSupport;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.ActionContext;
import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.ui.part.EditorActionBarContributor;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.texteditor.AddTaskAction;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.DefaultAnnotation;
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
import org.eclipse.ui.texteditor.DefaultRangeIndicator;
import org.eclipse.ui.texteditor.ExtendedTextEditor;
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IEditorStatusLine;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.MarkerAnnotation;
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
import org.eclipse.ui.texteditor.ResourceAction;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.TextEditorAction;
import org.eclipse.ui.texteditor.TextNavigationAction;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.search.ui.SearchUI;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICodeAssist;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportContainer;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.ui.IContextMenuConstants;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
import org.eclipse.jdt.ui.actions.JavaSearchActionGroup;
import org.eclipse.jdt.ui.actions.OpenEditorActionGroup;
import org.eclipse.jdt.ui.actions.OpenViewActionGroup;
import org.eclipse.jdt.ui.actions.ShowActionGroup;
import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;
import org.eclipse.jdt.ui.text.JavaTextTools;
import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.actions.CompositeActionGroup;
import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.GoToNextPreviousMemberAction;
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.SelectionHistory;
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectEnclosingAction;
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectHistoryAction;
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectNextAction;
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectPreviousAction;
import org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSelectionAction;
import org.eclipse.jdt.internal.ui.search.FindOccurrencesEngine;
import org.eclipse.jdt.internal.ui.text.HTMLTextPresenter;
import org.eclipse.jdt.internal.ui.text.IJavaPartitions;
import org.eclipse.jdt.internal.ui.text.JavaChangeHover;
import org.eclipse.jdt.internal.ui.text.JavaPairMatcher;
import org.eclipse.jdt.internal.ui.util.JavaUIHelp;
import org.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider;
/**
* Java specific text editor.
*/
public abstract class JavaEditor extends ExtendedTextEditor implements IViewPartInputProvider {
/**
* Internal implementation class for a change listener.
* @since 3.0
*/
protected abstract class AbstractSelectionChangedListener implements ISelectionChangedListener {
/**
* Installs this selection changed listener with the given selection provider. If
* the selection provider is a post selection provider, post selection changed
* events are the preferred choice, otherwise normal selection changed events
* are requested.
*
* @param selectionProvider
*/
public void install(ISelectionProvider selectionProvider) {
if (selectionProvider == null)
return;
if (selectionProvider instanceof IPostSelectionProvider) {
IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
provider.addPostSelectionChangedListener(this);
} else {
selectionProvider.addSelectionChangedListener(this);
}
}
/**
* Removes this selection changed listener from the given selection provider.
*
* @param selectionProvider
*/
public void uninstall(ISelectionProvider selectionProvider) {
if (selectionProvider == null)
return;
if (selectionProvider instanceof IPostSelectionProvider) {
IPostSelectionProvider provider= (IPostSelectionProvider) selectionProvider;
provider.removePostSelectionChangedListener(this);
} else {
selectionProvider.removeSelectionChangedListener(this);
}
}
}
/**
* Updates the Java outline page selection and this editor's range indicator.
*
* @since 3.0
*/
private class EditorSelectionChangedListener extends AbstractSelectionChangedListener {
/*
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
*/
public void selectionChanged(SelectionChangedEvent event) {
selectionChanged();
}
public void selectionChanged() {
ISourceReference element= computeHighlightRangeSourceReference();
synchronizeOutlinePage(element);
setSelection(element, false);
updateStatusLine();
updateOccurrences();
}
}
/**
* Updates the selection in the editor's widget with the selection of the outline page.
*/
class OutlineSelectionChangedListener extends AbstractSelectionChangedListener {
public void selectionChanged(SelectionChangedEvent event) {
doSelectionChanged(event);
}
}
/*
* Link mode.
*/
class MouseClickListener 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;
/**
* Style ranges before link mode.
* @since 3.0
*/
private StyleRange[] fOldStyleRanges;
/**
* Link mode style ranges region.
* @since 3.0
*/
IRegion fOldStyleRangeRegion;
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(BROWSER_LIKE_LINKS_KEY_MODIFIER);
fKeyModifierMask= computeStateMask(modifiers);
if (fKeyModifierMask == -1) {
// Fallback to stored state mask
fKeyModifierMask= getPreferenceStore().getInt(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(JavaEditor.LINK_COLOR)) {
ISourceViewer viewer= getSourceViewer();
if (viewer != null)
updateColor(viewer);
} else if (event.getProperty().equals(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(), JavaEditor.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;
int offset= fActiveRegion.getOffset();
int length= fActiveRegion.getLength();
fActiveRegion= null;
ISourceViewer viewer= getSourceViewer();
if (viewer != null) {
resetCursor(viewer);
// remove style
if (!redrawAll && viewer instanceof ITextViewerExtension2)
((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length);
else
viewer.invalidateTextPresentation();
if (viewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
offset= extension.modelOffset2WidgetOffset(offset);
} else {
offset -= viewer.getVisibleRegion().getOffset();
}
try {
StyledText text= viewer.getTextWidget();
// Removes style
text.replaceStyleRanges(fOldStyleRangeRegion.getOffset(), fOldStyleRangeRegion.getLength(), fOldStyleRanges);
// text.replaceStyleRanges(offset, length, fOldStyleRanges);
// Causes underline to disappear
text.redrawRange(offset, length, false);
} catch (IllegalArgumentException x) {
JavaPlugin.log(x);
}
}
}
// 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;
IJavaElement input= SelectionConverter.getInput(JavaEditor.this);
if (input == 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);
} 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();
}
fOldStyleRanges = text.getStyleRanges(offset, length);
fOldStyleRangeRegion= new Region(offset, length);
applyForgroundStyle(text, offset, length);
text.redrawRange(offset, length, false);
fActiveRegion= region;
}
private void applyForgroundStyle(StyledText fTextWidget, int offset, int length) {
StyleRange[] styleRanges= fTextWidget.getStyleRanges(offset, length);
ArrayList newStyleRanges= new ArrayList(styleRanges.length + 10);
int rangeOffset= offset;
for (int i= 0, max= styleRanges.length; i < max; i++) {
StyleRange sr= styleRanges[i];
if (rangeOffset < sr.start) {
// Unstyled range
StyleRange usr= new StyleRange(rangeOffset, sr.start - rangeOffset, fColor, null);
newStyleRanges.add(usr);
}
rangeOffset= sr.start + sr.length;
// Important: Must create a new one
sr= new StyleRange(sr.start, sr.length, fColor, sr.background, sr.fontStyle);
newStyleRanges.add(sr);
}
int endOffset= offset + length;
if (rangeOffset < endOffset) {
// Last unstyled range
StyleRange usr= new StyleRange(rangeOffset, endOffset - rangeOffset, fColor, null);
newStyleRanges.add(usr);
}
styleRanges= (StyleRange[])newStyleRanges.toArray(new StyleRange[newStyleRanges.size()]);
fTextWidget.replaceStyleRanges(offset, length, styleRanges);
}
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) {
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) {
if (!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();
}
});
}
}
} else {
fActiveRegion= null;
fRememberedPosition= null;
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;
}
}
/**
* This action dispatches into two behaviours: If there is no current text
* hover, the javadoc is displayed using information presenter. If there is
* a current text hover, it is converted into a information presenter in
* order to make it sticky.
*/
class InformationDispatchAction extends TextEditorAction {
/** The wrapped text operation action. */
private final TextOperationAction fTextOperationAction;
/**
* Creates a dispatch action.
*/
public InformationDispatchAction(ResourceBundle resourceBundle, String prefix, final TextOperationAction textOperationAction) {
super(resourceBundle, prefix, JavaEditor.this);
if (textOperationAction == null)
throw new IllegalArgumentException();
fTextOperationAction= textOperationAction;
}
/*
* @see org.eclipse.jface.action.IAction#run()
*/
public void run() {
/**
* Information provider used to present the information.
*
* @since 3.0
*/
class InformationProvider implements IInformationProvider, IInformationProviderExtension2 {
private IRegion fHoverRegion;
private String fHoverInfo;
private IInformationControlCreator fControlCreator;
InformationProvider(IRegion hoverRegion, String hoverInfo, IInformationControlCreator controlCreator) {
fHoverRegion= hoverRegion;
fHoverInfo= hoverInfo;
fControlCreator= controlCreator;
}
/*
* @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int)
*/
public IRegion getSubject(ITextViewer textViewer, int invocationOffset) {
return fHoverRegion;
}
/*
* @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
*/
public String getInformation(ITextViewer textViewer, IRegion subject) {
return fHoverInfo;
}
/*
* @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
* @since 3.0
*/
public IInformationControlCreator getInformationPresenterControlCreator() {
return fControlCreator;
}
}
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer == null) {
fTextOperationAction.run();
return;
}
if (sourceViewer instanceof ITextViewerExtension4) {
ITextViewerExtension4 extension4= (ITextViewerExtension4) sourceViewer;
if (extension4.moveFocusToWidgetToken())
return;
}
if (! (sourceViewer instanceof ITextViewerExtension2)) {
fTextOperationAction.run();
return;
}
ITextViewerExtension2 textViewerExtension2= (ITextViewerExtension2) sourceViewer;
// does a text hover exist?
ITextHover textHover= textViewerExtension2.getCurrentTextHover();
if (textHover == null) {
fTextOperationAction.run();
return;
}
Point hoverEventLocation= textViewerExtension2.getHoverEventLocation();
int offset= computeOffsetAtLocation(sourceViewer, hoverEventLocation.x, hoverEventLocation.y);
if (offset == -1) {
fTextOperationAction.run();
return;
}
try {
// get the text hover content
String contentType= TextUtilities.getContentType(sourceViewer.getDocument(), IJavaPartitions.JAVA_PARTITIONING, offset);
IRegion hoverRegion= textHover.getHoverRegion(sourceViewer, offset);
if (hoverRegion == null)
return;
String hoverInfo= textHover.getHoverInfo(sourceViewer, hoverRegion);
IInformationControlCreator controlCreator= null;
if (textHover instanceof IInformationProviderExtension2)
controlCreator= ((IInformationProviderExtension2)textHover).getInformationPresenterControlCreator();
IInformationProvider informationProvider= new InformationProvider(hoverRegion, hoverInfo, controlCreator);
fInformationPresenter.setOffset(offset);
fInformationPresenter.setInformationProvider(informationProvider, contentType);
fInformationPresenter.showInformation();
} catch (BadLocationException e) {
}
}
// modified version from TextViewer
private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) {
StyledText styledText= textViewer.getTextWidget();
IDocument document= textViewer.getDocument();
if (document == null)
return -1;
try {
int widgetLocation= styledText.getOffsetAtLocation(new Point(x, y));
if (textViewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) textViewer;
return extension.widgetOffset2ModelOffset(widgetLocation);
} else {
IRegion visibleRegion= textViewer.getVisibleRegion();
return widgetLocation + visibleRegion.getOffset();
}
} catch (IllegalArgumentException e) {
return -1;
}
}
}
static protected class AnnotationAccess extends DefaultMarkerAnnotationAccess {
public AnnotationAccess(MarkerAnnotationPreferences markerAnnotationPreferences) {
super(markerAnnotationPreferences);
}
/*
* @see org.eclipse.jface.text.source.IAnnotationAccess#getType(org.eclipse.jface.text.source.Annotation)
*/
public Object getType(Annotation annotation) {
if (annotation instanceof IJavaAnnotation) {
IJavaAnnotation javaAnnotation= (IJavaAnnotation) annotation;
if (javaAnnotation.isRelevant())
return javaAnnotation.getAnnotationType();
return null;
}
return super.getType(annotation);
}
/*
* @see org.eclipse.jface.text.source.IAnnotationAccess#isMultiLine(org.eclipse.jface.text.source.Annotation)
*/
public boolean isMultiLine(Annotation annotation) {
return true;
}
/*
* @see org.eclipse.jface.text.source.IAnnotationAccess#isTemporary(org.eclipse.jface.text.source.Annotation)
*/
public boolean isTemporary(Annotation annotation) {
if (annotation instanceof IJavaAnnotation) {
IJavaAnnotation javaAnnotation= (IJavaAnnotation) annotation;
if (javaAnnotation.isRelevant())
return javaAnnotation.isTemporary();
}
return false;
}
}
private class PropertyChangeListener implements org.eclipse.core.runtime.Preferences.IPropertyChangeListener {
/*
* @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
*/
public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
handlePreferencePropertyChanged(event);
}
}
/**
* This action implements smart home.
*
* Instead of going to the start of a line it does the following:
*
* - if smart home/end is enabled and the caret is after the line's first non-whitespace then the caret is moved directly before it, taking JavaDoc and multi-line comments into account.
* - if the caret is before the line's first non-whitespace the caret is moved to the beginning of the line
* - if the caret is at the beginning of the line see first case.
*
* @since 3.0
*/
protected class SmartLineStartAction extends LineStartAction {
/**
* Creates a new smart line start action
*
* @param textWidget the styled text widget
* @param doSelect a boolean flag which tells if the text up to the beginning of the line should be selected
*/
public SmartLineStartAction(final StyledText textWidget, final boolean doSelect) {
super(textWidget, doSelect);
}
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#getLineStartPosition(java.lang.String, int, java.lang.String)
*/
protected int getLineStartPosition(final IDocument document, final String line, final int length, final int offset) {
String type= IDocument.DEFAULT_CONTENT_TYPE;
try {
type= TextUtilities.getPartition(document, IJavaPartitions.JAVA_PARTITIONING, offset).getType();
} catch (BadLocationException exception) {
// Should not happen
}
int index= super.getLineStartPosition(document, line, length, offset);
if (type.equals(IJavaPartitions.JAVA_DOC) || type.equals(IJavaPartitions.JAVA_MULTI_LINE_COMMENT)) {
if (index < length - 1 && line.charAt(index) == '*' && line.charAt(index + 1) != '/') {
do {
++index;
} while (index < length && Character.isWhitespace(line.charAt(index)));
}
} else {
if (index < length - 1 && line.charAt(index) == '/' && line.charAt(++index) == '/') {
do {
++index;
} while (index < length && Character.isWhitespace(line.charAt(index)));
}
}
return index;
}
}
/**
* Text navigation action to navigate to the next sub-word.
*
* @since 3.0
*/
protected abstract class NextSubWordAction extends TextNavigationAction {
/** Collator to determine the sub-word boundaries */
private final RuleBasedCollator fCollator= (RuleBasedCollator)Collator.getInstance();
/**
* Creates a new next sub-word action.
*
* @param code Action code for the default operation. Must be an action code from @see org.eclipse.swt.custom.ST.
*/
protected NextSubWordAction(int code) {
super(getSourceViewer().getTextWidget(), code);
// Only compare upper-/lower case
fCollator.setStrength(Collator.TERTIARY);
}
/*
* @see org.eclipse.jface.action.IAction#run()
*/
public void run() {
try {
final ISourceViewer viewer= getSourceViewer();
final IDocument document= viewer.getDocument();
int position= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
// Check whether we are in a java code partititon and the preference is enabled
final IPreferenceStore store= getPreferenceStore();
final ITypedRegion region= TextUtilities.getPartition(document, IJavaPartitions.JAVA_PARTITIONING, position);
if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
super.run();
return;
}
// Check whether right hand character of caret is valid identifier start
if (Character.isJavaIdentifierStart(document.getChar(position))) {
int offset= 0;
int order= CollationElementIterator.NULLORDER;
short previous= Short.MAX_VALUE;
short next= Short.MAX_VALUE;
// Acquire collator for partition around caret
final String buffer= document.get(position, region.getOffset() + region.getLength() - position);
final CollationElementIterator iterator= fCollator.getCollationElementIterator(buffer);
// Iterate to first upper-case character
do {
// Check whether we reached end of word
offset= iterator.getOffset();
if (!Character.isJavaIdentifierPart(document.getChar(position + offset)))
throw new BadLocationException();
// Test next characters
order= iterator.next();
next= CollationElementIterator.tertiaryOrder(order);
if (next <= previous)
previous= next;
else
break;
} while (order != CollationElementIterator.NULLORDER);
// Check for leading underscores
position += offset;
if (Character.getType(document.getChar(position - 1)) != Character.CONNECTOR_PUNCTUATION) {
setCaretPosition(position);
getTextWidget().showSelection();
fireSelectionChanged();
return;
}
}
} catch (BadLocationException exception) {
// Use default behavior
}
super.run();
}
/**
* Sets the caret position to the sub-word boundary given with <code>position</code>.
*
* @param position Position where the action should move the caret
*/
protected abstract void setCaretPosition(int position);
}
/**
* Text navigation action to navigate to the next sub-word.
*
* @since 3.0
*/
protected class NavigateNextSubWordAction extends NextSubWordAction {
/**
* Creates a new navigate next sub-word action.
*/
public NavigateNextSubWordAction() {
super(ST.WORD_NEXT);
}
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
*/
protected void setCaretPosition(final int position) {
getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
}
}
/**
* Text operation action to delete the next sub-word.
*
* @since 3.0
*/
protected class DeleteNextSubWordAction extends NextSubWordAction {
/**
* Creates a new delete next sub-word action.
*/
public DeleteNextSubWordAction() {
super(ST.DELETE_WORD_NEXT);
}
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
*/
protected void setCaretPosition(final int position) {
final ISourceViewer viewer= getSourceViewer();
final int caret= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
try {
viewer.getDocument().replace(caret, position - caret, ""); //$NON-NLS-1$
} catch (BadLocationException exception) {
// Should not happen
}
}
}
/**
* Text operation action to select the next sub-word.
*
* @since 3.0
*/
protected class SelectNextSubWordAction extends NextSubWordAction {
/**
* Creates a new select next sub-word action.
*/
public SelectNextSubWordAction() {
super(ST.SELECT_WORD_NEXT);
}
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
*/
protected void setCaretPosition(final int position) {
final ISourceViewer viewer= getSourceViewer();
final StyledText text= viewer.getTextWidget();
if (text != null && !text.isDisposed()) {
final Point selection= text.getSelection();
final int caret= text.getCaretOffset();
final int offset= modelOffset2WidgetOffset(viewer, position);
if (caret == selection.x)
text.setSelectionRange(selection.y, offset - selection.y);
else
text.setSelectionRange(selection.x, offset - selection.x);
}
}
}
/**
* Text navigation action to navigate to the previous sub-word.
*
* @since 3.0
*/
protected abstract class PreviousSubWordAction extends TextNavigationAction {
/** Collator to determine the sub-word boundaries */
private final RuleBasedCollator fCollator= (RuleBasedCollator)Collator.getInstance();
/**
* Creates a new previous sub-word action.
*
* @param code Action code for the default operation. Must be an action code from @see org.eclipse.swt.custom.ST.
*/
protected PreviousSubWordAction(final int code) {
super(getSourceViewer().getTextWidget(), code);
// Only compare upper-/lower case
fCollator.setStrength(Collator.TERTIARY);
}
/*
* @see org.eclipse.jface.action.IAction#run()
*/
public void run() {
try {
final ISourceViewer viewer= getSourceViewer();
final IDocument document= viewer.getDocument();
int position= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()) - 1;
// Check whether we are in a java code partititon and the preference is enabled
final IPreferenceStore store= getPreferenceStore();
if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
super.run();
return;
}
// Ignore trailing white spaces
char character= document.getChar(position);
while (position > 0 && Character.isWhitespace(character)) {
--position;
character= document.getChar(position);
}
// Check whether left hand character of caret is valid identifier part
if (Character.isJavaIdentifierPart(character)) {
int offset= 0;
int order= CollationElementIterator.NULLORDER;
short previous= Short.MAX_VALUE;
short next= Short.MAX_VALUE;
// Acquire collator for partition around caret
final ITypedRegion region= TextUtilities.getPartition(document, IJavaPartitions.JAVA_PARTITIONING, position);
final String buffer= document.get(region.getOffset(), position - region.getOffset() + 1);
final CollationElementIterator iterator= fCollator.getCollationElementIterator(buffer);
// Iterate to first upper-case character
iterator.setOffset(buffer.length() - 1);
do {
// Check whether we reached begin of word or single upper-case start
offset= iterator.getOffset();
character= document.getChar(region.getOffset() + offset);
if (!Character.isJavaIdentifierPart(character))
throw new BadLocationException();
else if (Character.isUpperCase(character)) {
++offset;
break;
}
// Test next characters
order= iterator.previous();
next= CollationElementIterator.tertiaryOrder(order);
if (next <= previous)
previous= next;
else
break;
} while (order != CollationElementIterator.NULLORDER);
// Check left character for multiple upper-case characters
position= position - buffer.length() + offset - 1;
character= document.getChar(position);
while (position >= 0 && Character.isUpperCase(character))
character= document.getChar(--position);
setCaretPosition(position + 1);
getTextWidget().showSelection();
fireSelectionChanged();
return;
}
} catch (BadLocationException exception) {
// Use default behavior
}
super.run();
}
/**
* Sets the caret position to the sub-word boundary given with <code>position</code>.
*
* @param position Position where the action should move the caret
*/
protected abstract void setCaretPosition(int position);
}
/**
* Text navigation action to navigate to the previous sub-word.
*
* @since 3.0
*/
protected class NavigatePreviousSubWordAction extends PreviousSubWordAction {
/**
* Creates a new navigate previous sub-word action.
*/
public NavigatePreviousSubWordAction() {
super(ST.WORD_PREVIOUS);
}
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
*/
protected void setCaretPosition(final int position) {
getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
}
}
/**
* Text operation action to delete the previous sub-word.
*
* @since 3.0
*/
protected class DeletePreviousSubWordAction extends PreviousSubWordAction {
/**
* Creates a new delete previous sub-word action.
*/
public DeletePreviousSubWordAction() {
super(ST.DELETE_WORD_PREVIOUS);
}
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
*/
protected void setCaretPosition(final int position) {
final ISourceViewer viewer= getSourceViewer();
final int caret= widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
try {
viewer.getDocument().replace(position, caret - position, ""); //$NON-NLS-1$
} catch (BadLocationException exception) {
// Should not happen
}
}
}
/**
* Text operation action to select the previous sub-word.
*
* @since 3.0
*/
protected class SelectPreviousSubWordAction extends PreviousSubWordAction {
/**
* Creates a new select previous sub-word action.
*/
public SelectPreviousSubWordAction() {
super(ST.SELECT_WORD_PREVIOUS);
}
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
*/
protected void setCaretPosition(final int position) {
final ISourceViewer viewer= getSourceViewer();
final StyledText text= viewer.getTextWidget();
if (text != null && !text.isDisposed()) {
final Point selection= text.getSelection();
final int caret= text.getCaretOffset();
final int offset= modelOffset2WidgetOffset(viewer, position);
if (caret == selection.x)
text.setSelectionRange(selection.y, offset - selection.y);
else
text.setSelectionRange(selection.x, offset - selection.x);
}
}
}
/**
* Quick format action to format the enclosing java element.
* <p>
* The quick format action works as follows:
* <ul>
* <li>If there is no selection and the caret is positioned on a Java element,
* only this element is formatted. If the element has some accompanying comment,
* then the comment is formatted as well.</li>
* <li>If the selection spans one or more partitions of the document, then all
* partitions covered by the selection are entirely formatted.</li>
* <p>
* Partitions at the end of the selection are not completed, except for comments.
*
* @since 3.0
*/
protected class QuickFormatAction extends Action {
/*
* @see org.eclipse.jface.action.IAction#run()
*/
public void run() {
final JavaSourceViewer viewer= (JavaSourceViewer) getSourceViewer();
if (viewer.isEditable()) {
final Point selection= viewer.rememberSelection();
try {
viewer.setRedraw(false);
final String type= TextUtilities.getContentType(viewer.getDocument(), IJavaPartitions.JAVA_PARTITIONING, selection.x);
if (type.equals(IDocument.DEFAULT_CONTENT_TYPE) && selection.y == 0) {
try {
final IJavaElement element= getElementAt(selection.x, true);
if (element != null && element.exists()) {
final int kind= element.getElementType();
if (kind == IJavaElement.TYPE || kind == IJavaElement.METHOD || kind == IJavaElement.INITIALIZER) {
final ISourceReference reference= (ISourceReference)element;
final ISourceRange range= reference.getSourceRange();
if (range != null) {
viewer.setSelectedRange(range.getOffset(), range.getLength());
viewer.doOperation(ISourceViewer.FORMAT);
}
}
}
} catch (JavaModelException exception) {
// Should not happen
}
} else {
viewer.setSelectedRange(selection.x, 1);
viewer.doOperation(ISourceViewer.FORMAT);
}
} catch (BadLocationException exception) {
// Can not happen
} finally {
viewer.setRedraw(true);
viewer.restoreSelection();
}
}
}
}
/** Preference key for the link color */
protected final static String LINK_COLOR= PreferenceConstants.EDITOR_LINK_COLOR;
/** Preference key for matching brackets */
protected final static String MATCHING_BRACKETS= PreferenceConstants.EDITOR_MATCHING_BRACKETS;
/** Preference key for matching brackets color */
protected final static String MATCHING_BRACKETS_COLOR= PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
/** Preference key for compiler task tags */
private final static String COMPILER_TASK_TAGS= JavaCore.COMPILER_TASK_TAGS;
/** Preference key for browser like links */
private final static String BROWSER_LIKE_LINKS= PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS;
/** Preference key for key modifier of browser like links */
private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER= PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER;
/**
* Preference key for key modifier mask of browser like links.
* The value is only used if the value of <code>EDITOR_BROWSER_LIKE_LINKS</code>
* cannot be resolved to valid SWT modifier bits.
*
* @since 2.1.1
*/
private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK= PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK;
protected final static char[] BRACKETS= { '{', '}', '(', ')', '[', ']' };
/** The outline page */
protected JavaOutlinePage fOutlinePage;
/** Outliner context menu Id */
protected String fOutlinerContextMenuId;
/**
* The editor selection changed listener.
*
* @since 3.0
*/
private EditorSelectionChangedListener fEditorSelectionChangedListener;
/** The selection changed listener */
protected AbstractSelectionChangedListener fOutlineSelectionChangedListener= new OutlineSelectionChangedListener();
/** The editor's bracket matcher */
protected JavaPairMatcher fBracketMatcher= new JavaPairMatcher(BRACKETS);
/** This editor's encoding support */
private DefaultEncodingSupport fEncodingSupport;
/** The mouse listener */
private MouseClickListener fMouseListener;
/** The information presenter. */
private InformationPresenter fInformationPresenter;
/** History for structure select action */
private SelectionHistory fSelectionHistory;
/** The preference property change listener for java core. */
private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
/**
* Indicates whether this editor is about to update any annotation views.
* @since 3.0
*/
private boolean fIsUpdatingAnnotationViews= false;
/**
* The marker that served as last target for a goto marker request.
* @since 3.0
*/
private IMarker fLastMarkerTarget= null;
protected CompositeActionGroup fActionGroups;
private CompositeActionGroup fContextMenuGroup;
/**
* Holds the current occurrence annotations.
* @since 3.0
*/
private ArrayList fOccurrenceAnnotations= new ArrayList();
/**
* Counts the number of background computation requests.
* @since 3.0
*/
private volatile int fComputeCount;
private boolean fMarkOccurrenceAnnotations;
/**
* Returns the most narrow java element including the given offset.
*
* @param offset the offset inside of the requested element
* @return the most narrow java element
*/
abstract protected IJavaElement getElementAt(int offset);
/**
* Returns the java element of this editor's input corresponding to the given IJavaElement
*/
abstract protected IJavaElement getCorrespondingElement(IJavaElement element);
/**
* Sets the input of the editor's outline page.
*/
abstract protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input);
/**
* Default constructor.
*/
public JavaEditor() {
super();
JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
setSourceViewerConfiguration(new JavaSourceViewerConfiguration(textTools, this, IJavaPartitions.JAVA_PARTITIONING));
setRangeIndicator(new DefaultRangeIndicator());
IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
setPreferenceStore(store);
setKeyBindingScopes(new String[] { "org.eclipse.jdt.ui.javaEditorScope" }); //$NON-NLS-1$
fMarkOccurrenceAnnotations= store.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES);
}
/*
* @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
*/
protected final ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
ISourceViewer viewer= createJavaSourceViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles);
StyledText text= viewer.getTextWidget();
text.addBidiSegmentListener(new BidiSegmentListener() {
public void lineGetSegments(BidiSegmentEvent event) {
event.segments= getBidiLineSegments(event.lineOffset, event.lineText);
}
});
JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
// ensure source viewer decoration support has been created and configured
getSourceViewerDecorationSupport(viewer);
return viewer;
}
/*
* @see org.eclipse.ui.texteditor.ExtendedTextEditor#createAnnotationAccess()
*/
protected IAnnotationAccess createAnnotationAccess() {
return new AnnotationAccess(new MarkerAnnotationPreferences());
}
public final ISourceViewer getViewer() {
return getSourceViewer();
}
/*
* @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
*/
protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean isOverviewRulerVisible, int styles) {
return new JavaSourceViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles);
}
/*
* @see AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
*/
protected boolean affectsTextPresentation(PropertyChangeEvent event) {
JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
return textTools.affectsBehavior(event);
}
/**
* Sets the outliner's context menu ID.
*/
protected void setOutlinerContextMenuId(String menuId) {
fOutlinerContextMenuId= menuId;
}
/**
* Returns the standard action group of this editor.
*/
protected ActionGroup getActionGroup() {
return fActionGroups;
}
/*
* @see AbstractTextEditor#editorContextMenuAboutToShow
*/
public void editorContextMenuAboutToShow(IMenuManager menu) {
super.editorContextMenuAboutToShow(menu);
menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, new Separator(IContextMenuConstants.GROUP_OPEN));
menu.insertAfter(IContextMenuConstants.GROUP_OPEN, new GroupMarker(IContextMenuConstants.GROUP_SHOW));
ActionContext context= new ActionContext(getSelectionProvider().getSelection());
fContextMenuGroup.setContext(context);
fContextMenuGroup.fillContextMenu(menu);
fContextMenuGroup.setContext(null);
}
/**
* Creates the outline page used with this editor.
*/
protected JavaOutlinePage createOutlinePage() {
JavaOutlinePage page= new JavaOutlinePage(fOutlinerContextMenuId, this);
fOutlineSelectionChangedListener.install(page);
setOutlinePageInput(page, getEditorInput());
return page;
}
/**
* Informs the editor that its outliner has been closed.
*/
public void outlinePageClosed() {
if (fOutlinePage != null) {
fOutlineSelectionChangedListener.uninstall(fOutlinePage);
fOutlinePage= null;
resetHighlightRange();
}
}
/**
* Synchronizes the outliner selection with the given element
* position in the editor.
*
* @param element the java element to select
*/
protected void synchronizeOutlinePage(ISourceReference element) {
synchronizeOutlinePage(element, true);
}
/**
* Synchronizes the outliner selection with the given element
* position in the editor.
*
* @param element the java element to select
* @param checkIfOutlinePageActive <code>true</code> if check for active outline page needs to be done
*/
protected void synchronizeOutlinePage(ISourceReference element, boolean checkIfOutlinePageActive) {
if (fOutlinePage != null && element != null && !(checkIfOutlinePageActive && isJavaOutlinePageActive())) {
fOutlineSelectionChangedListener.uninstall(fOutlinePage);
fOutlinePage.select(element);
fOutlineSelectionChangedListener.install(fOutlinePage);
}
}
/**
* Synchronizes the outliner selection with the actual cursor
* position in the editor.
*/
public void synchronizeOutlinePageSelection() {
synchronizeOutlinePage(computeHighlightRangeSourceReference());
}
/*
* Get the desktop's StatusLineManager
*/
protected IStatusLineManager getStatusLineManager() {
IEditorActionBarContributor contributor= getEditorSite().getActionBarContributor();
if (contributor instanceof EditorActionBarContributor) {
return ((EditorActionBarContributor) contributor).getActionBars().getStatusLineManager();
}
return null;
}
/*
* @see AbstractTextEditor#getAdapter(Class)
*/
public Object getAdapter(Class required) {
if (IContentOutlinePage.class.equals(required)) {
if (fOutlinePage == null)
fOutlinePage= createOutlinePage();
return fOutlinePage;
}
if (IEncodingSupport.class.equals(required))
return fEncodingSupport;
if (required == IShowInTargetList.class) {
return new IShowInTargetList() {
public String[] getShowInTargetIds() {
return new String[] { JavaUI.ID_PACKAGES, IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV };
}
};
}
return super.getAdapter(required);
}
protected void setSelection(ISourceReference reference, boolean moveCursor) {
ISelection selection= getSelectionProvider().getSelection();
if (selection instanceof TextSelection) {
TextSelection textSelection= (TextSelection) selection;
// PR 39995: [navigation] Forward history cleared after going back in navigation history:
// mark only in navigation history if the cursor is being moved (which it isn't if
// this is called from a PostSelectionEvent that should only update the magnet)
if (moveCursor && (textSelection.getOffset() != 0 || textSelection.getLength() != 0))
markInNavigationHistory();
}
if (reference != null) {
StyledText textWidget= null;
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer != null)
textWidget= sourceViewer.getTextWidget();
if (textWidget == null)
return;
try {
ISourceRange range= reference.getSourceRange();
if (range == null)
return;
int offset= range.getOffset();
int length= range.getLength();
if (offset < 0 || length < 0)
return;
setHighlightRange(offset, length, moveCursor);
if (!moveCursor)
return;
offset= -1;
length= -1;
if (reference instanceof IMember) {
range= ((IMember) reference).getNameRange();
if (range != null) {
offset= range.getOffset();
length= range.getLength();
}
} else if (reference instanceof IImportDeclaration) {
String name= ((IImportDeclaration) reference).getElementName();
if (name != null && name.length() > 0) {
String content= reference.getSource();
if (content != null) {
offset= range.getOffset() + content.indexOf(name);
length= name.length();
}
}
} else if (reference instanceof IPackageDeclaration) {
String name= ((IPackageDeclaration) reference).getElementName();
if (name != null && name.length() > 0) {
String content= reference.getSource();
if (content != null) {
offset= range.getOffset() + content.indexOf(name);
length= name.length();
}
}
}
if (offset > -1 && length > 0) {
try {
textWidget.setRedraw(false);
sourceViewer.revealRange(offset, length);
sourceViewer.setSelectedRange(offset, length);
} finally {
textWidget.setRedraw(true);
}
markInNavigationHistory();
}
} catch (JavaModelException x) {
} catch (IllegalArgumentException x) {
}
} else if (moveCursor) {
resetHighlightRange();
markInNavigationHistory();
}
}
public void setSelection(IJavaElement element) {
if (element == null || element instanceof ICompilationUnit || element instanceof IClassFile) {
/*
* If the element is an ICompilationUnit this unit is either the input
* of this editor or not being displayed. In both cases, nothing should
* happened. (http://dev.eclipse.org/bugs/show_bug.cgi?id=5128)
*/
return;
}
IJavaElement corresponding= getCorrespondingElement(element);
if (corresponding instanceof ISourceReference) {
ISourceReference reference= (ISourceReference) corresponding;
// set hightlight range
setSelection(reference, true);
// set outliner selection
if (fOutlinePage != null) {
fOutlineSelectionChangedListener.uninstall(fOutlinePage);
fOutlinePage.select(reference);
fOutlineSelectionChangedListener.install(fOutlinePage);
}
}
}
protected void doSelectionChanged(SelectionChangedEvent event) {
ISourceReference reference= null;
ISelection selection= event.getSelection();
Iterator iter= ((IStructuredSelection) selection).iterator();
while (iter.hasNext()) {
Object o= iter.next();
if (o instanceof ISourceReference) {
reference= (ISourceReference) o;
break;
}
}
if (!isActivePart() && JavaPlugin.getActivePage() != null)
JavaPlugin.getActivePage().bringToTop(this);
setSelection(reference, !isActivePart());
}
/*
* @see AbstractTextEditor#adjustHighlightRange(int, int)
*/
protected void adjustHighlightRange(int offset, int length) {
try {
IJavaElement element= getElementAt(offset);
while (element instanceof ISourceReference) {
ISourceRange range= ((ISourceReference) element).getSourceRange();
if (offset < range.getOffset() + range.getLength() && range.getOffset() < offset + length) {
setHighlightRange(range.getOffset(), range.getLength(), true);
if (fOutlinePage != null) {
fOutlineSelectionChangedListener.uninstall(fOutlinePage);
fOutlinePage.select((ISourceReference) element);
fOutlineSelectionChangedListener.install(fOutlinePage);
}
return;
}
element= element.getParent();
}
} catch (JavaModelException x) {
JavaPlugin.log(x.getStatus());
}
resetHighlightRange();
}
protected boolean isActivePart() {
IWorkbenchPart part= getActivePart();
return part != null && part.equals(this);
}
private boolean isJavaOutlinePageActive() {
IWorkbenchPart part= getActivePart();
return part instanceof ContentOutline && ((ContentOutline)part).getCurrentPage() == fOutlinePage;
}
private IWorkbenchPart getActivePart() {
IWorkbenchWindow window= getSite().getWorkbenchWindow();
IPartService service= window.getPartService();
IWorkbenchPart part= service.getActivePart();
return part;
}
/*
* @see StatusTextEditor#getStatusHeader(IStatus)
*/
protected String getStatusHeader(IStatus status) {
if (fEncodingSupport != null) {
String message= fEncodingSupport.getStatusHeader(status);
if (message != null)
return message;
}
return super.getStatusHeader(status);
}
/*
* @see StatusTextEditor#getStatusBanner(IStatus)
*/
protected String getStatusBanner(IStatus status) {
if (fEncodingSupport != null) {
String message= fEncodingSupport.getStatusBanner(status);
if (message != null)
return message;
}
return super.getStatusBanner(status);
}
/*
* @see StatusTextEditor#getStatusMessage(IStatus)
*/
protected String getStatusMessage(IStatus status) {
if (fEncodingSupport != null) {
String message= fEncodingSupport.getStatusMessage(status);
if (message != null)
return message;
}
return super.getStatusMessage(status);
}
/*
* @see AbstractTextEditor#doSetInput
*/
protected void doSetInput(IEditorInput input) throws CoreException {
super.doSetInput(input);
if (fEncodingSupport != null)
fEncodingSupport.reset();
setOutlinePageInput(fOutlinePage, input);
}
/*
* @see IWorkbenchPart#dispose()
*/
public void dispose() {
// cancel possible running computation
fMarkOccurrenceAnnotations= false;
fComputeCount++;
if (isBrowserLikeLinks())
disableBrowserLikeLinks();
if (fEncodingSupport != null) {
fEncodingSupport.dispose();
fEncodingSupport= null;
}
if (fPropertyChangeListener != null) {
Preferences preferences= JavaCore.getPlugin().getPluginPreferences();
preferences.removePropertyChangeListener(fPropertyChangeListener);
fPropertyChangeListener= null;
}
if (fBracketMatcher != null) {
fBracketMatcher.dispose();
fBracketMatcher= null;
}
if (fSelectionHistory != null) {
fSelectionHistory.dispose();
fSelectionHistory= null;
}
if (fEditorSelectionChangedListener != null) {
fEditorSelectionChangedListener.uninstall(getSelectionProvider());
fEditorSelectionChangedListener= null;
}
super.dispose();
}
protected void createActions() {
super.createActions();
ResourceAction resAction= new AddTaskAction(JavaEditorMessages.getResourceBundle(), "AddTask.", this); //$NON-NLS-1$
resAction.setHelpContextId(IAbstractTextEditorHelpContextIds.ADD_TASK_ACTION);
resAction.setActionDefinitionId(ITextEditorActionDefinitionIds.ADD_TASK);
setAction(ITextEditorActionConstants.ADD_TASK, resAction);
ActionGroup oeg, ovg, jsg, sg;
fActionGroups= new CompositeActionGroup(new ActionGroup[] {
oeg= new OpenEditorActionGroup(this),
sg= new ShowActionGroup(this),
ovg= new OpenViewActionGroup(this),
jsg= new JavaSearchActionGroup(this)
});
fContextMenuGroup= new CompositeActionGroup(new ActionGroup[] {oeg, ovg, sg, jsg});
resAction= new TextOperationAction(JavaEditorMessages.getResourceBundle(), "ShowJavaDoc.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$
resAction= new InformationDispatchAction(JavaEditorMessages.getResourceBundle(), "ShowJavaDoc.", (TextOperationAction) resAction); //$NON-NLS-1$
resAction.setActionDefinitionId(IJavaEditorActionDefinitionIds.SHOW_JAVADOC);
setAction("ShowJavaDoc", resAction); //$NON-NLS-1$
WorkbenchHelp.setHelp(resAction, IJavaHelpContextIds.SHOW_JAVADOC_ACTION);
Action action= new GotoMatchingBracketAction(this);
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);
action= new TextOperationAction(JavaEditorMessages.getResourceBundle(),"ShowOutline.", this, JavaSourceViewer.SHOW_OUTLINE, true); //$NON-NLS-1$
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.SHOW_OUTLINE);
setAction(IJavaEditorActionDefinitionIds.SHOW_OUTLINE, action);
WorkbenchHelp.setHelp(action, IJavaHelpContextIds.SHOW_OUTLINE_ACTION);
action= new TextOperationAction(JavaEditorMessages.getResourceBundle(),"OpenStructure.", this, JavaSourceViewer.OPEN_STRUCTURE, true); //$NON-NLS-1$
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.OPEN_STRUCTURE);
setAction(IJavaEditorActionDefinitionIds.OPEN_STRUCTURE, action);
WorkbenchHelp.setHelp(action, IJavaHelpContextIds.OPEN_STRUCTURE_ACTION);
action= new TextOperationAction(JavaEditorMessages.getResourceBundle(),"OpenHierarchy.", this, JavaSourceViewer.SHOW_HIERARCHY, true); //$NON-NLS-1$
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.OPEN_HIERARCHY);
setAction(IJavaEditorActionDefinitionIds.OPEN_HIERARCHY, action);
WorkbenchHelp.setHelp(action, IJavaHelpContextIds.OPEN_HIERARCHY_ACTION);
fEncodingSupport= new DefaultEncodingSupport();
fEncodingSupport.initialize(this);
fSelectionHistory= new SelectionHistory(this);
action= new StructureSelectEnclosingAction(this, fSelectionHistory);
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.SELECT_ENCLOSING);
setAction(StructureSelectionAction.ENCLOSING, action);
action= new StructureSelectNextAction(this, fSelectionHistory);
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.SELECT_NEXT);
setAction(StructureSelectionAction.NEXT, action);
action= new StructureSelectPreviousAction(this, fSelectionHistory);
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.SELECT_PREVIOUS);
setAction(StructureSelectionAction.PREVIOUS, action);
StructureSelectHistoryAction historyAction= new StructureSelectHistoryAction(this, fSelectionHistory);
historyAction.setActionDefinitionId(IJavaEditorActionDefinitionIds.SELECT_LAST);
setAction(StructureSelectionAction.HISTORY, historyAction);
fSelectionHistory.setHistoryAction(historyAction);
action= GoToNextPreviousMemberAction.newGoToNextMemberAction(this);
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.GOTO_NEXT_MEMBER);
setAction(GoToNextPreviousMemberAction.NEXT_MEMBER, action);
action= GoToNextPreviousMemberAction.newGoToPreviousMemberAction(this);
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER);
setAction(GoToNextPreviousMemberAction.PREVIOUS_MEMBER, action);
action= new QuickFormatAction();
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.QUICK_FORMAT);
setAction(IJavaEditorActionDefinitionIds.QUICK_FORMAT, action);
action= new RemoveOccurrenceAnnotations(this);
action.setActionDefinitionId(IJavaEditorActionDefinitionIds.REMOVE_OCCURRENCE_ANNOTATIONS);
setAction("RemoveOccurrenceAnnotations", action); //$NON-NLS-1$
}
public void updatedTitleImage(Image image) {
setTitleImage(image);
}
/*
* @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
*/
protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
try {
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer == null)
return;
String property= event.getProperty();
if (PreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
Object value= event.getNewValue();
if (value instanceof Integer) {
sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
} else if (value instanceof String) {
sourceViewer.getTextWidget().setTabs(Integer.parseInt((String) value));
}
return;
}
if (isJavaEditorHoverProperty(property))
updateHoverBehavior();
if (BROWSER_LIKE_LINKS.equals(property)) {
if (isBrowserLikeLinks())
enableBrowserLikeLinks();
else
disableBrowserLikeLinks();
return;
}
if (PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE.equals(property)) {
if ((event.getNewValue() instanceof Boolean) && ((Boolean)event.getNewValue()).booleanValue()) {
fEditorSelectionChangedListener= new EditorSelectionChangedListener();
fEditorSelectionChangedListener.install(getSelectionProvider());
fEditorSelectionChangedListener.selectionChanged();
} else {
fEditorSelectionChangedListener.uninstall(getSelectionProvider());
fEditorSelectionChangedListener= null;
}
return;
}
if (PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE.equals(property)) {
if (event.getNewValue() instanceof Boolean) {
Boolean disable= (Boolean) event.getNewValue();
configureInsertMode(OVERWRITE, !disable.booleanValue());
}
}
if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) {
if (event.getNewValue() instanceof Boolean) {
fMarkOccurrenceAnnotations= ((Boolean)event.getNewValue()).booleanValue();
if (!fMarkOccurrenceAnnotations) {
fComputeCount++;
removeOccurrenceAnnotations();
}
}
}
} finally {
super.handlePreferenceStoreChanged(event);
}
}
/**
* Initializes the given viewer's colors.
*
* @param viewer the viewer to be initialized
* @since 3.0
*/
protected void initializeViewerColors(ISourceViewer viewer) {
// is handled by JavaSourceViewer
}
private boolean isJavaEditorHoverProperty(String property) {
return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property);
}
/**
* Return whether the browser like links should be enabled
* according to the preference store settings.
* @return <code>true</code> if the browser like links should be enabled
*/
private boolean isBrowserLikeLinks() {
IPreferenceStore store= getPreferenceStore();
return store.getBoolean(BROWSER_LIKE_LINKS);
}
/**
* Enables browser like links.
*/
private void enableBrowserLikeLinks() {
if (fMouseListener == null) {
fMouseListener= new MouseClickListener();
fMouseListener.install();
}
}
/**
* Disables browser like links.
*/
private void disableBrowserLikeLinks() {
if (fMouseListener != null) {
fMouseListener.uninstall();
fMouseListener= null;
}
}
/**
* Handles a property change event describing a change
* of the java core's preferences and updates the preference
* related editor properties.
*
* @param event the property change event
*/
protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer != null && affectsTextPresentation(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue())))
sourceViewer.invalidateTextPresentation();
}
}
/**
* Returns a segmentation of the line of the given viewer's input document appropriate for
* bidi rendering. The default implementation returns only the string literals of a java code
* line as segments.
*
* @param viewer the text viewer
* @param lineOffset the offset of the line
* @return the line's bidi segmentation
* @throws BadLocationException in case lineOffset is not valid in document
*/
public static int[] getBidiLineSegments(ITextViewer viewer, int lineOffset) throws BadLocationException {
IDocument document= viewer.getDocument();
if (document == null)
return null;
IRegion line= document.getLineInformationOfOffset(lineOffset);
ITypedRegion[] linePartitioning= TextUtilities.computePartitioning(document, IJavaPartitions.JAVA_PARTITIONING, lineOffset, line.getLength());
List segmentation= new ArrayList();
for (int i= 0; i < linePartitioning.length; i++) {
if (IJavaPartitions.JAVA_STRING.equals(linePartitioning[i].getType()))
segmentation.add(linePartitioning[i]);
}
if (segmentation.size() == 0)
return null;
int size= segmentation.size();
int[] segments= new int[size * 2 + 1];
int j= 0;
for (int i= 0; i < size; i++) {
ITypedRegion segment= (ITypedRegion) segmentation.get(i);
if (i == 0)
segments[j++]= 0;
int offset= segment.getOffset() - lineOffset;
if (offset > segments[j - 1])
segments[j++]= offset;
if (offset + segment.getLength() >= line.getLength())
break;
segments[j++]= offset + segment.getLength();
}
if (j < segments.length) {
int[] result= new int[j];
System.arraycopy(segments, 0, result, 0, j);
segments= result;
}
return segments;
}
/**
* Returns a segmentation of the given line appropriate for bidi rendering. The default
* implementation returns only the string literals of a java code line as segments.
*
* @param lineOffset the offset of the line
* @param line the content of the line
* @return the line's bidi segmentation
*/
protected int[] getBidiLineSegments(int widgetLineOffset, String line) {
if (line != null && line.length() > 0) {
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer != null) {
int lineOffset;
if (sourceViewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) sourceViewer;
lineOffset= extension.widgetOffset2ModelOffset(widgetLineOffset);
} else {
IRegion visible= sourceViewer.getVisibleRegion();
lineOffset= visible.getOffset() + widgetLineOffset;
}
try {
return getBidiLineSegments(sourceViewer, lineOffset);
} catch (BadLocationException x) {
// don't segment line in this case
}
}
}
return null;
}
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#updatePropertyDependentActions()
*/
protected void updatePropertyDependentActions() {
super.updatePropertyDependentActions();
if (fEncodingSupport != null)
fEncodingSupport.reset();
}
/*
* Update the hovering behavior depending on the preferences.
*/
private void updateHoverBehavior() {
SourceViewerConfiguration configuration= getSourceViewerConfiguration();
String[] types= configuration.getConfiguredContentTypes(getSourceViewer());
for (int i= 0; i < types.length; i++) {
String t= types[i];
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer instanceof ITextViewerExtension2) {
// Remove existing hovers
((ITextViewerExtension2)sourceViewer).removeTextHovers(t);
int[] stateMasks= configuration.getConfiguredTextHoverStateMasks(getSourceViewer(), t);
if (stateMasks != null) {
for (int j= 0; j < stateMasks.length; j++) {
int stateMask= stateMasks[j];
ITextHover textHover= configuration.getTextHover(sourceViewer, t, stateMask);
((ITextViewerExtension2)sourceViewer).setTextHover(textHover, t, stateMask);
}
} else {
ITextHover textHover= configuration.getTextHover(sourceViewer, t);
((ITextViewerExtension2)sourceViewer).setTextHover(textHover, t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
}
} else
sourceViewer.setTextHover(configuration.getTextHover(sourceViewer, t), t);
}
}
/*
* @see org.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
*/
public Object getViewPartInput() {
return getEditorInput().getAdapter(IJavaElement.class);
}
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection)
*/
protected void doSetSelection(ISelection selection) {
super.doSetSelection(selection);
synchronizeOutlinePageSelection();
}
/*
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
super.createPartControl(parent);
Preferences preferences= JavaCore.getPlugin().getPluginPreferences();
preferences.addPropertyChangeListener(fPropertyChangeListener);
IInformationControlCreator informationControlCreator= new IInformationControlCreator() {
public IInformationControl createInformationControl(Shell shell) {
boolean cutDown= false;
int style= cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
return new DefaultInformationControl(shell, SWT.RESIZE, style, new HTMLTextPresenter(cutDown));
}
};
fInformationPresenter= new InformationPresenter(informationControlCreator);
fInformationPresenter.setSizeConstraints(60, 10, true, true);
fInformationPresenter.install(getSourceViewer());
if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE)) {
fEditorSelectionChangedListener= new EditorSelectionChangedListener();
fEditorSelectionChangedListener.install(getSelectionProvider());
}
if (isBrowserLikeLinks())
enableBrowserLikeLinks();
if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE))
configureInsertMode(OVERWRITE, false);
}
protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
support.setCharacterPairMatcher(fBracketMatcher);
support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
super.configureSourceViewerDecorationSupport(support);
}
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#gotoMarker(org.eclipse.core.resources.IMarker)
*/
public void gotoMarker(IMarker marker) {
fLastMarkerTarget= marker;
if (!fIsUpdatingAnnotationViews)
super.gotoMarker(marker);
}
/**
* Jumps to the next enabled annotation according to the given direction.
* An annotation type is enabled if it is configured to be in the
* Next/Previous tool bar drop down menu and if it is checked.
*
* @param forward <code>true</code> if search direction is forward, <code>false</code> if backward
*/
public void gotoAnnotation(boolean forward) {
ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection();
Position position= new Position(0, 0);
if (false /* delayed - see bug 18316 */) {
getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
selectAndReveal(position.getOffset(), position.getLength());
} else /* no delay - see bug 18316 */ {
Annotation annotation= getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
setStatusLineErrorMessage(null);
setStatusLineMessage(null);
if (annotation != null) {
updateAnnotationViews(annotation);
selectAndReveal(position.getOffset(), position.getLength());
if (annotation instanceof IJavaAnnotation && ((IJavaAnnotation)annotation).isProblem())
setStatusLineMessage(((IJavaAnnotation)annotation).getMessage());
}
}
}
/**
* Updates the annotation views that show the given annotation.
*
* @param annotation the annotation
*/
private void updateAnnotationViews(Annotation annotation) {
IMarker marker= null;
if (annotation instanceof MarkerAnnotation)
marker= ((MarkerAnnotation) annotation).getMarker();
else if (annotation instanceof IJavaAnnotation) {
Iterator e= ((IJavaAnnotation) annotation).getOverlaidIterator();
if (e != null) {
while (e.hasNext()) {
Object o= e.next();
if (o instanceof MarkerAnnotation) {
marker= ((MarkerAnnotation) o).getMarker();
break;
}
}
}
}
if (marker != null && !marker.equals(fLastMarkerTarget)) {
try {
boolean isProblem= marker.isSubtypeOf(IMarker.PROBLEM);
IWorkbenchPage page= getSite().getPage();
IViewPart view= page.findView(isProblem ? IPageLayout.ID_PROBLEM_VIEW: IPageLayout.ID_TASK_LIST); //$NON-NLS-1$ //$NON-NLS-2$
if (view != null) {
Method method= view.getClass().getMethod("setSelection", new Class[] { IStructuredSelection.class, boolean.class}); //$NON-NLS-1$
method.invoke(view, new Object[] {new StructuredSelection(marker), Boolean.TRUE });
}
} catch (CoreException x) {
} catch (NoSuchMethodException x) {
} catch (IllegalAccessException x) {
} catch (InvocationTargetException x) {
}
// ignore exceptions, don't update any of the lists, just set statusline
}
}
/**
* Finds and marks occurrence annotations.
*
* @since 3.0
*/
class OccurrencesFinder implements Runnable, IDocumentListener {
private int fCount;
private IDocument fDocument;
private ITextSelection fSelection;
private boolean fCancelled= false;
public OccurrencesFinder(int count, IDocument document, ITextSelection selection) {
fCount= count;
fDocument= document;
fSelection= selection;
fDocument.addDocumentListener(this);
}
private boolean isCancelled() {
return fCount != fComputeCount || fCancelled;
}
/*
* @see java.lang.Runnable#run()
*/
public void run() {
try {
if (isCancelled())
return;
// Find occurrences
FindOccurrencesEngine engine= FindOccurrencesEngine.create(getInputJavaElement());
List matches= new ArrayList();
try {
matches= engine.findOccurrences(fSelection.getOffset(), fSelection.getLength());
} catch (JavaModelException e) {
JavaPlugin.log(e);
return;
}
if (matches == null || matches.isEmpty())
return;
if (isCancelled())
return;
removeOccurrenceAnnotations();
if (isCancelled())
return;
ITextViewer textViewer= getViewer();
if (textViewer == null)
return;
IDocument document= textViewer.getDocument();
if (document == null)
return;
IDocumentProvider documentProvider= getDocumentProvider();
if (documentProvider == null)
return;
IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
if (annotationModel == null)
return;
// Add occurrence annotations
ArrayList annotations= new ArrayList();
ArrayList positions= new ArrayList();
for (Iterator each= matches.iterator(); each.hasNext();) {
if (isCancelled())
return;
ASTNode node= (ASTNode) each.next();
if (node == null)
continue;
String message;
// Create & add annotation
try {
message= document.get(node.getStartPosition(), node.getLength());
} catch (BadLocationException ex) {
// Skip this match
continue;
}
annotations.add(new DefaultAnnotation(SearchUI.SEARCH_MARKER, IMarker.SEVERITY_INFO, true, message));
positions.add(new Position(node.getStartPosition(), node.getLength()));
}
if (isCancelled())
return;
synchronized (annotationModel) {
fOccurrenceAnnotations= annotations;
for (int i= 0, size= annotations.size(); i < size; i++)
annotationModel.addAnnotation((Annotation) annotations.get(i), (Position) positions.get(i));
}
} finally {
fDocument.removeDocumentListener(this);
}
}
/*
* @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
*/
public void documentAboutToBeChanged(DocumentEvent event) {
fCancelled= true;
}
/*
* @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
*/
public void documentChanged(DocumentEvent event) {
}
} /**
* Updates the occurrences annotations based
* on the current selection.
*
* @since 3.0
*/
protected void updateOccurrences() {
if (!fMarkOccurrenceAnnotations)
return;
IDocument document= getSourceViewer().getDocument();
if (document == null)
return;
OccurrencesFinder finder= new OccurrencesFinder(++fComputeCount, document, (ITextSelection) getSelectionProvider().getSelection());
Thread thread= new Thread(finder, "Occurrences Marker"); //$NON-NLS-1$
thread.setDaemon(true);
thread.start();
}
void removeOccurrenceAnnotations() {
IDocumentProvider documentProvider= getDocumentProvider();
if (documentProvider == null)
return;
IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput());
if (annotationModel == null)
return;
synchronized (annotationModel) {
for (int i= 0, size= fOccurrenceAnnotations.size(); i < size; i++)
annotationModel.removeAnnotation((Annotation)fOccurrenceAnnotations.get(i));
fOccurrenceAnnotations.clear();
}
}
/**
* Returns the Java element wrapped by this editors input.
*
* @return the Java element wrapped by this editors input.
* @since 3.0
*/
abstract protected IJavaElement getInputJavaElement();
protected void updateStatusLine() {
ITextSelection selection= (ITextSelection) getSelectionProvider().getSelection();
Annotation annotation= getAnnotation(selection.getOffset(), selection.getLength());
setStatusLineErrorMessage(null);
setStatusLineMessage(null);
if (annotation != null) {
try {
fIsUpdatingAnnotationViews= true;
updateAnnotationViews(annotation);
} finally {
fIsUpdatingAnnotationViews= false;
}
if (annotation instanceof IJavaAnnotation && ((IJavaAnnotation)annotation).isProblem())
setStatusLineMessage(((IJavaAnnotation)annotation).getMessage());
}
}
/**
* Jumps to the matching bracket.
*/
public void gotoMatchingBracket() {
ISourceViewer sourceViewer= getSourceViewer();
IDocument document= sourceViewer.getDocument();
if (document == null)
return;
IRegion selection= getSignedSelection(sourceViewer);
int selectionLength= Math.abs(selection.getLength());
if (selectionLength > 1) {
setStatusLineErrorMessage(JavaEditorMessages.getString("GotoMatchingBracket.error.invalidSelection")); //$NON-NLS-1$
sourceViewer.getTextWidget().getDisplay().beep();
return;
}
// #26314
int sourceCaretOffset= selection.getOffset() + selection.getLength();
if (isSurroundedByBrackets(document, sourceCaretOffset))
sourceCaretOffset -= selection.getLength();
IRegion region= fBracketMatcher.match(document, sourceCaretOffset);
if (region == null) {
setStatusLineErrorMessage(JavaEditorMessages.getString("GotoMatchingBracket.error.noMatchingBracket")); //$NON-NLS-1$
sourceViewer.getTextWidget().getDisplay().beep();
return;
}
int offset= region.getOffset();
int length= region.getLength();
if (length < 1)
return;
int anchor= fBracketMatcher.getAnchor();
// http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
int targetOffset= (JavaPairMatcher.RIGHT == anchor) ? offset + 1: offset + length;
boolean visible= false;
if (sourceViewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3) sourceViewer;
visible= (extension.modelOffset2WidgetOffset(targetOffset) > -1);
} else {
IRegion visibleRegion= sourceViewer.getVisibleRegion();
// http://dev.eclipse.org/bugs/show_bug.cgi?id=34195
visible= (targetOffset >= visibleRegion.getOffset() && targetOffset <= visibleRegion.getOffset() + visibleRegion.getLength());
}
if (!visible) {
setStatusLineErrorMessage(JavaEditorMessages.getString("GotoMatchingBracket.error.bracketOutsideSelectedElement")); //$NON-NLS-1$
sourceViewer.getTextWidget().getDisplay().beep();
return;
}
if (selection.getLength() < 0)
targetOffset -= selection.getLength();
sourceViewer.setSelectedRange(targetOffset, selection.getLength());
sourceViewer.revealRange(targetOffset, selection.getLength());
}
/**
* Sets the given message as error message to this editor's status line.
*
* @param msg message to be set
*/
protected void setStatusLineErrorMessage(String msg) {
IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
if (statusLine != null)
statusLine.setMessage(true, msg, null);
}
/**
* Sets the given message as message to this editor's status line.
*
* @param msg message to be set
* @since 3.0
*/
protected void setStatusLineMessage(String msg) {
IEditorStatusLine statusLine= (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
if (statusLine != null)
statusLine.setMessage(false, msg, null);
}
private static IRegion getSignedSelection(ITextViewer viewer) {
StyledText text= viewer.getTextWidget();
int caretOffset= text.getCaretOffset();
Point selection= text.getSelection();
// caret left
int offset, length;
if (caretOffset == selection.x) {
offset= selection.y;
length= selection.x - selection.y;
// caret right
} else {
offset= selection.x;
length= selection.y - selection.x;
}
return new Region(offset, length);
}
private static boolean isBracket(char character) {
for (int i= 0; i != BRACKETS.length; ++i)
if (character == BRACKETS[i])
return true;
return false;
}
private static boolean isSurroundedByBrackets(IDocument document, int offset) {
if (offset == 0 || offset == document.getLength())
return false;
try {
return
isBracket(document.getChar(offset - 1)) &&
isBracket(document.getChar(offset));
} catch (BadLocationException e) {
return false;
}
}
/**
* Returns the annotation closest to the given range respecting the given
* direction. If an annotation is found, the annotations current position
* is copied into the provided annotation position.
*
* @param offset the region offset
* @param length the region length
* @param forward <code>true</code> for forwards, <code>false</code> for backward
* @param annotationPosition the position of the found annotation
* @return the found annotation
*/
private Annotation getNextAnnotation(int offset, int length, boolean forward, Position annotationPosition) {
Annotation nextAnnotation= null;
Position nextAnnotationPosition= null;
Annotation containingAnnotation= null;
Position containingAnnotationPosition= null;
boolean currentAnnotation= false;
IDocument document= getDocumentProvider().getDocument(getEditorInput());
int endOfDocument= document.getLength();
int distance= 0;
IAnnotationAccess access= getAnnotationAccess();
IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
Iterator e= new JavaAnnotationIterator(model, true, true);
while (e.hasNext()) {
Annotation a= (Annotation) e.next();
Object type;
if (a instanceof IJavaAnnotation)
type= ((IJavaAnnotation) a).getAnnotationType();
else
type= access.getType(a);
boolean isNavigationTarget= isNavigationTargetType(type);
if ((a instanceof IJavaAnnotation) && ((IJavaAnnotation)a).hasOverlay() || !isNavigationTarget)
continue;
Position p= model.getPosition(a);
if (p == null)
continue;
if (!(p.includes(offset) || (p.getLength() == 0 && offset == p.offset))) {
int currentDistance= 0;
if (forward) {
currentDistance= p.getOffset() - offset;
if (currentDistance < 0)
currentDistance= endOfDocument - offset + p.getOffset();
} else {
currentDistance= offset - p.getOffset();
if (currentDistance < 0)
currentDistance= offset + endOfDocument - p.getOffset();
}
if (nextAnnotation == null || currentDistance < distance) {
distance= currentDistance;
nextAnnotation= a;
nextAnnotationPosition= p;
}
} else {
if (containingAnnotationPosition == null || containingAnnotationPosition.length > p.length) {
containingAnnotation= a;
containingAnnotationPosition= p;
if (length == p.length)
currentAnnotation= true;
}
}
}
if (containingAnnotationPosition != null && (!currentAnnotation || nextAnnotation == null)) {
annotationPosition.setOffset(containingAnnotationPosition.getOffset());
annotationPosition.setLength(containingAnnotationPosition.getLength());
return containingAnnotation;
}
if (nextAnnotationPosition != null) {
annotationPosition.setOffset(nextAnnotationPosition.getOffset());
annotationPosition.setLength(nextAnnotationPosition.getLength());
}
return nextAnnotation;
}
/**
* Returns the annotation overlapping with the given range or <code>null</code>.
*
* @param offset the region offset
* @param length the region length
* @return the found annotation or <code>null</code>
* @since 3.0
*/
private Annotation getAnnotation(int offset, int length) {
IAnnotationAccess access= getAnnotationAccess();
IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
Iterator e= new JavaAnnotationIterator(model, true, true);
while (e.hasNext()) {
Annotation a= (Annotation) e.next();
if (a instanceof IJavaAnnotation) {
IJavaAnnotation annotation= (IJavaAnnotation) a;
if (annotation.hasOverlay() || !isNavigationTargetType(annotation.getAnnotationType()))
continue;
} else if (!isNavigationTargetType(access.getType(a)))
continue;
Position p= model.getPosition(a);
if (p != null && p.overlapsWith(offset, length))
return a;
}
return null;
}
/**
* Returns whether the given annotation type is configured as a target type
* for the "Go to Next/Previous Annotation" actions
*
* @param type the annotation type
* @return <code>true</code> if this is a target type, <code>false</code>
* otherwise
* @since 3.0
*/
private boolean isNavigationTargetType(Object type) {
Preferences preferences= Platform.getPlugin("org.eclipse.ui.workbench.texteditor").getPluginPreferences(); //$NON-NLS-1$
Iterator i= getAnnotationPreferences().getAnnotationPreferences().iterator();
while (i.hasNext()) {
AnnotationPreference annotationPref= (AnnotationPreference) i.next();
if (annotationPref.getAnnotationType().equals(type)) {
// See bug 41689
// String key= forward ? annotationPref.getIsGoToNextNavigationTargetKey() : annotationPref.getIsGoToPreviousNavigationTargetKey();
String key= annotationPref.getIsGoToNextNavigationTargetKey();
if (key != null && preferences.getBoolean(key))
return true;
}
}
return false;
}
/**
* Computes and returns the source reference that includes the caret and
* serves as provider for the outline page selection and the editor range
* indication.
*
* @return the computed source reference
* @since 3.0
*/
protected ISourceReference computeHighlightRangeSourceReference() {
ISourceViewer sourceViewer= getSourceViewer();
if (sourceViewer == null)
return null;
StyledText styledText= sourceViewer.getTextWidget();
if (styledText == null)
return null;
int caret= 0;
if (sourceViewer instanceof ITextViewerExtension3) {
ITextViewerExtension3 extension= (ITextViewerExtension3)sourceViewer;
caret= extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
} else {
int offset= sourceViewer.getVisibleRegion().getOffset();
caret= offset + styledText.getCaretOffset();
}
IJavaElement element= getElementAt(caret, false);
if ( !(element instanceof ISourceReference))
return null;
if (element.getElementType() == IJavaElement.IMPORT_DECLARATION) {
IImportDeclaration declaration= (IImportDeclaration) element;
IImportContainer container= (IImportContainer) declaration.getParent();
ISourceRange srcRange= null;
try {
srcRange= container.getSourceRange();
} catch (JavaModelException e) {
}
if (srcRange != null && srcRange.getOffset() == caret)
return container;
}
return (ISourceReference) element;
}
/**
* Returns the most narrow java element including the given offset.
*
* @param offset the offset inside of the requested element
* @param reconcile <code>true</code> if editor input should be reconciled in advance
* @return the most narrow java element
* @since 3.0
*/
protected IJavaElement getElementAt(int offset, boolean reconcile) {
return getElementAt(offset);
}
/*
* @see org.eclipse.ui.texteditor.ExtendedTextEditor#createChangeHover()
*/
protected LineChangeHover createChangeHover() {
return new JavaChangeHover(IJavaPartitions.JAVA_PARTITIONING);
}
protected boolean isPrefQuickDiffAlwaysOn() {
return false; // never show change ruler for the non-editable java editor. Overridden in subclasses like CompilationUnitEditor
}
/*
* @see org.eclipse.ui.texteditor.AbstractTextEditor#createNavigationActions()
*/
protected void createNavigationActions() {
super.createNavigationActions();
final StyledText textWidget= getSourceViewer().getTextWidget();
IAction action= new SmartLineStartAction(textWidget, false);
action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_START);
setAction(ITextEditorActionDefinitionIds.LINE_START, action);
action= new SmartLineStartAction(textWidget, true);
action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_LINE_START);
setAction(ITextEditorActionDefinitionIds.SELECT_LINE_START, action);
action= new NavigatePreviousSubWordAction();
action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_PREVIOUS);
setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action);
textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL);
action= new NavigateNextSubWordAction();
action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT);
setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action);
textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL);
action= new DeletePreviousSubWordAction();
action.setActionDefinitionId(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD);
setAction(ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD, action);
textWidget.setKeyBinding(SWT.CTRL | SWT.BS, SWT.NULL);
action= new DeleteNextSubWordAction();
action.setActionDefinitionId(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD);
setAction(ITextEditorActionDefinitionIds.DELETE_NEXT_WORD, action);
textWidget.setKeyBinding(SWT.CTRL | SWT.DEL, SWT.NULL);
action= new SelectPreviousSubWordAction();
action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action);
textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT, SWT.NULL);
action= new SelectNextSubWordAction();
action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action);
textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT, SWT.NULL);
}
}