blob: f1a8d41c3c9cf986044cd683c10099738ca25be2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Red Hat, Inc.
* All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
*
* @author Bob Brodt
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.merrimac.dialogs;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.eclipse.bpmn2.modeler.core.Activator;
import org.eclipse.bpmn2.modeler.core.IConstants;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesProvider;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractDetailComposite;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.ui.celleditor.FeatureEditorDialog;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* EObject Reference List Editor.
* This class implements an EObject reference list editor. The feature must be an EList of EObject references.
* The list is rendered in a single-line text field with an "Edit" button to the right. Clicking the edit button
* displays an EMF FeatureEditorDialog, which allows adding, removing and reordering of available object references.
*
* @author Bob Brodt
*/
public class FeatureListObjectEditor extends MultivalueObjectEditor {
Text text;
List<EObject> references;
Composite buttons;
Button editButton;
protected IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore();
private class ListLabelProvider extends LabelProvider {
@Override
public Image getImage(Object element) {
return super.getImage(element);
}
@Override
public String getText(Object element) {
return ModelUtil.getTextValue(element);
}
}
/**
* @param parent
* @param object
* @param feature
*/
public FeatureListObjectEditor(AbstractDetailComposite parent, EObject object, EStructuralFeature feature) {
super(parent, object, feature, (EClass)feature.getEType());
}
/* (non-Javadoc)
* @see org.eclipse.bpmn2.modeler.ui.property.editors.ObjectEditor#createControl(org.eclipse.swt.widgets.Composite, java.lang.String, int)
*/
@Override
protected Control createControl(Composite composite, String label, int style) {
createLabel(composite, label);
text = getToolkit().createText(composite, ""); //$NON-NLS-1$
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
setEditable(false);
references = getValue();
updateTextField();
boolean canEdit = canEdit();
boolean canCreateNew = canCreateNew();
if (canEdit || canCreateNew) {
buttons = getToolkit().createComposite(composite);
buttons.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
buttons.setLayout(new FillLayout(SWT.HORIZONTAL));
if (canCreateNew) {
// TODO: this isn't working yet.
Button createButton = getToolkit().createButton(buttons, null, SWT.PUSH);
createButton.setImage( Activator.getDefault().getImage(IConstants.ICON_ADD_20));
createButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
// create a new target object
FeatureEditingDialog dialog = createFeatureEditingDialog(null);
if ( dialog.open() == Window.OK) {
updateEObject(dialog.getNewObject());
updateTextField();
}
}
});
}
if (canEdit) {
editButton = getToolkit().createButton(buttons, null, SWT.PUSH);
editButton.setImage( Activator.getDefault().getImage(IConstants.ICON_EDIT_20));
editButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Hashtable<String,Object> choices = getChoiceOfValues(object,feature);
List values = new ArrayList();
values.addAll(choices.values());
FeatureEditorDialog featureEditorDialog = new FeatureEditorDialog(parent.getShell(),
new ListLabelProvider(), object, feature, Messages.FeatureListObjectEditor_Title, values) {
protected Control createContents(Composite parent) {
Composite control = (Composite)super.createContents(parent);
setDialogSize(control);
return control;
}
@Override
protected void configureShell(Shell shell) {
// TODO Auto-generated method stub
super.configureShell(shell);
}
public void setDialogSize(final Control parent) {
final String key = featureEType.getName() + ".list"; //$NON-NLS-1$
Point p = getShell().getSize();
int width = preferenceStore.getInt("dialog."+key+".width"); //$NON-NLS-1$ //$NON-NLS-2$
if (width==0)
width = p.x;
int height = preferenceStore.getInt("dialog."+key+".height"); //$NON-NLS-1$ //$NON-NLS-2$
if (height==0)
height = p.y;
getShell().setSize(width,height);
p = getShell().getLocation();
int x = preferenceStore.getInt("dialog."+key+".x"); //$NON-NLS-1$ //$NON-NLS-2$
if (x==0)
x = p.x;
int y = preferenceStore.getInt("dialog."+key+".y"); //$NON-NLS-1$ //$NON-NLS-2$
if (y==0)
y = p.y;
getShell().setLocation(x,y);
getShell().addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e)
{
Point p = getShell().getLocation();
preferenceStore.setValue("dialog."+key+".x", p.x); //$NON-NLS-1$ //$NON-NLS-2$
preferenceStore.setValue("dialog."+key+".y", p.y); //$NON-NLS-1$ //$NON-NLS-2$
}
public void controlResized(ControlEvent e)
{
Point p = getShell().getSize();
preferenceStore.setValue("dialog."+key+".width", p.x); //$NON-NLS-1$ //$NON-NLS-2$
preferenceStore.setValue("dialog."+key+".height", p.y); //$NON-NLS-1$ //$NON-NLS-2$
}
});
if (parent.getLayoutData() instanceof GridData) {
GridData data = (GridData)parent.getLayoutData();
// TODO: figure out why this dialog insists on resizing its shell
// even after we've set the shell bounds.
data.widthHint = width - 16;
data.heightHint = height - 38;
}
// getShell().pack();
}
};
if (featureEditorDialog.open() == Window.OK) {
updateEObject((EList<EObject>) featureEditorDialog.getResult());
updateTextField();
}
}
});
}
}
return text;
}
private void updateEObject(final EObject result) {
TransactionalEditingDomain domain = getDiagramEditor().getEditingDomain();
domain.getCommandStack().execute(new RecordingCommand(domain) {
@Override
protected void doExecute() {
if (result == null) {
references.clear();
return;
}
if (!references.contains(result)) {
references.add(result);
}
}
});
}
private void updateEObject(final EList<EObject> result) {
TransactionalEditingDomain domain = getDiagramEditor().getEditingDomain();
domain.getCommandStack().execute(new RecordingCommand(domain) {
@Override
protected void doExecute() {
if (result == null) {
references.clear();
return;
}
references.retainAll(result);
for (EObject di : result) {
if (!references.contains(di)) {
references.add(di);
}
}
}
});
}
private void updateTextField() {
String listText = ""; //$NON-NLS-1$
if (references != null) {
for (int i = 0; i < references.size() - 1; i++) {
listText += ExtendedPropertiesProvider.getTextValue(references.get(i)) + ", "; //$NON-NLS-1$
}
if (references.size() > 0) {
listText += ExtendedPropertiesProvider.getTextValue(references.get(references.size() - 1));
}
}
if (editButton!=null)
editButton.setEnabled(getChoiceOfValues(object,feature).size()>0);
text.setText(listText);
}
@Override
public void notifyChanged(Notification notification) {
if ( notification.getEventType() == -1 ||
(object == notification.getNotifier() && feature == notification.getFeature())) {
super.notifyChanged(notification);
updateTextField();
}
}
public void setVisible(boolean visible) {
super.setVisible(visible);
text.setVisible(visible);
GridData data = (GridData)text.getLayoutData();
data.exclude = !visible;
if (buttons!=null) {
buttons.setVisible(visible);
data = (GridData)buttons.getLayoutData();
data.exclude = !visible;
}
}
public void dispose() {
super.dispose();
if (editButton!=null && !editButton.isDisposed()) {
editButton.dispose();
editButton = null;
}
if (text!=null && !text.isDisposed()) {
text.dispose();
text = null;
}
if (buttons!=null && !buttons.isDisposed()) {
buttons.dispose();
buttons = null;
}
}
public Control getControl() {
return text;
}
@Override
public List getValue() {
Object v = object.eGet(feature);
if (v instanceof List) {
return (List)v;
}
return null;
}
}