From 53c649c7cd26ef95fa7a108927e83e8ac55f4efd Mon Sep 17 00:00:00 2001 From: axelcl Date: Sun, 11 Jun 2006 10:11:23 +0000 Subject: [PATCH 1/1] Make PHPeclipse compile correctly under Eclipse Version: 3.2.0 Build id: I20060519-1206 --- .../internal/ui/text/java/JavaExpandHover.java | 188 ----- .../ui/text/java/hover/AnnotationExpandHover.java | 311 +++++++ .../java/hover/AnnotationExpansionControl.java | 849 ++++++++++++++++++++ .../ui/text/java/hover/JavaExpandHover.java | 204 +++++ .../text/java/hover/JavaHoverMessages.properties | 6 +- .../phpeclipse/phpeditor/PHPDocumentProvider.java | 2 +- .../phpeclipse/phpeditor/PHPEditor.java | 67 ++- 7 files changed, 1421 insertions(+), 206 deletions(-) delete mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java deleted file mode 100644 index 929f858..0000000 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package net.sourceforge.phpdt.internal.ui.text.java; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -import net.sourceforge.phpdt.internal.ui.PHPUiImages; -import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.phpeditor.JavaMarkerAnnotation; - -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IInformationControlExtension2; -import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.source.Annotation; -import org.eclipse.jface.text.source.CompositeRuler; -import org.eclipse.jface.text.source.IAnnotationAccess; -import org.eclipse.jface.text.source.IAnnotationAccessExtension; -import org.eclipse.jface.text.source.IAnnotationModel; -import org.eclipse.jface.text.source.IAnnotationPresentation; -import org.eclipse.jface.text.source.ISourceViewer; -import org.eclipse.jface.text.source.ImageUtilities; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Canvas; -import org.eclipse.ui.internal.texteditor.AnnotationExpandHover; -import org.eclipse.ui.internal.texteditor.AnnotationExpansionControl; -import org.eclipse.ui.internal.texteditor.AnnotationExpansionControl.AnnotationHoverInput; -import org.eclipse.ui.texteditor.AnnotationPreference; -import org.eclipse.ui.texteditor.AnnotationPreferenceLookup; - -/** - * - * - * @since 3.0 - */ -public class JavaExpandHover extends AnnotationExpandHover { - - /** Id of the no breakpoint fake annotation */ - public static final String NO_BREAKPOINT_ANNOTATION= "net.sourceforge.phpdt.internal.ui.NoBreakpointAnnotation"; //$NON-NLS-1$ - - private static class NoBreakpointAnnotation extends Annotation implements IAnnotationPresentation { - - public NoBreakpointAnnotation() { - super(NO_BREAKPOINT_ANNOTATION, false, JavaHoverMessages.getString("NoBreakpointAnnotation.addBreakpoint")); //$NON-NLS-1$ - } - - /* - * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle) - */ - public void paint(GC gc, Canvas canvas, Rectangle bounds) { - // draw affordance so the user know she can click here to get a breakpoint - Image fImage= PHPUiImages.get(PHPUiImages.IMG_FIELD_PUBLIC); - ImageUtilities.drawImage(fImage, gc, canvas, bounds, SWT.CENTER); - } - - /* - * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer() - */ - public int getLayer() { - return IAnnotationPresentation.DEFAULT_LAYER; - } - } - - private AnnotationPreferenceLookup fLookup= new AnnotationPreferenceLookup(); - private IPreferenceStore fStore= PHPeclipsePlugin.getDefault().getCombinedPreferenceStore(); - - public JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) { - super(ruler, access, doubleClickListener); - } - - /* - * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getHoverInfoForLine(org.eclipse.jface.text.source.ISourceViewer, int) - */ - protected Object getHoverInfoForLine(final ISourceViewer viewer, final int line) { - IAnnotationModel model= viewer.getAnnotationModel(); - IDocument document= viewer.getDocument(); - - if (model == null) - return null; - - List exact= new ArrayList(); - HashMap messagesAtPosition= new HashMap(); - - Iterator e= model.getAnnotationIterator(); - while (e.hasNext()) { - Annotation annotation= (Annotation) e.next(); - - // don't prune deleted ones as we don't get many errors this way -// if (annotation.isMarkedDeleted()) -// continue; - - if (fAnnotationAccess instanceof IAnnotationAccessExtension) - if (!((IAnnotationAccessExtension)fAnnotationAccess).isPaintable(annotation)) - continue; - -// TODO need a new check the this one is not OK -// -// if (annotation instanceof IJavaAnnotation && annotation instanceof IAnnotationPresentation) -// if (((IJavaAnnotation) annotation).getImage(display) == null) -// continue; - - AnnotationPreference pref= fLookup.getAnnotationPreference(annotation); - if (pref != null) { - String key= pref.getVerticalRulerPreferenceKey(); - if (key != null && !fStore.getBoolean(key)) - continue; - } - - Position position= model.getPosition(annotation); - if (position == null) - continue; - - if (compareRulerLine(position, document, line) == 1) { - - if (isDuplicateMessage(messagesAtPosition, position, annotation.getText())) - continue; - - exact.add(annotation); - } - } - - sort(exact, model); - - if (exact.size() > 0) - setLastRulerMouseLocation(viewer, line); - - if (exact.size() > 0) { - Annotation first= (Annotation) exact.get(0); - if (!isBreakpointAnnotation(first)) - exact.add(0, new NoBreakpointAnnotation()); - } - - if (exact.size() <= 1) -// if (exact.size() < 1) - return null; - - AnnotationHoverInput input= new AnnotationHoverInput(); - input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]); - input.fViewer= viewer; - input.fRulerInfo= fCompositeRuler; - input.fAnnotationListener= fgListener; - input.fDoubleClickListener= fDblClickListener; - input.redoAction= new AnnotationExpansionControl.ICallback() { - - public void run(IInformationControlExtension2 control) { - control.setInput(getHoverInfoForLine(viewer, line)); - } - - }; - input.model= model; - - return input; - } - - /* - * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getOrder(org.eclipse.jface.text.source.Annotation) - */ - protected int getOrder(Annotation annotation) { - if (isBreakpointAnnotation(annotation)) //$NON-NLS-1$ - return 1000; - else - return super.getOrder(annotation); - } - - private boolean isBreakpointAnnotation(Annotation a) { - if (a instanceof JavaMarkerAnnotation) { - JavaMarkerAnnotation jma= (JavaMarkerAnnotation) a; - // HACK to get breakpoints to show up first - return jma.getType().equals("org.eclipse.debug.core.breakpoint"); //$NON-NLS-1$ - } - return false; - } -} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java new file mode 100644 index 0000000..f8cea73 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpandHover.java @@ -0,0 +1,311 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.viewers.IDoubleClickListener; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IInformationControlCreatorExtension; +import org.eclipse.jface.text.ITextViewerExtension5; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.CompositeRuler; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationAccessExtension; +import org.eclipse.jface.text.source.IAnnotationHover; +import org.eclipse.jface.text.source.IAnnotationHoverExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ILineRange; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.IVerticalRulerListener; +import org.eclipse.jface.text.source.LineRange; +import org.eclipse.jface.text.source.VerticalRulerEvent; + +import net.sourceforge.phpdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput; + + +/** + * This class got moved here form Platform Text since it was not used there + * and caused discouraged access warnings. It will be moved down again once + * annotation roll-over support is provided by Platform Text. + * + * @since 3.2 + */ +public class AnnotationExpandHover implements IAnnotationHover, IAnnotationHoverExtension { + + private class InformationControlCreator implements IInformationControlCreator, IInformationControlCreatorExtension { + + /* + * @see org.eclipse.jface.text.IInformationControlCreator#createInformationControl(org.eclipse.swt.widgets.Shell) + */ + public IInformationControl createInformationControl(Shell parent) { + return new AnnotationExpansionControl(parent, SWT.NONE, fAnnotationAccess); + } + + /* + * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReuse(org.eclipse.jface.text.IInformationControl) + */ + public boolean canReuse(IInformationControl control) { + return control instanceof AnnotationExpansionControl; + } + + /* + * @see org.eclipse.jface.text.IInformationControlCreatorExtension#canReplace(org.eclipse.jface.text.IInformationControlCreator) + */ + public boolean canReplace(IInformationControlCreator creator) { + return creator == this; + } + } + + private class VerticalRulerListener implements IVerticalRulerListener { + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationSelected(org.eclipse.jface.text.source.VerticalRulerEvent) + */ + public void annotationSelected(VerticalRulerEvent event) { + fCompositeRuler.fireAnnotationSelected(event); + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationDefaultSelected(org.eclipse.jface.text.source.VerticalRulerEvent) + */ + public void annotationDefaultSelected(VerticalRulerEvent event) { + fCompositeRuler.fireAnnotationDefaultSelected(event); + } + + /* + * @see org.eclipse.jface.text.source.IVerticalRulerListener#annotationContextMenuAboutToShow(org.eclipse.jface.text.source.VerticalRulerEvent, org.eclipse.swt.widgets.Menu) + */ + public void annotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu) { + fCompositeRuler.fireAnnotationContextMenuAboutToShow(event, menu); + } + } + + + private final IInformationControlCreator fgCreator= new InformationControlCreator(); + protected final IVerticalRulerListener fgListener= new VerticalRulerListener(); + protected CompositeRuler fCompositeRuler; + protected IDoubleClickListener fDblClickListener; + protected IAnnotationAccess fAnnotationAccess; + + /** + * Creates a new hover instance. + * + * @param ruler + * @param access + * @param doubleClickListener + */ + public AnnotationExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) { + fCompositeRuler= ruler; + fAnnotationAccess= access; + fDblClickListener= doubleClickListener; + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int) + */ + public String getHoverInfo(ISourceViewer sourceViewer, int line) { + // we don't have any sensible return value as text + return null; + } + + protected Object getHoverInfoForLine(ISourceViewer viewer, int line) { + IAnnotationModel model= viewer.getAnnotationModel(); + IDocument document= viewer.getDocument(); + + if (model == null) + return null; + + List exact= new ArrayList(); + HashMap messagesAtPosition= new HashMap(); + + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Annotation annotation= (Annotation) e.next(); + Position position= model.getPosition(annotation); + if (position == null) + continue; + + if (compareRulerLine(position, document, line) == 1) { + if (isDuplicateMessage(messagesAtPosition, position, annotation.getText())) + continue; + + exact.add(annotation); + } + } + + if (exact.size() < 1) + return null; + + sort(exact, model); + + if (exact.size() > 0) + setLastRulerMouseLocation(viewer, line); + + AnnotationHoverInput input= new AnnotationHoverInput(); + input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]); + input.fViewer= viewer; + input.fRulerInfo= fCompositeRuler; + input.fAnnotationListener= fgListener; + input.fDoubleClickListener= fDblClickListener; + input.model= model; + + return input; + } + + protected void sort(List exact, final IAnnotationModel model) { + class AnnotationComparator implements Comparator { + + /* + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Object o1, Object o2) { + Annotation a1= (Annotation) o1; + Annotation a2= (Annotation) o2; + + Position p1= model.getPosition(a1); + Position p2= model.getPosition(a2); + + // annotation order: + // primary order: by position in line + // secondary: annotation importance + if (p1.offset == p2.offset) + return getOrder(a2) - getOrder(a1); + return p1.offset - p2.offset; + } + } + + Collections.sort(exact, new AnnotationComparator()); + + } + + protected int getOrder(Annotation annotation) { + if (fAnnotationAccess instanceof IAnnotationAccessExtension) { + IAnnotationAccessExtension extension= (IAnnotationAccessExtension) fAnnotationAccess; + return extension.getLayer(annotation); + } + return IAnnotationAccessExtension.DEFAULT_LAYER; + } + + protected boolean isDuplicateMessage(Map messagesAtPosition, Position position, String message) { + if (message == null) + return false; + + if (messagesAtPosition.containsKey(position)) { + Object value= messagesAtPosition.get(position); + if (message == null || message.equals(value)) + return true; + + if (value instanceof List) { + List messages= (List)value; + if (messages.contains(message)) + return true; + messages.add(message); + } else { + ArrayList messages= new ArrayList(); + messages.add(value); + messages.add(message); + messagesAtPosition.put(position, messages); + } + } else + messagesAtPosition.put(position, message); + return false; + } + + protected void setLastRulerMouseLocation(ISourceViewer viewer, int line) { + // set last mouse activity in order to get the correct context menu + if (fCompositeRuler != null) { + StyledText st= viewer.getTextWidget(); + if (st != null && !st.isDisposed()) { + if (viewer instanceof ITextViewerExtension5) { + int widgetLine= ((ITextViewerExtension5)viewer).modelLine2WidgetLine(line); + Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); + fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); + } else if (viewer instanceof TextViewer) { + // TODO remove once TextViewer implements the extension + int widgetLine= ((TextViewer)viewer).modelLine2WidgetLine(line); + Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); + fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); + } + } + } + } + + /** + * Returns the distance to the ruler line. + * + * @param position the position + * @param document the document + * @param line the line number + * @return the distance to the ruler line + */ + protected int compareRulerLine(Position position, IDocument document, int line) { + + if (position.getOffset() > -1 && position.getLength() > -1) { + try { + int firstLine= document.getLineOfOffset(position.getOffset()); + if (line == firstLine) + return 1; + if (firstLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength())) + return 2; + } catch (BadLocationException x) { + } + } + + return 0; + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator() + */ + public IInformationControlCreator getHoverControlCreator() { + return fgCreator; + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, org.eclipse.jface.text.source.ILineRange, int) + */ + public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) { + return getHoverInfoForLine(sourceViewer, lineRange.getStartLine()); + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(org.eclipse.jface.text.source.ISourceViewer, int) + */ + public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { + return new LineRange(lineNumber, 1); + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor() + */ + public boolean canHandleMouseCursor() { + return true; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java new file mode 100644 index 0000000..5f2d7c0 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AnnotationExpansionControl.java @@ -0,0 +1,849 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.MenuEvent; +import org.eclipse.swt.events.MenuListener; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.events.MouseTrackListener; +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.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Widget; + +import org.eclipse.jface.viewers.IDoubleClickListener; + +import org.eclipse.jface.text.AbstractInformationControlManager; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IInformationControlExtension; +import org.eclipse.jface.text.IInformationControlExtension2; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.IViewportListener; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationAccessExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.text.source.IVerticalRulerListener; +import org.eclipse.jface.text.source.VerticalRulerEvent; + + +/** + * A control that can display a number of annotations. The control can decide how it layouts the + * annotations to present them to the user. + *

+ * This class got moved here form Platform Text since it was not used there + * and caused discouraged access warnings. It will be moved down again once + * annotation roll-over support is provided by Platform Text. + *

+ *

Each annotation can have its custom context menu and hover.

+ * + * @since 3.2 + */ +public class AnnotationExpansionControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension2 { + + + public interface ICallback { + void run(IInformationControlExtension2 control); + } + + /** + * Input used by the control to display the annotations. + * TODO move to top-level class + * TODO encapsulate fields + * + * @since 3.0 + */ + public static class AnnotationHoverInput { + public Annotation[] fAnnotations; + public ISourceViewer fViewer; + public IVerticalRulerInfo fRulerInfo; + public IVerticalRulerListener fAnnotationListener; + public IDoubleClickListener fDoubleClickListener; + public ICallback redoAction; + public IAnnotationModel model; + } + + private final class Item { + Annotation fAnnotation; + Canvas canvas; + StyleRange[] oldStyles; + + public void selected() { + Display disp= fShell.getDisplay(); + canvas.setCursor(fHandCursor); + // TODO: shade - for now: set grey background + canvas.setBackground(getSelectionColor(disp)); + + // highlight the viewer background at its position + oldStyles= setViewerBackground(fAnnotation); + + // set the selection + fSelection= this; + + if (fHoverManager != null) + fHoverManager.showInformation(); + + if (fInput.fAnnotationListener != null) { + VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation); + fInput.fAnnotationListener.annotationSelected(event); + } + + } + + public void defaultSelected() { + if (fInput.fAnnotationListener != null) { + VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation); + fInput.fAnnotationListener.annotationDefaultSelected(event); + } + + dispose(); + } + + public void showContextMenu(Menu menu) { + if (fInput.fAnnotationListener != null) { + VerticalRulerEvent event= new VerticalRulerEvent(fAnnotation); + fInput.fAnnotationListener.annotationContextMenuAboutToShow(event, menu); + } + } + + public void deselect() { + // hide the popup +// fHoverManager.disposeInformationControl(); + + // deselect + fSelection= null; + + resetViewerBackground(oldStyles); + oldStyles= null; + + Display disp= fShell.getDisplay(); + canvas.setCursor(null); + // TODO: remove shading - for now: set standard background + canvas.setBackground(disp.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + + } + + } + + /** + * Disposes of an item + */ + private final static class MyDisposeListener implements DisposeListener { + /* + * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) + */ + public void widgetDisposed(DisposeEvent e) { + Item item= (Item) ((Widget) e.getSource()).getData(); + item.deselect(); + item.canvas= null; + item.fAnnotation= null; + item.oldStyles= null; + + ((Widget) e.getSource()).setData(null); + } + } + + /** + * Listener on context menu invocation on the items + */ + private final class MyMenuDetectListener implements Listener { + /* + * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) + */ + public void handleEvent(Event event) { + if (event.type == SWT.MenuDetect) { + // TODO: show per-item menu + // for now: show ruler context menu + if (fInput != null) { + Control ruler= fInput.fRulerInfo.getControl(); + if (ruler != null && !ruler.isDisposed()) { + Menu menu= ruler.getMenu(); + if (menu != null && !menu.isDisposed()) { + menu.setLocation(event.x, event.y); + menu.addMenuListener(new MenuListener() { + + public void menuHidden(MenuEvent e) { + dispose(); + } + + public void menuShown(MenuEvent e) { + } + + }); + menu.setVisible(true); + } + } + } + } + } + } + + + /** + * Listener on mouse events on the items. + */ + private final class MyMouseListener extends MouseAdapter { + /* + * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDoubleClick(MouseEvent e) { + Item item= (Item) ((Widget) e.getSource()).getData(); + if (e.button == 1 && item.fAnnotation == fInput.fAnnotations[0] && fInput.fDoubleClickListener != null) { + fInput.fDoubleClickListener.doubleClick(null); + // special code for JDT to renew the annotation set. + if (fInput.redoAction != null) + fInput.redoAction.run(AnnotationExpansionControl.this); + } +// dispose(); + // TODO special action to invoke double-click action on the vertical ruler + // how about +// Canvas can= (Canvas) e.getSource(); +// Annotation a= (Annotation) can.getData(); +// if (a != null) { +// a.getDoubleClickAction().run(); +// } + } + + /* + * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + public void mouseUp(MouseEvent e) { + Item item= (Item) ((Widget) e.getSource()).getData(); + // TODO for now, to make double click work: disable single click on the first item + // disable later when the annotationlistener selectively handles input + if (item != null && e.button == 1) // && item.fAnnotation != fInput.fAnnotations[0]) + item.defaultSelected(); + } + + /* + * @see org.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDown(MouseEvent e) { + super.mouseDown(e); + } + } + + /** + * Listener on mouse track events on the items. + */ + private final class MyMouseTrackListener implements MouseTrackListener { + /* + * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent) + */ + public void mouseEnter(MouseEvent e) { + Item item= (Item) ((Widget) e.getSource()).getData(); + if (item != null) + item.selected(); + } + + /* + * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent) + */ + public void mouseExit(MouseEvent e) { + + Item item= (Item) ((Widget) e.getSource()).getData(); + if (item != null) + item.deselect(); + + // if the event lies outside the entire popup, dispose + org.eclipse.swt.graphics.Region region= fShell.getRegion(); + Canvas can= (Canvas) e.getSource(); + Point p= can.toDisplay(e.x, e.y); + if (region == null) { + Rectangle bounds= fShell.getBounds(); +// p= fShell.toControl(p); + if (!bounds.contains(p)) + dispose(); + } else { + p= fShell.toControl(p); + if (!region.contains(p)) + dispose(); + } + + + } + + /* + * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent) + */ + public void mouseHover(MouseEvent e) { + if (fHoverManager == null) { + fHoverManager= new HoverManager(); + fHoverManager.takesFocusWhenVisible(false); + fHoverManager.install(fComposite); + fHoverManager.showInformation(); + } + } + } + + + /** + * + * + * @since 3.0 + */ + public class LinearLayouter { + + private static final int ANNOTATION_SIZE= 14; + private static final int BORDER_WIDTH= 2; + + public Layout getLayout(int itemCount) { + // simple layout: a row of items + GridLayout layout= new GridLayout(itemCount, true); + layout.horizontalSpacing= 1; + layout.verticalSpacing= 0; + layout.marginHeight= 1; + layout.marginWidth= 1; + return layout; + } + + public Object getLayoutData() { + GridData gridData= new GridData(ANNOTATION_SIZE + 2 * BORDER_WIDTH, ANNOTATION_SIZE + 2 * BORDER_WIDTH); + gridData.horizontalAlignment= GridData.CENTER; + gridData.verticalAlignment= GridData.CENTER; + return gridData; + } + + public int getAnnotationSize() { + return ANNOTATION_SIZE; + } + + public int getBorderWidth() { + return BORDER_WIDTH; + } + + public org.eclipse.swt.graphics.Region getShellRegion(int itemCount) { + // no special region - set to null for default shell size + return null; + } + + } + + + /** + * Listener on paint events on the items. Paints the annotation image on the given GC. + */ + private final class MyPaintListener implements PaintListener { + /* + * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent) + */ + public void paintControl(PaintEvent e) { + Canvas can= (Canvas) e.getSource(); + Annotation a= ((Item) can.getData()).fAnnotation; + if (a != null) { + Rectangle rect= new Rectangle(fLayouter.getBorderWidth(), fLayouter.getBorderWidth(), fLayouter.getAnnotationSize(), fLayouter.getAnnotationSize()); + if (fAnnotationAccessExtension != null) + fAnnotationAccessExtension.paint(a, e.gc, can, rect); + } + } + } + + /** + * Our own private hover manager used to shop per-item pop-ups. + */ + private final class HoverManager extends AbstractInformationControlManager { + + /** + * + */ + public HoverManager() { + super(new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell parent) { + return new DefaultInformationControl(parent); + } + }); + + setMargins(5, 10); + setAnchor(ANCHOR_BOTTOM); + setFallbackAnchors(new Anchor[] {ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT} ); + } + + /* + * @see org.eclipse.jface.text.AbstractInformationControlManager#computeInformation() + */ + protected void computeInformation() { + if (fSelection != null) { + Rectangle subjectArea= fSelection.canvas.getBounds(); + Annotation annotation= fSelection.fAnnotation; + String msg; + if (annotation != null) + msg= annotation.getText(); + else + msg= null; + + setInformation(msg, subjectArea); + } + } + + + } + + /** Model data. */ + protected AnnotationHoverInput fInput; + /** The control's shell */ + private Shell fShell; + /** The composite combining all the items. */ + protected Composite fComposite; + /** The hand cursor. */ + private Cursor fHandCursor; + /** The currently selected item, or null if none is selected. */ + private Item fSelection; + /** The hover manager for the per-item hovers. */ + private HoverManager fHoverManager; + /** The annotation access extension. */ + private IAnnotationAccessExtension fAnnotationAccessExtension; + + + /* listener legion */ + private final MyPaintListener fPaintListener; + private final MyMouseTrackListener fMouseTrackListener; + private final MyMouseListener fMouseListener; + private final MyMenuDetectListener fMenuDetectListener; + private final DisposeListener fDisposeListener; + private final IViewportListener fViewportListener; + + private LinearLayouter fLayouter; + + /** + * Creates a new control. + * + * @param parent + * @param shellStyle + * @param access + */ + public AnnotationExpansionControl(Shell parent, int shellStyle, IAnnotationAccess access) { + fPaintListener= new MyPaintListener(); + fMouseTrackListener= new MyMouseTrackListener(); + fMouseListener= new MyMouseListener(); + fMenuDetectListener= new MyMenuDetectListener(); + fDisposeListener= new MyDisposeListener(); + fViewportListener= new IViewportListener() { + + public void viewportChanged(int verticalOffset) { + dispose(); + } + + }; + fLayouter= new LinearLayouter(); + + if (access instanceof IAnnotationAccessExtension) + fAnnotationAccessExtension= (IAnnotationAccessExtension) access; + + fShell= new Shell(parent, shellStyle | SWT.NO_FOCUS | SWT.ON_TOP); + Display display= fShell.getDisplay(); + fShell.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); + fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM); +// fComposite= new Composite(fShell, SWT.NO_FOCUS | SWT.NO_REDRAW_RESIZE | SWT.NO_TRIM | SWT.V_SCROLL); + + GridLayout layout= new GridLayout(1, true); + layout.marginHeight= 0; + layout.marginWidth= 0; + fShell.setLayout(layout); + + GridData data= new GridData(GridData.FILL_BOTH); + data.heightHint= fLayouter.getAnnotationSize() + 2 * fLayouter.getBorderWidth() + 4; + fComposite.setLayoutData(data); + fComposite.addMouseTrackListener(new MouseTrackAdapter() { + + public void mouseExit(MouseEvent e) { + if (fComposite == null) + return; + Control[] children= fComposite.getChildren(); + Rectangle bounds= null; + for (int i= 0; i < children.length; i++) { + if (bounds == null) + bounds= children[i].getBounds(); + else + bounds.add(children[i].getBounds()); + if (bounds.contains(e.x, e.y)) + return; + } + + // if none of the children contains the event, we leave the popup + dispose(); + } + + }); + +// fComposite.getVerticalBar().addListener(SWT.Selection, new Listener() { +// +// public void handleEvent(Event event) { +// Rectangle bounds= fShell.getBounds(); +// int x= bounds.x - fLayouter.getAnnotationSize() - fLayouter.getBorderWidth(); +// int y= bounds.y; +// fShell.setBounds(x, y, bounds.width, bounds.height); +// } +// +// }); + + fHandCursor= new Cursor(display, SWT.CURSOR_HAND); + fShell.setCursor(fHandCursor); + fComposite.setCursor(fHandCursor); + + setInfoSystemColor(); + } + + private void setInfoSystemColor() { + Display display= fShell.getDisplay(); + setForegroundColor(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); + setBackgroundColor(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + } + + /* + * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String) + */ + public void setInformation(String information) { + setInput(null); + } + + + /* + * @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object) + */ + public void setInput(Object input) { + if (fInput != null && fInput.fViewer != null) + fInput.fViewer.removeViewportListener(fViewportListener); + + if (input instanceof AnnotationHoverInput) + fInput= (AnnotationHoverInput) input; + else + fInput= null; + + inputChanged(fInput, null); + } + + protected void inputChanged(Object newInput, Object newSelection) { + refresh(); + } + + protected void refresh() { + adjustItemNumber(); + + if (fInput == null) + return; + + if (fInput.fAnnotations == null) + return; + + if (fInput.fViewer != null) + fInput.fViewer.addViewportListener(fViewportListener); + + fShell.setRegion(fLayouter.getShellRegion(fInput.fAnnotations.length)); + + Layout layout= fLayouter.getLayout(fInput.fAnnotations.length); + fComposite.setLayout(layout); + + Control[] children= fComposite.getChildren(); + for (int i= 0; i < fInput.fAnnotations.length; i++) { + Canvas canvas= (Canvas) children[i]; + Item item= new Item(); + item.canvas= canvas; + item.fAnnotation= fInput.fAnnotations[i]; + canvas.setData(item); + canvas.redraw(); + } + + } + + protected void adjustItemNumber() { + if (fComposite == null) + return; + + Control[] children= fComposite.getChildren(); + int oldSize= children.length; + int newSize= fInput == null ? 0 : fInput.fAnnotations.length; + + Display display= fShell.getDisplay(); + + // add missing items + for (int i= oldSize; i < newSize; i++) { + Canvas canvas= new Canvas(fComposite, SWT.NONE); + Object gridData= fLayouter.getLayoutData(); + canvas.setLayoutData(gridData); + canvas.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); + + canvas.addPaintListener(fPaintListener); + + canvas.addMouseTrackListener(fMouseTrackListener); + + canvas.addMouseListener(fMouseListener); + + canvas.addListener(SWT.MenuDetect, fMenuDetectListener); + + canvas.addDisposeListener(fDisposeListener); + } + + // dispose of exceeding resources + for (int i= oldSize; i > newSize; i--) { + Item item= (Item) children[i - 1].getData(); + item.deselect(); + children[i - 1].dispose(); + } + + } + + /* + * @see IInformationControl#setVisible(boolean) + */ + public void setVisible(boolean visible) { + fShell.setVisible(visible); + } + + /* + * @see IInformationControl#dispose() + */ + public void dispose() { + if (fShell != null) { + if (!fShell.isDisposed()) + fShell.dispose(); + fShell= null; + fComposite= null; + if (fHandCursor != null) + fHandCursor.dispose(); + fHandCursor= null; + if (fHoverManager != null) + fHoverManager.dispose(); + fHoverManager= null; + fSelection= null; + } + } + + /* + * @see org.eclipse.jface.text.IInformationControlExtension#hasContents() + */ + public boolean hasContents() { + return fInput.fAnnotations != null && fInput.fAnnotations.length > 0; + } + + /* + * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, int) + */ + public void setSizeConstraints(int maxWidth, int maxHeight) { + //fMaxWidth= maxWidth; + //fMaxHeight= maxHeight; + } + + /* + * @see org.eclipse.jface.text.IInformationControl#computeSizeHint() + */ + public Point computeSizeHint() { + return fShell.computeSize(SWT.DEFAULT, SWT.DEFAULT); + } + + /* + * @see IInformationControl#setLocation(Point) + */ + public void setLocation(Point location) { + fShell.setLocation(location); + } + + /* + * @see IInformationControl#setSize(int, int) + */ + public void setSize(int width, int height) { + fShell.setSize(width, height); + } + + /* + * @see IInformationControl#addDisposeListener(DisposeListener) + */ + public void addDisposeListener(DisposeListener listener) { + fShell.addDisposeListener(listener); + } + + /* + * @see IInformationControl#removeDisposeListener(DisposeListener) + */ + public void removeDisposeListener(DisposeListener listener) { + fShell.removeDisposeListener(listener); + } + + /* + * @see IInformationControl#setForegroundColor(Color) + */ + public void setForegroundColor(Color foreground) { + fComposite.setForeground(foreground); + } + + /* + * @see IInformationControl#setBackgroundColor(Color) + */ + public void setBackgroundColor(Color background) { + fComposite.setBackground(background); + } + + /* + * @see IInformationControl#isFocusControl() + */ + public boolean isFocusControl() { + if (fComposite.isFocusControl()) + return true; + + Control[] children= fComposite.getChildren(); + for (int i= 0; i < children.length; i++) { + if (children[i].isFocusControl()) + return true; + } + return false; + } + + /* + * @see IInformationControl#setFocus() + */ + public void setFocus() { + fShell.forceFocus(); + } + + /* + * @see IInformationControl#addFocusListener(FocusListener) + */ + public void addFocusListener(FocusListener listener) { + fShell.addFocusListener(listener); + } + + /* + * @see IInformationControl#removeFocusListener(FocusListener) + */ + public void removeFocusListener(FocusListener listener) { + fShell.removeFocusListener(listener); + } + + private StyleRange[] setViewerBackground(Annotation annotation) { + StyledText text= fInput.fViewer.getTextWidget(); + if (text == null || text.isDisposed()) + return null; + + Display disp= text.getDisplay(); + + Position pos= fInput.model.getPosition(annotation); + if (pos == null) + return null; + + IRegion region= ((TextViewer)fInput.fViewer).modelRange2WidgetRange(new Region(pos.offset, pos.length)); + if (region == null) + return null; + + StyleRange[] ranges= text.getStyleRanges(region.getOffset(), region.getLength()); + + List undoRanges= new ArrayList(ranges.length); + for (int i= 0; i < ranges.length; i++) { + undoRanges.add(ranges[i].clone()); + } + + int offset= region.getOffset(); + StyleRange current= undoRanges.size() > 0 ? (StyleRange) undoRanges.get(0) : null; + int curStart= current != null ? current.start : region.getOffset() + region.getLength(); + int curEnd= current != null ? current.start + current.length : -1; + int index= 0; + + // fill no-style regions + while (curEnd < region.getOffset() + region.getLength()) { + // add empty range + if (curStart > offset) { + StyleRange undoRange= new StyleRange(offset, curStart - offset, null, null); + undoRanges.add(index, undoRange); + index++; + } + + // step + index++; + if (index < undoRanges.size()) { + offset= curEnd; + current= (StyleRange) undoRanges.get(index); + curStart= current.start; + curEnd= current.start + current.length; + } else if (index == undoRanges.size()) { + // last one + offset= curEnd; + current= null; + curStart= region.getOffset() + region.getLength(); + curEnd= -1; + } else + curEnd= region.getOffset() + region.getLength(); + } + + // create modified styles (with background) + List shadedRanges= new ArrayList(undoRanges.size()); + for (Iterator it= undoRanges.iterator(); it.hasNext(); ) { + StyleRange range= (StyleRange) ((StyleRange) it.next()).clone(); + shadedRanges.add(range); + range.background= getHighlightColor(disp); + } + + // set the ranges one by one + for (Iterator iter= shadedRanges.iterator(); iter.hasNext(); ) { + text.setStyleRange((StyleRange) iter.next()); + + } + + return (StyleRange[]) undoRanges.toArray(undoRanges.toArray(new StyleRange[0])); + } + + private void resetViewerBackground(StyleRange[] oldRanges) { + + if (oldRanges == null) + return; + + if (fInput == null) + return; + + StyledText text= fInput.fViewer.getTextWidget(); + if (text == null || text.isDisposed()) + return; + + // set the ranges one by one + for (int i= 0; i < oldRanges.length; i++) { + text.setStyleRange(oldRanges[i]); + } + } + + private Color getHighlightColor(Display disp) { + return disp.getSystemColor(SWT.COLOR_GRAY); + } + + private Color getSelectionColor(Display disp) { + return disp.getSystemColor(SWT.COLOR_GRAY); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java new file mode 100644 index 0000000..6237921 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaExpandHover.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java.hover; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.IJavaAnnotation; +import net.sourceforge.phpeclipse.phpeditor.JavaMarkerAnnotation; +import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider.ProblemAnnotation; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControlExtension2; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.CompositeRuler; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationAccessExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationPresentation; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.ImageUtilities; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.ui.texteditor.AnnotationPreference; +import org.eclipse.ui.texteditor.AnnotationPreferenceLookup; + +/** + * + * + * @since 3.0 + */ +public class JavaExpandHover extends AnnotationExpandHover { + + /** Id of the no breakpoint fake annotation */ + public static final String NO_BREAKPOINT_ANNOTATION= "net.sourceforge.phpdt.internal.ui.NoBreakpointAnnotation"; //$NON-NLS-1$ + + private static class NoBreakpointAnnotation extends Annotation implements IAnnotationPresentation { + + public NoBreakpointAnnotation() { + super(NO_BREAKPOINT_ANNOTATION, false, JavaHoverMessages.getString("NoBreakpointAnnotation.addBreakpoint")); + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle) + */ + public void paint(GC gc, Canvas canvas, Rectangle bounds) { + // draw affordance so the user know she can click here to get a breakpoint + Image fImage= PHPUiImages.get(PHPUiImages.IMG_FIELD_PUBLIC); + ImageUtilities.drawImage(fImage, gc, canvas, bounds, SWT.CENTER); + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer() + */ + public int getLayer() { + return IAnnotationPresentation.DEFAULT_LAYER; + } + } + + private AnnotationPreferenceLookup fLookup= new AnnotationPreferenceLookup(); + private IPreferenceStore fStore= PHPeclipsePlugin.getDefault().getCombinedPreferenceStore(); + + public JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) { + super(ruler, access, doubleClickListener); + } + + /* + * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getHoverInfoForLine(org.eclipse.jface.text.source.ISourceViewer, int) + */ + protected Object getHoverInfoForLine(final ISourceViewer viewer, final int line) { + final boolean showTemporaryProblems= PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION); + IAnnotationModel model= viewer.getAnnotationModel(); + IDocument document= viewer.getDocument(); + + if (model == null) + return null; + + List exact= new ArrayList(); + HashMap messagesAtPosition= new HashMap(); + + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Annotation annotation= (Annotation) e.next(); + + if (fAnnotationAccess instanceof IAnnotationAccessExtension) + if (!((IAnnotationAccessExtension)fAnnotationAccess).isPaintable(annotation)) + continue; + + if (annotation instanceof IJavaAnnotation && !isIncluded((IJavaAnnotation)annotation, showTemporaryProblems)) + continue; + + AnnotationPreference pref= fLookup.getAnnotationPreference(annotation); + if (pref != null) { + String key= pref.getVerticalRulerPreferenceKey(); + if (key != null && !fStore.getBoolean(key)) + continue; + } + + Position position= model.getPosition(annotation); + if (position == null) + continue; + + if (compareRulerLine(position, document, line) == 1) { + + if (isDuplicateMessage(messagesAtPosition, position, annotation.getText())) + continue; + + exact.add(annotation); + } + } + + sort(exact, model); + + if (exact.size() > 0) + setLastRulerMouseLocation(viewer, line); + + if (exact.size() > 0) { + Annotation first= (Annotation) exact.get(0); + if (!isBreakpointAnnotation(first)) + exact.add(0, new NoBreakpointAnnotation()); + } + + if (exact.size() <= 1) + return null; + + AnnotationHoverInput input= new AnnotationHoverInput(); + input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]); + input.fViewer= viewer; + input.fRulerInfo= fCompositeRuler; + input.fAnnotationListener= fgListener; + input.fDoubleClickListener= fDblClickListener; + input.redoAction= new AnnotationExpansionControl.ICallback() { + + public void run(IInformationControlExtension2 control) { + control.setInput(getHoverInfoForLine(viewer, line)); + } + + }; + input.model= model; + + return input; + } + + private boolean isIncluded(IJavaAnnotation annotation, boolean showTemporaryProblems) { + + // XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138601 + if (annotation instanceof ProblemAnnotation && JavaMarkerAnnotation.TASK_ANNOTATION_TYPE.equals(annotation.getType())) + return false; + + if (!annotation.isProblem()) + return true; + + if (annotation.isMarkedDeleted() && !annotation.hasOverlay()) + return true; + + if (annotation.hasOverlay() && !annotation.isMarkedDeleted()) + return true; + + + if (annotation.hasOverlay()) + return (!isIncluded(annotation.getOverlay(), showTemporaryProblems)); + + return showTemporaryProblems; //&& JavaCorrectionProcessor.hasCorrections((Annotation)annotation); + } + + /* + * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getOrder(org.eclipse.jface.text.source.Annotation) + */ + protected int getOrder(Annotation annotation) { + if (isBreakpointAnnotation(annotation)) + return 1000; + else + return super.getOrder(annotation); + } + + private boolean isBreakpointAnnotation(Annotation a) { + if (a instanceof JavaMarkerAnnotation) { + JavaMarkerAnnotation jma= (JavaMarkerAnnotation) a; + // HACK to get breakpoints to show up first + return jma.getType().equals("org.eclipse.debug.core.breakpoint"); //$NON-NLS-1$ + } + return false; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties index 2a9d7f5..ea58cad 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/JavaHoverMessages.properties @@ -11,4 +11,8 @@ TypeHover.more_to_come=\ ... -JavaTextHover.createTextHover=Could not create java text hover +JavaTextHover.createTextHover= Could not create PHP text hover + +JavaTextHover.makeStickyHint= Press ''{0}'' for focus. + +NoBreakpointAnnotation.addBreakpoint= Add a breakpoint \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java index 22c26b6..f659b91 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPDocumentProvider.java @@ -466,7 +466,7 @@ public class PHPDocumentProvider extends TextFileDocumentProvider implements ICo /** * Annotation representating an IProblem. */ - static protected class ProblemAnnotation extends Annotation implements IJavaAnnotation, IAnnotationPresentation { + static public class ProblemAnnotation extends Annotation implements IJavaAnnotation, IAnnotationPresentation { private static final String SPELLING_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.spelling"; 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 e692e83..0ba1930 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java @@ -48,7 +48,7 @@ import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder; import net.sourceforge.phpdt.internal.ui.text.JavaWordIterator; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter; -import net.sourceforge.phpdt.internal.ui.text.java.JavaExpandHover; +import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaExpandHover; import net.sourceforge.phpdt.internal.ui.viewsupport.ISelectionListenerWithAST; import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider; import net.sourceforge.phpdt.internal.ui.viewsupport.SelectionListenerWithASTManager; @@ -118,6 +118,7 @@ import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.ISourceViewerExtension2; import org.eclipse.jface.text.source.IVerticalRuler; +import org.eclipse.jface.text.source.IVerticalRulerColumn; import org.eclipse.jface.text.source.OverviewRuler; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.text.source.projection.ProjectionSupport; @@ -5394,12 +5395,53 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I /* * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createCompositeRuler() */ - protected CompositeRuler createCompositeRuler() { +// protected CompositeRuler createCompositeRuler() { +// if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER)) +// return super.createCompositeRuler(); +// +// CompositeRuler ruler = new CompositeRuler(); +// AnnotationRulerColumn column = new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess()); +// column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new IDoubleClickListener() { +// +// public void doubleClick(DoubleClickEvent event) { +// // for now: just invoke ruler double click action +// triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK); +// } +// +// private void triggerAction(String actionID) { +// IAction action = getAction(actionID); +// if (action != null) { +// if (action instanceof IUpdate) +// ((IUpdate) action).update(); +// // hack to propagate line change +// if (action instanceof ISelectionListener) { +// ((ISelectionListener) action).selectionChanged(null, null); +// } +// if (action.isEnabled()) +// action.run(); +// } +// } +// +// })); +// ruler.addDecorator(0, column); +// +// if (isLineNumberRulerVisible()) +// ruler.addDecorator(1, createLineNumberRulerColumn()); +// else if (isPrefQuickDiffAlwaysOn()) +// ruler.addDecorator(1, createChangeRulerColumn()); +// +// return ruler; +// } + + /* + * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createAnnotationRulerColumn(org.eclipse.jface.text.source.CompositeRuler) + * @since 3.2 + */ + protected IVerticalRulerColumn createAnnotationRulerColumn(CompositeRuler ruler) { if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER)) - return super.createCompositeRuler(); + return super.createAnnotationRulerColumn(ruler); - CompositeRuler ruler = new CompositeRuler(); - AnnotationRulerColumn column = new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess()); + AnnotationRulerColumn column= new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess()); column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { @@ -5408,13 +5450,13 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } private void triggerAction(String actionID) { - IAction action = getAction(actionID); + IAction action= getAction(actionID); if (action != null) { if (action instanceof IUpdate) ((IUpdate) action).update(); // hack to propagate line change if (action instanceof ISelectionListener) { - ((ISelectionListener) action).selectionChanged(null, null); + ((ISelectionListener)action).selectionChanged(null, null); } if (action.isEnabled()) action.run(); @@ -5422,16 +5464,9 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } })); - ruler.addDecorator(0, column); - - if (isLineNumberRulerVisible()) - ruler.addDecorator(1, createLineNumberRulerColumn()); - else if (isPrefQuickDiffAlwaysOn()) - ruler.addDecorator(1, createChangeRulerColumn()); - - return ruler; + + return column; } - /** * Returns the folding action group, or null if there is none. * -- 1.7.1