package net.enilink.komma.edit.ui.viewers; import net.enilink.commons.ui.editor.EditorWidgetFactory; import net.enilink.komma.common.adapter.IAdapterFactory; import net.enilink.komma.common.ui.celleditor.TextCellEditorWithContentProposal; import net.enilink.komma.core.IEntity; import net.enilink.komma.core.IReference; import net.enilink.komma.core.IStatement; import net.enilink.komma.core.IStatementPattern; import net.enilink.komma.core.Statement; import net.enilink.komma.edit.IEditImages; import net.enilink.komma.edit.KommaEditPlugin; import net.enilink.komma.edit.domain.IEditingDomain; import net.enilink.komma.edit.properties.EditingHelper; import net.enilink.komma.edit.properties.EditingHelper.Type; 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.edit.ui.celleditor.CellEditorHelper; import net.enilink.komma.edit.ui.provider.ExtendedImageRegistry; import net.enilink.komma.edit.ui.provider.reflective.StatementPatternContentProvider; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalListener; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.viewers.ContentViewer; import org.eclipse.jface.viewers.ICellEditorListener; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.LabelProviderChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import com.google.inject.Inject; import com.google.inject.Provider; public class PropertyViewer extends ContentViewer { private static final int PROPOSAL_DELAY = 1000; private Composite composite; private Label iconLabel; private Text valueText; private TextCellEditorWithContentProposal valueEditor; @Inject(optional = true) protected Provider<IEditingDomain> editingDomainProvider; @Inject(optional = true) protected Provider<IAdapterFactory> adapterFactoryProvider; IEditingSupport editingSupport; protected Object currentElement; private final EditingHelper helper = new EditingHelper(Type.VALUE) { protected IEditingSupport getEditingSupport(Object element) { return editingSupport != null ? editingSupport : super .getEditingSupport(element); } protected IAdapterFactory getAdapterFactory() { return adapterFactoryProvider.get(); } @Override protected IEditingDomain getEditingDomain() { return editingDomainProvider.get(); } }; public PropertyViewer(Composite parent, int textStyle) { this(parent, textStyle, null); } public PropertyViewer(Composite parent, int textStyle, EditorWidgetFactory widgetFactory) { composite = widgetFactory != null ? widgetFactory .createComposite(parent) : new Composite(parent, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); iconLabel = widgetFactory != null ? widgetFactory.createLabel( composite, "") : new Label(composite, SWT.NONE); defaultIcon(iconLabel); if (editingDomainProvider != null) { valueText = widgetFactory != null ? widgetFactory.createText( composite, "") : new Text(composite, textStyle); valueText.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false)); } else { int style = textStyle; if (widgetFactory != null) { style |= widgetFactory.getBorderStyle(); } valueEditor = createCellEditor(composite, style); valueEditor.getControl().setLayoutData( new GridData(SWT.FILL, SWT.BEGINNING, true, false)); if (widgetFactory != null) { widgetFactory.adapt(valueEditor.getControl(), false, false); } } hookControl(composite); setContentProvider(new StatementPatternContentProvider()); } protected TextCellEditorWithContentProposal createCellEditor( Composite parent, final int textStyle) { final IResourceProposal[] acceptedResourceProposal = { null }; final TextCellEditorWithContentProposal textCellEditor = new TextCellEditorWithContentProposal( parent, textStyle, null, null) { @Override public void deactivate() { } protected void focusLost() { } }; 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[0] = (IResourceProposal) delegate; } } }); textCellEditor.addListener(new ICellEditorListener() { @Override public void editorValueChanged(boolean oldValidState, boolean newValidState) { // user modifications reset the last value proposal acceptedResourceProposal[0] = null; } @Override public void cancelEditor() { } @Override public void applyEditorValue() { IStatement stmt = getStatement(currentElement); helper.setValue( stmt, ((IEntity) stmt.getSubject()).getEntityManager(), acceptedResourceProposal[0] != null ? acceptedResourceProposal[0] .getResource() : textCellEditor.getValue()); } }); return textCellEditor; } @Override public Control getControl() { return composite; } @Override public ISelection getSelection() { // not supported return null; } @Override public void setSelection(ISelection selection, boolean reveal) { // not supported } protected IStatement getStatement(Object element) { if (element instanceof IStatement) { return (IStatement) element; } if (element instanceof IStatementPattern) { return fillPattern((IStatementPattern) element, null); } return null; } public void setEditingSupport(IEditingSupport editingSupport) { this.editingSupport = editingSupport; } @Override protected void inputChanged(Object input, Object oldInput) { if (oldInput == null) { if (input == null) { return; } refresh(); return; } refresh(); } @Override protected void handleLabelProviderChanged(LabelProviderChangedEvent event) { if (event != null) { refresh(event.getElements()); } } protected Object unwrap(Object element) { if (element instanceof IStatement) { return ((IStatement) element).getObject(); } return element; } protected IStatement fillPattern(IStatementPattern pattern, Object value) { IReference s = pattern.getSubject() != null ? pattern.getSubject() : (value instanceof IReference ? (IReference) value : null); IReference p = pattern.getPredicate() != null ? pattern.getPredicate() : (value instanceof IReference ? (IReference) value : null); Object o = pattern.getObject() != null ? pattern.getObject() : value; return new Statement(s, p, o); } @Override public void refresh() { Object input = this.getInput(); if (input instanceof IStatementPattern && getContentProvider() instanceof IStructuredContentProvider) { // use content provider to get first element Object[] elements = ((IStructuredContentProvider) getContentProvider()) .getElements(input); if (elements.length > 0) { input = fillPattern((IStatementPattern) input, elements[0]); } } currentElement = input; if (currentElement instanceof IStatement) { ILabelProvider labelProvider = (ILabelProvider) getLabelProvider(); if (valueEditor != null) { valueEditor.setValue(helper .getValue(getStatement(currentElement))); } else { valueText .setText(labelProvider.getText(unwrap(currentElement))); } iconLabel.setImage(labelProvider.getImage(unwrap(currentElement))); } else { defaultIcon(iconLabel); if (valueEditor != null) { valueEditor.setValue(""); } else { valueText.setText(null); } } if (valueEditor != null) { CellEditorHelper.updateProposals(valueEditor, helper.getProposalSupport(getStatement(currentElement))); } } protected void defaultIcon(Label label) { label.setImage(ExtendedImageRegistry.getInstance().getImage( KommaEditPlugin.INSTANCE.getImage(IEditImages.ITEM))); } /** * Refreshes the presentation if currently chosen element is on the list. * * @param objs * list of changed object */ private void refresh(Object[] objs) { if (objs == null || getInput() == null) { return; } Object input = getInput(); for (int i = 0; i < objs.length; i++) { if (objs[i].equals(input)) { refresh(); break; } } } }