1 11 package org.eclipse.jdt.internal.ui.text.correction; 12 13 import java.util.ConcurrentModificationException ; 14 import java.util.Iterator ; 15 16 import org.eclipse.swt.SWT; 17 import org.eclipse.swt.graphics.GC; 18 import org.eclipse.swt.graphics.Image; 19 import org.eclipse.swt.graphics.Point; 20 import org.eclipse.swt.graphics.Rectangle; 21 import org.eclipse.swt.widgets.Canvas; 22 23 import org.eclipse.jface.util.IPropertyChangeListener; 24 import org.eclipse.jface.util.PropertyChangeEvent; 25 26 import org.eclipse.jface.text.BadLocationException; 27 import org.eclipse.jface.text.IDocument; 28 import org.eclipse.jface.text.ITextSelection; 29 import org.eclipse.jface.text.ITextViewer; 30 import org.eclipse.jface.text.Position; 31 import org.eclipse.jface.text.source.Annotation; 32 import org.eclipse.jface.text.source.IAnnotationAccessExtension; 33 import org.eclipse.jface.text.source.IAnnotationModel; 34 import org.eclipse.jface.text.source.IAnnotationPresentation; 35 import org.eclipse.jface.text.source.ImageUtilities; 36 37 import org.eclipse.ui.IEditorPart; 38 import org.eclipse.ui.texteditor.AnnotationPreference; 39 import org.eclipse.ui.texteditor.ITextEditor; 40 41 import org.eclipse.ui.editors.text.EditorsUI; 42 43 import org.eclipse.jdt.core.ICompilationUnit; 44 import org.eclipse.jdt.core.IJavaElement; 45 import org.eclipse.jdt.core.dom.CompilationUnit; 46 47 import org.eclipse.jdt.ui.JavaUI; 48 import org.eclipse.jdt.ui.PreferenceConstants; 49 import org.eclipse.jdt.ui.text.java.IInvocationContext; 50 51 import org.eclipse.jdt.internal.ui.JavaPluginImages; 52 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider; 53 import org.eclipse.jdt.internal.ui.viewsupport.ISelectionListenerWithAST; 54 import org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager; 55 56 59 public class QuickAssistLightBulbUpdater { 60 61 public static class AssistAnnotation extends Annotation implements IAnnotationPresentation { 62 63 private static final int LAYER; 65 66 static { 67 Annotation annotation= new Annotation("org.eclipse.jdt.ui.warning", false, null); AnnotationPreference preference= EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(annotation); 69 if (preference != null) 70 LAYER= preference.getPresentationLayer() - 1; 71 else 72 LAYER= IAnnotationAccessExtension.DEFAULT_LAYER; 73 74 } 75 76 private Image fImage; 77 78 public AssistAnnotation() { 79 } 80 81 84 public int getLayer() { 85 return LAYER; 86 } 87 88 private Image getImage() { 89 if (fImage == null) { 90 fImage= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_QUICK_ASSIST); 91 } 92 return fImage; 93 } 94 95 98 public void paint(GC gc, Canvas canvas, Rectangle r) { 99 ImageUtilities.drawImage(getImage(), gc, canvas, r, SWT.CENTER, SWT.TOP); 100 } 101 102 } 103 104 private final Annotation fAnnotation; 105 private boolean fIsAnnotationShown; 106 private ITextEditor fEditor; 107 private ITextViewer fViewer; 108 109 private ISelectionListenerWithAST fListener; 110 private IPropertyChangeListener fPropertyChangeListener; 111 112 public QuickAssistLightBulbUpdater(ITextEditor part, ITextViewer viewer) { 113 fEditor= part; 114 fViewer= viewer; 115 fAnnotation= new AssistAnnotation(); 116 fIsAnnotationShown= false; 117 fPropertyChangeListener= null; 118 } 119 120 public boolean isSetInPreferences() { 121 return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_QUICKASSIST_LIGHTBULB); 122 } 123 124 private void installSelectionListener() { 125 fListener= new ISelectionListenerWithAST() { 126 public void selectionChanged(IEditorPart part, ITextSelection selection, CompilationUnit astRoot) { 127 doSelectionChanged(selection.getOffset(), selection.getLength(), astRoot); 128 } 129 }; 130 SelectionListenerWithASTManager.getDefault().addListener(fEditor, fListener); 131 } 132 133 private void uninstallSelectionListener() { 134 if (fListener != null) { 135 SelectionListenerWithASTManager.getDefault().removeListener(fEditor, fListener); 136 fListener= null; 137 } 138 IAnnotationModel model= getAnnotationModel(); 139 if (model != null) { 140 removeLightBulb(model); 141 } 142 } 143 144 public void install() { 145 if (isSetInPreferences()) { 146 installSelectionListener(); 147 } 148 if (fPropertyChangeListener == null) { 149 fPropertyChangeListener= new IPropertyChangeListener() { 150 public void propertyChange(PropertyChangeEvent event) { 151 doPropertyChanged(event.getProperty()); 152 } 153 }; 154 PreferenceConstants.getPreferenceStore().addPropertyChangeListener(fPropertyChangeListener); 155 } 156 } 157 158 public void uninstall() { 159 uninstallSelectionListener(); 160 if (fPropertyChangeListener != null) { 161 PreferenceConstants.getPreferenceStore().removePropertyChangeListener(fPropertyChangeListener); 162 fPropertyChangeListener= null; 163 } 164 } 165 166 protected void doPropertyChanged(String property) { 167 if (property.equals(PreferenceConstants.EDITOR_QUICKASSIST_LIGHTBULB)) { 168 if (isSetInPreferences()) { 169 ICompilationUnit cu= getCompilationUnit(); 170 if (cu != null) { 171 installSelectionListener(); 172 Point point= fViewer.getSelectedRange(); 173 CompilationUnit astRoot= ASTProvider.getASTProvider().getAST(cu, ASTProvider.WAIT_ACTIVE_ONLY, null); 174 if (astRoot != null) { 175 doSelectionChanged(point.x, point.y, astRoot); 176 } 177 } 178 } else { 179 uninstallSelectionListener(); 180 } 181 } 182 } 183 184 private ICompilationUnit getCompilationUnit() { 185 IJavaElement elem= JavaUI.getEditorInputJavaElement(fEditor.getEditorInput()); 186 if (elem instanceof ICompilationUnit) { 187 return (ICompilationUnit) elem; 188 } 189 return null; 190 } 191 192 private IAnnotationModel getAnnotationModel() { 193 return JavaUI.getDocumentProvider().getAnnotationModel(fEditor.getEditorInput()); 194 } 195 196 private IDocument getDocument() { 197 return JavaUI.getDocumentProvider().getDocument(fEditor.getEditorInput()); 198 } 199 200 201 private void doSelectionChanged(int offset, int length, CompilationUnit astRoot) { 202 203 final IAnnotationModel model= getAnnotationModel(); 204 final ICompilationUnit cu= getCompilationUnit(); 205 if (model == null || cu == null) { 206 return; 207 } 208 209 final AssistContext context= new AssistContext(cu, offset, length); 210 context.setASTRoot(astRoot); 211 212 boolean hasQuickFix= hasQuickFixLightBulb(model, context.getSelectionOffset()); 213 if (hasQuickFix) { 214 removeLightBulb(model); 215 return; } 217 218 calculateLightBulb(model, context); 219 } 220 221 224 private void calculateLightBulb(IAnnotationModel model, IInvocationContext context) { 225 boolean needsAnnotation= JavaCorrectionProcessor.hasAssists(context); 226 if (fIsAnnotationShown) { 227 model.removeAnnotation(fAnnotation); 228 } 229 if (needsAnnotation) { 230 model.addAnnotation(fAnnotation, new Position(context.getSelectionOffset(), context.getSelectionLength())); 231 } 232 fIsAnnotationShown= needsAnnotation; 233 } 234 235 private void removeLightBulb(IAnnotationModel model) { 236 synchronized (this) { 237 if (fIsAnnotationShown) { 238 model.removeAnnotation(fAnnotation); 239 fIsAnnotationShown= false; 240 } 241 } 242 } 243 244 247 private boolean hasQuickFixLightBulb(IAnnotationModel model, int offset) { 248 try { 249 IDocument document= getDocument(); 250 if (document == null) { 251 return false; 252 } 253 254 258 int currLine= document.getLineOfOffset(offset); 260 261 Iterator iter= model.getAnnotationIterator(); 263 while (iter.hasNext()) { 264 Annotation annot= (Annotation) iter.next(); 265 if (JavaCorrectionProcessor.isQuickFixableType(annot)) { 266 Position pos= model.getPosition(annot); 268 if (pos != null) { 269 int startLine= document.getLineOfOffset(pos.getOffset()); 271 if (startLine == currLine && JavaCorrectionProcessor.hasCorrections(annot)) { 272 return true; 273 } 274 } 275 } 276 } 277 } catch (BadLocationException e) { 278 } catch (IndexOutOfBoundsException e) { 280 } catch (ConcurrentModificationException e) { 282 } 284 return false; 285 } 286 287 288 } 289 | Popular Tags |