blob: ae24b4d236b3be32e9463ef86dd687a881d48be3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2008 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
* Jeff Pound - Attachments
*******************************************************************************/
package org.eclipse.mylyn.bugzilla.deprecated;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.mylyn.commons.core.StatusHandler;
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.IBugzillaConstants;
import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration;
import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin;
import org.eclipse.mylyn.internal.bugzilla.ui.editor.KeywordsDialog;
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.deprecated.RepositoryOperation;
import org.eclipse.mylyn.internal.tasks.core.deprecated.RepositoryTaskAttribute;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.deprecated.AbstractRepositoryTaskEditor;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.custom.StyledText;
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.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.editor.FormEditor;
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.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.Section;
/**
* An editor used to view a bug report that exists on a server. It uses a <code>BugReport</code> object to store the
* data.
*
* @author Mik Kersten (hardening of prototype)
* @author Rob Elves
* @author Jeff Pound (Attachment work)
*/
public class BugzillaTaskEditor extends AbstractRepositoryTaskEditor {
private static final String LABEL_TIME_TRACKING = "Bugzilla Time Tracking";
protected Text keywordsText;
protected Text estimateText;
protected Text actualText;
protected Text remainingText;
protected Text addTimeText;
protected Text deadlineText;
protected DatePicker deadlinePicker;
protected Text votesText;
protected Text assignedTo;
/**
* Creates a new <code>ExistingBugEditor</code>.
*/
public BugzillaTaskEditor(FormEditor editor) {
super(editor);
// Set up the input for comparing the bug report to the server
// CompareConfiguration config = new CompareConfiguration();
// config.setLeftEditable(false);
// config.setRightEditable(false);
// config.setLeftLabel("Local Bug Report");
// config.setRightLabel("Remote Bug Report");
// config.setLeftImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT));
// config.setRightImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT));
// compareInput = new BugzillaCompareInput(config);
}
@Override
protected boolean supportsCommentSort() {
return false;
}
@Override
protected void createCustomAttributeLayout(Composite composite) {
RepositoryTaskAttribute attribute = null;
try {
RepositoryConfiguration configuration = BugzillaCorePlugin.getRepositoryConfiguration(this.repository,
false, new NullProgressMonitor());
if (configuration != null) {
List<BugzillaCustomField> customFields = configuration.getCustomFields();
if (!customFields.isEmpty()) {
for (BugzillaCustomField bugzillaCustomField : customFields) {
List<String> optionList = bugzillaCustomField.getOptions();
attribute = this.taskData.getAttribute(bugzillaCustomField.getName());
if (attribute == null) {
RepositoryTaskAttribute newattribute = new RepositoryTaskAttribute(
bugzillaCustomField.getName(), bugzillaCustomField.getDescription(), false);
newattribute.setReadOnly(false);
this.taskData.addAttribute(bugzillaCustomField.getName(), newattribute);
}
final RepositoryTaskAttribute cfattribute = this.taskData.getAttribute(bugzillaCustomField.getName());
Label label = createLabel(composite, cfattribute);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
if (optionList != null && !optionList.isEmpty()) {
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
data.horizontalSpan = 1;
final CCombo attributeCombo = new CCombo(composite, SWT.FLAT | SWT.READ_ONLY);
getManagedForm().getToolkit().adapt(attributeCombo, true, true);
attributeCombo.setFont(TEXT_FONT);
attributeCombo.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
if (hasChanged(cfattribute)) {
attributeCombo.setBackground(getColorIncoming());
}
attributeCombo.setLayoutData(data);
for (String val : optionList) {
if (val != null) {
attributeCombo.add(val);
}
}
String value = cfattribute.getValue();
if (value == null) {
value = "";
}
if (attributeCombo.indexOf(value) != -1) {
attributeCombo.select(attributeCombo.indexOf(value));
}
attributeCombo.clearSelection();
attributeCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
if (attributeCombo.getSelectionIndex() > -1) {
String sel = attributeCombo.getItem(attributeCombo.getSelectionIndex());
cfattribute.setValue(sel);
attributeChanged(cfattribute);
attributeCombo.clearSelection();
}
}
});
} else {
Text cfField = createTextField(composite, cfattribute, SWT.FLAT);
GridDataFactory.fillDefaults().hint(135, SWT.DEFAULT).applyTo(cfField);
}
}
getManagedForm().getToolkit().paintBordersFor(composite);
}
}
} catch (CoreException e) {
// ignore
}
attribute = this.taskData.getAttribute(BugzillaAttribute.DEPENDSON.getKey());
if (attribute != null && !attribute.isReadOnly()) {
Label label = createLabel(composite, attribute);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
Composite textFieldComposite = getManagedForm().getToolkit().createComposite(composite);
GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(textFieldComposite);
GridLayoutFactory.swtDefaults().margins(1, 3).spacing(0, 3).applyTo(textFieldComposite);
GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
textData.horizontalSpan = 1;
textData.widthHint = 135;
final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT);
text.setLayoutData(textData);
getManagedForm().getToolkit().paintBordersFor(textFieldComposite);
}
attribute = this.taskData.getAttribute(BugzillaAttribute.BLOCKED.getKey());
if (attribute != null && !attribute.isReadOnly()) {
Label label = createLabel(composite, attribute);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
Composite textFieldComposite = getManagedForm().getToolkit().createComposite(composite);
GridLayout textLayout = new GridLayout();
textLayout.marginWidth = 1;
textLayout.marginHeight = 3;
textLayout.verticalSpacing = 3;
textFieldComposite.setLayout(textLayout);
GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
textData.horizontalSpan = 1;
textData.widthHint = 135;
final Text text = createTextField(textFieldComposite, attribute, SWT.FLAT);
text.setLayoutData(textData);
getManagedForm().getToolkit().paintBordersFor(textFieldComposite);
}
String dependson = taskData.getAttributeValue(BugzillaAttribute.DEPENDSON.getKey());
String blocked = taskData.getAttributeValue(BugzillaAttribute.BLOCKED.getKey());
boolean addHyperlinks = (dependson != null && dependson.length() > 0)
|| (blocked != null && blocked.length() > 0);
if (addHyperlinks) {
getManagedForm().getToolkit().createLabel(composite, "");
addBugHyperlinks(composite, BugzillaAttribute.DEPENDSON.getKey());
}
if (addHyperlinks) {
getManagedForm().getToolkit().createLabel(composite, "");
addBugHyperlinks(composite, BugzillaAttribute.BLOCKED.getKey());
}
// NOTE: urlText should not be back ported to 3.3 due to background color failure
attribute = this.taskData.getAttribute(BugzillaAttribute.BUG_FILE_LOC.getKey());
if (attribute != null && !attribute.isReadOnly()) {
Label label = createLabel(composite, attribute);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
TextViewer urlTextViewer = addTextEditor(repository, composite, attribute.getValue(), //
false, SWT.FLAT);
final StyledText urlText = urlTextViewer.getTextWidget();
urlText.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
urlText.setIndent(2);
final RepositoryTaskAttribute urlAttribute = attribute;
urlTextViewer.setEditable(true);
urlTextViewer.addTextListener(new ITextListener() {
public void textChanged(TextEvent event) {
String newValue = urlText.getText();
if (!newValue.equals(urlAttribute.getValue())) {
urlAttribute.setValue(newValue);
attributeChanged(urlAttribute);
}
}
});
GridData textData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
textData.horizontalSpan = 1;
textData.widthHint = 135;
urlText.setLayoutData(textData);
if (hasChanged(attribute)) {
urlText.setBackground(getColorIncoming());
}
}
attribute = this.taskData.getAttribute(BugzillaAttribute.STATUS_WHITEBOARD.getKey());
if (attribute == null) {
this.taskData.setAttributeValue(BugzillaAttribute.STATUS_WHITEBOARD.getKey(), "");
attribute = this.taskData.getAttribute(BugzillaAttribute.STATUS_WHITEBOARD.getKey());
}
if (attribute != null && !attribute.isReadOnly()) {
Label label = createLabel(composite, attribute);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
Text whiteboardField = createTextField(composite, attribute, SWT.FLAT);
GridDataFactory.fillDefaults().hint(135, SWT.DEFAULT).applyTo(whiteboardField);
}
try {
addKeywordsList(composite);
} catch (IOException e) {
MessageDialog.openInformation(null, "Attribute Display Error",
"Could not retrieve keyword list, ensure proper configuration in "
+ TasksUiPlugin.LABEL_VIEW_REPOSITORIES + "\n\nError reported: " + e.getMessage());
}
addVoting(composite);
// If groups is available add roles
if (taskData.getAttribute(BugzillaAttribute.GROUP.getKey()) != null) {
addRoles(composite);
}
if (taskData.getAttribute(BugzillaAttribute.ESTIMATED_TIME.getKey()) != null) {
addBugzillaTimeTracker(getManagedForm().getToolkit(), composite);
}
}
private boolean hasCustomAttributeChanges() {
if (taskData == null) {
return false;
}
String customAttributeKeys[] = { BugzillaAttribute.BUG_FILE_LOC.getKey(), BugzillaAttribute.DEPENDSON.getKey(),
BugzillaAttribute.BLOCKED.getKey(), BugzillaAttribute.KEYWORDS.getKey(),
BugzillaAttribute.VOTES.getKey(), BugzillaAttribute.REPORTER_ACCESSIBLE.getKey(),
BugzillaAttribute.CCLIST_ACCESSIBLE.getKey(), BugzillaAttribute.ESTIMATED_TIME.getKey(),
BugzillaAttribute.REMAINING_TIME.getKey(), BugzillaAttribute.ACTUAL_TIME.getKey(),
BugzillaAttribute.DEADLINE.getKey(), BugzillaAttribute.STATUS_WHITEBOARD.getKey() };
for (String key : customAttributeKeys) {
RepositoryTaskAttribute attribute = taskData.getAttribute(key);
if (hasChanged(attribute)) {
return true;
}
}
return false;
}
@Override
protected boolean hasVisibleAttributeChanges() {
return super.hasVisibleAttributeChanges() || this.hasCustomAttributeChanges();
}
private void addBugHyperlinks(Composite composite, String key) {
Composite hyperlinksComposite = getManagedForm().getToolkit().createComposite(composite);
RowLayout rowLayout = new RowLayout();
rowLayout.marginBottom = 0;
rowLayout.marginLeft = 0;
rowLayout.marginRight = 0;
rowLayout.marginTop = 0;
rowLayout.spacing = 0;
hyperlinksComposite.setLayout(new RowLayout());
String values = taskData.getAttributeValue(key);
if (values != null && values.length() > 0) {
for (String bugNumber : values.split(",")) {
final String bugId = bugNumber.trim();
final String bugUrl = repository.getRepositoryUrl() + IBugzillaConstants.URL_GET_SHOW_BUG + bugId;
final AbstractTask task = (AbstractTask) TasksUiInternal.getTaskList().getTask(
repository.getRepositoryUrl(), bugId);
createTaskListHyperlink(hyperlinksComposite, bugId, bugUrl, task);
}
}
}
protected void addRoles(Composite parent) {
Section rolesSection = getManagedForm().getToolkit().createSection(parent, ExpandableComposite.SHORT_TITLE_BAR);
rolesSection.setText("Users in the roles selected below can always view this bug");
rolesSection.setDescription("(The assignee can always see a bug, and this section does not take effect unless the bug is restricted to at least one group.)");
GridLayout gl = new GridLayout();
GridData gd = new GridData(SWT.FILL, SWT.NONE, false, false);
gd.horizontalSpan = 4;
rolesSection.setLayout(gl);
rolesSection.setLayoutData(gd);
Composite rolesComposite = getManagedForm().getToolkit().createComposite(rolesSection);
GridLayout attributesLayout = new GridLayout();
attributesLayout.numColumns = 4;
attributesLayout.horizontalSpacing = 5;
attributesLayout.verticalSpacing = 4;
rolesComposite.setLayout(attributesLayout);
GridData attributesData = new GridData(GridData.FILL_BOTH);
attributesData.horizontalSpan = 1;
attributesData.grabExcessVerticalSpace = false;
rolesComposite.setLayoutData(attributesData);
rolesSection.setClient(rolesComposite);
RepositoryTaskAttribute attribute = taskData.getAttribute(BugzillaAttribute.REPORTER_ACCESSIBLE.getKey());
if (attribute == null) {
taskData.setAttributeValue(BugzillaAttribute.REPORTER_ACCESSIBLE.getKey(), "0");
attribute = taskData.getAttribute(BugzillaAttribute.REPORTER_ACCESSIBLE.getKey());
}
Button button = addButtonField(rolesComposite, attribute, SWT.CHECK);
if (hasChanged(attribute)) {
button.setBackground(getColorIncoming());
}
attribute = null;
attribute = taskData.getAttribute(BugzillaAttribute.CCLIST_ACCESSIBLE.getKey());
if (attribute == null) {
taskData.setAttributeValue(BugzillaAttribute.CCLIST_ACCESSIBLE.getKey(), "0");
attribute = taskData.getAttribute(BugzillaAttribute.CCLIST_ACCESSIBLE.getKey());
}
button = addButtonField(rolesComposite, attribute, SWT.CHECK);
if (hasChanged(attribute)) {
button.setBackground(getColorIncoming());
}
}
@Override
protected boolean hasContentAssist(RepositoryTaskAttribute attribute) {
return BugzillaAttribute.NEWCC.getKey().equals(attribute.getId());
}
@Override
protected boolean hasContentAssist(RepositoryOperation repositoryOperation) {
BugzillaOperation operation;
try {
operation = BugzillaOperation.valueOf(repositoryOperation.getKnobName());
} catch (RuntimeException e) {
// FIXME: ?
StatusHandler.log(new Status(IStatus.INFO, BugzillaUiPlugin.ID_PLUGIN, "Unrecognized operation: "
+ repositoryOperation.getKnobName(), e));
operation = null;
}
if (operation != null && operation == BugzillaOperation.reassign) {
return true;
} else {
return false;
}
}
private Button addButtonField(Composite rolesComposite, RepositoryTaskAttribute attribute, int style) {
if (attribute == null) {
return null;
}
String name = attribute.getName();
if (hasOutgoingChange(attribute)) {
name += "*";
}
final Button button = getManagedForm().getToolkit().createButton(rolesComposite, name, style);
if (!attribute.isReadOnly()) {
button.setData(attribute);
button.setSelection(attribute.getValue().equals("1"));
button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String sel = "1";
if (!button.getSelection()) {
sel = "0";
}
RepositoryTaskAttribute a = (RepositoryTaskAttribute) button.getData();
a.setValue(sel);
attributeChanged(a);
}
});
}
return button;
}
protected void addBugzillaTimeTracker(FormToolkit toolkit, Composite parent) {
Section timeSection = toolkit.createSection(parent, ExpandableComposite.SHORT_TITLE_BAR);
timeSection.setText(LABEL_TIME_TRACKING);
GridLayout gl = new GridLayout();
GridData gd = new GridData(SWT.FILL, SWT.NONE, false, false);
gd.horizontalSpan = 4;
timeSection.setLayout(gl);
timeSection.setLayoutData(gd);
Composite timeComposite = toolkit.createComposite(timeSection);
gl = new GridLayout(4, false);
timeComposite.setLayout(gl);
gd = new GridData();
gd.horizontalSpan = 5;
timeComposite.setLayoutData(gd);
RepositoryTaskAttribute attribute = this.taskData.getAttribute(BugzillaAttribute.ESTIMATED_TIME.getKey());
if (attribute != null && !attribute.isReadOnly()) {
createLabel(timeComposite, attribute);
estimateText = createTextField(timeComposite, attribute, SWT.FLAT);
estimateText.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
}
Label label = toolkit.createLabel(timeComposite, "Current Estimate:");
label.setForeground(toolkit.getColors().getColor(IFormColors.TITLE));
float total = 0;
try {
total = (Float.parseFloat(taskData.getAttributeValue(BugzillaAttribute.ACTUAL_TIME.getKey())) + Float.parseFloat(taskData.getAttributeValue(BugzillaAttribute.REMAINING_TIME.getKey())));
} catch (Exception e) {
// ignore likely NumberFormatException
}
Text currentEstimate = toolkit.createText(timeComposite, "" + total);
currentEstimate.setFont(TEXT_FONT);
currentEstimate.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
currentEstimate.setEditable(false);
attribute = this.taskData.getAttribute(BugzillaAttribute.ACTUAL_TIME.getKey());
if (attribute != null) {
createLabel(timeComposite, attribute);
Text actualText = createTextField(timeComposite, attribute, SWT.FLAT);
actualText.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
actualText.setEditable(false);
}
// Add Time
taskData.setAttributeValue(BugzillaAttribute.WORK_TIME.getKey(), "0");
final RepositoryTaskAttribute addTimeAttribute = this.taskData.getAttribute(BugzillaAttribute.WORK_TIME.getKey());
if (addTimeAttribute != null) {
createLabel(timeComposite, addTimeAttribute);
addTimeText = toolkit.createText(timeComposite,
taskData.getAttributeValue(BugzillaAttribute.WORK_TIME.getKey()), SWT.BORDER);
addTimeText.setFont(TEXT_FONT);
addTimeText.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
addTimeText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
addTimeAttribute.setValue(addTimeText.getText());
attributeChanged(addTimeAttribute);
}
});
}
attribute = this.taskData.getAttribute(BugzillaAttribute.REMAINING_TIME.getKey());
if (attribute != null) {
createLabel(timeComposite, attribute);
createTextField(timeComposite, attribute, SWT.FLAT);
}
attribute = this.taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey());
if (attribute != null) {
createLabel(timeComposite, attribute);
Composite dateWithClear = toolkit.createComposite(timeComposite);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = 1;
dateWithClear.setLayout(layout);
deadlinePicker = new DatePicker(dateWithClear, /* SWT.NONE */SWT.BORDER,
taskData.getAttributeValue(BugzillaAttribute.DEADLINE.getKey()), false, 0);
deadlinePicker.setFont(TEXT_FONT);
deadlinePicker.setDatePattern("yyyy-MM-dd");
if (hasChanged(attribute)) {
deadlinePicker.setBackground(getColorIncoming());
}
deadlinePicker.addPickerSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
// ignore
}
public void widgetSelected(SelectionEvent e) {
Calendar cal = deadlinePicker.getDate();
if (cal != null) {
Date d = cal.getTime();
SimpleDateFormat f = (SimpleDateFormat) DateFormat.getDateInstance();
f.applyPattern("yyyy-MM-dd");
taskData.setAttributeValue(BugzillaAttribute.DEADLINE.getKey(), f.format(d));
attributeChanged(taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey()));
// TODO goes dirty even if user presses cancel
// markDirty(true);
} else {
taskData.setAttributeValue(BugzillaAttribute.DEADLINE.getKey(), "");
attributeChanged(taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey()));
deadlinePicker.setDate(null);
}
}
});
ImageHyperlink clearDeadlineDate = toolkit.createImageHyperlink(dateWithClear, SWT.NONE);
clearDeadlineDate.setImage(CommonImages.getImage(CommonImages.REMOVE));
clearDeadlineDate.setToolTipText("Clear");
clearDeadlineDate.addHyperlinkListener(new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
taskData.setAttributeValue(BugzillaAttribute.DEADLINE.getKey(), "");
attributeChanged(taskData.getAttribute(BugzillaAttribute.DEADLINE.getKey()));
deadlinePicker.setDate(null);
}
});
}
timeSection.setClient(timeComposite);
}
protected void addKeywordsList(Composite attributesComposite) throws IOException {
// newLayout(attributesComposite, 1, "Keywords:", PROPERTY);
final RepositoryTaskAttribute attribute = taskData.getAttribute(RepositoryTaskAttribute.KEYWORDS);
if (attribute == null) {
return;
}
Label label = createLabel(attributesComposite, attribute);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
// toolkit.createText(attributesComposite, keywords)
keywordsText = createTextField(attributesComposite, attribute, SWT.FLAT);
keywordsText.setFont(TEXT_FONT);
GridData keywordsData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
keywordsData.horizontalSpan = 2;
keywordsData.widthHint = 200;
keywordsText.setLayoutData(keywordsData);
Button changeKeywordsButton = getManagedForm().getToolkit().createButton(attributesComposite, "Edit...",
SWT.FLAT);
GridData keyWordsButtonData = new GridData();
changeKeywordsButton.setLayoutData(keyWordsButtonData);
changeKeywordsButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
}
public void widgetSelected(SelectionEvent e) {
String keywords = attribute.getValue();
Shell shell = null;
if (PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
} else {
shell = new Shell(PlatformUI.getWorkbench().getDisplay());
}
List<String> validKeywords = new ArrayList<String>();
try {
validKeywords = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
new NullProgressMonitor()).getKeywords();
} catch (Exception ex) {
// ignore
}
KeywordsDialog keywordsDialog = new KeywordsDialog(shell, keywords, validKeywords);
int responseCode = keywordsDialog.open();
String newKeywords = keywordsDialog.getSelectedKeywordsString();
if (responseCode == Window.OK && keywords != null) {
keywordsText.setText(newKeywords);
attribute.setValue(newKeywords);
attributeChanged(attribute);
} else {
return;
}
}
});
}
protected void addVoting(Composite attributesComposite) {
Label label = getManagedForm().getToolkit().createLabel(attributesComposite, "Votes:");
label.setForeground(getManagedForm().getToolkit().getColors().getColor(IFormColors.TITLE));
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
Composite votingComposite = getManagedForm().getToolkit().createComposite(attributesComposite);
GridLayout layout = new GridLayout(3, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
votingComposite.setLayout(layout);
RepositoryTaskAttribute votesAttribute = taskData.getAttribute(BugzillaAttribute.VOTES.getKey());
votesText = createTextField(votingComposite, votesAttribute, SWT.FLAT | SWT.READ_ONLY);
votesText.setFont(TEXT_FONT);
GridDataFactory.fillDefaults().minSize(30, SWT.DEFAULT).hint(30, SWT.DEFAULT).applyTo(votesText);
if (votesAttribute != null && hasChanged(votesAttribute)) {
votesText.setBackground(getColorIncoming());
}
votesText.setEditable(false);
Hyperlink showVotesHyperlink = getManagedForm().getToolkit().createHyperlink(votingComposite, "Show votes",
SWT.NONE);
showVotesHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
if (BugzillaTaskEditor.this.getEditor() instanceof TaskEditor) {
TasksUiUtil.openUrl(repository.getRepositoryUrl() + IBugzillaConstants.URL_SHOW_VOTES
+ taskData.getTaskId());
}
}
});
Hyperlink voteHyperlink = getManagedForm().getToolkit().createHyperlink(votingComposite, "Vote", SWT.NONE);
voteHyperlink.addHyperlinkListener(new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
if (BugzillaTaskEditor.this.getEditor() instanceof TaskEditor) {
TasksUiUtil.openUrl(repository.getRepositoryUrl() + IBugzillaConstants.URL_VOTE
+ taskData.getTaskId());
}
}
});
}
@Override
protected void validateInput() {
}
@Override
protected String getHistoryUrl() {
if (repository != null && taskData != null) {
return repository.getRepositoryUrl() + IBugzillaConstants.URL_BUG_ACTIVITY + taskData.getTaskId();
} else {
return null;
}
}
/**
* @author Frank Becker (bug 198027) FIXME: A lot of duplicated code here between this and NewBugzillataskEditor
*/
@Override
protected void addAssignedTo(Composite peopleComposite) {
RepositoryTaskAttribute assignedAttribute = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
if (assignedAttribute != null) {
String bugzillaVersion;
try {
bugzillaVersion = BugzillaCorePlugin.getRepositoryConfiguration(repository, false,
new NullProgressMonitor()).getInstallVersion();
} catch (CoreException e1) {
// ignore
bugzillaVersion = "2.18";
}
if (bugzillaVersion.compareTo("3.1") < 0) {
// old bugzilla workflow is used
super.addAssignedTo(peopleComposite);
return;
}
Label label = createLabel(peopleComposite, assignedAttribute);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
assignedTo = createTextField(peopleComposite, assignedAttribute, SWT.FLAT);
GridDataFactory.fillDefaults().hint(150, SWT.DEFAULT).applyTo(assignedTo);
assignedTo.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
String sel = assignedTo.getText();
RepositoryTaskAttribute a = taskData.getAttribute(RepositoryTaskAttribute.USER_ASSIGNED);
if (!(a.getValue().equals(sel))) {
a.setValue(sel);
markDirty(true);
}
}
});
ContentAssistCommandAdapter adapter = applyContentAssist(assignedTo,
createContentProposalProvider(assignedAttribute));
ILabelProvider propsalLabelProvider = createProposalLabelProvider(assignedAttribute);
if (propsalLabelProvider != null) {
adapter.setLabelProvider(propsalLabelProvider);
}
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
FormToolkit toolkit = getManagedForm().getToolkit();
Label dummylabel = toolkit.createLabel(peopleComposite, "");
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(dummylabel);
RepositoryTaskAttribute attribute = taskData.getAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
if (attribute == null) {
taskData.setAttributeValue(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey(), "0");
attribute = taskData.getAttribute(BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey());
}
addButtonField(peopleComposite, attribute, SWT.CHECK);
}
}
@Override
protected boolean attributeChanged(RepositoryTaskAttribute attribute) {
if (attribute == null) {
return false;
}
// Support comment wrapping for bugzilla 2.18
if (attribute.getId().equals(BugzillaAttribute.NEW_COMMENT.getKey())) {
if (repository.getVersion().startsWith("2.18")) {
attribute.setValue(BugzillaUiPlugin.formatTextToLineWrap(attribute.getValue(), true));
}
}
return super.attributeChanged(attribute);
}
@Override
protected void addSelfToCC(Composite composite) {
// XXX: Work around for adding QAContact to People section. Update once bug#179254 is complete
boolean haveRealName = false;
RepositoryTaskAttribute qaContact = taskData.getAttribute(BugzillaAttribute.QA_CONTACT_NAME.getKey());
if (qaContact == null) {
qaContact = taskData.getAttribute(BugzillaAttribute.QA_CONTACT.getKey());
} else {
haveRealName = true;
}
if (qaContact != null) {
Label label = createLabel(composite, qaContact);
GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(label);
Text textField;
if (qaContact.isReadOnly()) {
textField = createTextField(composite, qaContact, SWT.FLAT | SWT.READ_ONLY);
} else {
textField = createTextField(composite, qaContact, SWT.FLAT);
ContentAssistCommandAdapter adapter = applyContentAssist(textField,
createContentProposalProvider(qaContact));
ILabelProvider propsalLabelProvider = createProposalLabelProvider(qaContact);
if (propsalLabelProvider != null) {
adapter.setLabelProvider(propsalLabelProvider);
}
adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
}
GridDataFactory.fillDefaults().grab(true, false).applyTo(textField);
if (haveRealName) {
textField.setText(textField.getText() + " <"
+ taskData.getAttributeValue(BugzillaAttribute.QA_CONTACT.getKey()) + ">");
}
}
super.addSelfToCC(composite);
}
}