1 11 package org.eclipse.jface.text.information; 12 13 import java.util.HashMap ; 14 import java.util.Map ; 15 16 import org.eclipse.swt.custom.StyledText; 17 import org.eclipse.swt.events.ControlEvent; 18 import org.eclipse.swt.events.ControlListener; 19 import org.eclipse.swt.events.FocusEvent; 20 import org.eclipse.swt.events.FocusListener; 21 import org.eclipse.swt.events.KeyEvent; 22 import org.eclipse.swt.events.KeyListener; 23 import org.eclipse.swt.events.MouseEvent; 24 import org.eclipse.swt.events.MouseListener; 25 import org.eclipse.swt.graphics.Point; 26 import org.eclipse.swt.graphics.Rectangle; 27 import org.eclipse.swt.widgets.Control; 28 import org.eclipse.swt.widgets.Display; 29 30 import org.eclipse.core.runtime.Assert; 31 32 import org.eclipse.jface.text.AbstractInformationControlManager; 33 import org.eclipse.jface.text.BadLocationException; 34 import org.eclipse.jface.text.IDocumentExtension3; 35 import org.eclipse.jface.text.IInformationControl; 36 import org.eclipse.jface.text.IInformationControlCreator; 37 import org.eclipse.jface.text.IRegion; 38 import org.eclipse.jface.text.ITextViewer; 39 import org.eclipse.jface.text.ITextViewerExtension5; 40 import org.eclipse.jface.text.IViewportListener; 41 import org.eclipse.jface.text.IWidgetTokenKeeper; 42 import org.eclipse.jface.text.IWidgetTokenKeeperExtension; 43 import org.eclipse.jface.text.IWidgetTokenOwner; 44 import org.eclipse.jface.text.IWidgetTokenOwnerExtension; 45 import org.eclipse.jface.text.Region; 46 import org.eclipse.jface.text.TextUtilities; 47 48 49 63 public class InformationPresenter extends AbstractInformationControlManager implements IInformationPresenter, IInformationPresenterExtension, IWidgetTokenKeeper, IWidgetTokenKeeperExtension { 64 65 66 72 75 public static final int WIDGET_PRIORITY= 5; 76 77 78 82 class Closer implements IInformationControlCloser, ControlListener, MouseListener, FocusListener, IViewportListener, KeyListener { 83 84 85 private Control fSubjectControl; 86 87 private IInformationControl fInformationControlToClose; 88 89 private boolean fIsActive= false; 90 91 94 public void setSubjectControl(Control control) { 95 fSubjectControl= control; 96 } 97 98 101 public void setInformationControl(IInformationControl control) { 102 fInformationControlToClose= control; 103 } 104 105 108 public void start(Rectangle informationArea) { 109 110 if (fIsActive) 111 return; 112 fIsActive= true; 113 114 if (fSubjectControl != null && ! fSubjectControl.isDisposed()) { 115 fSubjectControl.addControlListener(this); 116 fSubjectControl.addMouseListener(this); 117 fSubjectControl.addFocusListener(this); 118 fSubjectControl.addKeyListener(this); 119 } 120 121 if (fInformationControlToClose != null) 122 fInformationControlToClose.addFocusListener(this); 123 124 fTextViewer.addViewportListener(this); 125 } 126 127 130 public void stop() { 131 132 if (!fIsActive) 133 return; 134 fIsActive= false; 135 136 fTextViewer.removeViewportListener(this); 137 138 if (fInformationControlToClose != null) 139 fInformationControlToClose.removeFocusListener(this); 140 141 hideInformationControl(); 142 143 if (fSubjectControl != null && !fSubjectControl.isDisposed()) { 144 fSubjectControl.removeControlListener(this); 145 fSubjectControl.removeMouseListener(this); 146 fSubjectControl.removeFocusListener(this); 147 fSubjectControl.removeKeyListener(this); 148 } 149 } 150 151 154 public void controlResized(ControlEvent e) { 155 stop(); 156 } 157 158 161 public void controlMoved(ControlEvent e) { 162 stop(); 163 } 164 165 168 public void mouseDown(MouseEvent e) { 169 stop(); 170 } 171 172 175 public void mouseUp(MouseEvent e) { 176 } 177 178 181 public void mouseDoubleClick(MouseEvent e) { 182 stop(); 183 } 184 185 188 public void focusGained(FocusEvent e) { 189 } 190 191 194 public void focusLost(FocusEvent e) { 195 Display d= fSubjectControl.getDisplay(); 196 d.asyncExec(new Runnable () { 197 public void run() { 198 if (fInformationControlToClose == null || !fInformationControlToClose.isFocusControl()) 199 stop(); 200 } 201 }); 202 } 203 204 207 public void viewportChanged(int topIndex) { 208 stop(); 209 } 210 211 214 public void keyPressed(KeyEvent e) { 215 stop(); 216 } 217 218 221 public void keyReleased(KeyEvent e) { 222 } 223 } 224 225 226 227 private ITextViewer fTextViewer; 228 229 private Map fProviders; 230 231 private int fOffset= -1; 232 236 private String fPartitioning; 237 238 249 public InformationPresenter(IInformationControlCreator creator) { 250 super(creator); 251 setCloser(new Closer()); 252 takesFocusWhenVisible(true); 253 fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING; 254 } 255 256 262 public void setDocumentPartitioning(String partitioning) { 263 Assert.isNotNull(partitioning); 264 fPartitioning= partitioning; 265 } 266 267 271 public String getDocumentPartitioning() { 272 return fPartitioning; 273 } 274 275 283 public void setInformationProvider(IInformationProvider provider, String contentType) { 284 285 Assert.isNotNull(contentType); 286 287 if (fProviders == null) 288 fProviders= new HashMap (); 289 290 if (provider == null) 291 fProviders.remove(contentType); 292 else 293 fProviders.put(contentType, provider); 294 } 295 296 299 public IInformationProvider getInformationProvider(String contentType) { 300 if (fProviders == null) 301 return null; 302 303 return (IInformationProvider) fProviders.get(contentType); 304 } 305 306 312 public void setOffset(int offset) { 313 fOffset= offset; 314 } 315 316 319 protected void computeInformation() { 320 321 int offset= fOffset < 0 ? fTextViewer.getSelectedRange().x : fOffset; 322 if (offset == -1) 323 return; 324 325 fOffset= -1; 326 327 IInformationProvider provider= null; 328 try { 329 String contentType= TextUtilities.getContentType(fTextViewer.getDocument(), getDocumentPartitioning(), offset, true); 330 provider= getInformationProvider(contentType); 331 } catch (BadLocationException x) { 332 } 333 if (provider == null) 334 return; 335 336 IRegion subject= provider.getSubject(fTextViewer, offset); 337 if (subject == null) 338 return; 339 340 if (provider instanceof IInformationProviderExtension2) 341 setCustomInformationControlCreator(((IInformationProviderExtension2) provider).getInformationPresenterControlCreator()); 342 else 343 setCustomInformationControlCreator(null); 344 345 if (provider instanceof IInformationProviderExtension) { 346 IInformationProviderExtension extension= (IInformationProviderExtension) provider; 347 setInformation(extension.getInformation2(fTextViewer, subject), computeArea(subject)); 348 } else { 349 setInformation(provider.getInformation(fTextViewer, subject), computeArea(subject)); 351 } 352 } 353 354 360 private Rectangle computeArea(IRegion region) { 361 362 int start= 0; 363 int end= 0; 364 365 IRegion widgetRegion= modelRange2WidgetRange(region); 366 if (widgetRegion != null) { 367 start= widgetRegion.getOffset(); 368 end= widgetRegion.getOffset() + widgetRegion.getLength(); 369 } 370 371 StyledText styledText= fTextViewer.getTextWidget(); 372 Rectangle bounds; 373 if (end > 0 && start < end) 374 bounds= styledText.getTextBounds(start, end - 1); 375 else { 376 Point loc= styledText.getLocationAtOffset(start); 377 bounds= new Rectangle(loc.x, loc.y, 0, styledText.getLineHeight(start)); 378 } 379 380 return bounds; 381 } 382 383 391 private IRegion modelRange2WidgetRange(IRegion region) { 392 if (fTextViewer instanceof ITextViewerExtension5) { 393 ITextViewerExtension5 extension= (ITextViewerExtension5) fTextViewer; 394 return extension.modelRange2WidgetRange(region); 395 } 396 397 IRegion visibleRegion= fTextViewer.getVisibleRegion(); 398 int start= region.getOffset() - visibleRegion.getOffset(); 399 int end= start + region.getLength(); 400 if (end > visibleRegion.getLength()) 401 end= visibleRegion.getLength(); 402 403 return new Region(start, end - start); 404 } 405 406 409 public void install(ITextViewer textViewer) { 410 fTextViewer= textViewer; 411 install(fTextViewer.getTextWidget()); 412 } 413 414 417 public void uninstall() { 418 dispose(); 419 } 420 421 424 protected void showInformationControl(Rectangle subjectArea) { 425 if (fTextViewer instanceof IWidgetTokenOwnerExtension) { 426 IWidgetTokenOwnerExtension extension= (IWidgetTokenOwnerExtension) fTextViewer; 427 if (extension.requestWidgetToken(this, WIDGET_PRIORITY)) 428 super.showInformationControl(subjectArea); 429 } else if (fTextViewer instanceof IWidgetTokenOwner) { 430 IWidgetTokenOwner owner= (IWidgetTokenOwner) fTextViewer; 431 if (owner.requestWidgetToken(this)) 432 super.showInformationControl(subjectArea); 433 434 } 435 } 436 437 440 protected void hideInformationControl() { 441 try { 442 super.hideInformationControl(); 443 } finally { 444 if (fTextViewer instanceof IWidgetTokenOwner) { 445 IWidgetTokenOwner owner= (IWidgetTokenOwner) fTextViewer; 446 owner.releaseWidgetToken(this); 447 } 448 } 449 } 450 451 454 protected void handleInformationControlDisposed() { 455 try { 456 super.handleInformationControlDisposed(); 457 } finally { 458 if (fTextViewer instanceof IWidgetTokenOwner) { 459 IWidgetTokenOwner owner= (IWidgetTokenOwner) fTextViewer; 460 owner.releaseWidgetToken(this); 461 } 462 } 463 } 464 465 468 public boolean requestWidgetToken(IWidgetTokenOwner owner) { 469 return false; 470 } 471 472 476 public boolean requestWidgetToken(IWidgetTokenOwner owner, int priority) { 477 return false; 478 } 479 480 484 public boolean setFocus(IWidgetTokenOwner owner) { 485 return false; 486 } 487 } 488 489 | Popular Tags |