1 /******************************************************************************* 2 * Copyright (c) 2000, 2006 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 *******************************************************************************/ 11 package net.sourceforge.phpdt.internal.ui.text.java.hover; 12 13 import java.util.ArrayList; 14 import java.util.HashMap; 15 import java.util.Iterator; 16 import java.util.List; 17 18 import net.sourceforge.phpdt.internal.ui.PHPUiImages; 19 import net.sourceforge.phpdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput; 20 import net.sourceforge.phpdt.ui.PreferenceConstants; 21 import net.sourceforge.phpeclipse.PHPeclipsePlugin; 22 import net.sourceforge.phpeclipse.phpeditor.IJavaAnnotation; 23 import net.sourceforge.phpeclipse.phpeditor.JavaMarkerAnnotation; 24 import net.sourceforge.phpeclipse.phpeditor.PHPDocumentProvider.ProblemAnnotation; 25 26 import org.eclipse.jface.preference.IPreferenceStore; 27 import org.eclipse.jface.text.IDocument; 28 import org.eclipse.jface.text.IInformationControlExtension2; 29 import org.eclipse.jface.text.Position; 30 import org.eclipse.jface.text.source.Annotation; 31 import org.eclipse.jface.text.source.CompositeRuler; 32 import org.eclipse.jface.text.source.IAnnotationAccess; 33 import org.eclipse.jface.text.source.IAnnotationAccessExtension; 34 import org.eclipse.jface.text.source.IAnnotationModel; 35 import org.eclipse.jface.text.source.IAnnotationPresentation; 36 import org.eclipse.jface.text.source.ISourceViewer; 37 import org.eclipse.jface.text.source.ImageUtilities; 38 import org.eclipse.jface.viewers.IDoubleClickListener; 39 import org.eclipse.swt.SWT; 40 import org.eclipse.swt.graphics.GC; 41 import org.eclipse.swt.graphics.Image; 42 import org.eclipse.swt.graphics.Rectangle; 43 import org.eclipse.swt.widgets.Canvas; 44 import org.eclipse.ui.texteditor.AnnotationPreference; 45 import org.eclipse.ui.texteditor.AnnotationPreferenceLookup; 46 47 /** 48 * 49 * 50 * @since 3.0 51 */ 52 public class JavaExpandHover extends AnnotationExpandHover { 53 54 /** Id of the no breakpoint fake annotation */ 55 public static final String NO_BREAKPOINT_ANNOTATION = "net.sourceforge.phpdt.internal.ui.NoBreakpointAnnotation"; //$NON-NLS-1$ 56 57 private static class NoBreakpointAnnotation extends Annotation implements 58 IAnnotationPresentation { 59 NoBreakpointAnnotation()60 public NoBreakpointAnnotation() { 61 super(NO_BREAKPOINT_ANNOTATION, false, JavaHoverMessages 62 .getString("NoBreakpointAnnotation.addBreakpoint")); 63 } 64 65 /* 66 * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, 67 * org.eclipse.swt.widgets.Canvas, 68 * org.eclipse.swt.graphics.Rectangle) 69 */ paint(GC gc, Canvas canvas, Rectangle bounds)70 public void paint(GC gc, Canvas canvas, Rectangle bounds) { 71 // draw affordance so the user know she can click here to get a 72 // breakpoint 73 Image fImage = PHPUiImages.get(PHPUiImages.IMG_FIELD_PUBLIC); 74 ImageUtilities.drawImage(fImage, gc, canvas, bounds, SWT.CENTER); 75 } 76 77 /* 78 * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer() 79 */ getLayer()80 public int getLayer() { 81 return IAnnotationPresentation.DEFAULT_LAYER; 82 } 83 } 84 85 private AnnotationPreferenceLookup fLookup = new AnnotationPreferenceLookup(); 86 87 private IPreferenceStore fStore = PHPeclipsePlugin.getDefault() 88 .getCombinedPreferenceStore(); 89 JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener)90 public JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access, 91 IDoubleClickListener doubleClickListener) { 92 super(ruler, access, doubleClickListener); 93 } 94 95 /* 96 * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getHoverInfoForLine(org.eclipse.jface.text.source.ISourceViewer, 97 * int) 98 */ getHoverInfoForLine(final ISourceViewer viewer, final int line)99 protected Object getHoverInfoForLine(final ISourceViewer viewer, 100 final int line) { 101 final boolean showTemporaryProblems = PreferenceConstants 102 .getPreferenceStore().getBoolean( 103 PreferenceConstants.EDITOR_CORRECTION_INDICATION); 104 IAnnotationModel model = viewer.getAnnotationModel(); 105 IDocument document = viewer.getDocument(); 106 107 if (model == null) 108 return null; 109 110 List exact = new ArrayList(); 111 HashMap messagesAtPosition = new HashMap(); 112 113 Iterator e = model.getAnnotationIterator(); 114 while (e.hasNext()) { 115 Annotation annotation = (Annotation) e.next(); 116 117 if (fAnnotationAccess instanceof IAnnotationAccessExtension) 118 if (!((IAnnotationAccessExtension) fAnnotationAccess) 119 .isPaintable(annotation)) 120 continue; 121 122 if (annotation instanceof IJavaAnnotation 123 && !isIncluded((IJavaAnnotation) annotation, 124 showTemporaryProblems)) 125 continue; 126 127 AnnotationPreference pref = fLookup 128 .getAnnotationPreference(annotation); 129 if (pref != null) { 130 String key = pref.getVerticalRulerPreferenceKey(); 131 if (key != null && !fStore.getBoolean(key)) 132 continue; 133 } 134 135 Position position = model.getPosition(annotation); 136 if (position == null) 137 continue; 138 139 if (compareRulerLine(position, document, line) == 1) { 140 141 if (isDuplicateMessage(messagesAtPosition, position, annotation 142 .getText())) 143 continue; 144 145 exact.add(annotation); 146 } 147 } 148 149 sort(exact, model); 150 151 if (exact.size() > 0) 152 setLastRulerMouseLocation(viewer, line); 153 154 if (exact.size() > 0) { 155 Annotation first = (Annotation) exact.get(0); 156 if (!isBreakpointAnnotation(first)) 157 exact.add(0, new NoBreakpointAnnotation()); 158 } 159 160 if (exact.size() <= 1) 161 return null; 162 163 AnnotationHoverInput input = new AnnotationHoverInput(); 164 input.fAnnotations = (Annotation[]) exact.toArray(new Annotation[0]); 165 input.fViewer = viewer; 166 input.fRulerInfo = fCompositeRuler; 167 input.fAnnotationListener = fgListener; 168 input.fDoubleClickListener = fDblClickListener; 169 input.redoAction = new AnnotationExpansionControl.ICallback() { 170 171 public void run(IInformationControlExtension2 control) { 172 control.setInput(getHoverInfoForLine(viewer, line)); 173 } 174 175 }; 176 input.model = model; 177 178 return input; 179 } 180 isIncluded(IJavaAnnotation annotation, boolean showTemporaryProblems)181 private boolean isIncluded(IJavaAnnotation annotation, 182 boolean showTemporaryProblems) { 183 184 // XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=138601 185 if (annotation instanceof ProblemAnnotation 186 && JavaMarkerAnnotation.TASK_ANNOTATION_TYPE.equals(annotation 187 .getType())) 188 return false; 189 190 if (!annotation.isProblem()) 191 return true; 192 193 if (annotation.isMarkedDeleted() && !annotation.hasOverlay()) 194 return true; 195 196 if (annotation.hasOverlay() && !annotation.isMarkedDeleted()) 197 return true; 198 199 if (annotation.hasOverlay()) 200 return (!isIncluded(annotation.getOverlay(), showTemporaryProblems)); 201 202 return showTemporaryProblems; // && 203 // JavaCorrectionProcessor.hasCorrections((Annotation)annotation); 204 } 205 206 /* 207 * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getOrder(org.eclipse.jface.text.source.Annotation) 208 */ getOrder(Annotation annotation)209 protected int getOrder(Annotation annotation) { 210 if (isBreakpointAnnotation(annotation)) 211 return 1000; 212 else 213 return super.getOrder(annotation); 214 } 215 isBreakpointAnnotation(Annotation a)216 private boolean isBreakpointAnnotation(Annotation a) { 217 if (a instanceof JavaMarkerAnnotation) { 218 JavaMarkerAnnotation jma = (JavaMarkerAnnotation) a; 219 // HACK to get breakpoints to show up first 220 return jma.getType().equals("org.eclipse.debug.core.breakpoint"); //$NON-NLS-1$ 221 } 222 return false; 223 } 224 } 225