1 11 package org.eclipse.ui.internal.texteditor; 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.ui.internal.texteditor.AnnotationExpansionControl.AnnotationHoverInput; 51 52 55 public class AnnotationExpandHover implements IAnnotationHover, IAnnotationHoverExtension { 56 57 private class InformationControlCreator implements IInformationControlCreator, IInformationControlCreatorExtension { 58 59 62 public IInformationControl createInformationControl(Shell parent) { 63 return new AnnotationExpansionControl(parent, SWT.NONE, fAnnotationAccess); 64 } 65 66 69 public boolean canReuse(IInformationControl control) { 70 return control instanceof AnnotationExpansionControl; 71 } 72 73 76 public boolean canReplace(IInformationControlCreator creator) { 77 return creator == this; 78 } 79 } 80 81 private class VerticalRulerListener implements IVerticalRulerListener { 82 83 86 public void annotationSelected(VerticalRulerEvent event) { 87 fCompositeRuler.fireAnnotationSelected(event); 88 } 89 90 93 public void annotationDefaultSelected(VerticalRulerEvent event) { 94 fCompositeRuler.fireAnnotationDefaultSelected(event); 95 } 96 97 100 public void annotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu) { 101 fCompositeRuler.fireAnnotationContextMenuAboutToShow(event, menu); 102 } 103 } 104 105 106 private final IInformationControlCreator fgCreator= new InformationControlCreator(); 107 protected final IVerticalRulerListener fgListener= new VerticalRulerListener(); 108 protected CompositeRuler fCompositeRuler; 109 protected IDoubleClickListener fDblClickListener; 110 protected IAnnotationAccess fAnnotationAccess; 111 112 119 public AnnotationExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) { 120 fCompositeRuler= ruler; 121 fAnnotationAccess= access; 122 fDblClickListener= doubleClickListener; 123 } 124 125 128 public String getHoverInfo(ISourceViewer sourceViewer, int line) { 129 return null; 131 } 132 133 protected Object getHoverInfoForLine(ISourceViewer viewer, int line) { 134 IAnnotationModel model= viewer.getAnnotationModel(); 135 IDocument document= viewer.getDocument(); 136 137 if (model == null) 138 return null; 139 140 List exact= new ArrayList (); 141 HashMap messagesAtPosition= new HashMap (); 142 143 Iterator e= model.getAnnotationIterator(); 144 while (e.hasNext()) { 145 Annotation annotation= (Annotation) e.next(); 146 Position position= model.getPosition(annotation); 147 if (position == null) 148 continue; 149 150 if (compareRulerLine(position, document, line) == 1) { 151 if (isDuplicateMessage(messagesAtPosition, position, annotation.getText())) 152 continue; 153 154 exact.add(annotation); 155 } 156 } 157 158 if (exact.size() < 1) 159 return null; 160 161 sort(exact, model); 162 163 if (exact.size() > 0) 164 setLastRulerMouseLocation(viewer, line); 165 166 AnnotationHoverInput input= new AnnotationHoverInput(); 167 input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]); 168 input.fViewer= viewer; 169 input.fRulerInfo= fCompositeRuler; 170 input.fAnnotationListener= fgListener; 171 input.fDoubleClickListener= fDblClickListener; 172 input.model= model; 173 174 return input; 175 } 176 177 protected void sort(List exact, final IAnnotationModel model) { 178 class AnnotationComparator implements Comparator { 179 180 183 public int compare(Object o1, Object o2) { 184 Annotation a1= (Annotation) o1; 185 Annotation a2= (Annotation) o2; 186 187 Position p1= model.getPosition(a1); 188 Position p2= model.getPosition(a2); 189 190 if (p1.offset == p2.offset) 194 return getOrder(a2) - getOrder(a1); 195 return p1.offset - p2.offset; 196 } 197 } 198 199 Collections.sort(exact, new AnnotationComparator()); 200 201 } 202 203 protected int getOrder(Annotation annotation) { 204 if (fAnnotationAccess instanceof IAnnotationAccessExtension) { 205 IAnnotationAccessExtension extension= (IAnnotationAccessExtension) fAnnotationAccess; 206 return extension.getLayer(annotation); 207 } 208 return IAnnotationAccessExtension.DEFAULT_LAYER; 209 } 210 211 protected boolean isDuplicateMessage(Map messagesAtPosition, Position position, String message) { 212 if (messagesAtPosition.containsKey(position)) { 213 Object value= messagesAtPosition.get(position); 214 if (message == null || message.equals(value)) 215 return true; 216 217 if (value instanceof List ) { 218 List messages= (List )value; 219 if (messages.contains(message)) 220 return true; 221 messages.add(message); 222 } else { 223 ArrayList messages= new ArrayList (); 224 messages.add(value); 225 messages.add(message); 226 messagesAtPosition.put(position, messages); 227 } 228 } else 229 messagesAtPosition.put(position, message); 230 return false; 231 } 232 233 protected void setLastRulerMouseLocation(ISourceViewer viewer, int line) { 234 if (fCompositeRuler != null) { 236 StyledText st= viewer.getTextWidget(); 237 if (st != null && !st.isDisposed()) { 238 if (viewer instanceof ITextViewerExtension5) { 239 int widgetLine= ((ITextViewerExtension5)viewer).modelLine2WidgetLine(line); 240 Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); 241 fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); 242 } else if (viewer instanceof TextViewer) { 243 int widgetLine= ((TextViewer)viewer).modelLine2WidgetLine(line); 245 Point loc= st.getLocationAtOffset(st.getOffsetAtLine(widgetLine)); 246 fCompositeRuler.setLocationOfLastMouseButtonActivity(0, loc.y); 247 } 248 } 249 } 250 } 251 252 260 protected int compareRulerLine(Position position, IDocument document, int line) { 261 262 if (position.getOffset() > -1 && position.getLength() > -1) { 263 try { 264 int firstLine= document.getLineOfOffset(position.getOffset()); 265 if (line == firstLine) 266 return 1; 267 if (firstLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength())) 268 return 2; 269 } catch (BadLocationException x) { 270 } 271 } 272 273 return 0; 274 } 275 276 279 public IInformationControlCreator getHoverControlCreator() { 280 return fgCreator; 281 } 282 283 286 public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) { 287 return getHoverInfoForLine(sourceViewer, lineRange.getStartLine()); 288 } 289 290 293 public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) { 294 return new LineRange(lineNumber, 1); 295 } 296 297 300 public boolean canHandleMouseCursor() { 301 return true; 302 } 303 } 304 | Popular Tags |