/*******************************************************************************
* 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.gwt.editor.part;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.eef.runtime.ui.gwt.editor.EEFEditor;
import org.eclipse.emf.eef.runtime.ui.gwt.editor.property.ItemPropertyDescriptorFeatureEditor;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
/**
* @author glefur
*
*/
public class EEFPropertiesPanel extends DockLayoutPanel {
private Grid properties;
private Object oldSelection;
private Collection<Runnable> propertyUpdater;
private EEFEditor editor;
/**
* @param unit
*/
public EEFPropertiesPanel(EEFEditor editor, Unit unit) {
super(unit);
this.editor = editor;
propertyUpdater = new HashSet<Runnable>();
this.setStyleName("Properties", true);
this.setHeight("100%");
FlowPanel propertiesTitlePanel = new FlowPanel();
propertiesTitlePanel.setStyleName("PropertiesTitle", true);
final Label title = new Label("Properties");
title.setStyleName("PropertiesTitleLabel", true);
propertiesTitlePanel.add(title);
this.addNorth(propertiesTitlePanel, 28.0);
properties = new Grid();
properties.setWidth("100%");
ScrollPanel propertiesScrollPanel = new ScrollPanel();
propertiesScrollPanel.add(properties);
this.add(propertiesScrollPanel);
}
/**
* @return the propertyUpdater
*/
public Collection<Runnable> getPropertyUpdater() {
return propertyUpdater;
}
public void updateProperties(final Object newSelection) {
if (oldSelection == newSelection) {
for (Runnable runnable : propertyUpdater) {
runnable.run();
}
} else {
editor.getNavigationManager().setSelection(null);
oldSelection = newSelection;
List<IItemPropertyDescriptor> propertyDescriptors = editor.getItemDelegator().getPropertyDescriptors(newSelection);
if (propertyDescriptors != null) {
properties.clear();
propertyUpdater.clear();
int size = propertyDescriptors.size();
properties.resize(size, 2);
properties.getColumnFormatter().setWidth(0, "10%");
properties.getColumnFormatter().setWidth(1, "90%");
for (int i = 0; i < size; ++i) {
final IItemPropertyDescriptor propertyDescriptor = propertyDescriptors.get(i);
properties.setText(i, 0, propertyDescriptor.getDisplayName(newSelection));
Widget widget = null;
final IItemLabelProvider itemLabelProvider = propertyDescriptor.getLabelProvider(newSelection);
final Object feature = propertyDescriptor.getFeature(newSelection);
if (feature instanceof EReference[]) {
final ItemPropertyDescriptorFeatureEditor dialog = new ItemPropertyDescriptorFeatureEditor(newSelection, true, propertyDescriptor) {
@Override
protected void hook(ListBox listBox, List<?> values) {
editor.getNavigationManager().listenTo(listBox, values);
}
};
dialog.update();
widget = dialog;
propertyUpdater.add(new Runnable() {
public void run() {
dialog.update();
}
});
} else if (feature instanceof EStructuralFeature) {
final EStructuralFeature eStructureFeature = (EStructuralFeature) feature;
final EClassifier eType = eStructureFeature.getEType();
final Collection<?> choiceOfValues = propertyDescriptor.getChoiceOfValues(newSelection);
if (choiceOfValues != null) {
final List<?> listOfValues = new ArrayList<Object>(propertyDescriptor.getChoiceOfValues(newSelection));
if (propertyDescriptor.isMany(newSelection)) {
boolean valid = true;
for (Object choice : choiceOfValues) {
if (!eType.isInstance(choice)) {
valid = false;
break;
}
}
if (valid) {
final ItemPropertyDescriptorFeatureEditor dialog = new ItemPropertyDescriptorFeatureEditor(newSelection, true, propertyDescriptor) {
@Override
protected void hook(ListBox listBox, List<?> values) {
editor.getNavigationManager().listenTo(listBox, values);
}
};
dialog.update();
widget = dialog;
propertyUpdater.add(new Runnable() {
public void run() {
dialog.update();
}
});
}
}
if (widget == null) {
final ListBox listBox = new ListBox();
widget = listBox;
listBox.setVisibleItemCount(1);
Runnable runnable = new Runnable() {
public void run() {
listBox.clear();
editor.getNavigationManager().listenTo(listBox, listOfValues);
Object propertyValue = editor.getItemDelegator().getEditableValue(propertyDescriptor.getPropertyValue(newSelection));
for (Object value : choiceOfValues) {
listBox.addItem(itemLabelProvider.getText(value));
if (value == null ? propertyValue == null : value.equals(propertyValue)) {
listBox.setSelectedIndex(listBox.getItemCount() - 1);
}
}
}
};
listBox.addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent event) {
Object value = listOfValues.get(listBox.getSelectedIndex());
propertyDescriptor.setPropertyValue(newSelection, value);
}
});
runnable.run();
propertyUpdater.add(runnable);
}
} else if (eType instanceof EDataType) {
final EDataType eDataType = (EDataType) eType;
if (eDataType.isSerializable()) {
if (propertyDescriptor.isMany(newSelection)) {
final ItemPropertyDescriptorFeatureEditor dialog = new ItemPropertyDescriptorFeatureEditor(newSelection, propertyDescriptor) {
@Override
protected void hook(ListBox listBox, List<?> values) {
editor.getNavigationManager().listenTo(listBox, values);
}
};
dialog.update();
widget = dialog;
propertyUpdater.add(new Runnable() {
public void run() {
dialog.update();
}
});
} else {
if (eDataType.getInstanceClass() == Date.class) {
final DateBox dateBox = new DateBox();
widget = dateBox;
Runnable runnable = new Runnable() {
public void run() {
Object propertyValue = editor.getItemDelegator().getEditableValue(propertyDescriptor.getPropertyValue(newSelection));
dateBox.setValue((Date) propertyValue);
}
};
dateBox.addValueChangeHandler(new ValueChangeHandler<Date>() {
public void onValueChange(ValueChangeEvent<Date> event) {
propertyDescriptor.setPropertyValue(newSelection, event.getValue());
}
});
runnable.run();
propertyUpdater.add(runnable);
} else if (eDataType.getInstanceClass() == Boolean.class || eDataType.getInstanceClass() == boolean.class) {
final CheckBox checkBox = new CheckBox();
widget = checkBox;
Runnable runnable = new Runnable() {
public void run() {
Object propertyValue = editor.getItemDelegator().getEditableValue(propertyDescriptor.getPropertyValue(newSelection));
checkBox.setValue(Boolean.TRUE.equals(propertyValue));
}
};
checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
public void onValueChange(ValueChangeEvent<Boolean> event) {
propertyDescriptor.setPropertyValue(newSelection, event.getValue());
}
});
runnable.run();
propertyUpdater.add(runnable);
} else if (propertyDescriptor.isMultiLine(newSelection)) {
final TextArea textArea = new TextArea();
widget = textArea;
Runnable runnable = new Runnable() {
public void run() {
Object propertyValue = editor.getItemDelegator().getEditableValue(propertyDescriptor.getPropertyValue(newSelection));
textArea.setText(EcoreUtil.convertToString(eDataType, propertyValue));
}
};
textArea.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
propertyDescriptor.setPropertyValue(newSelection, EcoreUtil.createFromString(eDataType, event.getValue()));
}
});
runnable.run();
propertyUpdater.add(runnable);
} else {
final TextBox textBox = new TextBox();
widget = textBox;
textBox.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String value = event.getValue();
propertyDescriptor.setPropertyValue(newSelection, EcoreUtil.createFromString(eDataType, value));
// TOD0
// commandStack.execute(SetCommand.create(editingDomain,
// object, feature,
// EcoreUtil.createFromString(eDataType,
// value)));
}
});
Runnable runnable = new Runnable() {
public void run() {
Object propertyValue = editor.getItemDelegator().getEditableValue(propertyDescriptor.getPropertyValue(newSelection));
String stringValue = EcoreUtil.convertToString(eDataType, propertyValue);
if (!textBox.getText().equals(stringValue)) {
textBox.setText(stringValue);
}
}
};
runnable.run();
propertyUpdater.add(runnable);
}
}
}
}
} else {
final TextBox textBox = new TextBox();
widget = textBox;
textBox.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String value = event.getValue();
propertyDescriptor.setPropertyValue(newSelection, value);
}
});
Runnable runnable = new Runnable() {
public void run() {
Object propertyValue = editor.getItemDelegator().getEditableValue(propertyDescriptor.getPropertyValue(newSelection));
String stringValue = propertyValue == null ? null : propertyDescriptor.getLabelProvider(newSelection).getText(propertyValue);
if (!textBox.getText().equals(stringValue)) {
textBox.setText(stringValue);
}
}
};
runnable.run();
propertyUpdater.add(runnable);
}
if (widget != null) {
widget.setWidth("95%");
properties.setWidget(i, 1, widget);
if (!propertyDescriptor.canSetProperty(newSelection) && widget instanceof FocusWidget) {
((FocusWidget) widget).setEnabled(false);
}
}
}
}
}
}
}