X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java index 701ebf9..c37b2e4 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java @@ -12,135 +12,1231 @@ Contributors: Klaus Hartlage - www.eclipseproject.de **********************************************************************/ import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; - +import java.util.Map; +import java.util.ResourceBundle; +import java.util.StringTokenizer; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.ISourceRange; +import net.sourceforge.phpdt.core.ISourceReference; +import net.sourceforge.phpdt.core.JavaCore; +import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup; +import net.sourceforge.phpdt.internal.ui.actions.FoldingActionGroup; +import net.sourceforge.phpdt.internal.ui.text.CustomSourceInformationControl; import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider; +import net.sourceforge.phpdt.ui.IContextMenuConstants; +import net.sourceforge.phpdt.ui.JavaUI; import net.sourceforge.phpdt.ui.PreferenceConstants; -import net.sourceforge.phpdt.ui.actions.GenerateActionGroup; import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction; -import net.sourceforge.phpdt.ui.text.IColorManager; import net.sourceforge.phpdt.ui.text.JavaTextTools; +import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider; import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants; +import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Preferences; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; 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.ITextOperationTarget; +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.ITypedRegion; +import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.information.IInformationProvider; import org.eclipse.jface.text.information.InformationPresenter; -import org.eclipse.jface.text.source.AnnotationRulerColumn; -import org.eclipse.jface.text.source.CompositeRuler; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationModelExtension; +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.IVerticalRulerColumn; -import org.eclipse.jface.text.source.LineNumberRulerColumn; +import org.eclipse.jface.text.source.OverviewRuler; import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.jface.text.source.projection.ProjectionSupport; +import org.eclipse.jface.text.source.projection.ProjectionViewer; +import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; +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.swt.SWT; import org.eclipse.swt.custom.BidiSegmentEvent; import org.eclipse.swt.custom.BidiSegmentListener; +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.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.PartInitException; +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.texteditor.ContentAssistAction; +import org.eclipse.ui.editors.text.DefaultEncodingSupport; +import org.eclipse.ui.editors.text.IEncodingSupport; +import org.eclipse.ui.part.IShowInTargetList; +import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor; import org.eclipse.ui.texteditor.DefaultRangeIndicator; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IEditorStatusLine; import org.eclipse.ui.texteditor.ITextEditorActionConstants; -import org.eclipse.ui.texteditor.StatusTextEditor; +import org.eclipse.ui.texteditor.MarkerAnnotation; +import org.eclipse.ui.texteditor.ResourceAction; +import org.eclipse.ui.texteditor.TextEditorAction; import org.eclipse.ui.texteditor.TextOperationAction; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; +import org.eclipse.ui.views.tasklist.TaskList; + /** * PHP specific text editor. */ -public class PHPEditor extends StatusTextEditor implements IViewPartInputProvider { // extends TextEditor { +public abstract class PHPEditor extends AbstractDecoratedTextEditor implements IViewPartInputProvider { +//extends StatusTextEditor implements IViewPartInputProvider { // extends TextEditor { + /** + * "Smart" runnable for updating the outline page's selection. + */ + class OutlinePageSelectionUpdater implements Runnable { + + /** Has the runnable already been posted? */ + private boolean fPosted = false; + + public OutlinePageSelectionUpdater() { + } + + /* + * @see Runnable#run() + */ + public void run() { + synchronizeOutlinePageSelection(); + fPosted = false; + } + + /** + * Posts this runnable into the event queue. + */ + public void post() { + if (fPosted) + return; + + Shell shell = getSite().getShell(); + if (shell != null & !shell.isDisposed()) { + fPosted = true; + shell.getDisplay().asyncExec(this); + } + } + }; + class SelectionChangedListener implements ISelectionChangedListener { + 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; + + 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(PHPEditor.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(), PHPEditor.LINK_COLOR, display); + } + + /** + * Creates a color from the information stored in the given preference store. + * Returns null if there is no such information available. + */ + private Color createColor(IPreferenceStore store, String key, Display display) { + + RGB rgb = null; + + if (store.contains(key)) { + + if (store.isDefault(key)) + rgb = PreferenceConverter.getDefaultColor(store, key); + else + rgb = PreferenceConverter.getColor(store, key); + + if (rgb != null) + return new Color(display, rgb); + } + + return null; + } + + private void repairRepresentation() { + repairRepresentation(false); + } + + private void repairRepresentation(boolean redrawAll) { + + if (fActiveRegion == null) + return; + + ISourceViewer viewer = getSourceViewer(); + if (viewer != null) { + resetCursor(viewer); + + int offset = fActiveRegion.getOffset(); + int length = fActiveRegion.getLength(); + + // remove style + if (!redrawAll && viewer instanceof ITextViewerExtension2) + ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length); + else + viewer.invalidateTextPresentation(); + + // remove underline + if (viewer instanceof ITextViewerExtension3) { + ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + offset = extension.modelOffset2WidgetOffset(offset); + } else { + offset -= viewer.getVisibleRegion().getOffset(); + } + + StyledText text = viewer.getTextWidget(); + try { + text.redrawRange(offset, length, true); + } catch (IllegalArgumentException x) { + PHPeclipsePlugin.log(x); + } + } + + fActiveRegion = null; + } + + // will eventually be replaced by a method provided by jdt.core + private IRegion selectWord(IDocument document, int anchor) { + + try { + int offset = anchor; + char c; + + while (offset >= 0) { + c = document.getChar(offset); + if (!Character.isJavaIdentifierPart(c)) + break; + --offset; + } + + int start = offset; + + offset = anchor; + int length = document.getLength(); + + while (offset < length) { + c = document.getChar(offset); + if (!Character.isJavaIdentifierPart(c)) + break; + ++offset; + } + + int end = offset; + + if (start == end) + return new Region(start, 0); + else + return new Region(start + 1, end - start - 1); + + } catch (BadLocationException x) { + return null; + } + } + + IRegion getCurrentTextRegion(ISourceViewer viewer) { + + int offset = getCurrentTextOffset(viewer); + if (offset == -1) + return null; + + return null; + // IJavaElement input= SelectionConverter.getInput(PHPEditor.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(); + } + + StyleRange oldStyleRange = text.getStyleRangeAtOffset(offset); + Color foregroundColor = fColor; + Color backgroundColor = oldStyleRange == null ? text.getBackground() : oldStyleRange.background; + StyleRange styleRange = new StyleRange(offset, length, foregroundColor, backgroundColor); + text.setStyleRange(styleRange); + + // underline + text.redrawRange(offset, length, true); + + fActiveRegion = region; + } + + private void activateCursor(ISourceViewer viewer) { + StyledText text = viewer.getTextWidget(); + if (text == null || text.isDisposed()) + return; + Display display = text.getDisplay(); + if (fCursor == null) + fCursor = new Cursor(display, SWT.CURSOR_HAND); + text.setCursor(fCursor); + } + + private void resetCursor(ISourceViewer viewer) { + StyledText text = viewer.getTextWidget(); + if (text != null && !text.isDisposed()) + text.setCursor(null); + + if (fCursor != null) { + fCursor.dispose(); + fCursor = null; + } + } + + /* + * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) + */ + public void keyPressed(KeyEvent event) { + + if (fActive) { + deactivate(); + return; + } + + if (event.keyCode != fKeyModifierMask) { + deactivate(); + return; + } + + fActive = true; + + // removed for #25871 + // + // ISourceViewer viewer= getSourceViewer(); + // if (viewer == null) + // return; + // + // IRegion region= getCurrentTextRegion(viewer); + // if (region == null) + // return; + // + // highlightRegion(viewer, region); + // activateCursor(viewer); + } + + /* + * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + public void keyReleased(KeyEvent event) { + + if (!fActive) + return; + + deactivate(); + } + + /* + * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + } + /* + * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDown(MouseEvent event) { + + if (!fActive) + return; + + if (event.stateMask != fKeyModifierMask) { + deactivate(); + return; + } + + if (event.button != 1) { + deactivate(); + return; + } + } + + /* + * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + public void mouseUp(MouseEvent e) { + + if (!fActive) + return; + + if (e.button != 1) { + deactivate(); + return; + } + + boolean wasActive = fCursor != null; + + deactivate(); + + if (wasActive) { + IAction action = getAction("OpenEditor"); //$NON-NLS-1$ + if (action != null) + action.run(); + } + } + + /* + * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) + */ + public void mouseMove(MouseEvent event) { + + if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) { + deactivate(); + return; + } + + if (!fActive) { + if (event.stateMask != fKeyModifierMask) + return; + // modifier was already pressed + fActive = true; + } + + ISourceViewer viewer = getSourceViewer(); + if (viewer == null) { + deactivate(); + return; + } + + StyledText text = viewer.getTextWidget(); + if (text == null || text.isDisposed()) { + deactivate(); + return; + } + + if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) { + deactivate(); + return; + } + + IRegion region = getCurrentTextRegion(viewer); + if (region == null || region.getLength() == 0) { + repairRepresentation(); + return; + } + + highlightRegion(viewer, region); + activateCursor(viewer); + } + + /* + * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent) + */ + public void focusGained(FocusEvent e) { + } + + /* + * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) + */ + public void focusLost(FocusEvent event) { + deactivate(); + } + + /* + * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) + */ + public void documentAboutToBeChanged(DocumentEvent event) { + if (fActive && fActiveRegion != null) { + fRememberedPosition = new Position(fActiveRegion.getOffset(), fActiveRegion.getLength()); + try { + event.getDocument().addPosition(fRememberedPosition); + } catch (BadLocationException x) { + fRememberedPosition = null; + } + } + } + + /* + * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) + */ + public void documentChanged(DocumentEvent event) { + if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) { + event.getDocument().removePosition(fRememberedPosition); + fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength()); + } + fRememberedPosition = null; + + ISourceViewer viewer = getSourceViewer(); + if (viewer != null) { + StyledText widget = viewer.getTextWidget(); + if (widget != null && !widget.isDisposed()) { + widget.getDisplay().asyncExec(new Runnable() { + public void run() { + deactivate(); + } + }); + } + } + } + + /* + * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + if (oldInput == null) + return; + deactivate(); + oldInput.removeDocumentListener(this); + } + + /* + * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + if (newInput == null) + return; + newInput.addDocumentListener(this); + } + + /* + * @see PaintListener#paintControl(PaintEvent) + */ + public void paintControl(PaintEvent event) { + if (fActiveRegion == null) + return; + + ISourceViewer viewer = getSourceViewer(); + if (viewer == null) + return; + + StyledText text = viewer.getTextWidget(); + if (text == null || text.isDisposed()) + return; + + int offset = 0; + int length = 0; + + if (viewer instanceof ITextViewerExtension3) { + + ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + IRegion widgetRange = extension.modelRange2WidgetRange(new Region(offset, length)); + if (widgetRange == null) + return; + + offset = widgetRange.getOffset(); + length = widgetRange.getLength(); + + } else { + + IRegion region = viewer.getVisibleRegion(); + if (!includes(region, fActiveRegion)) + return; + + offset = fActiveRegion.getOffset() - region.getOffset(); + length = fActiveRegion.getLength(); + } + + // support for bidi + Point minLocation = getMinimumLocation(text, offset, length); + Point maxLocation = getMaximumLocation(text, offset, length); + + int x1 = minLocation.x; + int x2 = minLocation.x + maxLocation.x - minLocation.x - 1; + int y = minLocation.y + text.getLineHeight() - 1; + + GC gc = event.gc; + if (fColor != null && !fColor.isDisposed()) + gc.setForeground(fColor); + gc.drawLine(x1, y, x2, y); + } + + private boolean includes(IRegion region, IRegion position) { + return position.getOffset() >= region.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength(); + } + + private Point getMinimumLocation(StyledText text, int offset, int length) { + Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); + + for (int i = 0; i <= length; i++) { + Point location = text.getLocationAtOffset(offset + i); + + if (location.x < minLocation.x) + minLocation.x = location.x; + if (location.y < minLocation.y) + minLocation.y = location.y; + } + + return minLocation; + } + + private Point getMaximumLocation(StyledText text, int offset, int length) { + Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); + + for (int i = 0; i <= length; i++) { + Point location = text.getLocationAtOffset(offset + i); + + if (location.x > maxLocation.x) + maxLocation.x = location.x; + if (location.y > maxLocation.y) + maxLocation.y = location.y; + } + + return maxLocation; + } + }; + + /** + * 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, PHPEditor.this); + if (textOperationAction == null) + throw new IllegalArgumentException(); + fTextOperationAction = textOperationAction; + } + + /* + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + + ISourceViewer sourceViewer = getSourceViewer(); + if (sourceViewer == null) { + fTextOperationAction.run(); + 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 + IDocument document = sourceViewer.getDocument(); + String contentType = document.getContentType(offset); + + final IRegion hoverRegion = textHover.getHoverRegion(sourceViewer, offset); + if (hoverRegion == null) + return; + + final String hoverInfo = textHover.getHoverInfo(sourceViewer, hoverRegion); + + // with information provider + IInformationProvider informationProvider = new IInformationProvider() { + /* + * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int) + */ + public IRegion getSubject(ITextViewer textViewer, int offset) { + return hoverRegion; + } + /* + * @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 hoverInfo; + } + }; + 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 implements IAnnotationAccess { +// /* +// * @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; +// } +// +// /* +// * @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); + } + }; + + /** + * Finds and marks occurrence annotations. + * + * @since 3.0 + */ + class OccurrencesFinderJob extends Job implements IDocumentListener { + + private IDocument fDocument; + private boolean fCancelled= false; + private IProgressMonitor fProgressMonitor; + private Position[] fPositions; + + public OccurrencesFinderJob(IDocument document, Position[] positions) { + super("Occurrences Marker"); //$NON-NLS-1$ + fDocument= document; + fPositions= positions; + fDocument.addDocumentListener(this); + } + + private boolean isCancelled() { + return fCancelled || fProgressMonitor.isCanceled(); + } + + /* + * @see Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + public IStatus run(IProgressMonitor progressMonitor) { + + fProgressMonitor= progressMonitor; + + try { + + if (isCancelled()) + return Status.CANCEL_STATUS; + + ITextViewer textViewer= getViewer(); + if (textViewer == null) + return Status.CANCEL_STATUS; + + IDocument document= textViewer.getDocument(); + if (document == null) + return Status.CANCEL_STATUS; + + IDocumentProvider documentProvider= getDocumentProvider(); + if (documentProvider == null) + return Status.CANCEL_STATUS; + + IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput()); + if (annotationModel == null) + return Status.CANCEL_STATUS; + + // Add occurrence annotations + int length= fPositions.length; + Map annotationMap= new HashMap(length); + for (int i= 0; i < length; i++) { + + if (isCancelled()) + return Status.CANCEL_STATUS; + + String message; + Position position= fPositions[i]; + + // Create & add annotation + try { + message= document.get(position.offset, position.length); + } catch (BadLocationException ex) { + // Skip this match + continue; + } + annotationMap.put( + new Annotation("net.sourceforge.phpdt.ui.occurrences", false, message), //$NON-NLS-1$ + position); + } + + if (isCancelled()) + return Status.CANCEL_STATUS; + + synchronized (annotationModel) { + if (annotationModel instanceof IAnnotationModelExtension) { + ((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap); + } else { + removeOccurrenceAnnotations(); + Iterator iter= annotationMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry mapEntry= (Map.Entry)iter.next(); + annotationModel.addAnnotation((Annotation)mapEntry.getKey(), (Position)mapEntry.getValue()); + } + } + fOccurrenceAnnotations= (Annotation[])annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]); + } + } finally { + fDocument.removeDocumentListener(this); + } + return Status.OK_STATUS; + } + + /* + * @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) { + } + } + + + /** + * Holds the current occurrence annotations. + * @since 3.0 + */ + private Annotation[] fOccurrenceAnnotations= null; + + private Job fOccurrencesFinderJob; + /** Preference key for showing the line number ruler */ - private final static String LINE_NUMBER_RULER = PreferenceConstants.EDITOR_LINE_NUMBER_RULER; +// private final static String LINE_NUMBER_RULER = PreferenceConstants.EDITOR_LINE_NUMBER_RULER; /** Preference key for the foreground color of the line numbers */ - private final static String LINE_NUMBER_COLOR = PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR; + // private final static String LINE_NUMBER_COLOR = PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR; /** Preference key for the link color */ private final static String LINK_COLOR = PreferenceConstants.EDITOR_LINK_COLOR; + /** Preference key for compiler task tags */ + private final static String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS; // protected PHPActionGroup fActionGroups; + // /** The outline page */ + // private AbstractContentOutlinePage fOutlinePage; /** The outline page */ - private PHPContentOutlinePage fOutlinePage; - + protected JavaOutlinePage fOutlinePage; + /** Outliner context menu Id */ + protected String fOutlinerContextMenuId; + /** + * The editor selection changed listener. + * + * @since 3.0 + */ +// private EditorSelectionChangedListener fEditorSelectionChangedListener; + /** Indicates whether this editor should react on outline page selection changes */ + private int fIgnoreOutlinePageSelection; + + /** The outline page selection updater */ + private OutlinePageSelectionUpdater fUpdater; // protected PHPSyntaxParserThread fValidationThread = null; // private IPreferenceStore fPHPPrefStore; + /** The selection changed listener */ + protected ISelectionChangedListener fSelectionChangedListener = new SelectionChangedListener(); /** The editor's bracket matcher */ - private PHPPairMatcher fBracketMatcher; + private PHPPairMatcher fBracketMatcher = new PHPPairMatcher(BRACKETS); + + /** The line number ruler column */ - private LineNumberRulerColumn fLineNumberRulerColumn; +// private LineNumberRulerColumn fLineNumberRulerColumn; + /** This editor's encoding support */ + private DefaultEncodingSupport fEncodingSupport; + /** The mouse listener */ + private MouseClickListener fMouseListener; protected CompositeActionGroup fActionGroups; - /** The standard action groups added to the menu */ - private GenerateActionGroup fGenerateActionGroup; - private CompositeActionGroup fContextMenuGroup; - + protected CompositeActionGroup fContextMenuGroup; + + /** + * This editor's projection support + * @since 3.0 + */ + private ProjectionSupport fProjectionSupport; + /** + * This editor's projection model updater + * @since 3.0 + */ + private IJavaFoldingStructureProvider fProjectionModelUpdater; + /** + * The action group for folding. + * + * @since 3.0 + */ + private FoldingActionGroup fFoldingGroup; + /** The information presenter. */ private InformationPresenter fInformationPresenter; + /** The annotation access */ +// protected IAnnotationAccess fAnnotationAccess = new AnnotationAccess(); + /** The overview ruler */ + protected OverviewRuler isOverviewRulerVisible; + /** The source viewer decoration support */ + //protected SourceViewerDecorationSupport fSourceViewerDecorationSupport; + /** The overview ruler */ + //protected OverviewRuler fOverviewRuler; + + /** The preference property change listener for java core. */ + private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener(); + /** + * Returns the most narrow java element including the given offset + * + * @param offset the offset inside of the requested 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 PHPEditor() { super(); - JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); - setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this)); - setRangeIndicator(new DefaultRangeIndicator()); - setPreferenceStore(PHPeclipsePlugin.getDefault().getPreferenceStore()); - - // if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE)) - // fUpdater= new OutlinePageSelectionUpdater(); - - initializeEditor(); + JavaTextTools textTools= PHPeclipsePlugin.getDefault().getJavaTextTools(); + setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this)); //, IJavaPartitions.JAVA_PARTITIONING)); + setRangeIndicator(new DefaultRangeIndicator()); + IPreferenceStore store= PHPeclipsePlugin.getDefault().getPreferenceStore(); + setPreferenceStore(store); + setKeyBindingScopes(new String[] { "net.sourceforge.phpdt.ui.phpEditorScope" }); //$NON-NLS-1$ +// fMarkOccurrenceAnnotations= store.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES); +// fStickyOccurrenceAnnotations= store.getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES); + + // TODO changed in 3.x ? + if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE)) + fUpdater= new OutlinePageSelectionUpdater(); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#updatePropertyDependentActions() + */ + protected void updatePropertyDependentActions() { + super.updatePropertyDependentActions(); + if (fEncodingSupport != null) + fEncodingSupport.reset(); } - // - // /** - // * @see IMember#getCompilationUnit() - // */ - // public ICompilationUnit getCompilationUnit() { - // return this; - // } - // /** - // * @see org.phpeclipse.phpdt.internal.compiler.env.ICompilationUnit#getContents() - // */ - // public char[] getContents() { - // IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput()); - // - // return doc.get().toCharArray(); - // } /* * Update the hovering behavior depending on the preferences. @@ -172,13 +1268,25 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide } } + public void updatedTitleImage(Image image) { + setTitleImage(image); + } /* * @see net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput() */ public Object getViewPartInput() { return getEditorInput().getAdapter(IResource.class); } - + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection) + */ + protected void doSetSelection(ISelection selection) { + super.doSetSelection(selection); + synchronizeOutlinePageSelection(); + } + boolean isFoldingEnabled() { + return PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); + } /* * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt. * widgets.Composite) @@ -186,6 +1294,29 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide public void createPartControl(Composite parent) { super.createPartControl(parent); + //fSourceViewerDecorationSupport.install(getPreferenceStore()); + + ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer(); + + fProjectionSupport= new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); + fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$ + fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$ + fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell shell) { + return new CustomSourceInformationControl(shell, IDocument.DEFAULT_CONTENT_TYPE); + } + }); + fProjectionSupport.install(); + + fProjectionModelUpdater= PHPeclipsePlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider(); + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.install(this, projectionViewer); + + if (isFoldingEnabled()) + projectionViewer.doOperation(ProjectionViewer.TOGGLE); + Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences(); + preferences.addPropertyChangeListener(fPropertyChangeListener); + IInformationControlCreator informationControlCreator = new IInformationControlCreator() { public IInformationControl createInformationControl(Shell parent) { boolean cutDown = false; @@ -197,6 +1328,7 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide fInformationPresenter = new InformationPresenter(informationControlCreator); fInformationPresenter.setSizeConstraints(60, 10, true, true); fInformationPresenter.install(getSourceViewer()); + } /** @@ -210,15 +1342,22 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide } /** + * 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; } - public PHPContentOutlinePage getfOutlinePage() { - return fOutlinePage; - } + // public JavaOutlinePage getfOutlinePage() { + // return fOutlinePage; + // } /** The PHPEditor implementation of this * AbstractTextEditor method extend the @@ -226,73 +1365,119 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide */ protected void createActions() { super.createActions(); - - Action action; - // setAction( - // "ContentAssistProposal", - // new TextOperationAction( - // PHPEditorMessages.getResourceBundle(), - // "ContentAssistProposal.", - // this, - // ISourceViewer.CONTENTASSIST_PROPOSALS)); - action = new ContentAssistAction(PHPEditorMessages.getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$ - action.setActionDefinitionId(PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); - setAction("ContentAssistProposal", action); //$NON-NLS-1$ - - setAction( - "ContentAssistTip", - new TextOperationAction( - PHPEditorMessages.getResourceBundle(), - "ContentAssistTip.", - this, - ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION)); - - action = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "Comment.", this, ITextOperationTarget.PREFIX); - action.setActionDefinitionId(PHPEditorActionDefinitionIds.COMMENT); - setAction("Comment", action); - - action = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "Uncomment.", this, ITextOperationTarget.STRIP_PREFIX); - action.setActionDefinitionId(PHPEditorActionDefinitionIds.UNCOMMENT); - setAction("Uncomment", action); - - action = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$ - action.setActionDefinitionId(PHPEditorActionDefinitionIds.FORMAT); - setAction("Format", action); //$NON-NLS-1$ - - markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$ - markAsStateDependentAction("Comment", true); //$NON-NLS-1$ - markAsStateDependentAction("Uncomment", true); //$NON-NLS-1$ - markAsStateDependentAction("Format", true); //$NON-NLS-1$ - - action = new GotoMatchingBracketAction(this); - action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET); - setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action); - - fGenerateActionGroup = new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT); - - fActionGroups = new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup }); - - // We have to keep the context menu group separate to have better control over positioning - fContextMenuGroup = new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup }); - // rg, - // new LocalHistoryActionGroup(this, ITextEditorActionConstants.GROUP_EDIT)}); - - // if (fValidationThread == null) { - // fValidationThread = - // new PHPSyntaxParserThread(this, getSourceViewer()); - // //Thread defaults - // - // fValidationThread.start(); - // } - // - // fValidationThread.setText(getSourceViewer().getTextWidget().getText()); + + fFoldingGroup= new FoldingActionGroup(this, getViewer()); + + ResourceAction resAction= new TextOperationAction(PHPEditorMessages.getResourceBundle(), "ShowJavaDoc.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$ + resAction= new InformationDispatchAction(PHPEditorMessages.getResourceBundle(), "ShowJavaDoc.", (TextOperationAction) resAction); //$NON-NLS-1$ + resAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_JAVADOC); + setAction("ShowJavaDoc", resAction); //$NON-NLS-1$ +// WorkbenchHelp.setHelp(resAction, IJavaHelpContextIds.SHOW_JAVADOC_ACTION); + + Action action= new GotoMatchingBracketAction(this); + action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET); + setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action); + +// action= new TextOperationAction(PHPEditorMessages.getResourceBundle(),"ShowOutline.", this, JavaSourceViewer.SHOW_OUTLINE, true); //$NON-NLS-1$ +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE); +// setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE, action); +//// WorkbenchHelp.setHelp(action, IJavaHelpContextIds.SHOW_OUTLINE_ACTION); +// +// action= new TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenStructure.", this, JavaSourceViewer.OPEN_STRUCTURE, true); //$NON-NLS-1$ +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE); +// setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE, action); +//// WorkbenchHelp.setHelp(action, IJavaHelpContextIds.OPEN_STRUCTURE_ACTION); +// +// action= new TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenHierarchy.", this, JavaSourceViewer.SHOW_HIERARCHY, true); //$NON-NLS-1$ +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_HIERARCHY); +// setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.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(PHPEditorActionDefinitionIds.SELECT_ENCLOSING); +// setAction(StructureSelectionAction.ENCLOSING, action); +// +// action= new StructureSelectNextAction(this, fSelectionHistory); +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_NEXT); +// setAction(StructureSelectionAction.NEXT, action); +// +// action= new StructureSelectPreviousAction(this, fSelectionHistory); +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_PREVIOUS); +// setAction(StructureSelectionAction.PREVIOUS, action); +// +// StructureSelectHistoryAction historyAction= new StructureSelectHistoryAction(this, fSelectionHistory); +// historyAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_LAST); +// setAction(StructureSelectionAction.HISTORY, historyAction); +// fSelectionHistory.setHistoryAction(historyAction); +// +// action= GoToNextPreviousMemberAction.newGoToNextMemberAction(this); +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_NEXT_MEMBER); +// setAction(GoToNextPreviousMemberAction.NEXT_MEMBER, action); +// +// action= GoToNextPreviousMemberAction.newGoToPreviousMemberAction(this); +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER); +// setAction(GoToNextPreviousMemberAction.PREVIOUS_MEMBER, action); +// +// action= new QuickFormatAction(); +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.QUICK_FORMAT); +// setAction(IJavaEditorActionDefinitionIds.QUICK_FORMAT, action); +// +// action= new RemoveOccurrenceAnnotations(this); +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_OCCURRENCE_ANNOTATIONS); +// setAction("RemoveOccurrenceAnnotations", action); //$NON-NLS-1$ + + // add annotation actions + action= new JavaSelectMarkerRulerAction2(PHPEditorMessages.getResourceBundle(), "Editor.RulerAnnotationSelection.", this); //$NON-NLS-1$ + setAction("AnnotationAction", action); //$NON-NLS-1$ } + private void internalDoSetInput(IEditorInput input) throws CoreException { + super.doSetInput(input); + + if (fEncodingSupport != null) + fEncodingSupport.reset(); + + setOutlinePageInput(fOutlinePage, input); + + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.initialize(); + +// if (isShowingOverrideIndicators()) +// installOverrideIndicator(true); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#setPreferenceStore(org.eclipse.jface.preference.IPreferenceStore) + * @since 3.0 + */ + protected void setPreferenceStore(IPreferenceStore store) { + super.setPreferenceStore(store); + if (getSourceViewerConfiguration() instanceof PHPSourceViewerConfiguration) { + JavaTextTools textTools= PHPeclipsePlugin.getDefault().getJavaTextTools(); + setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools.getColorManager(), store, this, IPHPPartitions.PHP_PARTITIONING)); + } + if (getSourceViewer() instanceof JavaSourceViewer) + ((JavaSourceViewer)getSourceViewer()).setPreferenceStore(store); + } /** The PHPEditor implementation of this * AbstractTextEditor method performs any extra * disposal actions required by the php editor. */ public void dispose() { + if (fProjectionModelUpdater != null) { + fProjectionModelUpdater.uninstall(); + fProjectionModelUpdater= null; + } + + if (fProjectionSupport != null) { + fProjectionSupport.dispose(); + fProjectionSupport= null; + } // PHPEditorEnvironment.disconnect(this); if (fOutlinePage != null) fOutlinePage.setInput(null); @@ -300,6 +1485,29 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide if (fActionGroups != null) fActionGroups.dispose(); + if (isBrowserLikeLinks()) + disableBrowserLikeLinks(); + + if (fEncodingSupport != null) { + fEncodingSupport.dispose(); + fEncodingSupport = null; + } + + if (fPropertyChangeListener != null) { + Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences(); + preferences.removePropertyChangeListener(fPropertyChangeListener); + fPropertyChangeListener = null; + } + +// if (fSourceViewerDecorationSupport != null) { +// fSourceViewerDecorationSupport.dispose(); +// fSourceViewerDecorationSupport = null; +// } + + if (fBracketMatcher != null) { + fBracketMatcher.dispose(); + fBracketMatcher = null; + } super.dispose(); } @@ -307,54 +1515,100 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide * AbstractTextEditor method performs any extra * revert behavior required by the php editor. */ - public void doRevertToSaved() { - super.doRevertToSaved(); - if (fOutlinePage != null) - fOutlinePage.update(); - } + // public void doRevertToSaved() { + // super.doRevertToSaved(); + // if (fOutlinePage != null) + // fOutlinePage.update(); + // } /** The PHPEditor implementation of this * AbstractTextEditor method performs any extra * save behavior required by the php editor. */ - public void doSave(IProgressMonitor monitor) { - super.doSave(monitor); - // compile or not, according to the user preferences - IPreferenceStore store = getPreferenceStore(); // fPHPPrefStore; - if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) { - IAction a = PHPParserAction.getInstance(); - if (a != null) - a.run(); - } -// if (SWT.getPlatform().equals("win32")) { -// IAction a = ShowExternalPreviewAction.getInstance(); -// if (a != null) -// a.run(); -// } - if (fOutlinePage != null) - fOutlinePage.update(); - } + // public void doSave(IProgressMonitor monitor) { + // super.doSave(monitor); + // compile or not, according to the user preferences + // IPreferenceStore store = getPreferenceStore(); + + // the parse on save was changed to the eclipse "builders" concept + // if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) { + // IAction a = PHPParserAction.getInstance(); + // if (a != null) + // a.run(); + // } + + // if (SWT.getPlatform().equals("win32")) { + // IAction a = ShowExternalPreviewAction.getInstance(); + // if (a != null) + // a.run(); + // } + // if (fOutlinePage != null) + // fOutlinePage.update(); + // } /** The PHPEditor implementation of this * AbstractTextEditor method performs any extra * save as behavior required by the php editor. */ - public void doSaveAs() { - super.doSaveAs(); - if (fOutlinePage != null) - fOutlinePage.update(); + // public void doSaveAs() { + // super.doSaveAs(); + // if (fOutlinePage != null) + // fOutlinePage.update(); + // } + /* + * @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); + } /** The PHPEditor implementation of this * AbstractTextEditor method performs sets the * input of the outline page after AbstractTextEditor has set input. */ + // protected void doSetInput(IEditorInput input) throws CoreException { + // super.doSetInput(input); + // + // if (fEncodingSupport != null) + // fEncodingSupport.reset(); + // if (fOutlinePage != null) + // fOutlinePage.setInput(input); + // // setOutlinePageInput(fOutlinePage, input); + // } protected void doSetInput(IEditorInput input) throws CoreException { super.doSetInput(input); - if (fOutlinePage != null) - fOutlinePage.setInput(input); + if (fEncodingSupport != null) + fEncodingSupport.reset(); + setOutlinePageInput(fOutlinePage, input); } - /* * @see org.phpeclipse.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput() */ @@ -368,36 +1622,318 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide */ public void editorContextMenuAboutToShow(MenuManager menu) { super.editorContextMenuAboutToShow(menu); - - addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format"); //$NON-NLS-1$ + 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); + // addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format"); //$NON-NLS-1$ + // + // 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() { + + // AbstractContentOutlinePage page = new PHPContentOutlinePage(getDocumentProvider(), this); + // + // page.addSelectionChangedListener(fSelectionChangedListener); + // // setOutlinePageInput(page, getEditorInput()); + // if (getEditorInput() != null) + // fOutlinePage.setInput(getEditorInput()); + // + // return page; + JavaOutlinePage page = new JavaOutlinePage(fOutlinerContextMenuId, this); + + page.addSelectionChangedListener(fSelectionChangedListener); + setOutlinePageInput(page, getEditorInput()); + + return page; } - protected void updateStateDependentActions() { - super.updateStateDependentActions(); - fGenerateActionGroup.editorStateChanged(); + /** + * Informs the editor that its outliner has been closed. + */ + public void outlinePageClosed() { + if (fOutlinePage != null) { + fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener); + fOutlinePage = null; + resetHighlightRange(); + } } + /** + * Synchronizes the outliner selection with the actual cursor + * position in the editor. + */ + public void synchronizeOutlinePageSelection() { + + // if (isEditingScriptRunning()) + // return; + + ISourceViewer sourceViewer = getSourceViewer(); + if (sourceViewer == null || fOutlinePage == null) + return; + + StyledText styledText = sourceViewer.getTextWidget(); + if (styledText == null) + return; + + 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); + if (element instanceof ISourceReference) { + fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener); + fOutlinePage.select((ISourceReference) element); + fOutlinePage.addSelectionChangedListener(fSelectionChangedListener); + } + } + + protected void setSelection(ISourceReference reference, boolean moveCursor) { + + ISelection selection = getSelectionProvider().getSelection(); + if (selection instanceof TextSelection) { + TextSelection textSelection = (TextSelection) selection; + if (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; + + textWidget.setRedraw(false); + + 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) { + sourceViewer.revealRange(offset, length); + sourceViewer.setSelectedRange(offset, length); + } + + } catch (JavaModelException x) { + } catch (IllegalArgumentException x) { + } finally { + if (textWidget != null) + textWidget.setRedraw(true); + } + + } 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) { + fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener); + fOutlinePage.select(reference); + fOutlinePage.addSelectionChangedListener(fSelectionChangedListener); + } + } + } + + public synchronized void editingScriptStarted() { + ++ fIgnoreOutlinePageSelection; + } + + public synchronized void editingScriptEnded() { + -- fIgnoreOutlinePageSelection; + } + + public synchronized boolean isEditingScriptRunning() { + return (fIgnoreOutlinePageSelection > 0); + } + /** The PHPEditor implementation of this * AbstractTextEditor method performs gets * the java content outline page if request is for a an * outline page. */ public Object getAdapter(Class required) { + if (IContentOutlinePage.class.equals(required)) { - if (fOutlinePage == null) { - fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this); - if (getEditorInput() != null) - fOutlinePage.setInput(getEditorInput()); - } + 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 }; + } + + }; + } + if (fProjectionSupport != null) { + Object adapter= fProjectionSupport.getAdapter(getSourceViewer(), required); + if (adapter != null) + return adapter; + } + return super.getAdapter(required); } + // public Object getAdapter(Class required) { + // if (IContentOutlinePage.class.equals(required)) { + // if (fOutlinePage == null) { + // fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this); + // if (getEditorInput() != null) + // fOutlinePage.setInput(getEditorInput()); + // } + // return fOutlinePage; + // } + // + // if (IEncodingSupport.class.equals(required)) + // return fEncodingSupport; + // + // return super.getAdapter(required); + // } + + 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() && PHPeclipsePlugin.getActivePage() != null) + PHPeclipsePlugin.getActivePage().bringToTop(this); + + try { + editingScriptStarted(); + setSelection(reference, !isActivePart()); + } finally { + editingScriptEnded(); + } + } + /* + * @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) { + fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener); + fOutlinePage.select((ISourceReference) element); + fOutlinePage.addSelectionChangedListener(fSelectionChangedListener); + } + return; + } + element = element.getParent(); + } + + } catch (JavaModelException x) { + PHPeclipsePlugin.log(x.getStatus()); + } + + resetHighlightRange(); + } + protected boolean isActivePart() { + IWorkbenchWindow window = getSite().getWorkbenchWindow(); + IPartService service = window.getPartService(); + IWorkbenchPart part = service.getActivePart(); + return part != null && part.equals(this); + } + // public void openContextHelp() { // IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput()); @@ -454,27 +1990,91 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide } return; } + +// if (OVERVIEW_RULER.equals(property)) { +// if (isOverviewRulerVisible()) +// showOverviewRuler(); +// else +// hideOverviewRuler(); +// return; +// } + +// if (LINE_NUMBER_RULER.equals(property)) { +// if (isLineNumberRulerVisible()) +// showLineNumberRuler(); +// else +// hideLineNumberRuler(); +// return; +// } + +// if (fLineNumberRulerColumn != null +// && (LINE_NUMBER_COLOR.equals(property) || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) || PREFERENCE_COLOR_BACKGROUND.equals(property))) { +// +// initializeLineNumberRulerColumn(fLineNumberRulerColumn); +// } + + if (isJavaEditorHoverProperty(property)) + updateHoverBehavior(); - if (LINE_NUMBER_RULER.equals(property)) { - if (isLineNumberRulerVisible()) - showLineNumberRuler(); + if (BROWSER_LIKE_LINKS.equals(property)) { + if (isBrowserLikeLinks()) + enableBrowserLikeLinks(); else - hideLineNumberRuler(); + disableBrowserLikeLinks(); return; } - if (fLineNumberRulerColumn != null - && (LINE_NUMBER_COLOR.equals(property) - || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) - || PREFERENCE_COLOR_BACKGROUND.equals(property))) { - - initializeLineNumberRulerColumn(fLineNumberRulerColumn); - } - - if (isJavaEditorHoverProperty(property)) { - updateHoverBehavior(); - } - +// if (PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE.equals(property)) { +// if ((event.getNewValue() instanceof Boolean) && ((Boolean)event.getNewValue()).booleanValue()) +// fEditorSelectionChangedListener.selectionChanged(); +// return; +// } + + if (PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE.equals(property)) { + if (event.getNewValue() instanceof Boolean) { + Boolean disable= (Boolean) event.getNewValue(); + enableOverwriteMode(!disable.booleanValue()); + } + return; + } + +// if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) { +// if (event.getNewValue() instanceof Boolean) { +// boolean markOccurrenceAnnotations= ((Boolean)event.getNewValue()).booleanValue(); +// if (markOccurrenceAnnotations != fMarkOccurrenceAnnotations) { +// fMarkOccurrenceAnnotations= markOccurrenceAnnotations; +// if (!fMarkOccurrenceAnnotations) +// uninstallOccurrencesFinder(); +// else +// installOccurrencesFinder(); +// } +// } +// } +// if (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property)) { +// if (event.getNewValue() instanceof Boolean) { +// boolean stickyOccurrenceAnnotations= ((Boolean)event.getNewValue()).booleanValue(); +// if (stickyOccurrenceAnnotations != fStickyOccurrenceAnnotations) { +// fStickyOccurrenceAnnotations= stickyOccurrenceAnnotations; +//// if (!fMarkOccurrenceAnnotations) +//// uninstallOccurrencesFinder(); +//// else +//// installOccurrencesFinder(); +// } +// } +// } + if (PreferenceConstants.EDITOR_FOLDING_PROVIDER.equals(property)) { + if (sourceViewer instanceof ProjectionViewer) { + ProjectionViewer projectionViewer= (ProjectionViewer) sourceViewer; + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.uninstall(); + // either freshly enabled or provider changed + fProjectionModelUpdater= PHPeclipsePlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider(); + if (fProjectionModelUpdater != null) { + fProjectionModelUpdater.install(this, projectionViewer); + } + } + return; + } } finally { super.handlePreferenceStoreChanged(event); } @@ -524,134 +2124,169 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide // } // } + // private boolean isJavaEditorHoverProperty(String property) { + // return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_NONE_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property) + // || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property) + // || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property); + // } + + /** + * Shows the line number ruler column. + */ +// private void showLineNumberRuler() { +// IVerticalRuler v = getVerticalRuler(); +// if (v instanceof CompositeRuler) { +// CompositeRuler c = (CompositeRuler) v; +// c.addDecorator(1, createLineNumberRulerColumn()); +// } +// } private boolean isJavaEditorHoverProperty(String property) { - return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property) - || PreferenceConstants.EDITOR_NONE_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property) - || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property) - || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property) - || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property); + return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property); } /** - * Shows the line number ruler column. + * Return whether the browser like links should be enabled + * according to the preference store settings. + * @return true 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 showLineNumberRuler() { - IVerticalRuler v = getVerticalRuler(); - if (v instanceof CompositeRuler) { - CompositeRuler c = (CompositeRuler) v; - c.addDecorator(1, createLineNumberRulerColumn()); + private void enableBrowserLikeLinks() { + if (fMouseListener == null) { + fMouseListener = new MouseClickListener(); + fMouseListener.install(); } } /** - * Return whether the line number ruler column should be - * visible according to the preference store settings. - * @return true if the line numbers should be visible + * Disables browser like links. */ - private boolean isLineNumberRulerVisible() { - IPreferenceStore store = getPreferenceStore(); - return store.getBoolean(LINE_NUMBER_RULER); + private void disableBrowserLikeLinks() { + if (fMouseListener != null) { + fMouseListener.uninstall(); + fMouseListener = null; + } } /** - * Hides the line number ruler column. + * 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 */ - private void hideLineNumberRuler() { - IVerticalRuler v = getVerticalRuler(); - if (v instanceof CompositeRuler) { - CompositeRuler c = (CompositeRuler) v; - try { - c.removeDecorator(1); - } catch (Throwable e) { - } + 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(); } } /** + * Return whether the line number ruler column should be + * visible according to the preference store settings. + * @return true if the line numbers should be visible + */ +// protected boolean isLineNumberRulerVisible() { +// IPreferenceStore store = getPreferenceStore(); +// return store.getBoolean(LINE_NUMBER_RULER); +// } + /** + * Hides the line number ruler column. + */ +// private void hideLineNumberRuler() { +// IVerticalRuler v = getVerticalRuler(); +// if (v instanceof CompositeRuler) { +// CompositeRuler c = (CompositeRuler) v; +// try { +// c.removeDecorator(1); +// } catch (Throwable e) { +// } +// } +// } + + /* + * @see AbstractTextEditor#handleCursorPositionChanged() + */ + protected void handleCursorPositionChanged() { + super.handleCursorPositionChanged(); + if (!isEditingScriptRunning() && fUpdater != null) + fUpdater.post(); + } + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleElementContentReplaced() + */ + protected void handleElementContentReplaced() { + super.handleElementContentReplaced(); + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.initialize(); + } + /** * Initializes the given line number ruler column from the preference store. * @param rulerColumn the ruler column to be initialized */ - protected void initializeLineNumberRulerColumn(LineNumberRulerColumn rulerColumn) { - JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); - IColorManager manager = textTools.getColorManager(); - - IPreferenceStore store = getPreferenceStore(); - if (store != null) { - - RGB rgb = null; - // foreground color - if (store.contains(LINE_NUMBER_COLOR)) { - if (store.isDefault(LINE_NUMBER_COLOR)) - rgb = PreferenceConverter.getDefaultColor(store, LINE_NUMBER_COLOR); - else - rgb = PreferenceConverter.getColor(store, LINE_NUMBER_COLOR); - } - rulerColumn.setForeground(manager.getColor(rgb)); - - rgb = null; - // background color - if (!store.getBoolean(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) { - if (store.contains(PREFERENCE_COLOR_BACKGROUND)) { - if (store.isDefault(PREFERENCE_COLOR_BACKGROUND)) - rgb = PreferenceConverter.getDefaultColor(store, PREFERENCE_COLOR_BACKGROUND); - else - rgb = PreferenceConverter.getColor(store, PREFERENCE_COLOR_BACKGROUND); - } - } - rulerColumn.setBackground(manager.getColor(rgb)); - } - } +// protected void initializeLineNumberRulerColumn(LineNumberRulerColumn rulerColumn) { +// JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); +// IColorManager manager = textTools.getColorManager(); +// +// IPreferenceStore store = getPreferenceStore(); +// if (store != null) { +// +// RGB rgb = null; +// // foreground color +// if (store.contains(LINE_NUMBER_COLOR)) { +// if (store.isDefault(LINE_NUMBER_COLOR)) +// rgb = PreferenceConverter.getDefaultColor(store, LINE_NUMBER_COLOR); +// else +// rgb = PreferenceConverter.getColor(store, LINE_NUMBER_COLOR); +// } +// rulerColumn.setForeground(manager.getColor(rgb)); +// +// rgb = null; +// // background color +// if (!store.getBoolean(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) { +// if (store.contains(PREFERENCE_COLOR_BACKGROUND)) { +// if (store.isDefault(PREFERENCE_COLOR_BACKGROUND)) +// rgb = PreferenceConverter.getDefaultColor(store, PREFERENCE_COLOR_BACKGROUND); +// else +// rgb = PreferenceConverter.getColor(store, PREFERENCE_COLOR_BACKGROUND); +// } +// } +// rulerColumn.setBackground(manager.getColor(rgb)); +// } +// } /** * Creates a new line number ruler column that is appropriately initialized. */ - protected IVerticalRulerColumn createLineNumberRulerColumn() { - fLineNumberRulerColumn = new LineNumberRulerColumn(); - initializeLineNumberRulerColumn(fLineNumberRulerColumn); - return fLineNumberRulerColumn; - } +// protected IVerticalRulerColumn createLineNumberRulerColumn() { +// fLineNumberRulerColumn = new LineNumberRulerColumn(); +// initializeLineNumberRulerColumn(fLineNumberRulerColumn); +// return fLineNumberRulerColumn; +// } /* * @see AbstractTextEditor#createVerticalRuler() */ - protected IVerticalRuler createVerticalRuler() { - CompositeRuler ruler = new CompositeRuler(); - ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH)); - if (isLineNumberRulerVisible()) - ruler.addDecorator(1, createLineNumberRulerColumn()); - return ruler; - } - - /* (non-Javadoc) - * Method declared on TextEditor - */ - protected void initializeEditor() { - IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore(); - // PHPEditorEnvironment.connect(this); - - // store.addPropertyChangeListener(new IPropertyChangeListener() { - // public void propertyChange(PropertyChangeEvent event) { - // PHPCodeScanner scanner = PHPEditorEnvironment.getPHPCodeScanner(); - // if (scanner != null) { - // scanner.updateToken(PHPEditorEnvironment.getPHPColorProvider()); - // } - // if (getSourceViewer() != null) { - // getSourceViewer().invalidateTextPresentation(); - // } - // - // String property = event.getProperty(); - // if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) { - // if (isLineNumberRulerVisible()) - // showLineNumberRuler(); - // else - // hideLineNumberRuler(); - // return; - // } - // } - // }); - } +// protected IVerticalRuler createVerticalRuler() { +// CompositeRuler ruler = new CompositeRuler(); +// ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH)); +// if (isLineNumberRulerVisible()) +// ruler.addDecorator(1, createLineNumberRulerColumn()); +// return ruler; +// } private static IRegion getSignedSelection(ITextViewer viewer) { @@ -674,6 +2309,73 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide return new Region(offset, length); } + /** 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 highlighting current line */ + protected final static String CURRENT_LINE = PreferenceConstants.EDITOR_CURRENT_LINE; + /** Preference key for highlight color of current line */ + protected final static String CURRENT_LINE_COLOR = PreferenceConstants.EDITOR_CURRENT_LINE_COLOR; + /** Preference key for showing print marging ruler */ + protected final static String PRINT_MARGIN = PreferenceConstants.EDITOR_PRINT_MARGIN; + /** Preference key for print margin ruler color */ + protected final static String PRINT_MARGIN_COLOR = PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR; + /** Preference key for print margin ruler column */ + protected final static String PRINT_MARGIN_COLUMN = PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN; + /** Preference key for error indication */ +// protected final static String ERROR_INDICATION = PreferenceConstants.EDITOR_PROBLEM_INDICATION; + /** Preference key for error color */ +// protected final static String ERROR_INDICATION_COLOR = PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR; + /** Preference key for warning indication */ +// protected final static String WARNING_INDICATION = PreferenceConstants.EDITOR_WARNING_INDICATION; + /** Preference key for warning color */ +// protected final static String WARNING_INDICATION_COLOR = PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR; + /** Preference key for task indication */ + protected final static String TASK_INDICATION = PreferenceConstants.EDITOR_TASK_INDICATION; + /** Preference key for task color */ + protected final static String TASK_INDICATION_COLOR = PreferenceConstants.EDITOR_TASK_INDICATION_COLOR; + /** Preference key for bookmark indication */ + protected final static String BOOKMARK_INDICATION = PreferenceConstants.EDITOR_BOOKMARK_INDICATION; + /** Preference key for bookmark color */ + protected final static String BOOKMARK_INDICATION_COLOR = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR; + /** Preference key for search result indication */ + protected final static String SEARCH_RESULT_INDICATION = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION; + /** Preference key for search result color */ + protected final static String SEARCH_RESULT_INDICATION_COLOR = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR; + /** Preference key for unknown annotation indication */ + protected final static String UNKNOWN_INDICATION = PreferenceConstants.EDITOR_UNKNOWN_INDICATION; + /** Preference key for unknown annotation color */ + protected final static String UNKNOWN_INDICATION_COLOR = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR; + /** Preference key for shwoing the overview ruler */ + protected final static String OVERVIEW_RULER = PreferenceConstants.EDITOR_OVERVIEW_RULER; + /** Preference key for error indication in overview ruler */ + protected final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER; + /** Preference key for warning indication in overview ruler */ + protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER; + /** Preference key for task indication in overview ruler */ + protected final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER; + /** Preference key for bookmark indication in overview ruler */ + protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER; + /** Preference key for search result indication in overview ruler */ + protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER; + /** Preference key for unknown annotation indication in overview ruler */ + protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER; + // /** 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 EDITOR_BROWSER_LIKE_LINKS + * 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; + private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' }; private static boolean isBracket(char character) { @@ -694,14 +2396,60 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide return false; } } + +// protected void configureSourceViewerDecorationSupport() { +// +// fSourceViewerDecorationSupport.setCharacterPairMatcher(fBracketMatcher); +// +// fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys( +// AnnotationType.UNKNOWN, +// UNKNOWN_INDICATION_COLOR, +// UNKNOWN_INDICATION, +// UNKNOWN_INDICATION_IN_OVERVIEW_RULER, +// 0); +// fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys( +// AnnotationType.BOOKMARK, +// BOOKMARK_INDICATION_COLOR, +// BOOKMARK_INDICATION, +// BOOKMARK_INDICATION_IN_OVERVIEW_RULER, +// 1); +// fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys( +// AnnotationType.TASK, +// TASK_INDICATION_COLOR, +// TASK_INDICATION, +// TASK_INDICATION_IN_OVERVIEW_RULER, +// 2); +// fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys( +// AnnotationType.SEARCH, +// SEARCH_RESULT_INDICATION_COLOR, +// SEARCH_RESULT_INDICATION, +// SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER, +// 3); +// fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys( +// AnnotationType.WARNING, +// WARNING_INDICATION_COLOR, +// WARNING_INDICATION, +// WARNING_INDICATION_IN_OVERVIEW_RULER, +// 4); +// fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys( +// AnnotationType.ERROR, +// ERROR_INDICATION_COLOR, +// ERROR_INDICATION, +// ERROR_INDICATION_IN_OVERVIEW_RULER, +// 5); +// +// fSourceViewerDecorationSupport.setCursorLinePainterPreferenceKeys(CURRENT_LINE, CURRENT_LINE_COLOR); +// fSourceViewerDecorationSupport.setMarginPainterPreferenceKeys(PRINT_MARGIN, PRINT_MARGIN_COLOR, PRINT_MARGIN_COLUMN); +// fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR); +// +// fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey()); +// +// } /** * Jumps to the matching bracket. */ public void gotoMatchingBracket() { - if (fBracketMatcher == null) - fBracketMatcher = new PHPPairMatcher(BRACKETS); - ISourceViewer sourceViewer = getSourceViewer(); IDocument document = sourceViewer.getDocument(); if (document == null) @@ -784,7 +2532,7 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide List segmentation = new ArrayList(); for (int i = 0; i < linePartitioning.length; i++) { - if (IPHPPartitionScannerConstants.PHP_STRING.equals(linePartitioning[i].getType())) + if (IPHPPartitions.PHP_STRING_DQ.equals(linePartitioning[i].getType())) segmentation.add(linePartitioning[i]); } @@ -844,25 +2592,90 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide /* * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int) */ - protected final ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { - ISourceViewer viewer = createJavaSourceViewer(parent, ruler, 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); - return viewer; + // protected final ISourceViewer createSourceViewer( + // Composite parent, + // IVerticalRuler ruler, + // int styles) { + // ISourceViewer viewer = createJavaSourceViewer(parent, ruler, 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); + // return viewer; + // } + + public final ISourceViewer getViewer() { + return getSourceViewer(); } + + +// protected void showOverviewRuler() { +// if (fOverviewRuler != null) { +// if (getSourceViewer() instanceof ISourceViewerExtension) { +// ((ISourceViewerExtension) getSourceViewer()).showAnnotationsOverview(true); +// fSourceViewerDecorationSupport.updateOverviewDecorations(); +// } +// } +// } +// +// protected void hideOverviewRuler() { +// if (getSourceViewer() instanceof ISourceViewerExtension) { +// fSourceViewerDecorationSupport.hideAnnotationOverview(); +// ((ISourceViewerExtension) getSourceViewer()).showAnnotationsOverview(false); +// } +// } +// protected boolean isOverviewRulerVisible() { +// IPreferenceStore store = getPreferenceStore(); +// return store.getBoolean(OVERVIEW_RULER); +// } /* * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int) */ - protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { - return super.createSourceViewer(parent, ruler, styles); - } - +// protected ISourceViewer createJavaSourceViewer( +// Composite parent, +// IVerticalRuler ruler, +// IOverviewRuler overviewRuler, +// boolean isOverviewRulerVisible, +// int styles) { +// return new SourceViewer(parent, ruler, overviewRuler, isOverviewRulerVisible(), styles); +// } + /* + * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int) + */ + protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, boolean isOverviewRulerVisible, int styles, IPreferenceStore store) { + return new JavaSourceViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles, store); + } + /* + * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int) + */ + protected final ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) { + + ISourceViewer viewer= createJavaSourceViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles, getPreferenceStore()); + + 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 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) */ @@ -870,4 +2683,174 @@ public class PHPEditor extends StatusTextEditor implements IViewPartInputProvide JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools(); return textTools.affectsBehavior(event); } + + /** + * Jumps to the error next according to the given direction. + */ + public void gotoError(boolean forward) { + + ISelectionProvider provider = getSelectionProvider(); + + ITextSelection s = (ITextSelection) provider.getSelection(); + Position errorPosition = new Position(0, 0); + IJavaAnnotation nextError = getNextError(s.getOffset(), forward, errorPosition); + + if (nextError != null) { + + IMarker marker = null; + if (nextError instanceof MarkerAnnotation) + marker = ((MarkerAnnotation) nextError).getMarker(); + else { + Iterator e = nextError.getOverlaidIterator(); + if (e != null) { + while (e.hasNext()) { + Object o = e.next(); + if (o instanceof MarkerAnnotation) { + marker = ((MarkerAnnotation) o).getMarker(); + break; + } + } + } + } + + if (marker != null) { + IWorkbenchPage page = getSite().getPage(); + IViewPart view = view = page.findView("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$ + if (view instanceof TaskList) { + StructuredSelection ss = new StructuredSelection(marker); + ((TaskList) view).setSelection(ss, true); + } + } + + selectAndReveal(errorPosition.getOffset(), errorPosition.getLength()); +// setStatusLineErrorMessage(nextError.getMessage()); + + } else { + + setStatusLineErrorMessage(null); + + } + } + + private IJavaAnnotation getNextError(int offset, boolean forward, Position errorPosition) { + + IJavaAnnotation nextError = null; + Position nextErrorPosition = null; + + IDocument document = getDocumentProvider().getDocument(getEditorInput()); + int endOfDocument = document.getLength(); + int distance = 0; + + IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput()); + Iterator e = new JavaAnnotationIterator(model, false); + while (e.hasNext()) { + + IJavaAnnotation a = (IJavaAnnotation) e.next(); + if (a.hasOverlay() || !a.isProblem()) + continue; + + Position p = model.getPosition((Annotation) a); + if (!p.includes(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 (nextError == null || currentDistance < distance) { + distance = currentDistance; + nextError = a; + nextErrorPosition = p; + } + } + } + + if (nextErrorPosition != null) { + errorPosition.setOffset(nextErrorPosition.getOffset()); + errorPosition.setLength(nextErrorPosition.getLength()); + } + + return nextError; + } + void removeOccurrenceAnnotations() { + IDocumentProvider documentProvider= getDocumentProvider(); + if (documentProvider == null) + return; + + IAnnotationModel annotationModel= documentProvider.getAnnotationModel(getEditorInput()); + if (annotationModel == null || fOccurrenceAnnotations == null) + return; + + synchronized (annotationModel) { + if (annotationModel instanceof IAnnotationModelExtension) { + ((IAnnotationModelExtension)annotationModel).replaceAnnotations(fOccurrenceAnnotations, null); + } else { + for (int i= 0, length= fOccurrenceAnnotations.length; i < length; i++) + annotationModel.removeAnnotation(fOccurrenceAnnotations[i]); + } + fOccurrenceAnnotations= null; + } +} +// protected void uninstallOverrideIndicator() { +// if (fOverrideIndicatorManager != null) { +// fOverrideIndicatorManager.removeAnnotations(); +// fOverrideIndicatorManager= null; +// } +//} + +protected void installOverrideIndicator(boolean waitForReconcilation) { +// uninstallOverrideIndicator(); + IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput()); +// IJavaElement inputElement= getInputJavaElement(); + +// if (model == null || inputElement == null) +// return; + +// CompilationUnit ast= PHPeclipsePlugin.getDefault().getASTProvider().getAST(inputElement, true, null); +// fOverrideIndicatorManager= new OverrideIndicatorManager(model, inputElement, ast); +} + +/** + * Tells whether override indicators are shown. + * + * @return true if the override indicators are shown + * @since 3.0 + */ +//protected boolean isShowingOverrideIndicators() { +// AnnotationPreference preference= getAnnotationPreferenceLookup().getAnnotationPreference(OverrideIndicatorManager.ANNOTATION_TYPE); +// IPreferenceStore store= getPreferenceStore(); +// return getBoolean(store, preference.getHighlightPreferenceKey()) +// || getBoolean(store, preference.getVerticalRulerPreferenceKey()) +// || getBoolean(store, preference.getOverviewRulerPreferenceKey()) +// || getBoolean(store, preference.getTextPreferenceKey()); +//} + +/** + * Returns the boolean preference for the given key. + * + * @param store the preference store + * @param key the preference key + * @return true if the key exists in the store and its value is true + * @since 3.0 + */ +private boolean getBoolean(IPreferenceStore store, String key) { + return key != null && store.getBoolean(key); +} + + /** + * Returns the folding action group, or null if there is none. + * + * @return the folding action group, or null if there is none + * @since 3.0 + */ + protected FoldingActionGroup getFoldingActionGroup() { + return fFoldingGroup; + } }