### Eclipse Workspace Patch 1.0 #P org.eclipse.mylyn.bugzilla.ui Index: src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.bugzilla.ui/src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java,v retrieving revision 1.19 diff -u -r1.19 BugzillaTaskEditorPage.java --- src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java 16 Dec 2008 00:21:39 -0000 1.19 +++ src/org/eclipse/mylyn/internal/bugzilla/ui/editor/BugzillaTaskEditorPage.java 4 Jan 2009 18:17:46 -0000 @@ -7,20 +7,34 @@ * * Contributors: * Tasktop Technologies - initial API and implementation + * Frank Becker - enhancements for bug 166595 *******************************************************************************/ package org.eclipse.mylyn.internal.bugzilla.ui.editor; +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.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.IBugzillaConstants; +import org.eclipse.mylyn.internal.bugzilla.core.RepositoryConfiguration; +import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaUiPlugin; +import org.eclipse.mylyn.tasks.core.RepositoryStatus; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; 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.ui.TasksUi; import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor; import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage; @@ -28,6 +42,7 @@ import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory; import org.eclipse.mylyn.tasks.ui.editors.LayoutHint; import org.eclipse.mylyn.tasks.ui.editors.TaskEditor; +import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput; import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor; /** @@ -38,8 +53,12 @@ public static final String ID_PART_BUGZILLA_PLANNING = "org.eclipse.mylyn.bugzilla.ui.editors.part.planning"; //$NON-NLS-1$ + private final Map attributeEditorMap; + + private TaskDataModelListener productListener; + public BugzillaTaskEditorPage(TaskEditor editor) { - super(editor, BugzillaCorePlugin.CONNECTOR_KIND); + this(editor, BugzillaCorePlugin.CONNECTOR_KIND); } /** @@ -50,6 +69,7 @@ */ public BugzillaTaskEditorPage(TaskEditor editor, String connectorKind) { super(editor, connectorKind); + this.attributeEditorMap = new HashMap(); } @Override @@ -125,6 +145,7 @@ }); } + BugzillaTaskEditorPage.this.addToAttributeEditorMap(taskAttribute, editor); return editor; } }; @@ -132,11 +153,26 @@ } @Override + protected void createParts() { + attributeEditorMap.clear(); + super.createParts(); + } + + @Override + protected TaskDataModel createModel(TaskEditorInput input) throws CoreException { + TaskDataModel model = super.createModel(input); + productListener = new ProductSelectionListener(); + model.addModelListener(productListener); + return model; + } + + @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); + getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_short_summary_before_submitting, + IMessageProvider.ERROR); AbstractTaskEditorPart part = getPart(ID_PART_SUMMARY); if (part != null) { part.setFocus(); @@ -147,7 +183,8 @@ 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); + getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_select_a_component_before_submitting, + IMessageProvider.ERROR); AbstractTaskEditorPart part = getPart(ID_PART_ATTRIBUTES); if (part != null) { part.setFocus(); @@ -158,7 +195,8 @@ TaskAttribute descriptionAttribute = getModel().getTaskData().getRoot().getMappedAttribute( TaskAttribute.DESCRIPTION); if (descriptionAttribute != null && descriptionAttribute.getValue().length() == 0) { - getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_description_before_submitting, IMessageProvider.ERROR); + getTaskEditor().setMessage(Messages.BugzillaTaskEditorPage_Please_enter_a_description_before_submitting, + IMessageProvider.ERROR); AbstractTaskEditorPart descriptionPart = getPart(ID_PART_DESCRIPTION); if (descriptionPart != null) { descriptionPart.setFocus(); @@ -169,4 +207,119 @@ super.doSubmit(); } + /** + * @since 3.1 + */ + public void addToAttributeEditorMap(TaskAttribute attribute, AbstractAttributeEditor editor) { + if (attributeEditorMap.containsKey(attribute)) { + attributeEditorMap.remove(attribute); + } + attributeEditorMap.put(attribute, editor); + } + + /** + * @since 3.1 + */ + public AbstractAttributeEditor getEditorForAttribute(TaskAttribute attribute) { + return attributeEditorMap.get(attribute); + } + + /** + * @since 3.1 + */ + public Map getAttributeEditorMap() { + return attributeEditorMap; + } + + /** + * @since 3.1 + */ + public void refresh() { + try { + showEditorBusy(true); + for (AbstractAttributeEditor abstractAttributeEditor : attributeEditorMap.values()) { + try { + abstractAttributeEditor.refresh(); + } catch (UnsupportedOperationException e) { + // ignore + } + } + } finally { + showEditorBusy(false); + } + } + + public 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 { + repositoryConfiguration = BugzillaCorePlugin.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 optionValues = repositoryConfiguration.getComponents(taskAttribute.getValue()); + Collections.sort(optionValues); + attributeComponent.clearOptions(); + for (String option : optionValues) { + attributeComponent.putOption(option, option); + } + if (optionValues.size() == 1) { + attributeComponent.setValue(optionValues.get(0)); + } else { + attributeComponent.setValue(""); //$NON-NLS-1$ + } + refresh(attributeComponent); + } + + TaskAttribute attributeTargetMilestone = taskAttribute.getTaskData().getRoot().getMappedAttribute( + BugzillaAttribute.TARGET_MILESTONE.getKey()); + if (attributeTargetMilestone != null) { + List optionValues = repositoryConfiguration.getTargetMilestones(taskAttribute.getValue()); + Collections.sort(optionValues); + attributeTargetMilestone.clearOptions(); + for (String option : optionValues) { + attributeTargetMilestone.putOption(option, option); + } + if (optionValues.size() == 1) { + attributeTargetMilestone.setValue(optionValues.get(0)); + } else { + attributeTargetMilestone.setValue("---"); //$NON-NLS-1$ + } + refresh(attributeTargetMilestone); + } + + TaskAttribute attributeDefaultAssignee = taskAttribute.getTaskData().getRoot().getMappedAttribute( + BugzillaAttribute.SET_DEFAULT_ASSIGNEE.getKey()); + if (attributeDefaultAssignee != null) { + attributeDefaultAssignee.setValue("1"); //$NON-NLS-1$ + refresh(attributeDefaultAssignee); + } + } + } + } + } + } #P org.eclipse.mylyn.bugzilla.core Index: src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaAttribute.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.bugzilla.core/src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaAttribute.java,v retrieving revision 1.12 diff -u -r1.12 BugzillaAttribute.java --- src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaAttribute.java 16 Dec 2008 17:44:07 -0000 1.12 +++ src/org/eclipse/mylyn/internal/bugzilla/core/BugzillaAttribute.java 4 Jan 2009 18:17:47 -0000 @@ -109,7 +109,7 @@ PRIORITY(Messages.BugzillaAttribute_Priority, "priority", TaskAttribute.TYPE_SINGLE_SELECT, false, false), //$NON-NLS-1$ - PRODUCT(Messages.BugzillaAttribute_Product, "product", TaskAttribute.TYPE_SHORT_TEXT, false, true), //$NON-NLS-1$ + PRODUCT(Messages.BugzillaAttribute_Product, "product", TaskAttribute.TYPE_SINGLE_SELECT, false, false), //$NON-NLS-1$ REP_PLATFORM(Messages.BugzillaAttribute_Platform, "rep_platform", TaskAttribute.TYPE_SINGLE_SELECT, false, false), //$NON-NLS-1$ #P org.eclipse.mylyn.tasks.ui Index: src/org/eclipse/mylyn/internal/tasks/ui/editors/SingleSelectionAttributeEditor.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/SingleSelectionAttributeEditor.java,v retrieving revision 1.15 diff -u -r1.15 SingleSelectionAttributeEditor.java --- src/org/eclipse/mylyn/internal/tasks/ui/editors/SingleSelectionAttributeEditor.java 5 Dec 2008 23:25:50 -0000 1.15 +++ src/org/eclipse/mylyn/internal/tasks/ui/editors/SingleSelectionAttributeEditor.java 4 Jan 2009 18:17:47 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2004, 2008 Tasktop Technologies and others. + * 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 @@ -34,6 +34,10 @@ private CCombo combo; + private boolean ignoreNotification; + + private Text text; + public SingleSelectionAttributeEditor(TaskDataModel manager, TaskAttribute taskAttribute) { super(manager, taskAttribute); } @@ -41,48 +45,33 @@ @Override public void createControl(Composite parent, FormToolkit toolkit) { if (isReadOnly()) { - Text text = new Text(parent, SWT.FLAT | SWT.READ_ONLY); - text.setFont(EditorUtil.TEXT_FONT); + text = new Text(parent, SWT.FLAT | SWT.READ_ONLY); toolkit.adapt(text, false, false); + text.setFont(EditorUtil.TEXT_FONT); text.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE); - String label = getValueLabel(); - if ("".equals(label)) { //$NON-NLS-1$ - // if set to the empty string the label will use 64px on GTK - text.setText(" "); //$NON-NLS-1$ - } else { - text.setText(label); - } + refresh(); setControl(text); } else { combo = new CCombo(parent, SWT.FLAT | SWT.READ_ONLY); toolkit.adapt(combo, false, false); combo.setFont(EditorUtil.TEXT_FONT); combo.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); - - Map labelByValue = getAttributeMapper().getOptions(getTaskAttribute()); - if (labelByValue != null) { - values = labelByValue.keySet().toArray(new String[0]); - for (String value : values) { - combo.add(labelByValue.get(value)); - } - } - - select(getValue(), getValueLabel()); - + refresh(); if (values != null) { combo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - int index = combo.getSelectionIndex(); - if (index > -1) { - Assert.isNotNull(values); - Assert.isLegal(index >= 0 && index <= values.length - 1); - setValue(values[index]); + if (!ignoreNotification) { + int index = combo.getSelectionIndex(); + if (index > -1) { + Assert.isNotNull(values); + Assert.isLegal(index >= 0 && index <= values.length - 1); + setValue(values[index]); + } } } }); } - setControl(combo); } } @@ -109,8 +98,11 @@ } public void setValue(String value) { - getAttributeMapper().setValue(getTaskAttribute(), value); - attributeChanged(); + String oldValue = getAttributeMapper().getValue(getTaskAttribute()); + if (!oldValue.equals(value)) { + getAttributeMapper().setValue(getTaskAttribute(), value); + attributeChanged(); + } } void selectDefaultValue() { @@ -120,4 +112,33 @@ } } + @Override + public void refresh() { + try { + ignoreNotification = true; + if (text != null) { + String label = getValueLabel(); + if ("".equals(label)) { //$NON-NLS-1$ + // if set to the empty string the label will use 64px on GTK + text.setText(" "); //$NON-NLS-1$ + } else { + text.setText(label); + } + } else { + combo.removeAll(); + Map labelByValue = getAttributeMapper().getOptions(getTaskAttribute()); + if (labelByValue != null) { + values = labelByValue.keySet().toArray(new String[0]); + for (String value : values) { + combo.add(labelByValue.get(value)); + } + } + select(getValue(), getValueLabel()); + combo.redraw(); + } + } finally { + ignoreNotification = false; + } + } + } Index: src/org/eclipse/mylyn/internal/tasks/ui/editors/BooleanAttributeEditor.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/editors/BooleanAttributeEditor.java,v retrieving revision 1.7 diff -u -r1.7 BooleanAttributeEditor.java --- src/org/eclipse/mylyn/internal/tasks/ui/editors/BooleanAttributeEditor.java 5 Dec 2008 23:25:50 -0000 1.7 +++ src/org/eclipse/mylyn/internal/tasks/ui/editors/BooleanAttributeEditor.java 4 Jan 2009 18:17:47 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2004, 2008 Tasktop Technologies and others. + * 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 @@ -26,21 +26,27 @@ */ public class BooleanAttributeEditor extends AbstractAttributeEditor { + private Button button; + + private boolean ignoreNotification; + public BooleanAttributeEditor(TaskDataModel manager, TaskAttribute taskAttribute) { super(manager, taskAttribute); } @Override public void createControl(Composite parent, FormToolkit toolkit) { - final Button button = toolkit.createButton(parent, super.getLabel(), SWT.CHECK); + button = toolkit.createButton(parent, super.getLabel(), SWT.CHECK); button.setEnabled(!isReadOnly()); - button.setSelection(getValue()); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - setValue(button.getSelection()); + if (!ignoreNotification) { + setValue(button.getSelection()); + } } }); + refresh(); setControl(button); } @@ -58,4 +64,14 @@ attributeChanged(); } + @Override + public void refresh() { + try { + ignoreNotification = true; + button.setSelection(getValue()); + } finally { + ignoreNotification = false; + } + } + } Index: src/org/eclipse/mylyn/tasks/ui/editors/AbstractAttributeEditor.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/tasks/ui/editors/AbstractAttributeEditor.java,v retrieving revision 1.11 diff -u -r1.11 AbstractAttributeEditor.java --- src/org/eclipse/mylyn/tasks/ui/editors/AbstractAttributeEditor.java 7 Dec 2008 03:26:58 -0000 1.11 +++ src/org/eclipse/mylyn/tasks/ui/editors/AbstractAttributeEditor.java 4 Jan 2009 18:17:47 -0000 @@ -213,4 +213,19 @@ this.readOnly = readOnly; } + /** + * Refreshes the state of the widget from the data model. The default implementation throws + * UnsupportedOperationException. + * + *

+ * Subclasses should overwrite this method. + * + * @since 3.1 + * @throws UnsupportedOperationException + * if this method is not supported by the editor + */ + public void refresh() { + throw new UnsupportedOperationException(); + } + }