package copyto.target.http.ui.internal; import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.Collections; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.beans.BeansObservables; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.observable.value.WritableValue; import org.eclipse.core.databinding.property.INativePropertyListener; import org.eclipse.core.databinding.property.ISimplePropertyListener; import org.eclipse.core.databinding.property.NativePropertyListener; import org.eclipse.core.databinding.property.Properties; import org.eclipse.core.databinding.property.value.IValueProperty; import org.eclipse.core.databinding.property.value.SimpleValueProperty; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.databinding.viewers.CellEditorProperties; import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.CheckboxCellEditor; import org.eclipse.jface.viewers.ComboBoxCellEditor; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ICellEditorListener; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import org.osgi.framework.FrameworkUtil; import copyto.core.TargetParam; import copyto.core.models.BooleanTargetParamModel; import copyto.core.models.ChoiceTargetParamModel; import copyto.core.models.StringTargetParamModel; import copyto.target.http.core.HttpTarget; import copyto.target.http.core.internal.html.form.Form; import copyto.target.http.core.internal.html.form.FormParser; import copyto.target.http.core.internal.html.form.HtmlElement; import copyto.target.http.core.internal.html.form.SelectElement; import copyto.target.http.core.internal.html.form.TextAreaElement; import eclipseutils.jface.databinding.TableEditor; class ParamsViewer extends TableEditor<TargetParam<?>> { private IObservableValue hostValue; private final LocalResourceManager resources = new LocalResourceManager(JFaceResources.getResources()); @SuppressWarnings("unchecked") protected ParamsViewer(HttpTarget target, IObservableValue hostValue, Composite parent) { super(parent, BeansObservables.observeList(target, "params", TargetParam.class), 0); this.hostValue = hostValue; parent.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { resources.dispose(); } }); } @Override protected int getTableStyles() { return super.getTableStyles() | SWT.CHECK; } @Override protected String[] getColumnNames() { return new String[] { "name", "labelValue", "readOnly" }; } @Override protected String[] getColumnLabels() { return new String[] { "Name", "Value", "Show in UI" }; } @Override protected TargetParam<?> createItem(Shell shell) { return new StringTargetParamModel("name", "value"); } class ParamValueEditingSupport extends ObservableValueEditingSupport { TableViewer viewer; public ParamValueEditingSupport(TableViewer viewer, DataBindingContext dbc) { super(viewer, dbc); this.viewer = viewer; } @Override protected CellEditor getCellEditor(Object element) { if (element instanceof BooleanTargetParamModel) { return new CheckboxCellEditor(viewer.getTable()); } if (element instanceof ChoiceTargetParamModel) { String[] values = ((ChoiceTargetParamModel) element) .getValues(); return new ComboBoxCellEditor(viewer.getTable(), values); } return new TextCellEditor(viewer.getTable()); } @Override protected IObservableValue doCreateCellEditorObservable( CellEditor cellEditor) { if (cellEditor instanceof TextCellEditor) { return SWTObservables.observeText(cellEditor.getControl(), SWT.Modify); } if (cellEditor instanceof ComboBoxCellEditor || cellEditor instanceof CheckboxCellEditor) { return SWTObservables.observeSelection(cellEditor.getControl()); } return null; } @Override protected IObservableValue doCreateElementObservable(Object element, ViewerCell cell) { if (element instanceof ChoiceTargetParamModel) { final ChoiceTargetParamModel targetParam = (ChoiceTargetParamModel) element; return new WritableValue(targetParam.getLabelValue(), String.class) { @Override public void doSetValue(Object value) { targetParam.setValue(value.toString()); } }; } return BeansObservables.observeValue(element, "value"); } } @Override protected IBaseLabelProvider getLabelProvider( ObservableListContentProvider contentProvider) { return new ObservableMapLabelProvider(Properties.observeEach( contentProvider.getKnownElements(), BeanProperties .values(getColumnNames()))) { @Override public Image getColumnImage(Object element, int columnIndex) { if (columnIndex == 1 && element instanceof ChoiceTargetParamModel) { ChoiceTargetParamModel param = (ChoiceTargetParamModel) element; if (!param.isKnownValue()) { return FieldDecorationRegistry.getDefault() .getFieldDecoration( FieldDecorationRegistry.DEC_WARNING) .getImage(); } } return super.getColumnImage(element, columnIndex); } @Override public String getColumnText(Object element, int columnIndex) { if (columnIndex == 2) { return ((TargetParam<?>) element).isReadOnly() ? "yes" : "no"; } return super.getColumnText(element, columnIndex); } }; } public class CellEditorValueProperty extends SimpleValueProperty { private final CellEditor editor; private final Object valueType; /** * @param editor * @param valueType */ public CellEditorValueProperty(CellEditor editor, Object valueType) { this.editor = editor; this.valueType = valueType; } public Object getValueType() { return valueType; } protected Object doGetValue(Object source) { return ((CellEditor) source).getValue(); } protected void doSetValue(Object source, Object value) { ((CellEditor) source).setValue(value); } public INativePropertyListener adaptListener( ISimplePropertyListener listener) { return new Listener(listener); } private class Listener extends NativePropertyListener implements ICellEditorListener { public Listener(ISimplePropertyListener listener) { super(CellEditorValueProperty.this, listener); } protected void doAddTo(Object source) { Assert.isTrue(editor == source, "Expected " + editor //$NON-NLS-1$ + " as property source but received " + source); //$NON-NLS-1$ editor.addListener(this); } protected void doRemoveFrom(Object source) { Assert.isTrue(editor == source, "Expected " + editor //$NON-NLS-1$ + " as property source but received " + source); //$NON-NLS-1$ editor.removeListener(this); } public void applyEditorValue() { fireChange(editor, null); } public void cancelEditor() { } public void editorValueChanged(boolean oldValidState, boolean newValidState) { fireStale(editor); } } public String toString() { return "CellEditor.value <" + valueType + ">"; //$NON-NLS-1$ //$NON-NLS-2$ } } @Override protected EditingSupport createEditingSupport(String name, TableViewer viewer, DataBindingContext context) { if ("name".equals(name)) { IValueProperty cellEditorControlText = CellEditorProperties .control().value(WidgetProperties.text()); return ObservableValueEditingSupport.create(viewer, context, new TextCellEditor(viewer.getTable()), cellEditorControlText, BeanProperties.value( TargetParam.class, name)); } if ("labelValue".equals(name)) { return new ParamValueEditingSupport(viewer, context); } if ("readOnly".equals(name)) { CheckboxCellEditor cellEditor = new CheckboxCellEditor(viewer .getTable()); IValueProperty cellEditorControlText = new CellEditorValueProperty( cellEditor, boolean.class); return ObservableValueEditingSupport.create(viewer, context, cellEditor, cellEditorControlText, BeanProperties.value( TargetParam.class, name)); } return super.createEditingSupport(name, viewer, context); } @Override protected void createCustomButtons(Composite parent) { final Button button = createPushButton(parent, "Auto Detect..."); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { FormParser parser = new FormParser(); try { URL url = new URL(hostValue.getValue().toString()); Collection<Form> forms = parser.parse(url); if (forms.size() > 0) { Form form = forms.size() == 1 ? forms.iterator().next() : AutoDetectResultDialog.select(button .getShell(), url, forms); if (form != null) { clear(); for (HtmlElement element : form.getElements()) { String value = element .getAttribute("value", ""); if (element instanceof TextAreaElement) { value = "${copyto.text}"; } TargetParam<?> param; if (element instanceof SelectElement) { SelectElement selectElement = (SelectElement) element; param = new ChoiceTargetParamModel(element .getName(), selectElement .getOptions()); ((ChoiceTargetParamModel) param) .setValue(selectElement .getSelected()); } else { param = new StringTargetParamModel(element .getName(), value); } add(param, true); } hostValue.setValue(url.toString() + form.getAction()); } } } catch (MalformedURLException e) { } } }); } abstract class AddAction extends Action { public AddAction(String text, String imagePath) { super(text); ImageDescriptor image = JFaceResources.getImageRegistry().getDescriptor(imagePath); if (image == null) { URL url = FileLocator.find(FrameworkUtil.getBundle(getClass()), new Path(imagePath), null); if (url != null) { image = ImageDescriptor.createFromURL(url); if (image != null) { JFaceResources.getImageRegistry().put(imagePath, image); } } } setImageDescriptor(image); } @Override public final void run() { add((TargetParam<?>) createItem(), true); } protected abstract TargetParam<?> createItem(); } protected void fillAddButtonMenu(IMenuManager menu) { menu.add(new AddAction("String", "$nl$/icons/ui-text-field.png") { @Override protected TargetParam<?> createItem() { return new StringTargetParamModel("name", "value"); } }); menu.add(new AddAction("Boolean", "$nl$/icons/ui-check-box.png") { @Override protected TargetParam<?> createItem() { return new BooleanTargetParamModel("name", true, Boolean .toString(true)); } }); menu.add(new AddAction("Choice", "$nl$/icons/ui-combo-box.png") { @SuppressWarnings("unchecked") @Override protected TargetParam<?> createItem() { return new ChoiceTargetParamModel("name", Collections.EMPTY_MAP); } }); } }