package org.eclipse.mylyn.internal.tasks.ui.editors; import java.util.Calendar; import java.util.Date; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.mylyn.commons.core.DateUtil; import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages; import org.eclipse.mylyn.internal.provisional.commons.ui.DatePicker; import org.eclipse.mylyn.internal.tasks.core.AbstractTask; import org.eclipse.mylyn.internal.tasks.core.DateRange; import org.eclipse.mylyn.internal.tasks.core.LocalTask; import org.eclipse.mylyn.internal.tasks.core.TaskActivityUtil; import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants; import org.eclipse.mylyn.internal.tasks.ui.ScheduleDatePicker; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.monitor.ui.MonitorUi; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.ITaskActivityListener; import org.eclipse.mylyn.tasks.core.TaskActivityAdapter; import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage; import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Spinner; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ImageHyperlink; import org.eclipse.ui.forms.widgets.Section; public class TaskEditorPersonalPlanningPart extends AbstractTaskEditorPart { private int estimate = 0; private Date dueDate = null; private DateRange scheduledDate = null; private ITaskActivityListener timingListener; private ITask task = null; private static final String CLEAR = "Clear"; private static final String LABEL_DUE = "Due:"; private static final String LABEL_SCHEDULE = "Scheduled for:"; private static final String RESET = "Reset"; private static final String NO_TIME_ELAPSED = "0 seconds"; public TaskEditorPersonalPlanningPart() { setPartName("Personal Planning"); } @Override public void initialize(AbstractTaskEditorPage taskEditorPage) { super.initialize(taskEditorPage); task = taskEditorPage.getTask(); } private boolean dueDatesEqual() { if (dueDate == null && task.getDueDate() == null) { return true; } if (dueDate != null && task.getDueDate() != null) { return dueDate.equals(task.getDueDate()); } return false; } private boolean estimatedTimesEqual() { return estimate == task.getEstimatedTimeHours(); } private boolean scheduledDatesEqual() { if (scheduledDate == null && ((AbstractTask) task).getScheduledForDate() == null) { return true; } if (scheduledDate != null && ((AbstractTask) task).getScheduledForDate() != null) { return scheduledDate.equals(((AbstractTask) task).getScheduledForDate()); } return false; } @Override public void commit(boolean onSave) { Assert.isNotNull(task); boolean hasChanged = false; if (estimatedTimesEqual()) { task.setEstimatedTimeHours(estimate); hasChanged = true; } if (!dueDatesEqual()) { TasksUiPlugin.getTaskActivityManager().setDueDate(task, dueDate); hasChanged = true; } if (!scheduledDatesEqual() && task instanceof AbstractTask) { AbstractTask abstractTask = (AbstractTask) task; TasksUiPlugin.getTaskActivityManager().setScheduledFor(abstractTask, scheduledDate); abstractTask.setReminded(false); hasChanged = true; } if (hasChanged) { // XXX refresh the tasklist so that state is reflected? } super.commit(onSave); } @Override public void createControl(Composite parent, FormToolkit toolkit) { if (task == null) { return; } estimate = task.getEstimatedTimeHours(); dueDate = task.getDueDate(); Section section = createSection(parent, toolkit, true); Composite sectionClient = getManagedForm().getToolkit().createComposite(section); GridLayout layout = new GridLayout(); layout.numColumns = 3; layout.makeColumnsEqualWidth = false; sectionClient.setLayout(layout); GridData clientDataLayout = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); sectionClient.setLayoutData(clientDataLayout); if (task instanceof AbstractTask) { AbstractTask abstractTask = (AbstractTask) task; scheduledDate = abstractTask.getScheduledForDate(); Composite nameValueComp = makeComposite(toolkit, sectionClient, 3); Label label = toolkit.createLabel(nameValueComp, LABEL_SCHEDULE); label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); final ScheduleDatePicker scheduleDatePicker = new ScheduleDatePicker(nameValueComp, abstractTask, SWT.FLAT); scheduleDatePicker.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); toolkit.adapt(scheduleDatePicker, true, true); toolkit.paintBordersFor(nameValueComp); scheduleDatePicker.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); scheduleDatePicker.addPickerSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent arg0) { scheduledDate = scheduleDatePicker.getScheduledDate(); markDirty(); } public void widgetDefaultSelected(SelectionEvent arg0) { // ignore } }); ImageHyperlink clearScheduledDate = toolkit.createImageHyperlink(nameValueComp, SWT.NONE); clearScheduledDate.setImage(CommonImages.getImage(CommonImages.REMOVE)); clearScheduledDate.setToolTipText(CLEAR); clearScheduledDate.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { scheduleDatePicker.setScheduledDate(null); scheduledDate = null; markDirty(); } }); } if (task != null && !(task instanceof LocalTask)) { AbstractRepositoryConnectorUi connector = TasksUiPlugin.getConnectorUi(task.getConnectorKind()); if (connector != null && !connector.supportsDueDates(task)) { Composite nameValueComp = makeComposite(toolkit, sectionClient, 3); Label label = toolkit.createLabel(nameValueComp, LABEL_DUE); label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); final DatePicker dueDatePicker = new DatePicker(nameValueComp, SWT.FLAT, DatePicker.LABEL_CHOOSE, true, TasksUiPlugin.getDefault().getPreferenceStore().getInt( ITasksUiPreferenceConstants.PLANNING_ENDHOUR)); Calendar calendar = TaskActivityUtil.getCalendar(); if (task.getDueDate() != null) { calendar.setTime(task.getDueDate()); dueDatePicker.setDate(calendar); } dueDatePicker.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); dueDatePicker.addPickerSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent arg0) { dueDate = dueDatePicker.getDate().getTime(); markDirty(); } }); dueDatePicker.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); toolkit.adapt(dueDatePicker, true, true); toolkit.paintBordersFor(nameValueComp); ImageHyperlink clearDueDate = toolkit.createImageHyperlink(nameValueComp, SWT.NONE); clearDueDate.setImage(CommonImages.getImage(CommonImages.REMOVE)); clearDueDate.setToolTipText(CLEAR); clearDueDate.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { dueDatePicker.setDate(null); dueDate = null; markDirty(); } }); } } // 1 Blank column after Reminder clear button Composite nameValueComp = makeComposite(toolkit, sectionClient, 3); // Estimated time getManagedForm().getToolkit().createLabel(nameValueComp, "Estimated hours:"); // label.setForeground(toolkit.getColors().getColor(FormColors.TITLE)); // estimatedTime = new Spinner(sectionClient, SWT.FLAT); final Spinner estimatedTime = new Spinner(nameValueComp, SWT.FLAT); estimatedTime.setDigits(0); estimatedTime.setMaximum(100); estimatedTime.setMinimum(0); estimatedTime.setIncrement(1); estimatedTime.setSelection(estimate); estimatedTime.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); GridData estimatedDataLayout = new GridData(); estimatedDataLayout.widthHint = 30; estimatedTime.setLayoutData(estimatedDataLayout); estimatedTime.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { estimate = estimatedTime.getSelection(); markDirty(); } }); estimatedTime.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { estimate = estimatedTime.getSelection(); markDirty(); } }); // getManagedForm().getToolkit().createLabel(sectionClient, "hours "); // label.setForeground(toolkit.getColors().getColor(FormColors.TITLE)); ImageHyperlink clearEstimated = getManagedForm().getToolkit().createImageHyperlink(nameValueComp, SWT.NONE); clearEstimated.setImage(CommonImages.getImage(CommonImages.REMOVE)); clearEstimated.setToolTipText("Clear"); clearEstimated.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { estimatedTime.setSelection(0); estimate = 0; markDirty(); } }); getManagedForm().getToolkit().paintBordersFor(nameValueComp); // Active Time nameValueComp = makeComposite(toolkit, sectionClient, 3); GridDataFactory.fillDefaults().applyTo(nameValueComp); Label label = toolkit.createLabel(nameValueComp, "Active:"); label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE)); label.setToolTipText("Time working on this task"); String elapsedTimeString = NO_TIME_ELAPSED; try { elapsedTimeString = DateUtil.getFormattedDuration(TasksUiPlugin.getTaskActivityManager().getElapsedTime( task), false); if (elapsedTimeString.equals("")) { elapsedTimeString = NO_TIME_ELAPSED; } } catch (RuntimeException e) { // FIXME what exception is caught here? StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not format elapsed time", e)); } final Text elapsedTimeText = toolkit.createText(nameValueComp, elapsedTimeString); elapsedTimeText.setText(elapsedTimeString); GridData td = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); td.grabExcessHorizontalSpace = true; elapsedTimeText.setLayoutData(td); elapsedTimeText.setEditable(false); timingListener = new TaskActivityAdapter() { @Override public void elapsedTimeUpdated(ITask task, long newElapsedTime) { if (task.equals(task)) { String elapsedTimeString = NO_TIME_ELAPSED; try { elapsedTimeString = DateUtil.getFormattedDuration(newElapsedTime, false); if (elapsedTimeString.equals("")) { elapsedTimeString = NO_TIME_ELAPSED; } } catch (RuntimeException e) { StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not format elapsed time", e)); } final String elapsedString = elapsedTimeString; PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { if (!elapsedTimeText.isDisposed()) { elapsedTimeText.setText(elapsedString); } } }); } } }; TasksUiPlugin.getTaskActivityManager().addActivityListener(timingListener); ImageHyperlink resetActivityTimeButton = toolkit.createImageHyperlink(nameValueComp, SWT.NONE); resetActivityTimeButton.setImage(CommonImages.getImage(CommonImages.REMOVE)); resetActivityTimeButton.setToolTipText(RESET); resetActivityTimeButton.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { if (MessageDialog.openConfirm(getManagedForm().getForm().getShell(), "Confirm Activity Time Deletion", "Do you wish to reset your activity time on this task?\n\nThis will take immediate affect and can not be undone.")) { MonitorUi.getActivityContextManager().removeActivityTime(task.getHandleIdentifier(), 0l, System.currentTimeMillis()); } } }); getManagedForm().getToolkit().paintBordersFor(sectionClient); section.setClient(sectionClient); setSection(toolkit, section); } private Composite makeComposite(FormToolkit toolkit, Composite parent, int col) { Composite nameValueComp = toolkit.createComposite(parent); GridLayout layout = new GridLayout(3, false); layout.marginHeight = 3; nameValueComp.setLayout(layout); return nameValueComp; } @Override public void dispose() { if (timingListener != null) { TasksUiPlugin.getTaskActivityManager().removeActivityListener(timingListener); } super.dispose(); } }