blob: 57fe5da368316e35c2d35662ae33a8f56721d95e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.bugzilla.ui.editor;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.commons.workbench.WorkbenchUtil;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaAttribute;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCorePlugin;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaCustomField;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaOperation;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryConnector;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaRepositoryResponse;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaStatus;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaTaskDataHandler;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaUserMatchResponse;
import org.eclipse.mylyn.internal.bugzilla.core.BugzillaVersion;
import org.eclipse.mylyn.internal.bugzilla.core.IBugzillaConstants;
import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration;
import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider;
import org.eclipse.mylyn.internal.tasks.ui.editors.PersonAttributeEditor;
import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorActionPart;
import org.eclipse.mylyn.tasks.core.RepositoryResponse;
import org.eclipse.mylyn.tasks.core.RepositoryStatus;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMetaData;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataModel;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelEvent;
import org.eclipse.mylyn.tasks.core.data.TaskDataModelListener;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobEvent;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor;
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage;
import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart;
import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan;
import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor;
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.widgets.Control;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.keys.IBindingService;
/**
* @author Rob Elves
* @author Frank Becker
* @since 3.0
*/
public class BugzillaTaskEditorPage extends AbstractTaskEditorPage {
public static final String ID_PART_BUGZILLA_PLANNING = "org.eclipse.mylyn.bugzilla.ui.editors.part.planning"; //$NON-NLS-1$
public static final String ID_PART_BUGZILLA_FLAGS = "org.eclipse.mylyn.bugzilla.ui.editors.part.flags"; //$NON-NLS-1$
public static final String PATH_FLAGS = "flags"; //$NON-NLS-1$
private final Map<TaskAttribute, AbstractAttributeEditor> attributeEditorMap;
private TaskDataModelListener productListener;
private final List<ControlDecoration> errorDecorations = new ArrayList<ControlDecoration>();
private final List<PersonAttributeEditor> editorsWithError = new ArrayList<PersonAttributeEditor>(3);
public BugzillaTaskEditorPage(TaskEditor editor) {
this(editor, BugzillaCorePlugin.CONNECTOR_KIND);
}
/**
* Call this constructor if extending the Bugzilla connector
*
* @param editor
* @param connectorKind
*/
public BugzillaTaskEditorPage(TaskEditor editor, String connectorKind) {
super(editor, connectorKind);
this.attributeEditorMap = new HashMap<TaskAttribute, AbstractAttributeEditor>();
setNeedsPrivateSection(true);
setNeedsSubmitButton(true);
}
@Override
protected Set<TaskEditorPartDescriptor> createPartDescriptors() {
Set<TaskEditorPartDescriptor> descriptors = super.createPartDescriptors();
boolean hasPartComments = false;
boolean hasPartNewComment = false;
boolean hasPartDescription = false;
// remove unnecessary default editor parts
for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
if (taskEditorPartDescriptor.getId().equals(ID_PART_PEOPLE)) {
descriptors.remove(taskEditorPartDescriptor);
break;
}
}
for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
if (taskEditorPartDescriptor.getId().equals(ID_PART_COMMENTS)) {
descriptors.remove(taskEditorPartDescriptor);
hasPartComments = true;
break;
}
}
for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
if (taskEditorPartDescriptor.getId().equals(ID_PART_NEW_COMMENT)) {
descriptors.remove(taskEditorPartDescriptor);
hasPartNewComment = true;
break;
}
}
for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) {
if (taskEditorPartDescriptor.getId().equals(ID_PART_DESCRIPTION)) {
descriptors.remove(taskEditorPartDescriptor);
hasPartDescription = true;
break;
}
}
// Add Bugzilla Planning part
try {
TaskData data = TasksUi.getTaskDataManager().getTaskData(getTask());
if (data != null) {
// Add Bugzilla Flag part
Map<String, TaskAttribute> attributes = data.getRoot().getAttributes();
for (TaskAttribute attribute : attributes.values()) {
if (BugzillaAttribute.KIND_FLAG.equals(attribute.getMetaData().getKind())) {
descriptors.add(new TaskEditorPartDescriptor(ID_PART_BUGZILLA_FLAGS) {
@Override
public AbstractTaskEditorPart createPart() {
return new BugzillaFlagPart();
}
}.setPath(ID_PART_ATTRIBUTES + "/" + PATH_FLAGS)); //$NON-NLS-1$
break;
}
}
TaskAttribute attrEstimatedTime = data.getRoot()
.getMappedAttribute(BugzillaAttribute.ESTIMATED_TIME.getKey());
if (attrEstimatedTime != null) {
descriptors.add(new TaskEditorPartDescriptor(ID_PART_BUGZILLA_PLANNING) {
@Override
public AbstractTaskEditorPart createPart() {
return new BugzillaPlanningEditorPart();
}
}.setPath(ID_PART_ATTRIBUTES + "/" + PATH_PLANNING)); //$NON-NLS-1$
}
}
if (hasPartDescription) {
descriptors.add(new TaskEditorPartDescriptor(ID_PART_DESCRIPTION) {
@Override
public AbstractTaskEditorPart createPart() {
BugzillaTaskEditorDescriptionPart part = new BugzillaTaskEditorDescriptionPart();
if (getModel().getTaskData().isNew()) {
part.setExpandVertically(true);
part.setSectionStyle(ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED);
}
return part;
}
}.setPath(PATH_COMMENTS));
}
if (hasPartComments) {
descriptors.add(new TaskEditorPartDescriptor(ID_PART_COMMENTS) {
@Override
public AbstractTaskEditorPart createPart() {
return new BugzillaTaskEditorCommentPart();
}
}.setPath(PATH_COMMENTS));
}
} catch (CoreException e) {
// ignore
}
if (hasPartNewComment) {
// Add the updated Bugzilla new comment part
descriptors.add(new TaskEditorPartDescriptor(ID_PART_NEW_COMMENT) {
@Override
public AbstractTaskEditorPart createPart() {
return new BugzillaTaskEditorNewCommentPart();
}
}.setPath(PATH_COMMENTS));
}
// Add the updated Bugzilla people part
descriptors.add(new TaskEditorPartDescriptor(ID_PART_PEOPLE) {
@Override
public AbstractTaskEditorPart createPart() {
return new BugzillaPeoplePart();
}
}.setPath(PATH_PEOPLE));
return descriptors;
}
@Override
protected AttributeEditorFactory createAttributeEditorFactory() {
AttributeEditorFactory factory = new AttributeEditorFactory(getModel(), getTaskRepository(), getEditorSite()) {
@Override
public AbstractAttributeEditor createEditor(String type, final TaskAttribute taskAttribute) {
AbstractAttributeEditor editor;
if (IBugzillaConstants.EDITOR_TYPE_KEYWORDS.equals(type)) {
editor = new BugzillaKeywordAttributeEditor(getModel(), taskAttribute);
} else if (IBugzillaConstants.EDITOR_TYPE_REMOVECC.equals(type)) {
editor = new BugzillaCcAttributeEditor(getModel(), taskAttribute);
} else if (IBugzillaConstants.EDITOR_TYPE_VOTES.equals(type)) {
editor = new BugzillaVotesEditor(getModel(), taskAttribute);
} else if (IBugzillaConstants.EDITOR_TYPE_FLAG.equals(type)) {
editor = new FlagAttributeEditor(getModel(), taskAttribute);
} else if (IBugzillaConstants.EDITOR_TYPE_SEEALSO.equals(type)) {
editor = new BugzillaSeeAlsoAttributeEditor(getModel(), taskAttribute);
} else {
editor = super.createEditor(type, taskAttribute);
if (TaskAttribute.TYPE_BOOLEAN.equals(type)) {
editor.setDecorationEnabled(false);
}
}
if (editor != null && taskAttribute.getId().startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) {
editor.setLayoutHint(new LayoutHint(editor.getLayoutHint()) {
@Override
public int getPriority() {
return super.getPriority() * 10;
}
});
}
TaskAttributeMetaData properties = taskAttribute.getMetaData();
if (editor != null && IBugzillaConstants.EDITOR_TYPE_FLAG.equals(properties.getType())) {
editor.setLayoutHint(new LayoutHint(editor.getLayoutHint()) {
@Override
public int getPriority() {
return super.getPriority() * 5;
}
});
}
if (editor != null && BugzillaAttribute.NEWCC.getKey().equals(taskAttribute.getId())) {
editor.setLayoutHint(new LayoutHint(RowSpan.SINGLE, ColumnSpan.SINGLE));
}
BugzillaTaskEditorPage.this.addToAttributeEditorMap(taskAttribute, editor);
return editor;
}
};
return factory;
}
@Override
public void doSubmit() {
TaskAttribute summaryAttribute = getModel().getTaskData().getRoot().getMappedAttribute(TaskAttribute.SUMMARY);
if (summaryAttribute != null && summaryAttribute.getValue().length() == 0) {
getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_short_summary_before_submitting,
IMessageProvider.ERROR);
AbstractTaskEditorPart part = getPart(ID_PART_SUMMARY);
if (part != null) {
part.setFocus();
}
return;
}
TaskAttribute componentAttribute = getModel().getTaskData()
.getRoot()
.getMappedAttribute(BugzillaAttribute.COMPONENT.getKey());
if (componentAttribute != null && componentAttribute.getValue().length() == 0) {
getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_select_a_component_before_submitting,
IMessageProvider.ERROR);
AbstractTaskEditorPart part = getPart(ID_PART_ATTRIBUTES);
if (part != null) {
part.setFocus();
}
return;
}
TaskAttribute descriptionAttribute = getModel().getTaskData()
.getRoot()
.getMappedAttribute(TaskAttribute.DESCRIPTION);
if (descriptionAttribute != null && descriptionAttribute.getValue().length() == 0
&& getModel().getTaskData().isNew()) {
getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_description_before_submitting,
IMessageProvider.ERROR);
AbstractTaskEditorPart descriptionPart = getPart(ID_PART_DESCRIPTION);
if (descriptionPart != null) {
descriptionPart.setFocus();
}
return;
}
TaskAttribute targetMilestoneAttribute = getModel().getTaskData()
.getRoot()
.getMappedAttribute(BugzillaAttribute.TARGET_MILESTONE.getKey());
if (targetMilestoneAttribute != null && targetMilestoneAttribute.getValue().length() == 0
&& getModel().getTaskData().isNew()) {
getTaskEditor().setMessage(
Messages.BugzillaTaskEditorPage_Please_enter_a_target_milestone_before_submitting,
IMessageProvider.ERROR);
AbstractTaskEditorPart descriptionPart = getPart(ID_PART_ATTRIBUTES);
if (descriptionPart != null) {
descriptionPart.setFocus();
}
return;
}
TaskAttribute attributeOperation = getModel().getTaskData()
.getRoot()
.getMappedAttribute(TaskAttribute.OPERATION);
if (attributeOperation != null) {
if ("duplicate".equals(attributeOperation.getValue())) { //$NON-NLS-1$
TaskAttribute originalOperation = getModel().getTaskData()
.getRoot()
.getAttribute(TaskAttribute.PREFIX_OPERATION + attributeOperation.getValue());
String inputAttributeId = originalOperation.getMetaData()
.getValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID);
if (inputAttributeId != null && !inputAttributeId.equals("")) { //$NON-NLS-1$
TaskAttribute inputAttribute = attributeOperation.getTaskData()
.getRoot()
.getAttribute(inputAttributeId);
if (inputAttribute != null) {
String dupValue = inputAttribute.getValue();
if (dupValue == null || dupValue.equals("")) { //$NON-NLS-1$
getTaskEditor().setMessage(
Messages.BugzillaTaskEditorPage_Please_enter_a_bugid_for_duplicate_of_before_submitting,
IMessageProvider.ERROR);
AbstractTaskEditorPart part = getPart(ID_PART_ACTIONS);
if (part != null) {
part.setFocus();
}
return;
}
}
}
}
}
if (getModel().getTaskData().isNew()) {
TaskAttribute productAttribute = getModel().getTaskData()
.getRoot()
.getMappedAttribute(TaskAttribute.PRODUCT);
if (productAttribute != null && productAttribute.getValue().length() > 0) {
getModel().getTaskRepository().setProperty(IBugzillaConstants.LAST_PRODUCT_SELECTION,
productAttribute.getValue());
}
TaskAttribute componentSelectedAttribute = getModel().getTaskData()
.getRoot()
.getMappedAttribute(TaskAttribute.COMPONENT);
if (componentSelectedAttribute != null && componentSelectedAttribute.getValue().length() > 0) {
getModel().getTaskRepository().setProperty(IBugzillaConstants.LAST_COMPONENT_SELECTION,
componentSelectedAttribute.getValue());
}
}
// Force the most recent known good token onto the outgoing task data to ensure submit
// bug#263318
TaskAttribute attrToken = getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.TOKEN.getKey());
if (attrToken != null) {
String tokenString = getModel().getTask().getAttribute(BugzillaAttribute.TOKEN.getKey());
if (tokenString != null) {
attrToken.setValue(tokenString);
}
}
for (ControlDecoration decoration : errorDecorations) {
decoration.hide();
decoration.dispose();
}
errorDecorations.clear();
editorsWithError.clear();
if (!checkCanSubmit(IMessageProvider.ERROR)) {
return;
}
getTaskEditor().setMessage("", IMessageProvider.NONE); //$NON-NLS-1$
super.doSubmit();
}
@Override
protected void createParts() {
attributeEditorMap.clear();
super.createParts();
checkCanSubmit(IMessageProvider.INFORMATION);
}
@Override
protected TaskDataModel createModel(TaskEditorInput input) throws CoreException {
TaskDataModel model = super.createModel(input);
productListener = new ProductSelectionListener();
model.addModelListener(productListener);
return model;
}
/**
* @since 3.1
*/
private void addToAttributeEditorMap(TaskAttribute attribute, AbstractAttributeEditor editor) {
if (attributeEditorMap.containsKey(attribute)) {
attributeEditorMap.remove(attribute);
}
attributeEditorMap.put(attribute, editor);
}
/**
* @since 3.1
*/
private AbstractAttributeEditor getEditorForAttribute(TaskAttribute attribute) {
return attributeEditorMap.get(attribute);
}
private void refresh(TaskAttribute attributeComponent) {
AbstractAttributeEditor editor = getEditorForAttribute(attributeComponent);
if (editor != null) {
try {
editor.refresh();
} catch (UnsupportedOperationException e) {
// ignore
}
}
}
private class ProductSelectionListener extends TaskDataModelListener {
@Override
public void attributeChanged(TaskDataModelEvent event) {
TaskAttribute taskAttribute = event.getTaskAttribute();
if (taskAttribute != null) {
if (taskAttribute.getId().equals(BugzillaAttribute.PRODUCT.getKey())) {
RepositoryConfiguration repositoryConfiguration = null;
try {
BugzillaRepositoryConnector connector = (BugzillaRepositoryConnector) TasksUi
.getRepositoryConnector(getModel().getTaskRepository().getConnectorKind());
repositoryConfiguration = connector.getRepositoryConfiguration(getModel().getTaskRepository(),
false, new NullProgressMonitor());
} catch (CoreException e) {
StatusHandler.log(new RepositoryStatus(getTaskRepository(), IStatus.ERROR,
BugzillaUiPlugin.ID_PLUGIN, 0, "Failed to obtain repository configuration", e)); //$NON-NLS-1$
getTaskEditor().setMessage("Problem occured when updating attributes", IMessageProvider.ERROR); //$NON-NLS-1$
return;
}
TaskAttribute attributeComponent = taskAttribute.getTaskData()
.getRoot()
.getMappedAttribute(BugzillaAttribute.COMPONENT.getKey());
if (attributeComponent != null) {
List<String> optionValues = repositoryConfiguration
.getProductOptionValues(BugzillaAttribute.COMPONENT, taskAttribute.getValue());
Collections.sort(optionValues);
attributeComponent.clearOptions();
for (String option : optionValues) {
attributeComponent.putOption(option, option);
}
if (optionValues.size() > 0) {
attributeComponent.setValue(optionValues.get(0));
}
refresh(attributeComponent);
}
TaskAttribute attributeTargetMilestone = taskAttribute.getTaskData()
.getRoot()
.getMappedAttribute(BugzillaAttribute.TARGET_MILESTONE.getKey());
if (attributeTargetMilestone != null) {
List<String> optionValues = repositoryConfiguration
.getProductOptionValues(BugzillaAttribute.TARGET_MILESTONE, taskAttribute.getValue());
Collections.sort(optionValues);
attributeTargetMilestone.clearOptions();
for (String option : optionValues) {
attributeTargetMilestone.putOption(option, option);
}
String defaultMilestones = repositoryConfiguration
.getDefaultMilestones(taskAttribute.getValue());
if (defaultMilestones != null) {
attributeTargetMilestone.setValue(defaultMilestones);
} else if (optionValues.size() == 1) {
attributeTargetMilestone.setValue(optionValues.get(0));
} else {
attributeTargetMilestone.setValue("---"); //$NON-NLS-1$
}
refresh(attributeTargetMilestone);
}
TaskAttribute attributeVersion = taskAttribute.getTaskData()
.getRoot()
.getMappedAttribute(BugzillaAttribute.VERSION.getKey());
if (attributeVersion != null) {
List<String> optionValues = repositoryConfiguration
.getProductOptionValues(BugzillaAttribute.VERSION, taskAttribute.getValue());
Collections.sort(optionValues);
attributeVersion.clearOptions();
for (String option : optionValues) {
attributeVersion.putOption(option, option);
}
if (optionValues.size() == 1) {
attributeVersion.setValue(optionValues.get(0));
} else {
attributeVersion.setValue("unspecified"); //$NON-NLS-1$
}
refresh(attributeVersion);
}
TaskAttribute attributeDefaultAssignee = taskAttribute.getTaskData()
.getRoot()
.getMappedAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
if (attributeDefaultAssignee != null) {
attributeDefaultAssignee.setValue("1"); //$NON-NLS-1$
refresh(attributeDefaultAssignee);
}
if (taskAttribute.getTaskData().isNew()) {
BugzillaVersion bugzillaVersion = repositoryConfiguration.getInstallVersion();
if (bugzillaVersion == null) {
bugzillaVersion = BugzillaVersion.MIN_VERSION;
}
if (bugzillaVersion.compareMajorMinorOnly(BugzillaVersion.BUGZILLA_4_0) >= 0) {
AbstractTaskEditorPart part = getPart(ID_PART_ACTIONS);
boolean unconfirmedAllowed = repositoryConfiguration
.getUnconfirmedAllowed(taskAttribute.getValue());
TaskAttribute unconfirmedAttribute = taskAttribute.getTaskData().getRoot().getAttribute(
TaskAttribute.PREFIX_OPERATION + BugzillaOperation.unconfirmed.toString());
if (unconfirmedAttribute != null) {
unconfirmedAttribute.getMetaData().setReadOnly(!unconfirmedAllowed);
}
if (part != null) {
TaskEditorActionPart actionPart = (TaskEditorActionPart) part;
actionPart.refreshOperations();
}
}
}
/*
* add confirm_product_change to avoid verification page on submit
*/
TaskAttribute attributeConfirmeProductChange = taskAttribute.getTaskData()
.getRoot()
.getMappedAttribute(BugzillaAttribute.CONFIRM_PRODUCT_CHANGE.getKey());
if (attributeConfirmeProductChange == null) {
attributeConfirmeProductChange = BugzillaTaskDataHandler.createAttribute(
taskAttribute.getTaskData().getRoot(), BugzillaAttribute.CONFIRM_PRODUCT_CHANGE);
}
if (attributeConfirmeProductChange != null) {
attributeConfirmeProductChange.setValue("1"); //$NON-NLS-1$
}
}
}
}
}
@Override
protected void handleTaskSubmitted(SubmitJobEvent event) {
if (event.getJob().getStatus() != null) {
switch (event.getJob().getStatus().getCode()) {
case BugzillaStatus.ERROR_CONFIRM_MATCH:
case BugzillaStatus.ERROR_MATCH_FAILED:
showError((BugzillaStatus) event.getJob().getStatus());
return;
}
}
if (event.getJob().getResponse() != null
&& event.getJob().getResponse() instanceof BugzillaRepositoryResponse) {
final RepositoryResponse response = event.getJob().getResponse();
if (response instanceof BugzillaRepositoryResponse) {
final BugzillaRepositoryResponse bugzillaResponse = (BugzillaRepositoryResponse) response;
if (bugzillaResponse.getResponseData().size() > 0) {
getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Changes_Submitted_Message,
IMessageProvider.INFORMATION, new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent event) {
showSubmitResponse(bugzillaResponse);
}
});
} else {
getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Changes_Submitted_Message,
IMessageProvider.INFORMATION);
}
}
} else {
super.handleTaskSubmitted(event);
}
}
@Override
public void refresh() {
super.refresh();
checkCanSubmit(IMessageProvider.INFORMATION);
}
private boolean checkCanSubmit(final int type) {
final TaskRepository taskRepository = getModel().getTaskRepository();
String username = taskRepository.getUserName();
if (username == null || username.length() == 0) {
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Anonymous_can_not_submit_Tasks, type,
new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
TasksUiUtil.openEditRepositoryWizard(taskRepository);
refresh();
}
});
}
});
return false;
}
if (!getModel().getTaskData().isNew()) {
TaskAttribute exporter = getModel().getTaskData()
.getRoot()
.getAttribute(BugzillaAttribute.EXPORTER_NAME.getKey());
if (exporter == null || exporter.getValue().equals("")) { //$NON-NLS-1$
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_submit_disabled_please_refresh, type,
new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
TasksUiUtil.openEditRepositoryWizard(taskRepository);
refresh();
}
});
}
});
return false;
}
}
return true;
}
private void showError(BugzillaStatus bugzillaStatus) {
int count = 0;
BugzillaUserMatchResponse response = bugzillaStatus.getUserMatchResponse();
FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
FieldDecoration fieldDecoration = registry.getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
FieldDecoration fieldDecorationWarning = registry.getFieldDecoration(FieldDecorationRegistry.DEC_WARNING);
StringBuilder fields = new StringBuilder();
StringBuilder detail = new StringBuilder();
count += decorateControlsAndUpdateMessages(response.getAssignedToMsg(), response.getAssignedToProposals(),
getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.ASSIGNED_TO.getKey()), fields, detail,
fieldDecoration, fieldDecorationWarning);
count += decorateControlsAndUpdateMessages(response.getQaContactMsg(), response.getQaContactProposals(),
getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.QA_CONTACT.getKey()), fields, detail,
fieldDecoration, fieldDecorationWarning);
count += decorateControlsAndUpdateMessages(response.getNewCCMsg(), response.getNewCCProposals(),
getModel().getTaskData().getRoot().getAttribute(BugzillaAttribute.NEWCC.getKey()), fields, detail,
fieldDecoration, fieldDecorationWarning);
updateTaskEditorPageMessageWithError(bugzillaStatus, detail.toString(), count == 1, fields.toString());
}
private int decorateControlsAndUpdateMessages(String message, List<String> proposals, TaskAttribute attribute,
StringBuilder fields, StringBuilder detail, FieldDecoration fieldDecoration,
FieldDecoration fieldDecorationWarning) {
if (attribute == null || (message == null && proposals.size() == 0)) {
return 0;
}
Map<String, String> newPersonProposalMap = new HashMap<String, String>();
if (fields.length() > 0) {
fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_N,
attribute.getMetaData().getLabel()));
} else {
fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_1,
attribute.getMetaData().getLabel()));
}
detail.append(attribute.getMetaData().getLabel() + "\n"); //$NON-NLS-1$
if (message != null && !message.equals("")) { //$NON-NLS-1$
detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, message));
} else {
for (String proposalValue : proposals) {
detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, proposalValue));
newPersonProposalMap.put(proposalValue, proposalValue);
}
}
AbstractAttributeEditor editor = getEditorForAttribute(attribute);
if (editor != null) {
decorateEditorWithError(fieldDecoration, fieldDecorationWarning, message, newPersonProposalMap, editor);
}
return 1;
}
private int decorateControlsAndUpdateMessages(String message, Map<String, List<String>> proposals,
TaskAttribute attribute, StringBuilder fields, StringBuilder detail, FieldDecoration fieldDecoration,
FieldDecoration fieldDecorationWarning) {
if (attribute == null || (message == null && proposals.size() == 0)) {
return 0;
}
Map<String, String> newPersonProposalMap = new HashMap<String, String>();
if (fields.length() > 0) {
fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_N,
attribute.getMetaData().getLabel()));
} else {
fields.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Error_Label_1,
attribute.getMetaData().getLabel()));
}
detail.append(attribute.getMetaData().getLabel() + "\n"); //$NON-NLS-1$
if (message != null && !message.equals("")) { //$NON-NLS-1$
detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, message));
} else {
for (String key : proposals.keySet()) {
detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_Proposal_Detail, key));
for (String proposalValue : proposals.get(key)) {
detail.append(MessageFormat.format(Messages.BugzillaTaskEditorPage_DetailLine, proposalValue));
newPersonProposalMap.put(proposalValue, proposalValue);
}
}
}
AbstractAttributeEditor editor = getEditorForAttribute(attribute);
if (editor != null) {
decorateEditorWithError(fieldDecoration, fieldDecorationWarning, message, newPersonProposalMap, editor);
}
return 1;
}
/**
* @param bugzillaStatus
* @param resultDetail
* @param oneError
* @param fieldString
*/
private void updateTaskEditorPageMessageWithError(BugzillaStatus bugzillaStatus, String resultDetail,
boolean oneError, String fieldString) {
String resultString;
final String titleString;
switch (bugzillaStatus.getCode()) {
case BugzillaStatus.ERROR_CONFIRM_MATCH:
if (oneError) {
resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_one,
Messages.BugzillaTaskEditorPage_Confirm, fieldString);
} else {
resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_more,
Messages.BugzillaTaskEditorPage_Confirm, fieldString);
}
titleString = Messages.BugzillaTaskEditorPage_ConfirmDetailTitle;
break;
case BugzillaStatus.ERROR_MATCH_FAILED:
if (oneError) {
resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_one,
Messages.BugzillaTaskEditorPage_Error, fieldString);
} else {
resultString = MessageFormat.format(Messages.BugzillaTaskEditorPage_Message_more,
Messages.BugzillaTaskEditorPage_Error, fieldString);
}
titleString = Messages.BugzillaTaskEditorPage_ErrorDetailTitle;
break;
default:
throw new RuntimeException("unexpected BugzillaStatus: " + bugzillaStatus.getCode()); //$NON-NLS-1$
}
final String resultDetailString = resultDetail;
getTaskEditor().setMessage(resultString, IMessageProvider.ERROR, new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent event) {
BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(WorkbenchUtil.getShell(),
titleString, resultDetailString);
dialog.open();
}
});
}
/**
* @param fieldDecoration
* @param message
* @param newPersonProposalMap
* @param editor
*/
private void decorateEditorWithError(FieldDecoration fieldDecoration, FieldDecoration fieldDecorationWarning,
String message, Map<String, String> newPersonProposalMap, AbstractAttributeEditor editor) {
final Control control = editor.getControl();
final ControlDecoration decoration = new ControlDecoration(control, SWT.LEFT | SWT.DOWN);
decoration.setImage(
newPersonProposalMap.size() == 1 ? fieldDecorationWarning.getImage() : fieldDecoration.getImage());
IBindingService bindingService = PlatformUI.getWorkbench().getService(IBindingService.class);
if (message != null && !message.equals("")) { //$NON-NLS-1$
decoration.setDescriptionText(message);
errorDecorations.add(decoration);
} else {
decoration.setDescriptionText(
NLS.bind(Messages.BugzillaTaskEditorPage_Content_Assist_for_Error_Available, bindingService
.getBestActiveBindingFormattedFor(ContentAssistCommandAdapter.CONTENT_PROPOSAL_COMMAND)));
errorDecorations.add(decoration);
final PersonAttributeEditor personEditor = ((PersonAttributeEditor) editor);
final PersonProposalProvider personProposalProvider = (PersonProposalProvider) personEditor
.getContentAssistCommandAdapter().getContentProposalProvider();
personProposalProvider.setErrorProposals(newPersonProposalMap);
editorsWithError.add(personEditor);
if (newPersonProposalMap.size() == 1) {
personEditor.setValue(newPersonProposalMap.keySet().iterator().next());
}
personEditor.getText().addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
decoration.hide();
errorDecorations.remove(decoration);
decoration.dispose();
personProposalProvider.setErrorProposals(null);
}
});
}
}
/**
* @param bugzillaResponse
*/
private void showSubmitResponse(final BugzillaRepositoryResponse bugzillaResponse) {
StringBuilder message = new StringBuilder();
for (String iterable_map : bugzillaResponse.getResponseData().keySet()) {
if (message.length() > 0) {
message.append("\n"); //$NON-NLS-1$
}
message.append(NLS.bind(Messages.BugzillaTaskEditorPage_Bug_Line, iterable_map));
Map<String, List<String>> responseMap = bugzillaResponse.getResponseData().get(iterable_map);
for (String iterable_list : responseMap.keySet()) {
message.append(NLS.bind(Messages.BugzillaTaskEditorPage_Action_Line, iterable_list));
List<String> responseList = responseMap.get(iterable_list);
for (String string : responseList) {
message.append(NLS.bind(Messages.BugzillaTaskEditorPage_Email_Line, string));
}
}
}
BugzillaResponseDetailDialog dialog = new BugzillaResponseDetailDialog(WorkbenchUtil.getShell(),
Messages.BugzillaTaskEditorPage_submitted_Changes_Details, message.toString());
dialog.open();
}
}