/**************************************************************************
* ERA - Eclipse Requirements Analysis
* ==============================================
* Copyright (C) 2009-2013 by Georg Blaschke, Christoph P. Neumann
* and Bernd Haberstumpf (http://era.origo.ethz.ch)
**************************************************************************
* Licensed under the Eclipse Public License - v 1.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.eclipse.org/org/documents/epl-v10.html
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**************************************************************************
*/
package era.foss.typeeditor.spectype;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.databinding.FeaturePath;
import org.eclipse.emf.databinding.IEMFListProperty;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.CellEditorProperties;
import org.eclipse.jface.databinding.viewers.IViewerObservableValue;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapCellLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ComboBoxViewerCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import era.foss.erf.AttributeDefinition;
import era.foss.erf.AttributeValueSimple;
import era.foss.erf.DatatypeDefinition;
import era.foss.erf.ErfPackage;
import era.foss.erf.SpecType;
import era.foss.typeeditor.common.AbstractErfTypesForm;
import era.foss.typeeditor.common.AddDeleteTableViewer;
import era.foss.typeeditor.common.Ui;
/**
* A form for editing the {@link SpecType}.
* <p>
* At the moment there exists exactly one {@link SpecType} in an ERA ERF model. The form holds a reference to this
* single {@link SpecType}.
* <p>
* Each {@link SpecType} essentially consists of list of {@link AttributeDefinition}s which are linked to a
* {@link DatatypeDefinition}.
* <p>
* The inner class {@link .AttributesAdapterFactoryContentProvider} is registered to the {@link AddDeleteTableViewer}
* and extracts all {@link AttributeDefinition}s for a {@link SpecType} from the ERF model -- by the {@link SpecType}'s
* reference named "specAttributes".
* <p>
* The inner class {@link .AttributesLabelProvider} is registered to the {@link AddDeleteTableViewer} and provides the
* cell values from the {@link AttributeDefinition} element.
*
* @see SpecType
* @see AttributeDefinition
* @see AttributeValueSimple
*/
public class SpecTypeForm extends AbstractErfTypesForm {
/** Table viewer showing the attributes of a SpecType. */
private AddDeleteTableViewer specAttributeTableViewer;
/** object for create data binding from model to UI widgets */
private DataBindingContext dataBindContext;
/** object for creating and binding ui elements. */
private Ui ui;
private IViewerObservableValue specTypeMaster;
/**
* Instantiates a new spec type form.
*
* @param parent the parent
* @param editor the editor
*/
public SpecTypeForm( Composite parent, IEditorPart editor ) {
super( parent, editor, SWT.NONE );
dataBindContext = new DataBindingContext();
ui = new Ui( editingDomain );
// set-up layout
GridLayout gridLayout = new GridLayout( 3, true );
this.setLayout( gridLayout );
// set up table viewer for attributes of the selected SpecType
createSpecTypeTableViewer();
// set up table viewer for attributes of the selected SpecType
createSpecAttributeTableViewer();
// set up viewer for details of a SpecAttribitute
createSpecAttributeDetailViewer();
}
/**
* Create table viewer showing the SpecTypes
*/
private void createSpecTypeTableViewer() {
AddDeleteTableViewer specTypeTableViewer = new AddDeleteTableViewer( this, SWT.MULTI
| SWT.V_SCROLL
| SWT.BORDER
| SWT.FULL_SELECTION );
specTypeTableViewer.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
specTypeTableViewer.setEditingDomain( editingDomain );
specTypeTableViewer.setElementInformation( erfModel.getCoreContent(),
ErfPackage.Literals.CONTENT__SPEC_TYPES,
ErfPackage.Literals.SPEC_TYPE );
ObservableListContentProvider cp = new ObservableListContentProvider();
specTypeTableViewer.setContentProvider( cp );
TableColumnLayout columnLayout = (TableColumnLayout)specTypeTableViewer.getTable().getParent().getLayout();
// create column with name of the SpecType
TableViewerColumn nameColumn = new TableViewerColumn( specTypeTableViewer, SWT.NONE );
columnLayout.setColumnData( nameColumn.getColumn(), new ColumnWeightData( 100, 70 ) );
nameColumn.getColumn().setResizable( false );
nameColumn.getColumn().setMoveable( false );
nameColumn.getColumn().setText( Ui.getUiName( ErfPackage.Literals.IDENTIFIABLE__LONG_NAME ) );
EStructuralFeature[] structuralFeature = {ErfPackage.Literals.IDENTIFIABLE__LONG_NAME};
ui.bindColumn( nameColumn, structuralFeature );
// provide input for the table
IEMFListProperty specTypeProperty = EMFProperties.list( ErfPackage.Literals.CONTENT__SPEC_TYPES );
specTypeTableViewer.setInput( specTypeProperty.observe( erfModel.getCoreContent() ) );
specTypeTableViewer.getTable().select( 0 );
this.specTypeMaster = ViewerProperties.singleSelection().observe( specTypeTableViewer );
}
/**
* Create Table viewer showing attributes of the selected SpecType
*/
private void createSpecAttributeTableViewer() {
specAttributeTableViewer = new AddDeleteTableViewer( this, SWT.MULTI
| SWT.V_SCROLL
| SWT.BORDER
| SWT.FULL_SELECTION ) {
@Override
public void addElement() {
this.elementOwner = (EObject)specTypeMaster.getValue();
super.addElement();
}
};
specAttributeTableViewer.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
specAttributeTableViewer.setEditingDomain( editingDomain );
specAttributeTableViewer.setElementInformation( (EObject)specTypeMaster.getValue(),
ErfPackage.Literals.SPEC_TYPE__SPEC_ATTRIBUTES,
ErfPackage.Literals.ATTRIBUTE_DEFINITION_SIMPLE );
ObservableListContentProvider contentProvider = new ObservableListContentProvider();
specAttributeTableViewer.setContentProvider( contentProvider );
TableColumnLayout columnLayout = (TableColumnLayout)specAttributeTableViewer.getTable()
.getParent()
.getLayout();
// create column with name of attribute definition
createSpecAttributeNameColumn( specAttributeTableViewer, columnLayout );
// create column with reference to datatype defintion
createSpecAttributeTypeColumn( specAttributeTableViewer, columnLayout );
// provide input for the table
IEMFListProperty specAttributeProperty = EMFProperties.list( ErfPackage.Literals.SPEC_TYPE__SPEC_ATTRIBUTES );
specAttributeTableViewer.setInput( specAttributeProperty.observeDetail( specTypeMaster ) );
specAttributeTableViewer.getTable().select( 0 );
}
/** Create column for selecting the DatatypeDefinition associated with the AttributeDefinition */
private void createSpecAttributeNameColumn( AddDeleteTableViewer specAttributeTableViewer,
TableColumnLayout columnLayout ) {
//
TableViewerColumn nameColumn = new TableViewerColumn( specAttributeTableViewer, SWT.NONE );
nameColumn.getColumn().setText( Ui.getUiName( ErfPackage.Literals.IDENTIFIABLE__LONG_NAME ) );
nameColumn.getColumn().setResizable( true );
nameColumn.getColumn().setMoveable( false );
columnLayout.setColumnData( nameColumn.getColumn(), new ColumnWeightData( 34, 100 ) );
IValueProperty nameColumnElementProperty = EMFEditProperties.value( editingDomain,
ErfPackage.Literals.IDENTIFIABLE__LONG_NAME );
// add label provider
IObservableMap nameColumnAttributeMap = nameColumnElementProperty.observeDetail( ((ObservableListContentProvider)specAttributeTableViewer.getContentProvider()).getKnownElements() );
nameColumn.setLabelProvider( new ObservableMapCellLabelProvider( nameColumnAttributeMap ) );
// add editing support
IValueProperty nameColumnCellEditorProperty = CellEditorProperties.control()
.value( WidgetProperties.text( SWT.Modify ) );
EditingSupport editingSupport = ObservableValueEditingSupport.create( specAttributeTableViewer,
dataBindContext,
new TextCellEditor(
specAttributeTableViewer.getTable() ),
nameColumnCellEditorProperty,
nameColumnElementProperty );
nameColumn.setEditingSupport( editingSupport );
}
/** Create column for selecting the DatatypeDefinition associated with the AttributeDefinition */
private void createSpecAttributeTypeColumn( TableViewer specAttributeTableViewer, TableColumnLayout columnLayout ) {
TableViewerColumn dataTypeColumn = new TableViewerColumn( specAttributeTableViewer, SWT.NONE );
dataTypeColumn.getColumn().setText( Ui.getUiName( ErfPackage.Literals.ATTRIBUTE_DEFINITION__TYPE ) );
dataTypeColumn.getColumn().setResizable( false );
dataTypeColumn.getColumn().setMoveable( false );
columnLayout.setColumnData( dataTypeColumn.getColumn(), new ColumnWeightData( 33, 100 ) );
IValueProperty dataTypeNameProperty = EMFEditProperties.value( editingDomain,
FeaturePath.fromList( new EStructuralFeature[]{
ErfPackage.Literals.ATTRIBUTE_DEFINITION__TYPE,
ErfPackage.Literals.IDENTIFIABLE__LONG_NAME} ) );
// add label provider
ObservableMapCellLabelProvider labelProvider = new ObservableMapCellLabelProvider(
dataTypeNameProperty.observeDetail( ((ObservableListContentProvider)specAttributeTableViewer.getContentProvider()).getKnownElements() ) );
dataTypeColumn.setLabelProvider( labelProvider );
// add editing support
dataTypeColumn.setEditingSupport( new AttributeDefinitionTypeEditingSupport( specAttributeTableViewer ) );
}
/**
* create detailed viewer for selected element.
*/
private void createSpecAttributeDetailViewer() {
// setup Data type properties viewer
AttributeDefinitionDetailViewer detailViewer = new AttributeDefinitionDetailViewer(
this,
SWT.NONE,
editingDomain,
ViewerProperties.singleSelection().observe( specAttributeTableViewer ) );
detailViewer.setLayoutData( new GridData( SWT.FILL, SWT.FILL, true, true ) );
}
/**
* The Class DatatypeDefinitionEditingSupport.
*/
private class AttributeDefinitionTypeEditingSupport extends EditingSupport {
/** The cell editor. */
private CellEditor cellEditor;
/**
* Instantiates a new datatype definition editing support.
*
* @param viewer the viewer
* @param column the column
*/
public AttributeDefinitionTypeEditingSupport( ColumnViewer viewer ) {
super( viewer );
ComboBoxViewerCellEditor comboCellEditor = new ComboBoxViewerCellEditor(
((TableViewer)viewer).getTable(),
SWT.READ_ONLY );
// set content provider
ObservableListContentProvider contentProvider = new ObservableListContentProvider();
comboCellEditor.setContentProvider( contentProvider );
// set label provider
comboCellEditor.setLabelProvider( new ObservableMapLabelProvider(
EMFProperties.value( ErfPackage.Literals.IDENTIFIABLE__LONG_NAME )
.observeDetail( contentProvider.getKnownElements() ) ) );
IEMFListProperty dataTypeDefinitions = EMFProperties.list( ErfPackage.Literals.CONTENT__DATA_TYPES );
comboCellEditor.setInput( dataTypeDefinitions.observe( erfModel.getCoreContent() ) );
this.cellEditor = comboCellEditor;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang.Object)
*/
@Override
protected boolean canEdit( Object element ) {
return true;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.EditingSupport#getCellEditor(java.lang.Object)
*/
@Override
protected CellEditor getCellEditor( Object element ) {
return this.cellEditor;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.EditingSupport#getValue(java.lang.Object)
*/
@Override
protected Object getValue( Object element ) {
return ((AttributeDefinition)element).getType();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object, java.lang.Object)
*/
@Override
protected void setValue( Object element, Object value ) {
assert (element instanceof AttributeDefinition);
AttributeDefinition attributeDefinition = (AttributeDefinition)element;
assert (value instanceof DatatypeDefinition);
DatatypeDefinition newDatatypeDefinition = (DatatypeDefinition)value;
if( newDatatypeDefinition != null
&& attributeDefinition.getType() != null
&& attributeDefinition.getType().getID() == newDatatypeDefinition.getID() ) {
// do nothing as exactly the same Datatype has been set as it was before
return;
}
EList<Adapter> l = new BasicEList<Adapter>( attributeDefinition.eAdapters() );
attributeDefinition.eAdapters().clear();
// set selected DatatypeDefintion
Command setCommand = new SetCommand(
editingDomain,
attributeDefinition,
ErfPackage.Literals.ATTRIBUTE_DEFINITION__TYPE,
newDatatypeDefinition );
editingDomain.getCommandStack().execute( setCommand );
// adapt AttributeDefintion to selected datatypeDefinition
AttributeDefinition newAttributeDefinition = adaptAttributeDefintion( attributeDefinition );
if( attributeDefinition.eClass().getClassifierID() != newAttributeDefinition.eClass().getClassifierID() ) {
// reset the cellEditor (remember: there is only one object, which handles all cell in its row)
// because the selected value must not propagate if another row is selected
((ComboBoxViewerCellEditor)this.cellEditor).setValue( null );
((CCombo)((ComboBoxViewerCellEditor)this.cellEditor).getControl()).clearSelection();
// set the selection of the viewer to the newly created AttributeDefintion object
super.getViewer().setSelection( new StructuredSelection( newAttributeDefinition ) );
} else {
attributeDefinition.eAdapters().addAll( l );
}
// refresh the tableViewer
super.getViewer().refresh();
}
}
}