| /******************************************************************************* |
| * Copyright (c) 2004, 2011 Mylyn project committers 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 |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.bugzilla.ui.editor; |
| |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.jface.fieldassist.ContentProposalAdapter; |
| import org.eclipse.jface.fieldassist.IContentProposalProvider; |
| import org.eclipse.jface.fieldassist.TextContentAdapter; |
| import org.eclipse.jface.layout.GridDataFactory; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.mylyn.commons.ui.CommonImages; |
| import org.eclipse.mylyn.internal.tasks.ui.PersonProposalLabelProvider; |
| import org.eclipse.mylyn.internal.tasks.ui.PersonProposalProvider; |
| import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil; |
| import org.eclipse.mylyn.internal.tasks.ui.editors.Messages; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttribute; |
| import org.eclipse.mylyn.tasks.core.data.TaskDataModel; |
| import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor; |
| 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.swt.SWT; |
| import org.eclipse.swt.custom.CCombo; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.events.KeyListener; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.MouseTrackAdapter; |
| import org.eclipse.swt.events.MouseTrackListener; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Text; |
| 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.FormToolkit; |
| import org.eclipse.ui.forms.widgets.ImageHyperlink; |
| import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; |
| |
| /** |
| * @author Frank Becker |
| */ |
| public class FlagAttributeEditor extends AbstractAttributeEditor { |
| |
| private String[] values; |
| |
| private CCombo combo; |
| |
| private Text requesteeText; |
| |
| private ImageHyperlink selfLink; |
| |
| private Text flagText; |
| |
| private Text requesteeROText; |
| |
| private boolean suppressRefresh; |
| |
| private Composite flagComposite; |
| |
| public FlagAttributeEditor(TaskDataModel manager, TaskAttribute taskAttribute) { |
| super(manager, taskAttribute); |
| setLayoutHint(new LayoutHint(RowSpan.SINGLE, ColumnSpan.SINGLE)); |
| if (taskAttribute.getAttribute("state") != null) { //$NON-NLS-1$ |
| setReadOnly(taskAttribute.getAttribute("state").getMetaData().isReadOnly()); //$NON-NLS-1$ |
| } |
| } |
| |
| @Override |
| public void createControl(Composite parent, FormToolkit toolkit) { |
| flagComposite = toolkit.createComposite(parent); |
| |
| GridLayout layout = new GridLayout(2, false); |
| layout.marginHeight = 1; |
| layout.marginWidth = 1; |
| layout.horizontalSpacing = 10; |
| flagComposite.setLayout(layout); |
| if (isReadOnly()) { |
| flagText = new Text(flagComposite, SWT.FLAT | SWT.READ_ONLY); |
| toolkit.adapt(flagText, false, false); |
| flagText.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE); |
| flagText.setText(getValueLabel()); |
| flagText.setBackground(parent.getBackground()); |
| flagText.setEditable(false); |
| String tooltip = getTaskAttribute().getMetaData().getLabel(); |
| if (tooltip == null) { |
| tooltip = getDescription(); |
| } |
| if (tooltip != null) { |
| flagText.setToolTipText(tooltip); |
| } |
| TaskAttribute requestee = getTaskAttribute().getAttribute("requestee"); //$NON-NLS-1$ |
| requesteeROText = new Text(flagComposite, SWT.FLAT | SWT.READ_ONLY); |
| toolkit.adapt(requesteeROText, false, false); |
| requesteeROText.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE); |
| requesteeROText.setText(requestee.getValue()); |
| requesteeROText.setBackground(parent.getBackground()); |
| requesteeROText.setEditable(false); |
| requesteeROText.setToolTipText(requestee.getMetaData().getValue(TaskAttribute.META_DESCRIPTION)); |
| } else { |
| combo = new CCombo(flagComposite, SWT.FLAT | SWT.READ_ONLY); |
| toolkit.adapt(combo, false, false); |
| combo.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); |
| String tooltip = getTaskAttribute().getMetaData().getLabel(); |
| if (tooltip == null) { |
| tooltip = getDescription(); |
| } |
| if (tooltip != null) { |
| combo.setToolTipText(tooltip); |
| } |
| EditorUtil.addScrollListener(combo); |
| |
| updateComboWithOptions(); |
| |
| select(getValue(), getValueLabel()); |
| |
| 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); |
| try { |
| suppressRefresh = true; |
| setValue(values[index]); |
| selectionChanged(index); |
| } finally { |
| suppressRefresh = false; |
| } |
| } |
| } |
| }); |
| } |
| TaskAttribute requestee = getTaskAttribute().getAttribute("requestee"); //$NON-NLS-1$ |
| if (requestee != null && !requestee.getMetaData().isReadOnly()) { |
| final Composite requesteeComposite = new Composite(flagComposite, SWT.NONE); |
| GridLayout requesteeLayout = new GridLayout(2, false); |
| requesteeLayout.marginHeight = 0; |
| requesteeLayout.marginWidth = 0; |
| requesteeLayout.horizontalSpacing = 0; |
| requesteeComposite.setLayout(requesteeLayout); |
| requesteeComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); |
| requesteeComposite.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); |
| |
| requesteeText = toolkit.createText(requesteeComposite, requestee.getValue()); |
| boolean enabled = "?".equals(getValueLabel()); //$NON-NLS-1$ |
| requesteeText.setEnabled(enabled); |
| requesteeText.setToolTipText(requestee.getMetaData().getValue(TaskAttribute.META_DESCRIPTION)); |
| IContentProposalProvider contentProposalProvider = new PersonProposalProvider(null, |
| requestee.getTaskData()); |
| ILabelProvider labelPropsalProvider = new PersonProposalLabelProvider(); |
| if (contentProposalProvider != null && labelPropsalProvider != null) { |
| ContentAssistCommandAdapter adapter = new ContentAssistCommandAdapter(requesteeText, |
| new TextContentAdapter(), contentProposalProvider, |
| ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new char[0], true); |
| adapter.setLabelProvider(labelPropsalProvider); |
| adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); |
| } |
| |
| selfLink = new ImageHyperlink(requesteeComposite, SWT.NO_FOCUS); |
| selfLink.setToolTipText(Messages.PersonAttributeEditor_Insert_My_User_Id_Tooltip); |
| selfLink.setActiveImage(CommonImages.getImage(CommonImages.PERSON_ME_SMALL)); |
| selfLink.setHoverImage(CommonImages.getImage(CommonImages.PERSON_ME_SMALL)); |
| selfLink.setEnabled(enabled); |
| selfLink.setBackground(requesteeText.getBackground()); |
| selfLink.addHyperlinkListener(new HyperlinkAdapter() { |
| @Override |
| public void linkActivated(HyperlinkEvent e) { |
| String userName = getModel().getTaskRepository().getUserName(); |
| if (userName != null && userName.length() > 0) { |
| requesteeText.setText(userName); |
| setValue(userName); |
| } |
| } |
| }); |
| GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).exclude(true).applyTo(selfLink); |
| MouseTrackListener mouseListener = new MouseTrackAdapter() { |
| int version = 0; |
| |
| @Override |
| public void mouseEnter(MouseEvent e) { |
| ((GridData) selfLink.getLayoutData()).exclude = false; |
| requesteeComposite.layout(); |
| selfLink.setImage(CommonImages.getImage(CommonImages.PERSON_ME_SMALL)); |
| selfLink.redraw(); |
| version++; |
| } |
| |
| @Override |
| public void mouseExit(MouseEvent e) { |
| final int lastVersion = version; |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| if (version != lastVersion || selfLink.isDisposed()) { |
| return; |
| } |
| selfLink.setImage(null); |
| selfLink.redraw(); |
| ((GridData) selfLink.getLayoutData()).exclude = true; |
| requesteeComposite.layout(); |
| } |
| }); |
| } |
| }; |
| requesteeText.addMouseTrackListener(mouseListener); |
| selfLink.addMouseTrackListener(mouseListener); |
| GridData requesteeData = new GridData(SWT.FILL, SWT.CENTER, true, false); |
| requesteeText.setLayoutData(requesteeData); |
| requesteeText.setFont(EditorUtil.TEXT_FONT); |
| requesteeText.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); |
| |
| requesteeText.addKeyListener(new KeyListener() { |
| |
| public void keyReleased(KeyEvent e) { |
| try { |
| suppressRefresh = true; |
| setRequestee(requesteeText.getText()); |
| } finally { |
| suppressRefresh = false; |
| } |
| } |
| |
| public void keyPressed(KeyEvent e) { |
| } |
| }); |
| requesteeText.addModifyListener(new ModifyListener() { |
| |
| public void modifyText(ModifyEvent e) { |
| try { |
| suppressRefresh = true; |
| setRequestee(requesteeText.getText()); |
| } finally { |
| suppressRefresh = false; |
| } |
| } |
| }); |
| toolkit.adapt(requesteeText, false, false); |
| |
| } |
| } |
| toolkit.paintBordersFor(flagComposite); |
| setControl(flagComposite); |
| } |
| |
| private void updateComboWithOptions() { |
| Map<String, String> labelByValue = getAttributeMapper().getAssoctiatedAttribute(getTaskAttribute()) |
| .getOptions(); |
| if (labelByValue != null) { |
| combo.removeAll(); |
| values = labelByValue.keySet().toArray(new String[0]); |
| for (String value : values) { |
| combo.add(labelByValue.get(value)); |
| } |
| } |
| } |
| |
| public String getValue() { |
| return getAttributeMapper().getValue(getAttributeMapper().getAssoctiatedAttribute(getTaskAttribute())); |
| } |
| |
| public String getValueLabel() { |
| return getAttributeMapper().getValueLabel(getAttributeMapper().getAssoctiatedAttribute(getTaskAttribute())); |
| } |
| |
| private void select(String value, String label) { |
| if (values != null) { |
| for (int i = 0; i < values.length; i++) { |
| if (values[i].equals(value)) { |
| combo.select(i); |
| break; |
| } |
| } |
| } else { |
| combo.setText(label); |
| } |
| } |
| |
| public void setRequestee(String value) { |
| TaskAttribute requestee = getTaskAttribute().getAttribute("requestee"); //$NON-NLS-1$ |
| if (requestee != null) { |
| if (!requestee.getValue().equals(value)) { |
| getAttributeMapper().setValue(requestee, value); |
| attributeChanged(); |
| } |
| } |
| } |
| |
| public void setValue(String value) { |
| getAttributeMapper().setValue(getAttributeMapper().getAssoctiatedAttribute(getTaskAttribute()), value); |
| attributeChanged(); |
| } |
| |
| @Override |
| public String getLabel() { |
| String label = getAttributeMapper().getLabel(getAttributeMapper().getAssoctiatedAttribute(getTaskAttribute())); |
| if (label != null) { |
| label.replace("&", "&&"); //$NON-NLS-1$//$NON-NLS-2$ |
| } else { |
| label = ""; //$NON-NLS-1$ |
| } |
| |
| TaskAttribute setter = getTaskAttribute().getAttribute("setter"); //$NON-NLS-1$ |
| if (setter != null) { |
| String setterValue = setter.getValue(); |
| if (setterValue != null && !setterValue.equals("")) { //$NON-NLS-1$ |
| if (setterValue.indexOf("@") > -1) { //$NON-NLS-1$ |
| setterValue = setterValue.substring(0, setterValue.indexOf("@")); //$NON-NLS-1$ |
| } |
| label = setterValue + ": " + label; //$NON-NLS-1$ |
| } |
| } |
| return label; |
| } |
| |
| @Override |
| public void refresh() { |
| if (flagText != null && !flagText.isDisposed()) { |
| flagText.setText(getValueLabel()); |
| } |
| if (combo != null && !combo.isDisposed()) { |
| updateComboWithOptions(); |
| select(getValue(), getValueLabel()); |
| if (combo.getSelectionIndex() >= 0) { |
| selectionChanged(combo.getSelectionIndex()); |
| } |
| } |
| TaskAttribute requestee = getTaskAttribute().getAttribute("requestee"); //$NON-NLS-1$ |
| if (requestee != null) { |
| if (requesteeROText != null && !requesteeROText.isDisposed()) { |
| requesteeROText.setText(requestee.getValue()); |
| } |
| if (requesteeText != null && !requesteeText.isDisposed()) { |
| requesteeText.setText(requestee.getValue()); |
| } |
| } |
| updateLabel(); |
| if (flagComposite != null && !flagComposite.isDisposed()) { |
| flagComposite.layout(); |
| } |
| } |
| |
| @Override |
| public boolean shouldAutoRefresh() { |
| return !suppressRefresh; |
| } |
| |
| private void selectionChanged(int index) { |
| if (requesteeText != null) { |
| requesteeText.setEnabled(values[index].equals("?")); //$NON-NLS-1$ |
| selfLink.setEnabled(values[index].equals("?")); //$NON-NLS-1$ |
| } |
| } |
| } |