| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.ui.views.tasklist; |
| |
| import java.util.*; |
| |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.TraverseEvent; |
| import org.eclipse.swt.events.TraverseListener; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.*; |
| |
| import org.eclipse.jface.dialogs.*; |
| import org.eclipse.jface.dialogs.Dialog; // disambiguate |
| |
| import org.eclipse.ui.help.WorkbenchHelp; |
| |
| /** |
| * Shows the properties of a new or existing task, or a problem. |
| */ |
| public class TaskPropertiesDialog extends Dialog { |
| |
| /** |
| * The task or problem being shown, or <code>null</code> for a new task. |
| */ |
| private IMarker marker = null; |
| |
| /** |
| * The resource on which to create a new task. |
| */ |
| private IResource resource = null; |
| |
| /** |
| * The initial attributes to use when creating a new task. |
| */ |
| private Map initialAttributes = null; |
| |
| /** |
| * The text control for the Description field. |
| */ |
| private Text descriptionText; |
| |
| /** |
| * The control for the Creation Time field. |
| */ |
| private Label creationTime; |
| |
| /** |
| * The combo box control for the Priority field. |
| */ |
| private Combo priorityCombo; |
| |
| /** |
| * The checkbox button for the Completed field. |
| */ |
| private Button completedCheckbox; |
| |
| /** |
| * The control for the Severity field. |
| */ |
| private Label severityLabel; |
| |
| /** |
| * The text control for the Resource field. |
| */ |
| private Text resourceText; |
| |
| /** |
| * The text control for the Folder field. |
| */ |
| private Text folderText; |
| |
| /** |
| * The text control for the Location field. |
| */ |
| private Text locationText; |
| |
| /** |
| * Dirty flag. True if any changes have been made. |
| */ |
| private boolean dirty; |
| |
| /** |
| * Creates the dialog. By default this dialog creates a new task. |
| * To set the resource and initial attributes for the new task, |
| * use <code>setResource</code> and <code>setInitialAttributes</code>. |
| * To show or modify an existing task, use <code>setMarker</code>. |
| * |
| * @param shell the parent shell |
| */ |
| public TaskPropertiesDialog(Shell parentShell) { |
| super(parentShell); |
| } |
| |
| /** |
| * Sets the marker to show or modify. |
| * |
| * @param marker the marker, or <code>null</code> to create a new marker |
| */ |
| public void setMarker(IMarker marker) { |
| this.marker = marker; |
| } |
| |
| /** |
| * Returns the marker being created or modified. |
| * For a new marker, this returns <code>null</code> until |
| * the dialog returns, but is non-null after. |
| */ |
| public IMarker getMarker() { |
| return marker; |
| } |
| |
| /** |
| * Sets the resource to use when creating a new task. |
| * If not set, the new task is created on the workspace root. |
| */ |
| public void setResource(IResource resource) { |
| this.resource = resource; |
| } |
| |
| /** |
| * Returns the resource to use when creating a new task, |
| * or <code>null</code> if none has been set. |
| * If not set, the new task is created on the workspace root. |
| */ |
| public IResource getResource() { |
| return resource; |
| } |
| |
| /** |
| * Sets initial attributes to use when creating a new task. |
| * If not set, the new task is created with default attributes. |
| */ |
| public void setInitialAttributes(Map initialAttributes) { |
| this.initialAttributes = initialAttributes; |
| } |
| |
| /** |
| * Returns the initial attributes to use when creating a new task, |
| * or <code>null</code> if not set. |
| * If not set, the new task is created with default attributes. |
| */ |
| public Map getInitialAttributes() { |
| return initialAttributes; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on Window. |
| */ |
| protected void configureShell(Shell newShell) { |
| super.configureShell(newShell); |
| |
| if (marker == null) { |
| newShell.setText(TaskListMessages.getString("TaskProp.newTaskTitle")); //$NON-NLS-1$ |
| } |
| else { |
| String kind = MarkerUtil.getKindText(marker); |
| newShell.setText(TaskListMessages.format("TaskProp.propertiesTitle", new Object[] { kind })); //$NON-NLS-1$ |
| } |
| |
| WorkbenchHelp.setHelp(newShell, ITaskListHelpContextIds.PROPERTIES_DIALOG); |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on Dialog. |
| */ |
| protected Control createDialogArea(Composite parent) { |
| Composite composite = (Composite) super.createDialogArea(parent); |
| initializeDialogUnits(composite); |
| createDescriptionArea(composite); |
| if (marker != null) |
| createCreationTimeArea(composite); |
| if (isTask()) { |
| createPriorityAndStatusArea(composite); |
| } |
| else { |
| createSeverityArea(composite); |
| } |
| createResourceArea(composite); |
| updateDialogFromMarker(); |
| return composite; |
| } |
| |
| /** |
| * Method createCreationTimeArea. |
| * @param composite |
| */ |
| private void createCreationTimeArea(Composite parent) { |
| Font font = parent.getFont(); |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| composite.setLayout(layout); |
| |
| Label label = new Label(composite, SWT.NONE); |
| label.setText(TaskListMessages.getString("TaskProp.creationTime")); //$NON-NLS-1$ |
| label.setFont(font); |
| |
| creationTime = new Label(composite, SWT.NONE); |
| creationTime.setFont(font); |
| } |
| |
| /** |
| * Creates only the OK button if showing problem properties, otherwise creates |
| * both OK and Cancel buttons. |
| */ |
| protected void createButtonsForButtonBar(Composite parent) { |
| createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); |
| if (isEditable()) { |
| createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); |
| } |
| } |
| |
| /** |
| * Creates the area for the Description field. |
| */ |
| private void createDescriptionArea(Composite parent) { |
| Font font = parent.getFont(); |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| composite.setLayout(layout); |
| Label label = new Label(composite, SWT.NONE); |
| label.setText(TaskListMessages.getString("TaskProp.description")); //$NON-NLS-1$ |
| label.setFont(font); |
| int style = SWT.SINGLE | SWT.BORDER; |
| if (!isEditable()) { |
| style |= SWT.READ_ONLY; |
| } |
| descriptionText = new Text(composite, style); |
| GridData gridData = new GridData(GridData.FILL_HORIZONTAL); |
| gridData.widthHint = convertHorizontalDLUsToPixels(400); |
| descriptionText.setLayoutData(gridData); |
| descriptionText.setFont(font); |
| } |
| |
| /** |
| * Creates the area for the Priority and Status fields. |
| */ |
| private void createPriorityAndStatusArea(Composite parent) { |
| Font font = parent.getFont(); |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 3; |
| composite.setLayout(layout); |
| |
| Label label = new Label(composite, SWT.NONE); |
| label.setText(TaskListMessages.getString("TaskProp.priority")); //$NON-NLS-1$ |
| label.setFont(font); |
| priorityCombo = new Combo(composite, SWT.READ_ONLY); |
| priorityCombo.setItems(new String[] { |
| TaskListMessages.getString("TaskList.high"), //$NON-NLS-1$ |
| TaskListMessages.getString("TaskList.normal"), //$NON-NLS-1$ |
| TaskListMessages.getString("TaskList.low") //$NON-NLS-1$ |
| }); |
| // Prevent Esc and Return from closing the dialog when the combo is active. |
| priorityCombo.addTraverseListener(new TraverseListener() { |
| public void keyTraversed(TraverseEvent e) { |
| if (e.detail == SWT.TRAVERSE_ESCAPE || e.detail == SWT.TRAVERSE_RETURN) { |
| e.doit = false; |
| } |
| } |
| }); |
| priorityCombo.setFont(font); |
| |
| completedCheckbox = new Button(composite, SWT.CHECK); |
| completedCheckbox.setText(TaskListMessages.getString("TaskProp.completed")); //$NON-NLS-1$ |
| GridData gridData = new GridData(); |
| gridData.horizontalIndent = convertHorizontalDLUsToPixels(20); |
| completedCheckbox.setLayoutData(gridData); |
| completedCheckbox.setFont(font); |
| |
| if (!isEditable()) { |
| priorityCombo.setEnabled(false); |
| completedCheckbox.setEnabled(false); |
| } |
| } |
| |
| /** |
| * Creates the area for the Severity field. |
| */ |
| private void createSeverityArea(Composite parent) { |
| Font font = parent.getFont(); |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| composite.setLayout(layout); |
| |
| Label label = new Label(composite, SWT.NONE); |
| label.setText(TaskListMessages.getString("TaskProp.severity")); //$NON-NLS-1$ |
| label.setFont(font); |
| // workaround for bug 11078: Can't get a read-only combo box |
| severityLabel = new Label(composite, SWT.NONE); |
| severityLabel.setFont(font); |
| /* |
| severityCombo = new Combo(composite, SWT.READ_ONLY); |
| severityCombo.setItems(new String[] { |
| TaskListMessages.getString("TaskList.error"), //$NON-NLS-1$ |
| TaskListMessages.getString("TaskList.warning"), //$NON-NLS-1$ |
| TaskListMessages.getString("TaskList.info") //$NON-NLS-1$ |
| }); |
| */ |
| } |
| |
| /** |
| * Creates the area for the Resource field. |
| */ |
| private void createResourceArea(Composite parent) { |
| IResource resource = getResource(); |
| if (marker == null) { |
| if (resource == null) |
| return; |
| if ((resource.getType() & (IResource.FILE | IResource.FOLDER | IResource.PROJECT)) == 0) |
| return; |
| } |
| |
| Font font = parent.getFont(); |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridData gridData = new GridData(GridData.FILL_HORIZONTAL); |
| composite.setLayoutData(gridData); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| composite.setLayout(layout); |
| |
| Label resourceLabel = new Label(composite, SWT.NONE); |
| resourceLabel.setText(TaskListMessages.getString("TaskProp.onResource")); //$NON-NLS-1$ |
| resourceLabel.setFont(font); |
| resourceText = new Text(composite, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY | SWT.BORDER); |
| gridData = new GridData(GridData.FILL_HORIZONTAL); |
| resourceText.setLayoutData(gridData); |
| resourceText.setFont(font); |
| |
| Label folderLabel = new Label(composite, SWT.NONE); |
| folderLabel.setText(TaskListMessages.getString("TaskProp.inFolder")); //$NON-NLS-1$ |
| folderLabel.setFont(font); |
| folderText = new Text(composite, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY | SWT.BORDER); |
| gridData = new GridData(GridData.FILL_HORIZONTAL); |
| folderText.setLayoutData(gridData); |
| folderText.setFont(font); |
| |
| Label locationLabel = new Label(composite, SWT.NONE); |
| locationLabel.setText(TaskListMessages.getString("TaskProp.location")); //$NON-NLS-1$ |
| locationLabel.setFont(font); |
| locationText = new Text(composite, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY | SWT.BORDER); |
| gridData = new GridData(GridData.FILL_HORIZONTAL); |
| locationText.setLayoutData(gridData); |
| locationText.setFont(font); |
| } |
| |
| /** |
| * Updates the dialog from the marker state. |
| */ |
| private void updateDialogFromMarker() { |
| if (marker == null) { |
| updateDialogForNewMarker(); |
| return; |
| } |
| descriptionText.setText(MarkerUtil.getMessage(marker)); |
| descriptionText.selectAll(); |
| creationTime.setText(MarkerUtil.getCreationTime(marker)); |
| if (isTask()) { |
| priorityCombo.clearSelection(); |
| priorityCombo.select(IMarker.PRIORITY_HIGH - MarkerUtil.getPriority(marker)); |
| completedCheckbox.setSelection(MarkerUtil.isComplete(marker)); |
| markDirty(); |
| } |
| else { |
| /* workaround for bug 11078: Can't get a read-only combo box |
| severityCombo.clearSelection(); |
| severityCombo.select(IMarker.SEVERITY_ERROR - MarkerUtil.getSeverity(marker)); |
| */ |
| String sev = ""; //$NON-NLS-1$ |
| switch (MarkerUtil.getSeverity(marker)) { |
| case IMarker.SEVERITY_ERROR: |
| sev = TaskListMessages.getString("TaskList.error"); //$NON-NLS-1$ |
| break; |
| case IMarker.SEVERITY_WARNING: |
| sev = TaskListMessages.getString("TaskList.warning"); //$NON-NLS-1$ |
| break; |
| case IMarker.SEVERITY_INFO: |
| sev = TaskListMessages.getString("TaskList.info"); //$NON-NLS-1$ |
| break; |
| } |
| severityLabel.setText(sev); |
| |
| } |
| resourceText.setText(MarkerUtil.getResourceName(marker)); |
| folderText.setText(MarkerUtil.getContainerName(marker)); |
| locationText.setText(MarkerUtil.getLineAndLocation(marker)); |
| } |
| |
| /** |
| * Updates the dialog to reflect the state for a new marker. |
| */ |
| private void updateDialogForNewMarker() { |
| Map attrs = getInitialAttributes(); |
| |
| String desc = ""; //$NON-NLS-1$ |
| if (attrs != null) { |
| Object o = attrs.get(IMarker.MESSAGE); |
| if (o instanceof String) { |
| desc = (String) o; |
| } |
| } |
| descriptionText.setText(desc); |
| descriptionText.selectAll(); |
| |
| int pri = IMarker.PRIORITY_NORMAL; |
| if (attrs != null) { |
| Object o = attrs.get(IMarker.PRIORITY); |
| if (o instanceof Integer) { |
| int val = ((Integer) o).intValue(); |
| if (val >= IMarker.PRIORITY_LOW && val <= IMarker.PRIORITY_HIGH) { |
| pri = val; |
| } |
| } |
| } |
| priorityCombo.deselectAll(); |
| priorityCombo.select(IMarker.PRIORITY_HIGH - pri); |
| |
| boolean completed = false; |
| if (attrs != null) { |
| Object o = attrs.get(IMarker.DONE); |
| if (o instanceof Boolean) { |
| completed = ((Boolean) o).booleanValue(); |
| } |
| } |
| completedCheckbox.setSelection(completed); |
| |
| IResource resource = getResource(); |
| if (resource != null && resourceText != null) { |
| resourceText.setText(resource.getName()); |
| IResource parent = resource.getParent(); |
| folderText.setText(parent == null ? "" : parent.getFullPath().toString().substring(1)); //$NON-NLS-1$ |
| } |
| |
| int line = -1; |
| String loc = ""; //$NON-NLS-1$ |
| if (attrs != null) { |
| Object o = attrs.get(IMarker.LINE_NUMBER); |
| if (o instanceof Integer) { |
| line = ((Integer) o).intValue(); |
| } |
| o = attrs.get(IMarker.LOCATION); |
| if (o instanceof String) { |
| loc = (String) o; |
| } |
| } |
| if (locationText != null) |
| locationText.setText(MarkerUtil.getLineAndLocation(line, loc)); |
| |
| markDirty(); |
| return; |
| |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on Dialog |
| */ |
| protected void okPressed() { |
| saveChanges(); |
| super.okPressed(); |
| } |
| |
| private void markDirty() { |
| dirty = true; |
| } |
| |
| private boolean isDirty() { |
| return dirty; |
| } |
| |
| /** |
| * Returns whether the marker is editable. |
| */ |
| private boolean isEditable() { |
| return marker == null || MarkerUtil.isEditable(marker); |
| } |
| |
| /** |
| * Returns <code>true</code> if a task is being created or modified. |
| * Returns <code>false</code> if a problem is being shown. |
| */ |
| private boolean isTask() { |
| return marker == null || MarkerUtil.isMarkerType(marker, IMarker.TASK); |
| } |
| |
| /** |
| * Saves the changes made in the dialog if needed. |
| * Creates a new task if needed. |
| * Updates the existing task only if there have been changes. |
| * Does nothing for problems, since they cannot be modified. |
| */ |
| private void saveChanges() { |
| if (!isEditable() || !isDirty()) { |
| return; |
| } |
| try { |
| ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { |
| public void run(IProgressMonitor monitor) throws CoreException { |
| createOrUpdateMarker(); |
| } |
| }, null); |
| } catch (CoreException e) { |
| ErrorDialog.openError( |
| getShell(), |
| TaskListMessages.getString("TaskProp.errorMessage"), //$NON-NLS-1$ |
| null, |
| e.getStatus()); |
| return; |
| } |
| } |
| |
| /** |
| * Creates or updates the marker. Must be called within a workspace runnable. |
| */ |
| private void createOrUpdateMarker() throws CoreException { |
| if (marker == null) { |
| IResource resource = getResource(); |
| if (resource == null) { |
| resource = ResourcesPlugin.getWorkspace().getRoot(); |
| } |
| marker = resource.createMarker(IMarker.TASK); |
| Map initialAttrs = getInitialAttributes(); |
| if (initialAttrs != null) { |
| marker.setAttributes(initialAttrs); |
| } |
| } |
| |
| // Set the marker attributes from the current dialog field values. |
| // Do not use setAttributes(Map) as that overwrites any attributes |
| // not covered by the dialog. |
| Map attrs = getMarkerAttributesFromDialog(); |
| for (Iterator i = attrs.keySet().iterator(); i.hasNext();) { |
| String key = (String) i.next(); |
| Object val = attrs.get(key); |
| marker.setAttribute(key, val); |
| } |
| } |
| |
| /** |
| * Returns the marker attributes to save back to the marker, |
| * based on the current dialog fields. |
| */ |
| private Map getMarkerAttributesFromDialog() { |
| Map attribs = new HashMap(11); |
| if (isTask()) { |
| attribs.put(IMarker.MESSAGE, descriptionText.getText()); |
| int i = priorityCombo.getSelectionIndex(); |
| if (i != -1) { |
| attribs.put(IMarker.PRIORITY, new Integer(IMarker.PRIORITY_HIGH - i)); |
| } |
| attribs.put(IMarker.DONE, completedCheckbox.getSelection() ? Boolean.TRUE : Boolean.FALSE); |
| } |
| return attribs; |
| } |
| } |