/******************************************************************************* * Copyright (c) 2006-2013 The RCP Company 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: * The RCP Company - initial API and implementation *******************************************************************************/ /** * */ package com.rcpcompany.uibindings.internal.cellEditors; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ComboBoxCellEditor; import org.eclipse.jface.viewers.ICellEditorListener; import org.eclipse.swt.widgets.Composite; import com.rcpcompany.uibindings.Constants; import com.rcpcompany.uibindings.IBindingContext; import com.rcpcompany.uibindings.ICellEditorFactory; import com.rcpcompany.uibindings.ICellEditorFactoryContext; import com.rcpcompany.uibindings.IUIBindingsPackage; import com.rcpcompany.uibindings.IValueBinding; import com.rcpcompany.uibindings.IValueBindingCell; import com.rcpcompany.uibindings.internal.InternalConstants; import com.rcpcompany.uibindings.internal.observables.IUpdatableObservable; import com.rcpcompany.utils.logging.LogUtils; /** * The default cell editor factory used if no specific factory is specified for a cell. * * @author Tonny Madsen, The RCP Company */ public class SimpleCellEditorFactory implements ICellEditorFactory { /** * Factory methods. */ public static final class Factory { private Factory() { } /** * Returns the singleton factory. * * @return the factory */ public static ICellEditorFactory getFactory() { if (theFactory == null) { theFactory = new SimpleCellEditorFactory(); } return theFactory; } /** * The factory singleton. */ private static ICellEditorFactory theFactory = null; }; /** * Constructs a new factory. */ protected SimpleCellEditorFactory() { } /** * Items argument for the {@link ComboBoxCellEditor}. */ protected static final String[] NO_ITEMS = new String[0]; @Override public CellEditor create(ICellEditorFactoryContext factoryContext) { final IValueBindingCell cell = factoryContext.getCell(); final IValueBinding labelBinding = cell.getLabelBinding(); final IBindingContext context = labelBinding.getContext(); final IObservableValue value = cell.getObjectValue(); String preferredCellEditor = labelBinding.getArgument(Constants.ARG_PREFERRED_CELL_EDITOR, String.class, InternalConstants.CELL_EDITOR_TYPE_CONTROL); /* * The original value of the cell - used it the edit is canceled. */ final Object originalValue = value.getValue(); /* * The simple case: the boolean editor. This case does not have a visible editor... */ if (InternalConstants.CELL_EDITOR_TYPE_BUTTON.equals(preferredCellEditor)) { final Class<?> valueType = labelBinding.getDataType().getDataType(); if (valueType == Boolean.class || valueType == Boolean.TYPE) return new ImmediateCellEditor(new Runnable() { @Override public void run() { final Boolean v = (Boolean) originalValue; value.setValue(v ? false : true); } }); LogUtils.error(labelBinding, "modelType '" + value.getValueType() + "' specifies illegal cell editor type: '" + preferredCellEditor + "'. Assumes " + InternalConstants.CELL_EDITOR_TYPE_TEXT); preferredCellEditor = InternalConstants.CELL_EDITOR_TYPE_TEXT; } /* * The general case: the widget-based editors */ CellEditor ce; final Composite parent = factoryContext.getParent(); if (InternalConstants.CELL_EDITOR_TYPE_STYLED_TEXT.equals(preferredCellEditor)) { ce = new MyStyledTextCellEditor(parent, context); } else if (InternalConstants.CELL_EDITOR_TYPE_DIALOG.equals(preferredCellEditor)) { ce = new DialogControlCellEditor(parent, cell); } else { ce = new ControlCellEditor(parent, cell); } /* * The binding for the text while editing */ final IValueBinding editorBinding = context.addBinding().ui(ce.getControl()).model(value); if (labelBinding.hasArguments()) { editorBinding.getExtraArgumentProviders().add(labelBinding); } if (labelBinding.eIsSet(IUIBindingsPackage.Literals.BINDING__EXTRA_ARGUMENT_PROVIDERS)) { editorBinding.getExtraArgumentProviders().addAll(labelBinding.getExtraArgumentProviders()); } editorBinding.setCell(cell); /* * Check if a special type has been specified for the cell editor */ final String cellEditorType = labelBinding.getArgument(Constants.ARG_CELL_EDITOR_TYPE, String.class, null); if (cellEditorType != null) { editorBinding.type(cellEditorType); } if (ce instanceof ControlCellEditor) { ((ControlCellEditor) ce).setEditorBinding(editorBinding); } else if (ce instanceof DialogControlCellEditor) { ((DialogControlCellEditor) ce).setEditorBinding(editorBinding); } /* * We added a new binding to call finish as well... */ context.finish(); /* * And force an update */ editorBinding.updateUI(); ce.addListener(new ICellEditorListener() { @Override public void editorValueChanged(boolean oldValidState, boolean newValidState) { } @Override public void cancelEditor() { value.setValue(originalValue); editorBinding.updateUI(); editorBinding.dispose(); } @Override public void applyEditorValue() { if (editorBinding.getUIObservable() instanceof IUpdatableObservable) { final IUpdatableObservable u = (IUpdatableObservable) editorBinding.getUIObservable(); u.forceUpdateValue(); } editorBinding.updateUI(); editorBinding.dispose(); } }); return ce; } }