/******************************************************************************* * Copyright (c) 2008, 2011 Obeo. * 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: * Obeo - initial API and implementation *******************************************************************************/ package org.eclipse.emf.eef.runtime.ui.widgets; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.common.notify.AdapterFactory; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.emf.eef.runtime.api.component.IPropertiesEditionComponent; import org.eclipse.emf.eef.runtime.impl.utils.EEFUtils; import org.eclipse.emf.eef.runtime.ui.viewers.PropertiesEditionContentProvider; import org.eclipse.emf.eef.runtime.ui.viewers.PropertiesEditionViewer; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.SharedScrolledComposite; /** * @param <T> * @deprecated */ public class SingleCompositionViewer<T extends EObject> extends Composite { EObjectFlatComboViewer comboViewer; /** * The Form tool kit use to use this widget in an Eclipse Forms compliant mode */ private FormToolkit widgetFactory; /** * The adapter factory. */ private AdapterFactory adapterFactory = new ComposedAdapterFactory( ComposedAdapterFactory.Descriptor.Registry.INSTANCE); /** * The viewer to display the feature. */ private PropertiesEditionViewer viewer; /** * */ private Button setActiveEEFViewerCheckBox; /** * The label of the feature. */ private Label label; /** * The top part of the feature (usually the checkbox and the flat combo viewer). */ private Composite top; /** * */ private ArrayList<EObject> instanciableObjectsInHierarchy; /** * The kind of the part. */ private int kind; private EditingDomain editingDomain; private String labelText; private boolean isRequired; private List<ISelectionChangedListener> comboListeners = new ArrayList<ISelectionChangedListener>(); /** * The constructor of the single composition viewer. * * @param label * the label of the feature represented by this widget. * @param parent * the parent composite. * @param style * the SWT style. * @param widgetFactory * the widget factory needed to create all contained widgets. * @param kind * the kind of the part. */ public SingleCompositionViewer(String label, Composite parent, int style, FormToolkit widgetFactory, int kind, boolean isRequired) { super(parent, style); this.layout(true); this.isRequired = isRequired; this.labelText = label; this.widgetFactory = widgetFactory; GridLayout layout = new GridLayout(); layout.numColumns = 1; this.setLayout(layout); createTop(label); this.kind = kind; } /** * Creates the top part of the single composition viewer. The top includes the check box to activate or * not the widget and the flat combo viewer to select what kind of object to instantiate. * * @param label * the label of the feature */ private void createTop(String label) { top = new Composite(this, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 3; top.setLayout(layout); GridData data = new GridData(GridData.FILL_HORIZONTAL); top.setLayoutData(data); createCheckBox(top); createLabel(label, top); createFlatComboViewer(top); } /** * This method is used to re-create the top part without the checkbox. The reason to do this is that the * feature lower bound is higher than 1. In this case, the single composition viewer cannot be disable. */ private void resetTopWithoutCheckBox() { top.dispose(); setActiveEEFViewerCheckBox = null; top = new Composite(this, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; top.setLayout(layout); GridData data = new GridData(GridData.FILL_HORIZONTAL); top.setLayoutData(data); createLabel(labelText, top); createFlatComboViewer(top); for (ISelectionChangedListener listener : comboListeners) comboViewer.addSelectionChangedListener(listener); } /** * Creates the label on the top left-side. * * @param label * The text to display. * @param top * the top part. */ private void createLabel(String label, Composite top) { this.label = new Label(top, SWT.NONE); if (isRequired) this.label.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT)); this.label.setText(label); } /** * Create the check box. * * @param top * the top part. */ private void createCheckBox(Composite top) { setActiveEEFViewerCheckBox = new Button(top, SWT.CHECK); } /** * Create the flat combo viewer. * * @param top * the top part. */ private void createFlatComboViewer(Composite top) { comboViewer = new EObjectFlatComboViewer(top, false); comboViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory)); comboViewer.setEnabled(true); GridData matchData = new GridData(GridData.FILL_HORIZONTAL); comboViewer.setLayoutData(matchData); if (setActiveEEFViewerCheckBox != null) { comboViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { setActiveEEFViewerCheckBox.setSelection(true); } }); setActiveEEFViewerCheckBox.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { if (getCheckBoxSelection()) comboViewer.getSelectionAdapter(false).widgetSelected(e); } public void widgetDefaultSelected(SelectionEvent e) { } }); } } /** * Creates the viewer that will display the selected object properties. * * @param kind * the kind of the part. */ private void createViewer(int kind) { GridData viewerStrategyData = new GridData(GridData.FILL_HORIZONTAL); viewerStrategyData.horizontalSpan = 3; this.viewer = new PropertiesEditionViewer(this, null, SWT.BORDER, kind); viewer.getControl().setLayoutData(viewerStrategyData); if (widgetFactory != null) viewer.setToolkit(widgetFactory); viewer.setDynamicTabHeader(true); } /** * Update the single composition viewer with the given new eObject. * * @param newValue * the new selected eObject. */ public void update(EObject newValue) { if (newValue != null) comboViewer.setSelection(new StructuredSelection(newValue)); else clearComboViewer(); updateEEFViewer(newValue); refresh(); } /** * @param newValue */ private void updateEEFViewer(EObject newValue) { if (viewer == null && hasFeatures(newValue)) { createViewer(kind); initViewer(editingDomain); } if (viewer != null) { viewer.setInput(newValue); if (!hasFeatures(newValue)) { viewer.getControl().dispose(); viewer = null; } else viewer.getControl().setVisible(true); } } /** * Clear the combo viewer selection. */ private void clearComboViewer() { comboViewer.selectedElement = null; comboViewer.initComponent(); } /** * Set the input feature of the viewer. * * @param current * the eObject of the feature. * @param feature * the feature to display. * @param allResources * the resource set required to get all instanciable types in the hierarchy of the feature * type. */ public void setInput(EObject current, EReference feature, ResourceSet allResources) { List<EClass> instanciableTypesInHierarchy = EEFUtils.instanciableTypesInHierarchy(feature.getEType(), allResources); instanciableObjectsInHierarchy = new ArrayList<EObject>(); for (EClass eClass : instanciableTypesInHierarchy) { instanciableObjectsInHierarchy.add(EcoreUtil.create(eClass)); } if (feature.getLowerBound() > 0) { resetTopWithoutCheckBox(); } comboViewer.setInput(instanciableObjectsInHierarchy); if (instanciableObjectsInHierarchy.size() == 1) { comboViewer.setVisible(false); } } /** * Returns the current Object selected by the flat combo viewer. * * @return the selected eObject. */ public EObject getElement() { if (comboViewer.getSelection() instanceof StructuredSelection) { Object firstElement = ((StructuredSelection)comboViewer.getSelection()).getFirstElement(); if (firstElement instanceof EObject) { if (kind == 0 && viewer != null) { // firstElement = viewer // .getPropertiesEditionObject(((EObject) firstElement)); // TODO: getPropertiesEditionObject doesn't exists anymore, // it must be a getInput() instead firstElement = viewer.getInput(); } return (EObject)firstElement; } } return null; } /** * Adds a selection change listener on the combo viewer. * * @param listener * the selection changed listener. */ public void addSelectionChangedListener(ISelectionChangedListener listener) { comboViewer.addSelectionChangedListener(listener); this.comboListeners.add(listener); } /** * Adds a selection listener on the check box. * * @param selectionListener * the selection listener. */ public void addCheckBoxSelectionListener(SelectionListener selectionListener) { if (setActiveEEFViewerCheckBox != null) setActiveEEFViewerCheckBox.addSelectionListener(selectionListener); } /** * @param provider */ public void setLabelProvider(AdapterFactoryLabelProvider provider) { comboViewer.setLabelProvider(provider); } /** * @param structuredSelection * @param feature */ public void setSelection(StructuredSelection structuredSelection, EReference feature) { EObject selectedObject = (EObject)((EObject)structuredSelection.getFirstElement()).eGet(feature); if (selectedObject != null) { StructuredSelection selection = new StructuredSelection(selectedObject); comboViewer.setSelection(selection); if (hasFeatures(selectedObject)) { if (viewer == null) createViewer(kind); initViewer(editingDomain); viewer.setInput(selectedObject); } if (setActiveEEFViewerCheckBox != null) setActiveEEFViewerCheckBox.setSelection(true); } comboViewer.initComponent(); } /** * @param editingDomain */ private void initViewer(EditingDomain editingDomain) { if (editingDomain != null) viewer.setContentProvider(new PropertiesEditionContentProvider(adapterFactory, IPropertiesEditionComponent.LIVE_MODE, editingDomain)); else { try { viewer.setContentProvider(new PropertiesEditionContentProvider(adapterFactory, IPropertiesEditionComponent.BATCH_MODE)); } catch (InstantiationException e) { e.printStackTrace(); } } } /** * @param editingDomain */ public void init(EditingDomain editingDomain) { this.editingDomain = editingDomain; } /** * @return */ public boolean getCheckBoxSelection() { return setActiveEEFViewerCheckBox.getSelection(); } /** * */ public void refresh() { this.reflow(); layout(); } /** * @param value */ public void setEnable(boolean value) { this.comboViewer.setEnabled(value); this.setActiveEEFViewerCheckBox.setEnabled(value); } /** * Returns whether the given eObject has one feature at least. This method is usually used to know whether * to display the check box or not. * * @param eObject * the eObject. * @return true if has one feature or more otherwise false. */ private boolean hasFeatures(EObject eObject) { if (eObject != null) return eObject.eClass().getEAllStructuralFeatures().size() > 0; return false; } /** * Reflows this section and all the parents up the hierarchy until a SharedScrolledComposite is reached. */ protected void reflow() { Composite c = this; while (c != null) { c.setRedraw(false); c = c.getParent(); if (c instanceof SharedScrolledComposite || c instanceof Shell) { break; } } c = this; while (c != null) { c.layout(true); c = c.getParent(); if (c instanceof SharedScrolledComposite) { ((SharedScrolledComposite)c).reflow(true); break; } } c = this; while (c != null) { c.setRedraw(true); c = c.getParent(); if (c instanceof SharedScrolledComposite || c instanceof Shell) { break; } } } @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); comboViewer.setEnabled(enabled); setActiveEEFViewerCheckBox.setEnabled(enabled); label.setEnabled(enabled); } }