/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.uml.properties.widgets; import java.util.HashSet; import java.util.Set; import org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor; import org.eclipse.papyrus.uml.properties.expression.ExpressionList.Expression; import org.eclipse.papyrus.uml.properties.preferences.LanguageRegistry; import org.eclipse.papyrus.views.properties.modelelement.ModelElement; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; /** * An editor to edit an expression body. * Depending on the matching language, a different widget will be used to edit * the expression body. * * @author Camille Letavernier * */ public class DynamicBodyEditor extends AbstractValueEditor implements Listener { private BodyEditor currentEditor; private final Composite bodyEditorContainer; private final Set<Listener> changeListeners = new HashSet<Listener>(); private boolean readOnly = false; private ModelElement context = null; /** * * Constructor. * * @param parent * The composite in which the widget will be displayed * @param style * The widget's composite style */ public DynamicBodyEditor(Composite parent, int style) { super(parent, style); bodyEditorContainer = new Composite(this, style); bodyEditorContainer.setLayout(new FillLayout()); bodyEditorContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); currentEditor = new NullBodyEditor(); currentEditor.createWidget(bodyEditorContainer, SWT.NONE); } /** * Sets the {@link Expression} to edit. * This will refresh the widget used to edit the expression body. * * @param expression * the expression to edit */ public void display(Expression expression) { if(currentEditor != null) { disposeBodyEditor(); } BodyEditor editor; if(expression == null) { editor = new NullBodyEditor(); editor.createWidget(bodyEditorContainer, SWT.NONE); bodyEditorContainer.layout(); return; } String language = expression.getLanguage(); String initialText = expression.getBody(); editor = getEditor(language); editor.createWidget(bodyEditorContainer, SWT.NONE); if(context != null) { editor.setContext(context); } editor.setInput(initialText); editor.addChangeListener(this); editor.setReadOnly(readOnly); bodyEditorContainer.layout(); currentEditor = editor; } /** * Adds a listener to this object * Events will be fired when the body has changed * * @param listener */ //TODO : isn't it simply a commit listener ? public void addChangeListener(Listener listener) { changeListeners.add(listener); } /** * Removes a listener from this object * * @param listener */ public void removeChangeListener(Listener listener) { changeListeners.remove(listener); } private BodyEditor getEditor(String language) { return LanguageRegistry.instance.getEditorFor(language); } private void disposeBodyEditor() { currentEditor.removeChangeListener(this); currentEditor.dispose(); for(Control control : bodyEditorContainer.getChildren()) { control.dispose(); } } @Override public String getValue() { if(currentEditor != null) { return currentEditor.getValue(); } return null; } @Override public Object getEditableType() { return String.class; } @Override public void setReadOnly(boolean readOnly) { if(currentEditor != null) { currentEditor.setReadOnly(readOnly); } this.readOnly = readOnly; } @Override public boolean isReadOnly() { return readOnly; } @Override public void setToolTipText(String text) { super.setLabelToolTipText(text); } public void handleEvent(Event event) { for(Listener listener : changeListeners) { listener.handleEvent(event); } } @Override protected GridData getLabelLayoutData() { GridData result = super.getLabelLayoutData(); result.verticalAlignment = SWT.BEGINNING; return result; } /** * Sets the ModelElement used by this editor * * @param modelElement */ public void setContext(ModelElement modelElement) { this.context = modelElement; if(currentEditor != null) { currentEditor.setContext(context); } } }