1 11 package org.eclipse.jdt.internal.ui.text.java.hover; 12 13 import java.util.ArrayList ; 14 import java.util.Collections ; 15 import java.util.Comparator ; 16 import java.util.HashMap ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Map ; 20 21 import org.eclipse.swt.SWT; 22 import org.eclipse.swt.custom.StyledText; 23 import org.eclipse.swt.graphics.Point; 24 import org.eclipse.swt.widgets.Menu; 25 import org.eclipse.swt.widgets.Shell; 26 27 import org.eclipse.jface.viewers.IDoubleClickListener; 28 29 import org.eclipse.jface.text.BadLocationException; 30 import org.eclipse.jface.text.IDocument; 31 import org.eclipse.jface.text.IInformationControl; 32 import org.eclipse.jface.text.IInformationControlCreator; 33 import org.eclipse.jface.text.IInformationControlCreatorExtension; 34 import org.eclipse.jface.text.ITextViewerExtension5; 35 import org.eclipse.jface.text.Position; 36 import org.eclipse.jface.text.TextViewer; 37 import org.eclipse.jface.text.source.Annotation; 38 import org.eclipse.jface.text.source.CompositeRuler; 39 import org.eclipse.jface.text.source.IAnnotationAccess; 40 import org.eclipse.jface.text.source.IAnnotationAccessExtension; 41 import org.eclipse.jface.text.source.IAnnotationHover; 42 import org.eclipse.jface.text.source.IAnnotationHoverExtension; 43 import org.eclipse.jface.text.source.IAnnotationModel; 44 import org.eclipse.jface.text.source.ILineRange; 45 import org.eclipse.jface.text.source.ISourceViewer; 46 import org.eclipse.jface.text.source.IVerticalRulerListener; 47 import org.eclipse.jface.text.source.LineRange; 48 import org.eclipse.jface.text.source.VerticalRulerEvent; 49 50 import org.eclipse.jdt.internal.ui.text.java.hover.AnnotationExpansionControl.AnnotationHoverInput; 51 52 53 60 public class AnnotationExpandHover implements IAnnotationHover, IAnnotationHoverExtension { 61 62 private class InformationControlCreator implements IInformationControlCreator, IInformationControlCreatorExtension { 63 64 67 public IInformationControl createInformationControl(Shell parent) { 68 return new AnnotationExpansionControl(parent, SWT.NONE, fAnnotationAccess); 69 } 70 71 74 public boolean canReuse(IInformationControl control) { 75 return control instanceof AnnotationExpansionControl; 76 } 77 78 81 public boolean canReplace(IInformationControlCreator creator) { 82 return creator == this; 83 } 84 } 85 86 private class VerticalRulerListener implements IVerticalRulerListener { 87 88 91 public void annotationSelected(VerticalRulerEvent event) { 92 fCompositeRuler.fireAnnotationSelected(event); 93 } 94 95 98 public void annotationDefaultSelected(VerticalRulerEvent event) { 99 fCompositeRuler.fireAnnotationDefaultSelected(event); 100 } 101 102 105 public void annotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu) { 106 fCompositeRuler.fireAnnotationContextMenuAboutToShow(event, menu); 107 } 108 } 109 110 111 private final IInformationControlCreator fgCreator= new InformationControlCreator(); 112 protected final IVerticalRulerListener fgListener= new VerticalRulerListener(); 113 protected CompositeRuler fCompositeRuler; 114 protected IDoubleClickListener fDblClickListener; 115 protected IAnnotationAccess fAnnotationAccess; 116 117 124 public AnnotationExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) { 125 fCompositeRuler= ruler; 126 fAnnotationAccess= access; 127 fDblClickListener= doubleClickListener; 128 } 129 130 133 public String getHoverInfo(ISourceViewer sourceViewer, int line) { 134 return null; 136 } 137 138 protected Object getHoverInfoForLine(ISourceViewer viewer, int line) { 139 IAnnotationModel model= viewer.getAnnotationModel(); 140 IDocument document= viewer.getDocument(); 141 142 if (model == null) 143 return null; 144 145 List exact= new ArrayList (); 146 HashMap messagesAtPosition= new HashMap (); 147 148 Iterator e= model.getAnnotationIterator(); 149 while (e.hasNext()) { 150 Annotation annotation= (Annotation) e.next(); 151 Position position= model.getPosition(annotation); 152 if (position == null) 153 continue; 154 155 if (compareRulerLine(position, document, line) == 1) { 156 if (isDuplicateMessage(messagesAtPosition, position, annotation.getText())) 157 continue; 158 159 exact.add(annotation); 160 } 161 } 162 163 if (exact.size() < 1) 164 return null; 165 166 sort(exact, model); 167 168 if (exact.size() > 0) 169 setLastRulerMouseLocation(viewer, line); 170 171 AnnotationHoverInput input= new AnnotationHoverInput(); 172 input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]); 173 input.fViewer= viewer; 174 input.fRulerInfo= fCompositeRuler; 175 input.fAnnotationListener= fgListener; 176 input.fDoubleClickListener= fDblClickListener; 177 input.model= model; 178 179 return input; 180 } 181 182 protected void sort(List exact, final IAnnotationModel model) { 183 class AnnotationComparator implements Comparator { 184 185 188 public int compare(Object o1, Object o2) { 189 Annotation a1= (Annotation) o1; 190 Annotation a2= (Annotation) o2; 191 192 Position p1= model.getPosition(a1); 193 Position p2= model.getPosition(a2); 194 195 if (p1.offset == p2.offset) 199 return getOrder(a2) - getOrder(a1); 200 return p1.offset - p2.offset; 201 } 202 } 203 204 Collections.sort(exact, new AnnotationComparator()); 205 206 } 207 208 protected int getOrder(Annotation annotation) { 209 if (fAnnotationAccess instanceof IAnnotationAccessExtension) { 210 IAnnotationAccessExtension extension= (IAnnotationAccessExtension) fAnnotationAccess; 211 return extension.getLayer(annotation); 212 } 213 return IAnnotationAccessExtension.DEFAULT_LAYER; 214 } 215 216 protected boolean isDuplicateMessage(Map messagesAtPosition, Position position, String message) { 217 if (message == null) 218 return false; 219 220 if (messagesAtPosition.containsKey(position)) { 221 Object value= messagesAtPosition.get(position); 222 if (message == null || message.equals(value)) 223 return true; 224 225 if (value instanceof List ) { 226 List messages= (List )value; 227 if (messages.contains(message)) 228 return true; 229 messages.add(message); 230 } else { 231 ArrayList messages= new ArrayList (); 232 messages.add(value); 233 messages.add(message); 234 messagesAtPosition.put(position, messages); 235 } 236 } else 237 messagesAtPosition.put(position, message); 238 return false; 239 } 240 241 protected void setLastRulerMouseLocation(ISourceViewer viewer, int line) { 242 if (fCompositeRuler != null) { 244 StyledText st= viewer.getTextWidget(); 245 if (st != null && !st.isDisposed()) { 246 if (viewer instanceof ITextViewerExtension5) { 247 int widgetLine= ((ITextViewerExtension5)viewer).modelLine2WidgetLine(line); 248 Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); 249 fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); 250 } else if (viewer instanceof TextViewer) { 251 int widgetLine= ((TextViewer)viewer).modelLine2WidgetLine(line); 253 Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); 254 fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); 255 } 256 } 257 } 258 } 259 260 268 protected int compareRulerLine(Position position, IDocument document, int line) { 269 270 if (position.getOffset() > -1 && position.getLength() > -1) { 271 try { 272 int firstLine= document.getLineOfOffset(position.getOffset()); 273 if (line == firstLine) 274 return 1; 275 if (firstLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength())) 276 return 2; 277 } catch (BadLocationException x) { 278 } 279 } 280 281 return 0; 282 } 283 284 287 public IInformationControlCreator getHoverControlCreator() { 288 return fgCreator; 289 } 290 291 294 public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) { 295 return getHoverInfoForLine(sourceViewer, lineRange.getStartLine()); 296 } 297 298 301 public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { 302 return new LineRange(lineNumber, 1); 303 } 304 305 308 public boolean canHandleMouseCursor() { 309 return true; 310 } 311 } 312 | Popular Tags |