/******************************************************************************* * Copyright (c) 2008 * The code, documentation and other materials contained herein have been * licensed under the Eclipse Public License - v 1.0 by the individual * copyright holders listed below, as Initial Contributors under such license. * The text of such license is available at * http://www.eclipse.org/legal/epl-v10.html. * * Contributors: * Henrik Lindberg *******************************************************************************/ package org.eclipse.equinox.p2.authoring; import java.util.EventObject; import org.eclipse.equinox.p2.authoring.forms.EditAdapter; import org.eclipse.equinox.p2.authoring.forms.Mutator; import org.eclipse.equinox.p2.authoring.forms.RichDetailsPage; import org.eclipse.equinox.p2.authoring.forms.validators.IEditValidator; import org.eclipse.equinox.p2.authoring.forms.validators.NullValidator; import org.eclipse.equinox.p2.authoring.internal.IEditEventBusProvider; import org.eclipse.equinox.p2.authoring.internal.IEditorEventBus; import org.eclipse.equinox.p2.authoring.internal.IEditorListener; import org.eclipse.equinox.p2.authoring.internal.InstallableUnitBuilder; import org.eclipse.equinox.p2.authoring.internal.ModelChangeEvent; import org.eclipse.equinox.p2.authoring.internal.InstallableUnitBuilder.Parameter; import org.eclipse.equinox.p2.authoring.internal.InstallableUnitBuilder.TouchpointActionBuilder; import org.eclipse.equinox.p2.authoring.internal.InstallableUnitBuilder.TouchpointTypeBuilder; import org.eclipse.equinox.p2.authoring.spi.ITouchpointActionDescriptor; import org.eclipse.equinox.p2.authoring.spi.ITouchpointActionParameterDescriptor; import org.eclipse.equinox.p2.authoring.spi.ITouchpointTypeDescriptor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; 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.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.FormColors; import org.eclipse.ui.forms.IFormPart; import org.eclipse.ui.forms.editor.IFormPage; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; /** * A Detail page for p2 Touchpoint Action tree nodes. * * @author Henrik Lindberg * */ public class TouchpointActionPage extends RichDetailsPage { private static final String ACTION_TEXT = "actionText"; /** The currently selected input. */ private TouchpointActionBuilder m_input; private static int MAX_PARAMETERS = 5; /** The dynamic labels, changed depending on the displayed action */ private Label m_labels[] = new Label[MAX_PARAMETERS]; /** The dynamic labels, changed depending on the displayed action */ private Text m_texts[] = new Text[MAX_PARAMETERS]; /** Parameter info from meta data descriptors, updated based on selected type, and * selected action. */ private ParameterInfo m_params[]; /** Composite that needs re-layout when labels are changed. */ private Composite m_sectionClient; /** The current action descriptor. */ private ITouchpointActionDescriptor m_actionDesc; /** A label showing a warning message if the selected action is not applicable for the touchpoint type */ private Label m_warningLabel; /** The validator to use for parameter values */ private ParameterValidator m_parameterValidator; private TouchpointTypeBuilder m_lastTouchpointType; public TouchpointActionPage() { // initialize the parameter info with default stuff m_params = new ParameterInfo[MAX_PARAMETERS]; for(int i = 0; i < m_params.length;i++) m_params[i] = new ParameterInfo("param"+Integer.toString(i+1)); m_parameterValidator = new ParameterValidator(); } public void createContents(Composite parent) { TableWrapLayout lo = new TableWrapLayout(); lo.leftMargin = 0; lo.rightMargin = 0; lo.topMargin = 0; lo.numColumns = 1; parent.setLayout(lo); FormToolkit toolkit = m_mform.getToolkit(); Section section = toolkit.createSection(parent, // // Section.DESCRIPTION | // Section.TITLE_BAR | // Section.EXPANDED); TableWrapData td = new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP) ; td.colspan = 1; section.setLayoutData(td); section.setText("Touchpoint Action"); m_sectionClient = toolkit.createComposite(section); GridLayout layout = new GridLayout(2, false); m_sectionClient.setLayout(layout); FormColors colors = toolkit.getColors(); Color headerColor = colors.getColor("org.eclipse.ui.forms.TITLE"); // Include a label that is used to signal that this action is not described in the // currently selected touchpoint. m_warningLabel = toolkit.createLabel(m_sectionClient, ""); m_warningLabel.setLayoutData(new GridData(SWT.LEFT, SWT.TOP,true,false,2,1)); m_warningLabel.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED)); m_warningLabel.setText("Action not applicable to selected touchpoint type."); m_warningLabel.setVisible(false); // -- ACTION NAME Label label = toolkit.createLabel(m_sectionClient, "Action:"); label.setForeground(headerColor); Text actionText = toolkit.createText(m_sectionClient, ""); actionText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); m_editAdapters.createEditAdapter(ACTION_TEXT, actionText, //$NON-NLS-1$ NullValidator.instance(), new Mutator() { @Override public String getValue() { return m_input != null && m_input.getActionKey() != null ? m_input.getActionKey() : ""; //$NON-NLS-1$ } @Override public void setValue(String input) throws Exception { // Do nothing - action text can not be changed } }); // The action key/action name can not be changed - disable it m_editAdapters.getAdapter(ACTION_TEXT).setEnabled(false); // -- LABEL TEXT for(int i = 0; i < MAX_PARAMETERS; i++) { m_labels[i] = toolkit.createLabel(m_sectionClient, m_params[i].label + ":"); m_labels[i].setForeground(headerColor); m_texts[i] = toolkit.createText(m_sectionClient, ""); m_texts[i].setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); m_editAdapters.createEditAdapter(getIndexedEditAdapterKey(i), m_texts[i], //$NON-NLS-1$ m_parameterValidator, new IndexedMutator(i)); } section.setClient(m_sectionClient); // Add listener to touchpoint type change so that labels and errors can be displayed // IEditorEventBus eventBus = ((IEditEventBusProvider)toolkit).getEventBus(); eventBus.addListener(new IEditorListener(){ public void notify(EventObject o) { if(!(o instanceof ModelChangeEvent)) return; Object detail = ((ModelChangeEvent)o).getDetail(); if(detail instanceof InstallableUnitBuilder) { TouchpointTypeBuilder type = ((InstallableUnitBuilder)detail).getTouchpointType(); if(type != m_lastTouchpointType) refreshLabels(); } } }); } private String getIndexedEditAdapterKey(int index) { return "text"+Integer.toString(index); } /** * Mutator for an indexed parameter * @author Henrik Lindberg * */ private class IndexedMutator extends Mutator { private final int m_index; IndexedMutator(int index) { m_index = index; } @Override public String getValue() { // disabled fields are not in use. if(!m_editAdapters.getAdapter(getIndexedEditAdapterKey(m_index)).isEnabled()) return ""; return m_input != null && m_input.getParameter(m_params[m_index].name) != null ? m_input.getParameter(m_params[m_index].name) : ""; //$NON-NLS-1$ } @Override public void setValue(String input) throws Exception { if(m_input == null) return; // disabled fields are not in use if(!m_editAdapters.getAdapter(getIndexedEditAdapterKey(m_index)).isEnabled()) return; m_input.setParameter(m_params[m_index].name, input == null ? "" : input); //$NON-NLS-1$ } } /** * The ParameterValidator filters out "," from the input. * @author Henrik Lindberg */ public class ParameterValidator implements IEditValidator { public String inputFilter(String input) { if(input.indexOf(',') == -1) return null; else return input.replace(",", ""); } public boolean isValid(String input, EditAdapter editAdapter) { editAdapter.clearMessages(); return true; } } public void setFocus() { // sets focus on first parameter (may be hidden - but that is ok). m_texts[0].setFocus(); } @Override public void selectionChanged(IFormPart part, ISelection selection) { IStructuredSelection ssel = (IStructuredSelection)selection; m_input = null; // clear old input if(ssel.size() == 1 && ssel.getFirstElement() instanceof TouchpointActionBuilder) { m_input = (TouchpointActionBuilder)ssel.getFirstElement(); refreshLabels(); } refresh(); } /** * Update the labels to reflect the action parameters, and hide unused parameter fields */ private void refreshLabels() { Parameter[] parameters = m_input.getParameters(); IFormPage formPage = (IFormPage)m_mform.getContainer(); m_lastTouchpointType = ((InstallableUnitEditor)formPage.getEditor()).getInstallableUnit().getTouchpointType(); ITouchpointTypeDescriptor desc = P2AuthoringUIPlugin.getDefault().getTouchpointType(m_lastTouchpointType); m_actionDesc = desc.getActionDescriptor(m_input.getActionKey()); int i = 0; for(; i < parameters.length && i < MAX_PARAMETERS; i++) { // the param name is always from the IU data. m_params[i].name = parameters[i].getName(); // pick up label and type from meta data descriptor if(m_actionDesc != null) { ITouchpointActionParameterDescriptor paramDesc = m_actionDesc.getParameter(parameters[i].getName()); m_params[i].label = paramDesc.getLabel(); m_params[i].type = paramDesc.getType(); } else { m_params[i].label = m_params[i].name; m_params[i].type = ITouchpointActionParameterDescriptor.TYPE_STRING; } m_warningLabel.setVisible(m_actionDesc == null); // TODO: set the validation type for the text field // TODO: hook advanced (browse) function to applicable types m_labels[i].setText(m_params[i].label + ":"); m_labels[i].setVisible(true); m_texts[i].setVisible(true); m_editAdapters.getAdapter(getIndexedEditAdapterKey(i)).setEnabled(true); } for(; i < MAX_PARAMETERS; i++) { m_labels[i].setVisible(false); m_texts[i].setVisible(false); m_editAdapters.getAdapter(getIndexedEditAdapterKey(i)).setEnabled(false); } // Labels may have different width m_sectionClient.layout(); } /** Convenient structure for parameter info */ private static class ParameterInfo { public String label; public String name; public String type; ParameterInfo(String paramName) { label = name = paramName; type = ITouchpointActionParameterDescriptor.TYPE_STRING; } } }