package net.enilink.komma.edit.ui.celleditor; import net.enilink.komma.common.ui.celleditor.TextCellEditorWithContentProposal; import net.enilink.komma.core.IEntity; import net.enilink.komma.core.IStatement; import net.enilink.komma.edit.domain.IEditingDomain; import net.enilink.komma.edit.properties.EditingHelper; import net.enilink.komma.edit.properties.IEditingSupport; import net.enilink.komma.edit.properties.IResourceProposal; import net.enilink.komma.edit.ui.assist.JFaceContentProposal; import net.enilink.komma.em.concepts.IProperty; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalListener; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.ICellEditorListener; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Tree; /** * An abstract base class for editing of cells which represent RDF statements. */ public abstract class PropertyCellEditingSupport extends EditingSupport { private static final int PROPOSAL_DELAY = 1000; protected EditingHelper.Type type; protected EditingHelper helper; private Object currentElement; private TextCellEditorWithContentProposal textCellEditor; private IResourceProposal acceptedResourceProposal; private ICellEditorListener cellEditorListener = new ICellEditorListener() { @Override public void editorValueChanged(boolean oldValidState, boolean newValidState) { // user modifications reset the last value proposal acceptedResourceProposal = null; } @Override public void cancelEditor() { applyEditorValue(); } @Override public void applyEditorValue() { // ensure that initial state is restored editorClosed(currentElement); } }; public PropertyCellEditingSupport(ColumnViewer viewer) { this(viewer, EditingHelper.Type.VALUE, SWT.NONE); } public PropertyCellEditingSupport(final ColumnViewer viewer, EditingHelper.Type type, final int cellEditorStyle) { super(viewer); this.type = type; helper = new EditingHelper(type) { @Override protected IEditingDomain getEditingDomain() { return PropertyCellEditingSupport.this.getEditingDomain(); } @Override protected void setProperty(Object element, IProperty property) { PropertyCellEditingSupport.this.setProperty(currentElement, property); } @Override protected IEditingSupport getEditingSupport(Object element) { IEditingSupport support = PropertyCellEditingSupport.this .getEditingSupport(element); return support != null ? support : super .getEditingSupport(element); } }; textCellEditor = new TextCellEditorWithContentProposal( (Composite) viewer.getControl(), cellEditorStyle | SWT.BORDER, null, null) { @Override public void deactivate() { fireApplyEditorValue(); super.deactivate(); } protected void focusLost() { } @Override public LayoutData getLayoutData() { LayoutData layoutData = super.getLayoutData(); if ((cellEditorStyle & SWT.MULTI) != 0) { layoutData.verticalAlignment = SWT.TOP; layoutData.minimumHeight = getItemHeight() * 6; } else { // required for editors with SWT.SINGLE layoutData.minimumHeight = 0; } return layoutData; } }; textCellEditor.getContentProposalAdapter().setAutoActivationDelay( PROPOSAL_DELAY); textCellEditor.getContentProposalAdapter().addContentProposalListener( new IContentProposalListener() { @Override public void proposalAccepted(IContentProposal proposal) { Object delegate = proposal instanceof JFaceContentProposal ? ((JFaceContentProposal) proposal) .getDelegate() : proposal; if (delegate instanceof IResourceProposal && ((IResourceProposal) delegate) .getUseAsValue()) { acceptedResourceProposal = (IResourceProposal) delegate; } } }); textCellEditor.addListener(cellEditorListener); } protected int getItemHeight() { Control control = getViewer().getControl(); if (control instanceof Tree) { return ((Tree) control).getItemHeight(); } if (control instanceof Table) { return ((Table) control).getItemHeight(); } return 0; } @Override protected boolean canEdit(Object element) { return helper.canEdit(getStatement(element)); } @Override protected CellEditor getCellEditor(Object element) { acceptedResourceProposal = null; currentElement = unwrap(element); CellEditorHelper.updateProposals(textCellEditor, helper.getProposalSupport(getStatement(currentElement))); return textCellEditor; } protected IEditingSupport getEditingSupport(Object element) { return null; } protected Object unwrap(Object itemOrData) { if (itemOrData instanceof Item) { return ((Item) itemOrData).getData(); } return itemOrData; } /** * Returns the editing domain for executing commands. */ abstract protected IEditingDomain getEditingDomain(); /** * Returns the statement that is represented by the current cell. */ abstract protected IStatement getStatement(Object element); /** * Notifies that the editor for the given element was recently closed. */ protected void editorClosed(Object element) { } /** * Assigns a property to an element if operating in property editing mode. */ protected void setProperty(Object element, IProperty property) { } /** * Notifies about the resulting status of an editing operation and related * commands. */ protected void setEditStatus(Object element, IStatus status, Object value) { } @Override protected Object getValue(Object element) { return helper.getValue(getStatement(unwrap(element))); } @Override protected void setValue(Object element, Object value) { if (value == null || value.equals(getValue(element))) { return; } if (acceptedResourceProposal != null) { value = acceptedResourceProposal.getResource(); } IStatement stmt = getStatement(element); IStatus status = helper.setValue(stmt, ((IEntity) stmt.getSubject()).getEntityManager(), value) .getStatus(); setEditStatus(element, status, value); } }