| package org.eclipse.ui.texteditor; |
| |
| /* |
| * (c) Copyright IBM Corp. 2000, 2001. |
| * All Rights Reserved. |
| */ |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.ResourceBundle; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.ILog; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.IInputValidator; |
| import org.eclipse.jface.dialogs.InputDialog; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.text.Position; |
| import org.eclipse.jface.text.source.IAnnotationModel; |
| import org.eclipse.jface.text.source.IVerticalRulerInfo; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.views.tasklist.TaskPropertiesDialog; |
| |
| |
| |
| /** |
| * A ruler action which can add and remove markers which have a visual |
| * representation in the ruler. |
| * <p> |
| * This class may be instantiated but is not intended for subclassing. |
| * </p> |
| */ |
| public class MarkerRulerInfoAction extends ResourceAction implements IUpdate { |
| |
| private IVerticalRulerInfo fRuler; |
| private ITextEditor fTextEditor; |
| private String fMarkerType; |
| private List fMarkers; |
| private boolean fAskForLabel; |
| |
| private ResourceBundle fBundle; |
| private String fPrefix; |
| |
| private String fAddLabel; |
| private String fRemoveLabel; |
| |
| /** |
| * Creates a new action for the given ruler and editor. The action configures |
| * its visual representation from the given resource bundle. |
| * |
| * @param bundle the resource bundle |
| * @param prefix a prefix to be prepended to the various resource keys |
| * (described in <code>ResourceAction</code> constructor), or |
| * <code>null</code> if none |
| * @param ruler the ruler |
| * @param editor the editor |
| * @param markerType the type of marker |
| * @param askForLabel <code>true</code> if the user should be asked for |
| * a label when a new marker is created |
| * @see ResourceAction#ResourceAction |
| */ |
| public MarkerRulerInfoAction(ResourceBundle bundle, String prefix, IVerticalRulerInfo ruler, ITextEditor editor, String markerType, boolean askForLabel) { |
| super(bundle, prefix); |
| fRuler= ruler; |
| fTextEditor= editor; |
| fMarkerType= markerType; |
| fAskForLabel= askForLabel; |
| |
| fBundle= bundle; |
| fPrefix= prefix; |
| |
| fAddLabel= getString(bundle, prefix + "add.label", prefix + "add.label"); //$NON-NLS-2$ //$NON-NLS-1$ |
| fRemoveLabel= getString(bundle, prefix + "remove.label", prefix + "remove.label"); //$NON-NLS-2$ //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns this action's editor. |
| * |
| * @return this action's editor |
| */ |
| protected ITextEditor getTextEditor() { |
| return fTextEditor; |
| } |
| |
| /** |
| * Returns this action's vertical ruler info. |
| * |
| * @return this action's vertical ruler info |
| */ |
| protected IVerticalRulerInfo getVerticalRulerInfo() { |
| return fRuler; |
| } |
| |
| /** |
| * Returns this action's resource bundle. |
| * |
| * @return this action's resource bundle |
| */ |
| protected ResourceBundle getResourceBundle() { |
| return fBundle; |
| } |
| |
| /** |
| * Returns this action's resource key prefix. |
| * |
| * @return this action's resource key prefix |
| */ |
| protected String getResourceKeyPrefix() { |
| return fPrefix; |
| } |
| |
| /* |
| * @see IUpdate#update() |
| */ |
| public void update() { |
| fMarkers= getMarkers(); |
| setText(fMarkers.isEmpty() ? fAddLabel : fRemoveLabel); |
| } |
| |
| /* |
| * @see Action#run() |
| */ |
| public void run() { |
| if (fMarkers.isEmpty()) |
| addMarker(); |
| else |
| removeMarkers(fMarkers); |
| } |
| |
| /** |
| * Returns the resource for which to create the marker, |
| * or <code>null</code> if there is no applicable resource. |
| * |
| * @return the resource for which to create the marker or <code>null</code> |
| */ |
| protected IResource getResource() { |
| IEditorInput input= fTextEditor.getEditorInput(); |
| |
| IResource resource= (IResource) input.getAdapter(IFile.class); |
| |
| if (resource == null) |
| resource= (IResource) input.getAdapter(IResource.class); |
| |
| return resource; |
| } |
| |
| /** |
| * Returns the <code>AbstractMarkerAnnotationModel</code> of the editor's input. |
| * |
| * @return the marker annotation model |
| */ |
| protected AbstractMarkerAnnotationModel getAnnotationModel() { |
| IDocumentProvider provider= fTextEditor.getDocumentProvider(); |
| IAnnotationModel model= provider.getAnnotationModel(fTextEditor.getEditorInput()); |
| if (model instanceof AbstractMarkerAnnotationModel) |
| return (AbstractMarkerAnnotationModel) model; |
| return null; |
| } |
| |
| /** |
| * Returns the <code>IDocument</code> of the editor's input. |
| * |
| * @return the document of the editor's input |
| */ |
| protected IDocument getDocument() { |
| IDocumentProvider provider= fTextEditor.getDocumentProvider(); |
| return provider.getDocument(fTextEditor.getEditorInput()); |
| } |
| |
| /** |
| * Checks whether a position includes the ruler's line of activity. |
| * |
| * @param position the position to be checked |
| * @param document the document the position refers to |
| * @return <code>true</code> if the line is included by the given position |
| */ |
| protected boolean includesRulerLine(Position position, IDocument document) { |
| |
| if (position != null) { |
| try { |
| int markerLine= document.getLineOfOffset(position.getOffset()); |
| int line= fRuler.getLineOfLastMouseButtonActivity(); |
| if (line == markerLine) |
| return true; |
| // commented because of "1GEUOZ9: ITPJUI:ALL - Confusing UI for multiline Bookmarks and Tasks" |
| // return (markerLine <= line && line <= document.getLineOfOffset(position.getOffset() + position.getLength())); |
| } catch (BadLocationException x) { |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Handles core exceptions. This implementation logs the exceptions |
| * with the workbech plugin. |
| * |
| * @param exception the exception to be handled |
| * @param message the message to be logged with the given exception |
| */ |
| protected void handleCoreException(CoreException exception, String message) { |
| ILog log= Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog(); |
| |
| if (message != null) |
| log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, message, null)); |
| |
| log.log(exception.getStatus()); |
| |
| |
| Shell shell= getTextEditor().getSite().getShell(); |
| String title= getString(fBundle, fPrefix + "error.dialog.title", fPrefix + "error.dialog.title"); //$NON-NLS-2$ //$NON-NLS-1$ |
| String msg= getString(fBundle, fPrefix + "error.dialog.message", fPrefix + "error.dialog.message"); //$NON-NLS-2$ //$NON-NLS-1$ |
| |
| ErrorDialog.openError(shell, title, msg, exception.getStatus()); |
| } |
| |
| /** |
| * Returns all markers which include the ruler's line of activity. |
| * |
| * @returns all markers which include the ruler's line of activity |
| */ |
| protected List getMarkers() { |
| |
| List markers= new ArrayList(); |
| |
| IResource resource= getResource(); |
| IDocument document= getDocument(); |
| AbstractMarkerAnnotationModel model= getAnnotationModel(); |
| |
| if (resource != null && model != null) { |
| try { |
| IMarker[] allMarkers= resource.findMarkers(fMarkerType, true, IResource.DEPTH_ZERO); |
| if (allMarkers != null) { |
| for (int i= 0; i < allMarkers.length; i++) { |
| if (includesRulerLine(model.getMarkerPosition(allMarkers[i]), document)) { |
| markers.add(allMarkers[i]); |
| } |
| } |
| } |
| } catch (CoreException x) { |
| handleCoreException(x, EditorMessages.getString("MarkerRulerAction.getMarker")); //$NON-NLS-1$ |
| } |
| } |
| |
| return markers; |
| } |
| |
| /** |
| * Creates a new marker according to the specification of this action and |
| * adds it to the marker resource. |
| */ |
| protected void addMarker() { |
| IResource resource= getResource(); |
| if (resource == null) |
| return; |
| Map attributes= getInitialAttributes(); |
| if (fAskForLabel) { |
| if (IMarker.TASK.equals(fMarkerType)) { |
| TaskPropertiesDialog dialog = new TaskPropertiesDialog(getTextEditor().getSite().getShell()); |
| dialog.setResource(resource); |
| dialog.setInitialAttributes(attributes); |
| dialog.open(); |
| return; |
| } |
| if (!askForLabel(attributes)) |
| return; |
| } |
| |
| try { |
| MarkerUtilities.createMarker(resource, attributes, fMarkerType); |
| } catch (CoreException x) { |
| handleCoreException(x, EditorMessages.getString("MarkerRulerAction.addMarker")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Removes the given markers. |
| * |
| * @param markers the markers to be deleted |
| */ |
| protected void removeMarkers(final List markers) { |
| try { |
| getResource().getWorkspace().run(new IWorkspaceRunnable() { |
| public void run(IProgressMonitor monitor) throws CoreException { |
| for (int i= 0; i < markers.size(); ++i) { |
| IMarker marker= (IMarker) markers.get(i); |
| marker.delete(); |
| } |
| } |
| }, null); |
| } catch (CoreException x) { |
| handleCoreException(x, EditorMessages.getString("MarkerRulerAction.removeMarkers")); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Asks the user for a marker label. Returns <code>true</code> if a label |
| * is entered, <code>false</code> if the user cancels the input dialog. |
| * Sets the value of the attribute <code>message</code> in the given |
| * map of attributes. |
| * |
| * @param attributes the map of attributes |
| */ |
| protected boolean askForLabel(Map attributes) { |
| |
| Object o= attributes.get("message"); //$NON-NLS-1$ |
| String proposal= (o instanceof String) ? (String) o : ""; //$NON-NLS-1$ |
| if (proposal == null) |
| proposal= ""; //$NON-NLS-1$ |
| |
| String title= getString(fBundle, fPrefix + "add.dialog.title", fPrefix + "add.dialog.title"); //$NON-NLS-2$ //$NON-NLS-1$ |
| String message= getString(fBundle, fPrefix + "add.dialog.message", fPrefix + "add.dialog.message"); //$NON-NLS-2$ //$NON-NLS-1$ |
| IInputValidator inputValidator = new IInputValidator() { |
| public String isValid(String newText) { |
| return (newText == null || newText.length() == 0) ? " " : null; //$NON-NLS-1$ |
| } |
| }; |
| InputDialog dialog= new InputDialog(fTextEditor.getSite().getShell(), title, message, proposal, inputValidator); |
| |
| String label= null; |
| if (dialog.open() != Window.CANCEL) |
| label= dialog.getValue(); |
| |
| if (label == null) |
| return false; |
| |
| label= label.trim(); |
| if (label.length() == 0) |
| return false; |
| |
| MarkerUtilities.setMessage(attributes, label); |
| return true; |
| } |
| |
| /** |
| * Returns the attributes with which a newly created marker will be |
| * initialized. |
| * |
| * @return the initial marker attributes |
| */ |
| protected Map getInitialAttributes() { |
| |
| Map attributes= new HashMap(11); |
| |
| IDocumentProvider provider= fTextEditor.getDocumentProvider(); |
| IDocument document= provider.getDocument(fTextEditor.getEditorInput()); |
| int line= fRuler.getLineOfLastMouseButtonActivity(); |
| int start= -1; |
| int end= -1; |
| |
| try { |
| |
| IRegion lineInformation= document.getLineInformation(line); |
| start= lineInformation.getOffset(); |
| int length= lineInformation.getLength(); |
| |
| end= start + length; |
| |
| } catch (BadLocationException x) { |
| } |
| |
| // marker line numbers are 1-based |
| MarkerUtilities.setLineNumber(attributes, line + 1); |
| MarkerUtilities.setCharStart(attributes, start); |
| MarkerUtilities.setCharEnd(attributes, end); |
| |
| return attributes; |
| } |
| } |
| |