### Eclipse Workspace Patch 1.0 #P org.eclipse.mylyn.jira.core Index: src/org/eclipse/mylyn/internal/jira/core/model/JiraWorkLog.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.core/src/org/eclipse/mylyn/internal/jira/core/model/JiraWorkLog.java,v retrieving revision 1.2 diff -u -r1.2 JiraWorkLog.java --- src/org/eclipse/mylyn/internal/jira/core/model/JiraWorkLog.java 26 Feb 2009 02:21:02 -0000 1.2 +++ src/org/eclipse/mylyn/internal/jira/core/model/JiraWorkLog.java 4 May 2009 22:21:42 -0000 @@ -16,6 +16,7 @@ /** * @author Steffen Pingel + * @author Thomas Ehrnhoefer */ public class JiraWorkLog implements Serializable { @@ -41,9 +42,15 @@ private Date updated; + private boolean autoAdjustEstimate; + public JiraWorkLog() { } + public boolean isAutoAdjustEstimate() { + return autoAdjustEstimate; + } + public String getAuthor() { return author; } @@ -87,6 +94,10 @@ return updated; } + public void setAutoAdjustEstimate(boolean autoAdjustEstimate) { + this.autoAdjustEstimate = autoAdjustEstimate; + } + public void setAuthor(String author) { this.author = author; } @@ -127,4 +138,105 @@ this.updated = updated; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((author == null) ? 0 : author.hashCode()); + result = prime * result + (autoAdjustEstimate ? 1231 : 1237); + result = prime * result + ((comment == null) ? 0 : comment.hashCode()); + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + ((groupLevel == null) ? 0 : groupLevel.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((roleLevelId == null) ? 0 : roleLevelId.hashCode()); + result = prime * result + ((startDate == null) ? 0 : startDate.hashCode()); + result = prime * result + (int) (timeSpent ^ (timeSpent >>> 32)); + result = prime * result + ((updateAuthor == null) ? 0 : updateAuthor.hashCode()); + result = prime * result + ((updated == null) ? 0 : updated.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + JiraWorkLog other = (JiraWorkLog) obj; + if (author == null) { + if (other.author != null) { + return false; + } + } else if (!author.equals(other.author)) { + return false; + } + if (autoAdjustEstimate != other.autoAdjustEstimate) { + return false; + } + if (comment == null) { + if (other.comment != null) { + return false; + } + } else if (!comment.equals(other.comment)) { + return false; + } + if (created == null) { + if (other.created != null) { + return false; + } + } else if (!created.equals(other.created)) { + return false; + } + if (groupLevel == null) { + if (other.groupLevel != null) { + return false; + } + } else if (!groupLevel.equals(other.groupLevel)) { + return false; + } + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (roleLevelId == null) { + if (other.roleLevelId != null) { + return false; + } + } else if (!roleLevelId.equals(other.roleLevelId)) { + return false; + } + if (startDate == null) { + if (other.startDate != null) { + return false; + } + } else if (!startDate.equals(other.startDate)) { + return false; + } + if (timeSpent != other.timeSpent) { + return false; + } + if (updateAuthor == null) { + if (other.updateAuthor != null) { + return false; + } + } else if (!updateAuthor.equals(other.updateAuthor)) { + return false; + } + if (updated == null) { + if (other.updated != null) { + return false; + } + } else if (!updated.equals(other.updated)) { + return false; + } + return true; + } } Index: src/org/eclipse/mylyn/internal/jira/core/AbstractComplexAttributeConverter.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.core/src/org/eclipse/mylyn/internal/jira/core/AbstractComplexAttributeConverter.java,v retrieving revision 1.2 diff -u -r1.2 AbstractComplexAttributeConverter.java --- src/org/eclipse/mylyn/internal/jira/core/AbstractComplexAttributeConverter.java 27 Nov 2008 05:14:17 -0000 1.2 +++ src/org/eclipse/mylyn/internal/jira/core/AbstractComplexAttributeConverter.java 4 May 2009 22:21:42 -0000 @@ -75,6 +75,11 @@ if (value == null) { value = 0; } + } else if (TaskAttribute.TYPE_BOOLEAN.equals(taskField.getType())) { + value = mapper.getBooleanValue(attribute); + if (value == null) { + value = false; + } } else { value = attribute.getValue(); } Index: src/org/eclipse/mylyn/internal/jira/core/JiraTaskDataHandler.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.core/src/org/eclipse/mylyn/internal/jira/core/JiraTaskDataHandler.java,v retrieving revision 1.70 diff -u -r1.70 JiraTaskDataHandler.java --- src/org/eclipse/mylyn/internal/jira/core/JiraTaskDataHandler.java 10 Apr 2009 21:02:52 -0000 1.70 +++ src/org/eclipse/mylyn/internal/jira/core/JiraTaskDataHandler.java 4 May 2009 22:21:42 -0000 @@ -268,6 +268,8 @@ } securityLevelAttribute.setValue(SecurityLevel.NONE.getId()); } + + data.getRoot().createAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW); } public TaskAttribute createAttribute(TaskData data, JiraAttribute key) { @@ -957,8 +959,12 @@ IProgressMonitor monitor) throws JiraException { TaskAttribute attribute = taskData.getRoot().getMappedAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW); if (attribute != null) { - JiraWorkLog log = new WorkLogConverter().createFrom(attribute); - client.addWorkLog(issue.getKey(), log, monitor); + TaskAttribute submitFlagAttribute = attribute.getAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW_SUBMIT_FLAG); + //if no flag is set or flag is set and true, submit + if (submitFlagAttribute == null || submitFlagAttribute.getValue().equals(String.valueOf(true))) { + JiraWorkLog log = new WorkLogConverter().createFrom(attribute); + client.addWorkLog(issue.getKey(), log, monitor); + } } } Index: src/org/eclipse/mylyn/internal/jira/core/WorkLogConverter.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.core/src/org/eclipse/mylyn/internal/jira/core/WorkLogConverter.java,v retrieving revision 1.3 diff -u -r1.3 WorkLogConverter.java --- src/org/eclipse/mylyn/internal/jira/core/WorkLogConverter.java 26 Feb 2009 02:21:02 -0000 1.3 +++ src/org/eclipse/mylyn/internal/jira/core/WorkLogConverter.java 4 May 2009 22:21:42 -0000 @@ -22,6 +22,7 @@ /** * @author Steffen Pingel + * @author Thomas Ehrnhoefer */ public class WorkLogConverter extends AbstractComplexAttributeConverter { @@ -53,6 +54,8 @@ public static final String ATTRIBUTE_WORKLOG_NEW = "attribute.jira.worklog.new"; //$NON-NLS-1$ + public static final String ATTRIBUTE_WORKLOG_NEW_SUBMIT_FLAG = "attribute.jira.worklog.new.submit.flag"; //$NON-NLS-1$ + public final static JiraField ROLE_LEVEL_ID = create(String.class, "roleLevelId", Messages.WorkLogConverter_Role_Level, //$NON-NLS-1$ TaskAttribute.TYPE_SHORT_TEXT); @@ -69,6 +72,9 @@ public final static JiraField UPDATE_AUTHOR = create(IRepositoryPerson.class, "updateAuthor", //$NON-NLS-1$ Messages.WorkLogConverter_Author, TaskAttribute.TYPE_PERSON); + public static final JiraField ADJUST_ESTIMATE = create(Boolean.class, + "autoAdjustEstimate", Messages.WorkLogConverter_Auto_Adjust_Estimate, TaskAttribute.TYPE_BOOLEAN); //$NON-NLS-1$ + private static JiraField create(Class clazz, String key, String label, String type) { JiraField field = new JiraField(clazz, "attribute.jira.worklog." + key, key, label, type); //$NON-NLS-1$ _taskFields.add(field); Index: src/org/eclipse/mylyn/internal/jira/core/messages.properties =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.core/src/org/eclipse/mylyn/internal/jira/core/messages.properties,v retrieving revision 1.3 diff -u -r1.3 messages.properties --- src/org/eclipse/mylyn/internal/jira/core/messages.properties 12 Feb 2009 06:30:07 -0000 1.3 +++ src/org/eclipse/mylyn/internal/jira/core/messages.properties 4 May 2009 22:21:42 -0000 @@ -42,6 +42,8 @@ JiraTaskDataHandler_Getting_task=Getting task JiraTaskDataHandler_Leave_as_X=Leave as {0} JiraTaskDataHandler_Sending_task=Sending task + +WorkLogConverter_Auto_Adjust_Estimate=Auto Adjust Estimate WorkLogConverter_Author=Author WorkLogConverter_Comment=Comment WorkLogConverter_Created=Created Index: src/org/eclipse/mylyn/internal/jira/core/Messages.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.core/src/org/eclipse/mylyn/internal/jira/core/Messages.java,v retrieving revision 1.3 diff -u -r1.3 Messages.java --- src/org/eclipse/mylyn/internal/jira/core/Messages.java 12 Feb 2009 06:30:09 -0000 1.3 +++ src/org/eclipse/mylyn/internal/jira/core/Messages.java 4 May 2009 22:21:42 -0000 @@ -107,6 +107,8 @@ public static String JiraTaskDataHandler_Sending_task; + public static String WorkLogConverter_Auto_Adjust_Estimate; + public static String WorkLogConverter_Author; public static String WorkLogConverter_Comment; #P org.eclipse.mylyn.jira.ui Index: src/org/eclipse/mylyn/internal/jira/ui/editor/Messages.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.ui/src/org/eclipse/mylyn/internal/jira/ui/editor/Messages.java,v retrieving revision 1.1 diff -u -r1.1 Messages.java --- src/org/eclipse/mylyn/internal/jira/ui/editor/Messages.java 12 Dec 2008 02:57:40 -0000 1.1 +++ src/org/eclipse/mylyn/internal/jira/ui/editor/Messages.java 4 May 2009 22:21:43 -0000 @@ -16,14 +16,38 @@ public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.mylyn.internal.jira.ui.editor.messages"; //$NON-NLS-1$ + public static String WorkLogPart_Adjust_Estimate; + + public static String WorkLogPart_Auto_Adjust; + + public static String WorkLogPart_Auto_Adjust_Explanation_Tooltip; + public static String WorkLogPart_Creator; public static String WorkLogPart_Date; public static String WorkLogPart_Description; + public static String WorkLogPart_Form_allows_log_work_done; + + public static String WorkLogPart_Leave_Existing_Estimate; + + public static String WorkLogPart_Leave_Existing_Explanation_Tooltip; + + public static String WorkLogPart_Log_Work_Done; + public static String WorkLogPart_No_work_logged; + public static String WorkLogPart_Start_Date; + + public static String WorkLogPart_Time_Spent; + + public static String WorkLogPart_Time_Spent_Error_Decorator_Hover; + + public static String WorkLogPart_Time_Spent_Explanation_Tooltip; + + public static String WorkLogPart_Work_Description; + public static String WorkLogPart_Work_Log; public static String WorkLogPart_Worked; Index: src/org/eclipse/mylyn/internal/jira/ui/editor/WorkLogPart.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.ui/src/org/eclipse/mylyn/internal/jira/ui/editor/WorkLogPart.java,v retrieving revision 1.2 diff -u -r1.2 WorkLogPart.java --- src/org/eclipse/mylyn/internal/jira/ui/editor/WorkLogPart.java 12 Dec 2008 02:57:40 -0000 1.2 +++ src/org/eclipse/mylyn/internal/jira/ui/editor/WorkLogPart.java 4 May 2009 22:21:43 -0000 @@ -12,13 +12,19 @@ package org.eclipse.mylyn.internal.jira.ui.editor; import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.List; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.fieldassist.FieldDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.IOpenListener; @@ -29,31 +35,45 @@ import org.eclipse.jface.window.ToolTip; import org.eclipse.mylyn.internal.jira.core.WorkLogConverter; import org.eclipse.mylyn.internal.jira.core.model.JiraWorkLog; +import org.eclipse.mylyn.internal.jira.core.service.JiraTimeFormat; +import org.eclipse.mylyn.internal.jira.core.util.JiraUtil; import org.eclipse.mylyn.internal.jira.ui.JiraConnectorUi; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.ui.TasksUiUtil; import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart; +import org.eclipse.osgi.util.NLS; 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.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DateTime; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; +import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; /** * @author Steffen Pingel + * @author Thomas Ehrnhoefer */ public class WorkLogPart extends AbstractTaskEditorPart { private static final String ID_POPUP_MENU = "org.eclipse.mylyn.jira.ui.editor.menu.worklog"; //$NON-NLS-1$ - private final String[] columns = { Messages.WorkLogPart_Creator, Messages.WorkLogPart_Date, Messages.WorkLogPart_Worked, Messages.WorkLogPart_Description }; + private final String[] columns = { Messages.WorkLogPart_Creator, Messages.WorkLogPart_Date, + Messages.WorkLogPart_Worked, Messages.WorkLogPart_Description }; private final int[] columnWidths = { 130, 70, 100, 150 }; @@ -65,6 +85,26 @@ private Composite composite; + private long newWorkDoneAmount; + + private Calendar newWorkDoneDate = new GregorianCalendar(); + + private String newWorkDoneDescription; + + private boolean newWorkDoneAutoAdjust = true; + + private DateTime dateWidget; + + private DateTime timeWidget; + + private Text timeSpentText; + + private ControlDecoration amountTextControlDecoration; + + private boolean includeWorklog; + + private JiraWorkLog newWorkLog; + public WorkLogPart() { setPartName(Messages.WorkLogPart_Work_Log); } @@ -117,7 +157,7 @@ workLogList.add(log); } attachmentsViewer.setContentProvider(new ArrayContentProvider()); - attachmentsViewer.setLabelProvider(new WorkLogTableLabelProvider()); + attachmentsViewer.setLabelProvider(new WorkLogTableLabelProvider()); attachmentsViewer.addOpenListener(new IOpenListener() { public void open(OpenEvent event) { TasksUiUtil.openUrl(JiraConnectorUi.getTaskWorkLogUrl(getModel().getTaskRepository(), @@ -175,6 +215,8 @@ getTaskEditorPage().registerDefaultDropListener(label); } + createNewWorkLogSection(toolkit, composite); + section.setClient(composite); } @@ -195,6 +237,271 @@ break; } } + + TaskAttribute newWorkLogAttribute = getTaskData().getRoot() + .getAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW); + JiraWorkLog log = null; + if (newWorkLogAttribute != null) { + log = new WorkLogConverter().createFrom(newWorkLogAttribute); + } + + if (newWorkLogAttribute != null && log != null) { + newWorkDoneAmount = log.getTimeSpent(); + newWorkDoneDate = new GregorianCalendar(); + if (log.getStartDate() != null) { + newWorkDoneDate.setTime(log.getStartDate()); + } + newWorkDoneDescription = log.getComment(); + newWorkDoneAutoAdjust = log.isAutoAdjustEstimate(); + TaskAttribute newWorkLogSubmitAttribute = newWorkLogAttribute.getAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW_SUBMIT_FLAG); + if (newWorkLogSubmitAttribute != null && newWorkLogSubmitAttribute.getValue().equals(String.valueOf(true))) { + includeWorklog = true; + } else { + includeWorklog = false; + } + } else { + newWorkDoneAmount = 0; + newWorkDoneDate = new GregorianCalendar(); + newWorkDoneDescription = ""; //$NON-NLS-1$ + newWorkDoneAutoAdjust = true; + } + } + + private String getTimeSpentString(long timeSpent) { + return new JiraTimeFormat(JiraUtil.getWorkDaysPerWeek(getTaskEditorPage().getTaskRepository()), + JiraUtil.getWorkHoursPerDay(getTaskEditorPage().getTaskRepository())).format(new Long(timeSpent)); + } + + private void createNewWorkLogSection(FormToolkit toolkit, Composite parent) { + final Section newWorkLogSection = toolkit.createSection(parent, ExpandableComposite.LEFT_TEXT_CLIENT_ALIGNMENT + | ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT); + newWorkLogSection.setText(""); //$NON-NLS-1$ + newWorkLogSection.setLayout(GridLayoutFactory.fillDefaults().create()); + + final Button createNewWorkLog = toolkit.createButton(newWorkLogSection, Messages.WorkLogPart_Log_Work_Done, + SWT.CHECK); + GridDataFactory.fillDefaults().span(1, 1).grab(true, false).align(SWT.LEFT, SWT.CENTER).applyTo( + createNewWorkLog); + createNewWorkLog.setSelection(includeWorklog); + newWorkLogSection.setExpanded(includeWorklog); + createNewWorkLog.addSelectionListener(new SelectionListener() { + public void widgetDefaultSelected(SelectionEvent e) { + } + + public void widgetSelected(SelectionEvent e) { + if (e.getSource().equals(createNewWorkLog)) { + newWorkLogSection.setExpanded(createNewWorkLog.getSelection()); + addWorkLogToModel(); + includeWorklog = createNewWorkLog.getSelection(); + setSubmitWorklog(); + } + } + }); + + newWorkLogSection.setTextClient(createNewWorkLog); + + Composite newWorkLogComposite = toolkit.createComposite(newWorkLogSection, SWT.NONE); + newWorkLogSection.setClient(newWorkLogComposite); + newWorkLogComposite.setLayout(GridLayoutFactory.swtDefaults().spacing(10, 5).numColumns(3).create()); + GridDataFactory.fillDefaults().applyTo(newWorkLogComposite); + + Label introLabel = toolkit.createLabel(newWorkLogComposite, Messages.WorkLogPart_Form_allows_log_work_done); + GridDataFactory.fillDefaults().span(3, 1).applyTo(introLabel); + + toolkit.createLabel(newWorkLogComposite, Messages.WorkLogPart_Time_Spent); + timeSpentText = toolkit.createText(newWorkLogComposite, getTimeSpentString(newWorkDoneAmount)); + timeSpentText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + validateWorkDone(timeSpentText.getText()); + addWorkLogToModel(); + } + }); + timeSpentText.setToolTipText(NLS.bind(Messages.WorkLogPart_Time_Spent_Explanation_Tooltip, + JiraUtil.getWorkDaysPerWeek(getTaskEditorPage().getTaskRepository()), + JiraUtil.getWorkHoursPerDay(getTaskEditorPage().getTaskRepository()))); + GridDataFactory.fillDefaults().span(2, 1).hint(45, SWT.DEFAULT).align(SWT.BEGINNING, SWT.FILL).applyTo( + timeSpentText); + + toolkit.createLabel(newWorkLogComposite, Messages.WorkLogPart_Start_Date); + dateWidget = new DateTime(newWorkLogComposite, SWT.DATE); + dateWidget.setDate(newWorkDoneDate.get(Calendar.YEAR), newWorkDoneDate.get(Calendar.MONTH), + newWorkDoneDate.get(Calendar.DAY_OF_MONTH)); + toolkit.adapt(dateWidget, true, true); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.FILL).applyTo(dateWidget); + + timeWidget = new DateTime(newWorkLogComposite, SWT.TIME); + timeWidget.setTime(newWorkDoneDate.get(Calendar.HOUR_OF_DAY), newWorkDoneDate.get(Calendar.MINUTE), + newWorkDoneDate.get(Calendar.SECOND)); + toolkit.adapt(timeWidget, true, true); + GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.FILL).applyTo(timeWidget); + dateWidget.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + collectDate(); + addWorkLogToModel(); + } + }); + timeWidget.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + collectDate(); + addWorkLogToModel(); + } + }); + + Label adjustLabel = toolkit.createLabel(newWorkLogComposite, Messages.WorkLogPart_Adjust_Estimate); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).applyTo(adjustLabel); + Composite adjustComposite = toolkit.createComposite(newWorkLogComposite); + adjustComposite.setLayout(GridLayoutFactory.fillDefaults().create()); + GridDataFactory.fillDefaults().span(2, 1).applyTo(adjustComposite); + final Button autoAdjustButton = toolkit.createButton(adjustComposite, Messages.WorkLogPart_Auto_Adjust, + SWT.RADIO); + autoAdjustButton.setSelection(newWorkDoneAutoAdjust); + autoAdjustButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + newWorkDoneAutoAdjust = autoAdjustButton.getSelection(); + addWorkLogToModel(); + } + }); + autoAdjustButton.setToolTipText(Messages.WorkLogPart_Auto_Adjust_Explanation_Tooltip); + Button leaveAdjustButton = toolkit.createButton(adjustComposite, Messages.WorkLogPart_Leave_Existing_Estimate, + SWT.RADIO); + leaveAdjustButton.setSelection(!newWorkDoneAutoAdjust); + leaveAdjustButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + newWorkDoneAutoAdjust = autoAdjustButton.getSelection(); + addWorkLogToModel(); + } + }); + leaveAdjustButton.setToolTipText(Messages.WorkLogPart_Leave_Existing_Explanation_Tooltip); + + Label descriptionLabel = toolkit.createLabel(newWorkLogComposite, Messages.WorkLogPart_Work_Description); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).applyTo(descriptionLabel); + final Text descriptionText = toolkit.createText(newWorkLogComposite, newWorkDoneDescription, SWT.WRAP + | SWT.MULTI | SWT.V_SCROLL); + descriptionText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + newWorkDoneDescription = descriptionText.getText(); + addWorkLogToModel(); + } + }); + GridDataFactory.fillDefaults().grab(true, true).hint(150, 100).span(2, 1).applyTo(descriptionText); + + } + + protected void validateWorkDone(String text) { + newWorkDoneAmount = 0; + boolean invalid = false; + if (text != null && text.length() > 0) { + String[] parts = text.split(" "); //$NON-NLS-1$ + for (int i = 0; i < parts.length && !invalid; i++) { + parts[i] = parts[i].trim(); + if (parts[i].length() == 0) { + continue; + } + if (parts[i].length() == 1) { + invalid = true; + break; + } + char lastChar = parts[i].charAt(parts[i].length() - 1); + String number = parts[i].substring(0, parts[i].length() - 1); + try { + int amount = Integer.parseInt(number); + if (amount >= 0) { + int workHoursPerDay = JiraUtil.getWorkHoursPerDay(getTaskEditorPage().getTaskRepository()); + switch (lastChar) { + case 'm': //fallthrough intended + case 'M': + newWorkDoneAmount += amount * 60; + break; + case 'h': //fallthrough intended + case 'H': + newWorkDoneAmount += amount * 60 * 60; + break; + case 'd': //fallthrough intended + case 'D': + newWorkDoneAmount += amount * workHoursPerDay * 60 * 60; + break; + case 'w': //fallthrough intended + case 'W': + int workDaysPerWeek = JiraUtil.getWorkDaysPerWeek(getTaskEditorPage().getTaskRepository()); + newWorkDoneAmount += amount * workDaysPerWeek * workHoursPerDay * 60 * 60; + break; + default: + invalid = true; + break; + } + } + } catch (NumberFormatException e) { + invalid = true; + } + } + } else { + invalid = true; + } + if (amountTextControlDecoration == null) { + amountTextControlDecoration = new ControlDecoration(timeSpentText, SWT.TOP | SWT.LEFT); + amountTextControlDecoration.setShowOnlyOnFocus(false); + FieldDecoration errorImage = FieldDecorationRegistry.getDefault().getFieldDecoration( + FieldDecorationRegistry.DEC_ERROR); + amountTextControlDecoration.setImage(errorImage.getImage()); + amountTextControlDecoration.setDescriptionText(Messages.WorkLogPart_Time_Spent_Error_Decorator_Hover); + } + if (invalid) { + amountTextControlDecoration.show(); + } else { + amountTextControlDecoration.hide(); + } + } + + protected void collectDate() { + if (newWorkDoneDate == null) { + newWorkDoneDate = new GregorianCalendar(); + } + newWorkDoneDate.set(dateWidget.getYear(), dateWidget.getMonth(), dateWidget.getDay(), timeWidget.getHours(), + timeWidget.getMinutes(), timeWidget.getSeconds()); + } + + /** + * Updates the worklog and returns true if it has changed + */ + private boolean updateNewWorkLog() { + JiraWorkLog tempworkLog = new JiraWorkLog(); + tempworkLog.setAuthor(getTaskEditorPage().getTaskRepository().getUserName()); + tempworkLog.setComment(newWorkDoneDescription); + tempworkLog.setStartDate(newWorkDoneDate.getTime()); + tempworkLog.setTimeSpent(newWorkDoneAmount); + tempworkLog.setAutoAdjustEstimate(newWorkDoneAutoAdjust); + if (tempworkLog.equals(newWorkLog)) { + return false; + } + newWorkLog = tempworkLog; + return true; + } + + public boolean isAutoAdjust() { + return newWorkDoneAutoAdjust; } + private void addWorkLogToModel() { + if (updateNewWorkLog()) { + TaskAttribute attribute = getTaskData().getRoot().getAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW); + if (attribute == null) { + attribute = getTaskData().getRoot().createAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW); + } + new WorkLogConverter().applyTo(newWorkLog, attribute); + getModel().attributeChanged(attribute); + } + } + + private void setSubmitWorklog() { + TaskAttribute attribute = getTaskData().getRoot().getAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW); + if (attribute != null) { + attribute.createAttribute(WorkLogConverter.ATTRIBUTE_WORKLOG_NEW_SUBMIT_FLAG).setValue( + String.valueOf(includeWorklog)); + getModel().attributeChanged(attribute); + } + } } Index: src/org/eclipse/mylyn/internal/jira/ui/editor/messages.properties =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.jira.ui/src/org/eclipse/mylyn/internal/jira/ui/editor/messages.properties,v retrieving revision 1.1 diff -u -r1.1 messages.properties --- src/org/eclipse/mylyn/internal/jira/ui/editor/messages.properties 12 Dec 2008 02:57:40 -0000 1.1 +++ src/org/eclipse/mylyn/internal/jira/ui/editor/messages.properties 4 May 2009 22:21:43 -0000 @@ -1,6 +1,18 @@ +WorkLogPart_Adjust_Estimate=Adjust Estimate: +WorkLogPart_Auto_Adjust=Auto Adjust +WorkLogPart_Auto_Adjust_Explanation_Tooltip=The estimate will be reduced by the amount of work done, but never below 0. WorkLogPart_Creator=Creator WorkLogPart_Date=Date WorkLogPart_Description=Description +WorkLogPart_Form_allows_log_work_done=This form allows you to log work that you have done on this issue. +WorkLogPart_Leave_Existing_Estimate=Leave existing estimate +WorkLogPart_Leave_Existing_Explanation_Tooltip=You can also manually adjust the estimate in the Attributes section +WorkLogPart_Log_Work_Done=Log Work Done WorkLogPart_No_work_logged=No work has yet been logged on this issue. +WorkLogPart_Start_Date=Start Date: +WorkLogPart_Time_Spent=Time Spent: +WorkLogPart_Time_Spent_Error_Decorator_Hover=Invalid entry.\nThe format of this is ' *w *d *h *m ' (representing weeks, days, hours and minutes - where * can be any number)\nExamples: 4d, 5h 30m, 60m and 3w.\nNote: Your current conversion rates are 1w = 5d and 1d = 8h +WorkLogPart_Time_Spent_Explanation_Tooltip=An estimate of how much time you have spent working.\nThe format of this is ' *w *d *h *m ' (representing weeks, days, hours and minutes - where * can be any number)\nExamples: 4d, 5h 30m, 60m and 3w.\nNote: Your current conversion rates are 1w = {0}d and 1d = {1}h +WorkLogPart_Work_Description=Work Description: WorkLogPart_Work_Log=Work Log WorkLogPart_Worked=Worked