1 12 package org.eclipse.ui.texteditor; 13 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 import java.util.ResourceBundle ; 20 21 import org.osgi.framework.Bundle; 22 23 import org.eclipse.swt.widgets.Shell; 24 25 import org.eclipse.core.commands.ExecutionException; 26 import org.eclipse.core.commands.operations.IOperationHistory; 27 import org.eclipse.core.commands.operations.IUndoableOperation; 28 29 import org.eclipse.core.runtime.Assert; 30 import org.eclipse.core.runtime.CoreException; 31 import org.eclipse.core.runtime.IAdaptable; 32 import org.eclipse.core.runtime.ILog; 33 import org.eclipse.core.runtime.IStatus; 34 import org.eclipse.core.runtime.Platform; 35 import org.eclipse.core.runtime.Status; 36 37 import org.eclipse.core.resources.IFile; 38 import org.eclipse.core.resources.IMarker; 39 import org.eclipse.core.resources.IResource; 40 41 import org.eclipse.jface.dialogs.ErrorDialog; 42 import org.eclipse.jface.dialogs.IInputValidator; 43 import org.eclipse.jface.dialogs.InputDialog; 44 import org.eclipse.jface.window.Window; 45 46 import org.eclipse.jface.text.BadLocationException; 47 import org.eclipse.jface.text.IDocument; 48 import org.eclipse.jface.text.IRegion; 49 import org.eclipse.jface.text.Position; 50 import org.eclipse.jface.text.source.IAnnotationModel; 51 import org.eclipse.jface.text.source.IVerticalRuler; 52 import org.eclipse.jface.text.source.IVerticalRulerInfo; 53 54 import org.eclipse.ui.IEditorInput; 55 import org.eclipse.ui.PlatformUI; 56 import org.eclipse.ui.ide.undo.CreateMarkersOperation; 57 import org.eclipse.ui.ide.undo.DeleteMarkersOperation; 58 59 66 public class MarkerRulerAction extends ResourceAction implements IUpdate { 67 68 69 private static final int MAX_LABEL_LENGTH= 80; 70 71 72 private IVerticalRulerInfo fRuler; 73 74 private ITextEditor fTextEditor; 75 76 private String fMarkerType; 77 78 private List fMarkers; 79 80 private boolean fAskForLabel; 81 82 private ResourceBundle fBundle; 83 84 private String fPrefix; 85 86 private String fAddLabel; 87 88 private String fRemoveLabel; 89 90 91 105 public MarkerRulerAction(ResourceBundle bundle, String prefix, ITextEditor editor, IVerticalRulerInfo ruler, String markerType, boolean askForLabel) { 106 super(bundle, prefix); 107 Assert.isLegal(editor != null); 108 109 fRuler= ruler; 110 fTextEditor= editor; 111 fMarkerType= markerType; 112 fAskForLabel= askForLabel; 113 114 fBundle= bundle; 115 fPrefix= prefix; 116 117 fAddLabel= getString(bundle, prefix + "add.label", prefix + "add.label"); fRemoveLabel= getString(bundle, prefix + "remove.label", prefix + "remove.label"); } 120 121 133 public MarkerRulerAction(ResourceBundle bundle, String prefix, IVerticalRuler ruler, ITextEditor editor, String markerType, boolean askForLabel) { 134 this(bundle, prefix, editor, ruler, markerType, askForLabel); 135 } 136 137 138 143 protected ITextEditor getTextEditor() { 144 return fTextEditor; 145 } 146 147 153 protected IVerticalRuler getVerticalRuler() { 154 if (fRuler instanceof IVerticalRuler) 155 return (IVerticalRuler) fRuler; 156 return null; 157 } 158 159 165 protected IVerticalRulerInfo getVerticalRulerInfo() { 166 return fRuler; 167 } 168 169 174 protected ResourceBundle getResourceBundle() { 175 return fBundle; 176 } 177 178 183 protected String getResourceKeyPrefix() { 184 return fPrefix; 185 } 186 187 190 public void update() { 191 int line= getVerticalRuler().getLineOfLastMouseButtonActivity() + 1; 193 IDocument document= getDocument(); 194 if (document != null) { 195 if (line > getDocument().getNumberOfLines()) { 196 setEnabled(false); 197 setText(fAddLabel); 198 } else { 199 fMarkers= getMarkers(); 200 setEnabled(getResource() != null && (fMarkers.isEmpty() || markersUserEditable(fMarkers))); 201 setText(fMarkers.isEmpty() ? fAddLabel : fRemoveLabel); 202 } 203 } 204 } 205 206 213 private boolean markersUserEditable(List markers) { 214 Iterator iter= markers.iterator(); 215 while (iter.hasNext()) { 216 if (!isUserEditable((IMarker)iter.next())) 217 return false; 218 } 219 return true; 220 } 221 222 229 private boolean isUserEditable(IMarker marker) { 230 return marker != null && marker.exists() && marker.getAttribute(IMarker.USER_EDITABLE, true); 231 } 232 233 236 public void run() { 237 if (fMarkers.isEmpty()) 238 addMarker(); 239 else 240 removeMarkers(fMarkers); 241 } 242 243 249 protected IResource getResource() { 250 IEditorInput input= fTextEditor.getEditorInput(); 251 252 IResource resource= (IResource) input.getAdapter(IFile.class); 253 254 if (resource == null) 255 resource= (IResource) input.getAdapter(IResource.class); 256 257 return resource; 258 } 259 260 265 protected AbstractMarkerAnnotationModel getAnnotationModel() { 266 IDocumentProvider provider= fTextEditor.getDocumentProvider(); 267 IAnnotationModel model= provider.getAnnotationModel(fTextEditor.getEditorInput()); 268 if (model instanceof AbstractMarkerAnnotationModel) 269 return (AbstractMarkerAnnotationModel) model; 270 return null; 271 } 272 273 278 protected IDocument getDocument() { 279 IDocumentProvider provider= fTextEditor.getDocumentProvider(); 280 return provider.getDocument(fTextEditor.getEditorInput()); 281 } 282 283 290 protected boolean includesRulerLine(Position position, IDocument document) { 291 292 if (position != null) { 293 try { 294 int markerLine= document.getLineOfOffset(position.getOffset()); 295 int line= fRuler.getLineOfLastMouseButtonActivity(); 296 if (line == markerLine) 297 return true; 298 } catch (BadLocationException x) { 301 } 302 } 303 304 return false; 305 } 306 307 314 protected void handleCoreException(CoreException exception, String message) { 315 Bundle bundle= Platform.getBundle(PlatformUI.PLUGIN_ID); 316 ILog log= Platform.getLog(bundle); 317 318 if (message != null) 319 log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, message, exception)); 320 else 321 log.log(exception.getStatus()); 322 323 324 Shell shell= getTextEditor().getSite().getShell(); 325 String title= getString(fBundle, fPrefix + "error.dialog.title", fPrefix + "error.dialog.title"); String msg= getString(fBundle, fPrefix + "error.dialog.message", fPrefix + "error.dialog.message"); 328 ErrorDialog.openError(shell, title, msg, exception.getStatus()); 329 } 330 331 336 protected List getMarkers() { 337 338 List markers= new ArrayList (); 339 340 IResource resource= getResource(); 341 IDocument document= getDocument(); 342 AbstractMarkerAnnotationModel model= getAnnotationModel(); 343 344 if (resource != null && model != null && resource.exists()) { 345 try { 346 IMarker[] allMarkers= resource.findMarkers(fMarkerType, true, IResource.DEPTH_ZERO); 347 if (allMarkers != null) { 348 for (int i= 0; i < allMarkers.length; i++) { 349 if (includesRulerLine(model.getMarkerPosition(allMarkers[i]), document)) { 350 markers.add(allMarkers[i]); 351 } 352 } 353 } 354 } catch (CoreException x) { 355 handleCoreException(x, TextEditorMessages.MarkerRulerAction_getMarker); 356 } 357 } 358 359 return markers; 360 } 361 362 366 protected void addMarker() { 367 IResource resource= getResource(); 368 if (resource == null) 369 return; 370 Map attributes= getInitialAttributes(); 371 if (fAskForLabel) { 372 if (!askForLabel(attributes)) 373 return; 374 } 375 execute(new CreateMarkersOperation(fMarkerType, attributes, resource, getOperationName())); 376 } 377 378 383 protected void removeMarkers(final List markers) { 384 IMarker[] markersArray= (IMarker[])markers.toArray(new IMarker[markers.size()]); 385 execute(new DeleteMarkersOperation(markersArray, getOperationName())); 386 } 387 388 397 protected boolean askForLabel(Map attributes) { 398 399 Object o= attributes.get("message"); String proposal= (o instanceof String ) ? (String ) o : ""; if (proposal == null) 402 proposal= ""; 404 String title= getString(fBundle, fPrefix + "add.dialog.title", fPrefix + "add.dialog.title"); String message= getString(fBundle, fPrefix + "add.dialog.message", fPrefix + "add.dialog.message"); IInputValidator inputValidator= new IInputValidator() { 407 public String isValid(String newText) { 408 return (newText == null || newText.trim().length() == 0) ? " " : null; } 410 }; 411 InputDialog dialog= new InputDialog(fTextEditor.getSite().getShell(), title, message, proposal, inputValidator); 412 413 String label= null; 414 if (dialog.open() != Window.CANCEL) 415 label= dialog.getValue(); 416 417 if (label == null) 418 return false; 419 420 label= label.trim(); 421 if (label.length() == 0) 422 return false; 423 424 MarkerUtilities.setMessage(attributes, label); 425 return true; 426 } 427 428 434 protected Map getInitialAttributes() { 435 436 Map attributes= new HashMap (11); 437 438 IDocumentProvider provider= fTextEditor.getDocumentProvider(); 439 IDocument document= provider.getDocument(fTextEditor.getEditorInput()); 440 int line= fRuler.getLineOfLastMouseButtonActivity(); 441 int start= -1; 442 int end= -1; 443 int length= 0; 444 445 try { 446 447 IRegion lineInformation= document.getLineInformation(line); 448 start= lineInformation.getOffset(); 449 length= lineInformation.getLength(); 450 451 end= start + length; 452 453 454 } catch (BadLocationException x) { 455 } 456 457 MarkerUtilities.setMessage(attributes, getLabelProposal(document, start, length)); 459 MarkerUtilities.setLineNumber(attributes, line + 1); 460 MarkerUtilities.setCharStart(attributes, start); 461 MarkerUtilities.setCharEnd(attributes, end); 462 463 return attributes; 464 } 465 466 475 protected String getLabelProposal(IDocument document, int offset, int length) { 476 try { 477 String label= document.get(offset, length).trim(); 478 if (label.length() <= MAX_LABEL_LENGTH) 479 return label; 480 return label.substring(0, MAX_LABEL_LENGTH); 481 } catch (BadLocationException x) { 482 return null; 484 } 485 } 486 487 493 private String getOperationName() { 494 String name= getText(); 495 return name == null ? TextEditorMessages.AddMarkerAction_addMarker : name; 496 } 497 498 504 private void execute(IUndoableOperation operation) { 505 final Shell shell= getTextEditor().getSite().getShell(); 506 IAdaptable context= new IAdaptable() { 507 public Object getAdapter(Class adapter) { 508 if (adapter == Shell.class) 509 return shell; 510 return null; 511 } 512 }; 513 514 IOperationHistory operationHistory= PlatformUI.getWorkbench().getOperationSupport().getOperationHistory(); 515 try { 516 operationHistory.execute(operation, null, context); 517 } catch (ExecutionException e) { 518 Bundle bundle= Platform.getBundle(PlatformUI.PLUGIN_ID); 519 ILog log= Platform.getLog(bundle); 520 String msg= getString(fBundle, fPrefix + "error.dialog.message", fPrefix + "error.dialog.message"); log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, msg, e)); 522 } 523 } 524 } 525 | Popular Tags |