blob: 3f5aae72a099a5bd18144278d10d456f236d0ee4 [file] [log] [blame]
/**
* Copyright (c) 2010 Ed Merks and others.
* 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:
* Ed Merks - Initial API and implementation
*/
package org.eclipse.emf.edit.ui;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.Callback;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EPackage.Registry;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.URIService;
import org.eclipse.emf.ecore.resource.URIServiceAsync;
import org.eclipse.emf.ecore.resource.URIServiceCallback;
import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl;
import org.eclipse.emf.ecore.resource.impl.ResourceFactoryImpl;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.command.CopyToClipboardCommand;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.CutToClipboardCommand;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.command.PasteFromClipboardCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ComposedImage;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.edit.provider.ItemProvider;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.TreeNode;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
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.RootPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SplitLayoutPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;
public abstract class EditorEntryPoint implements EntryPoint
{
public static abstract class CommandHandler implements ClickHandler
{
protected Command command;
protected EditingDomain editingDomain;
protected Button button;
public CommandHandler(EditingDomain editingDomain, Button button)
{
this.editingDomain = editingDomain;
this.button = button;
button.addClickHandler(this);
button.setEnabled(false);
}
public void setSelection(Object value)
{
command = createCommand(value);
button.setEnabled(command.canExecute());
}
public abstract Command createCommand(Object value);
public void onClick(ClickEvent event)
{
editingDomain.getCommandStack().execute(command);
}
}
public void onModuleLoad()
{
ComposedAdapterFactory composedAdapterFactory = new ComposedAdapterFactory();
composedAdapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
configureItemProviderAdapterFactories(composedAdapterFactory);
composedAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
final BasicCommandStack commandStack = new BasicCommandStack();
final AdapterFactoryEditingDomain editingDomain = new AdapterFactoryEditingDomain(composedAdapterFactory, commandStack);
final ResourceSet resourceSet = editingDomain.getResourceSet();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put
(Resource.Factory.Registry.DEFAULT_EXTENSION,
new ResourceFactoryImpl()
{
@Override
public Resource createResource(URI uri)
{
return new BinaryResourceImpl(uri);
}
});
final URIServiceAsync uriService = GWT.create(URIService.class);
URIServiceCallback uriServiceCallback = new URIServiceCallback(uriService);
resourceSet.getURIConverter().getURIHandlers().add(uriServiceCallback);
final List<Resource> originalResources = new ArrayList<Resource>();
Resource listingResource =
resourceSet.getResource
(URI.createURI("datastore:/"),
new Callback<Resource>()
{
public void onFailure(Throwable caught)
{
System.err.println("Failed");
caught.printStackTrace();
}
public void onSuccess(Resource result)
{
EAnnotation eAnnotation = (EAnnotation)result.getContents().get(0);
for (Map.Entry<String, String> entry : eAnnotation.getDetails())
{
resourceSet.createResource(URI.createURI(entry.getKey()));
}
originalResources.clear();
originalResources.addAll(resourceSet.getResources());
}
});
resourceSet.getResources().remove(listingResource);
registerPackages(resourceSet.getPackageRegistry());
final AdapterFactoryItemDelegator itemDelegator = new AdapterFactoryItemDelegator(composedAdapterFactory);
DockLayoutPanel mainPanel = new DockLayoutPanel(Unit.PX);
mainPanel.setStyleName("Main", true);
mainPanel.setHeight("100%");
FlowPanel headerPanel = new FlowPanel();
headerPanel.setStyleName("Header", true);
final Label header = new Label(getApplicationTitle());
header.setStyleName("HeaderLabel", true);
headerPanel.add(header);
mainPanel.addNorth(headerPanel, 56.0);
DockLayoutPanel bodyPanel = new DockLayoutPanel(Unit.PX);
bodyPanel.setStyleName("Body", true);
bodyPanel.setHeight("100%");
mainPanel.add(bodyPanel);
FlowPanel toolBar = new FlowPanel();
toolBar.setStyleName("ToolBar", true);
SplitLayoutPanel contentPanel = new SplitLayoutPanel();
contentPanel.setStyleName("Content", true);
DockLayoutPanel propertiesPanel = new DockLayoutPanel(Unit.PX);
propertiesPanel.setStyleName("Properties", true);
propertiesPanel.setHeight("100%");
FlowPanel propertiesTitlePanel = new FlowPanel();
propertiesTitlePanel.setStyleName("PropertiesTitle", true);
final Label title = new Label("Properties");
title.setStyleName("PropertiesTitleLabel", true);
propertiesTitlePanel.add(title);
propertiesPanel.addNorth(propertiesTitlePanel, 28.0);
final Grid properties = new Grid();
properties.setWidth("100%");
ScrollPanel propertiesScrollPanel = new ScrollPanel();
propertiesScrollPanel.add(properties);
propertiesPanel.add(propertiesScrollPanel);
final Button createButton = new Button();
createButton.setText("Create...");
createButton.setStyleName("ToolBarButtonLeftMargin");
toolBar.add(createButton);
final Button deleteButton = new Button();
deleteButton.setText("Delete");
final CommandHandler deleteCommandHandler =
new CommandHandler(editingDomain, deleteButton)
{
@Override
public Command createCommand(Object value)
{
if (value instanceof Resource)
{
final Resource resource = (Resource)value;
final Command deleteContentsCommand = DeleteCommand.create(editingDomain, resource.getContents());
final RemoveCommand removeResourceCommand = new RemoveCommand(editingDomain, resourceSet.getResources(), resource);
return
new CompoundCommand()
{
@Override
protected boolean prepare()
{
return true;
}
@Override
public void execute()
{
appendAndExecute(deleteContentsCommand);
appendAndExecute(removeResourceCommand);
}
};
}
else
{
return DeleteCommand.create(editingDomain, value);
}
}
};
deleteButton.setStyleName("ToolBarButton");
toolBar.add(deleteButton);
final Button validateButton = new Button();
validateButton.setText("Validate");
validateButton.setStyleName("ToolBarButtonLeftMargin");
toolBar.add(validateButton);
final Button saveButton = new Button();
saveButton.setText("Save");
saveButton.setStyleName("ToolBarButton");
toolBar.add(saveButton);
final Button undoButton = new Button();
undoButton.setText("Undo");
undoButton.setStyleName("ToolBarButtonLeftMargin");
toolBar.add(undoButton);
final Button redoButton = new Button();
redoButton.setText("Redo");
redoButton.setStyleName("ToolBarButton");
toolBar.add(redoButton);
final Button cutButton = new Button();
cutButton.setText("Cut");
final CommandHandler cutCommandHandler =
new CommandHandler(editingDomain, cutButton)
{
@Override
public Command createCommand(Object value)
{
return CutToClipboardCommand.create(editingDomain, value);
}
};
cutButton.setStyleName("ToolBarButtonLeftMargin");
toolBar.add(cutButton);
final Button copyButton = new Button();
copyButton.setText("Copy");
final CommandHandler copyCommandHandler =
new CommandHandler(editingDomain, copyButton)
{
@Override
public Command createCommand(Object value)
{
return value instanceof EObject ? CopyToClipboardCommand.create(editingDomain, value) : UnexecutableCommand.INSTANCE;
}
};
copyButton.setStyleName("ToolBarButton");
toolBar.add(copyButton);
final Button pasteButton = new Button();
pasteButton.setText("Paste");
final CommandHandler pasteCommandHandler =
new CommandHandler(editingDomain, pasteButton)
{
@Override
public Command createCommand(Object value)
{
return PasteFromClipboardCommand.create(editingDomain, value, null);
}
};
pasteButton.setStyleName("ToolBarButton");
toolBar.add(pasteButton);
final Button upButton = new Button();
upButton.setText("Up ^");
final CommandHandler upCommandHandler =
new CommandHandler(editingDomain, upButton)
{
@Override
public Command createCommand(Object value)
{
Object owner = editingDomain.getParent(value);
if (owner != null)
{
List<?> children = new ArrayList<Object>(editingDomain.getChildren(owner));
int index = children.indexOf(value);
if (index != -1)
{
return MoveCommand.create(editingDomain, owner, null, value, index - 1);
}
}
return UnexecutableCommand.INSTANCE;
}
};
upButton.setStyleName("ToolBarButtonLeftMargin");
toolBar.add(upButton);
final Button downButton = new Button();
downButton.setText("Down v");
final CommandHandler downCommandHandler =
new CommandHandler(editingDomain, downButton)
{
@Override
public Command createCommand(Object value)
{
Object owner = editingDomain.getParent(value);
if (owner != null)
{
List<?> children = new ArrayList<Object>(editingDomain.getChildren(owner));
int index = children.indexOf(value);
if (index != -1)
{
return MoveCommand.create(editingDomain, owner, null, value, index + 1);
}
}
return UnexecutableCommand.INSTANCE;
}
};
downButton.setStyleName("ToolBarButton");
toolBar.add(downButton);
final Button navigateButton = new Button();
navigateButton.setText("Navigate");
navigateButton.setEnabled(false);
navigateButton.setStyleName("ToolBarButtonLeftMargin");
toolBar.add(navigateButton);
final SingleSelectionModel<Object> treeSelection = new SingleSelectionModel<Object>();
final Collection<Runnable> propertyUpdater = new HashSet<Runnable>();
TreeViewModel treeViewModel =
new TreeViewModel()
{
public <T> NodeInfo<?> getNodeInfo(final T value)
{
final ListDataProvider<Object> abstractListViewAdapter =
new ListDataProvider<Object>()
{
int size;
class NodeAdapter extends AdapterImpl implements INotifyChangedListener
{
Set<Object> children = new HashSet<Object>();
@Override
public void notifyChanged(Notification msg)
{
if (msg.getEventType() != Notification.REMOVING_ADAPTER)
{
update();
if (!(msg.getNotifier() instanceof EObject))
{
for (Runnable runnable : propertyUpdater)
{
runnable.run();
}
}
}
}
public void listenTo(Object target)
{
if (target instanceof Notifier)
{
((Notifier)target).eAdapters().add(this);
}
else if (target instanceof IChangeNotifier)
{
((IChangeNotifier)target).addListener(this);
}
}
public void stopListeningTo(Object target)
{
if (target instanceof Notifier)
{
((Notifier)target).eAdapters().remove(this);
}
else if (target instanceof IChangeNotifier)
{
((IChangeNotifier)target).removeListener(this);
}
}
public void listenTo(List<Object> children)
{
// TODO
// I don't know how to update just one child. :-(
boolean isListeningToValue = !this.children.isEmpty();
Set<Object> oldChildren = new HashSet<Object>(this.children);
for (Object child : children)
{
if (this.children.contains(child))
{
oldChildren.remove(child);
}
else
{
this.children.add(child);
listenTo(child);
}
}
for (Object child : oldChildren)
{
stopListeningTo(child);
this.children.remove(child);
}
if (isListeningToValue)
{
if (children.isEmpty())
{
stopListeningTo(value);
}
}
else if (!children.isEmpty())
{
listenTo(value);
}
}
}
protected NodeAdapter nodeAdapter = new NodeAdapter();
@Override
protected void onRangeChanged(HasData<Object> display)
{
if (value instanceof Resource)
{
Resource resource = (Resource)value;
if (!resource.isLoaded())
{
try
{
resource.load(resourceSet.getLoadOptions());
}
catch (IOException e)
{
// Ignore.
}
}
}
update();
}
protected void update()
{
Collection<?> children = itemDelegator.getChildren(value);
ArrayList<Object> childrenList = new ArrayList<Object>(children);
nodeAdapter.listenTo(childrenList);
int size = children.size();
if (this.size < size)
{
updateRowCount(size, true);
this.size = size;
}
else
{
// Pad with dummy objects.
for (int i = size; i < this.size; ++i)
{
childrenList.add(new Object());
}
}
updateRowData(0, childrenList);
if (this.size > size)
{
updateRowCount(size, true);
this.size = size;
}
}
};
Cell<Object> cell =
new AbstractCell<Object>()
{
@Override
public void render(Context context, Object value, SafeHtmlBuilder safeHtmlBuilder)
{
StringBuilder sb = new StringBuilder();
Object image = itemDelegator.getImage(value);
if (image instanceof ImageResource)
{
ImageResource imageResource = (ImageResource)image;
sb.append("<div style='position:relative;padding-left:");
sb.append(imageResource.getWidth() + 6);
sb.append("px;'>");
sb.append("<div style=\"position:absolute;left:0px;top:0px;height:100%;");
sb.append("width:").append(imageResource.getWidth()).append("px;");
sb.append("background:url('").append(imageResource.getSafeUri()).append("') ");
sb.append("no-repeat scroll center center transparent;");
sb.append("\"></div>");
sb.append(itemDelegator.getText(value));
sb.append("</div>");
}
else if (image instanceof ComposedImage)
{
ComposedImage composedImage = (ComposedImage)image;
List<ComposedImage.Size> sizes = new ArrayList<ComposedImage.Size>();
List<Object> images = new ArrayList<Object>(composedImage.getImages());
List<ImageData> nestedImagesData = new ArrayList<ImageData>();
for (Object nestedImage : images)
{
ImageData nestedImageData = getImageData(nestedImage);
ComposedImage.Size size = new ComposedImage.Size();
size.height = nestedImageData.height;
size.width = nestedImageData.width;
sizes.add(size);
nestedImagesData.add(nestedImageData);
}
ComposedImage.Size size = composedImage.getSize(sizes);
sb.append("<div style='position:relative;padding-left:");
sb.append(size.width + 6);
sb.append("px;'>");
List<ComposedImage.Point> drawPoints = composedImage.getDrawPoints(size);
int i = 0;
for (ComposedImage.Point drawPoint : drawPoints)
{
ImageResource nestedImage = (ImageResource)images.get(i++);
sb.append("<div style=\"position:absolute;left:").append(drawPoint.x).append("px;top:").append(drawPoint.y).append("px;height:100%;");
sb.append("width:").append(nestedImage.getWidth()).append("px;");
sb.append("background:url('").append(nestedImage.getSafeUri()).append("') ");
sb.append("no-repeat scroll center center transparent;");
sb.append("\"></div>");
}
sb.append(itemDelegator.getText(value));
sb.append("</div>");
}
else
{
sb.append(itemDelegator.getText(value));
}
safeHtmlBuilder.appendHtmlConstant(sb.toString());
}
};
return new DefaultNodeInfo<Object>(abstractListViewAdapter, cell, treeSelection, null);
}
public boolean isLeaf(Object value)
{
return !itemDelegator.hasChildren(value);
}
};
treeSelection.setSelected(resourceSet, true);
final MyCellTree cellTree = new MyCellTree(treeViewModel, new ItemProvider(Collections.singleton(resourceSet)));
ScrollPanel treeScrollPanel = new ScrollPanel();
treeScrollPanel.add(cellTree);
class NavigationListener
{
Object selection;
{
navigateButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
final Object oldSelection = treeSelection.getSelectedObject();
Object newSelection = selection;
cellTree.expand(editingDomain.getTreePath(editingDomain.getParent(newSelection)));
treeSelection.setSelected(newSelection, true);
Scheduler.get().scheduleDeferred
(new Scheduler.ScheduledCommand()
{
public void execute()
{
setSelection(oldSelection);
}
});
}
});
}
public void listenTo(final ListBox listBox, final List<?> values)
{
listBox.addFocusHandler
(new FocusHandler()
{
protected HandlerRegistration changeHandlerRegistration;
{
listBox.addBlurHandler
(new BlurHandler()
{
public void onBlur(BlurEvent event)
{
if (changeHandlerRegistration != null)
{
changeHandlerRegistration.removeHandler();
changeHandlerRegistration = null;
}
}
});
}
public void onFocus(FocusEvent event)
{
updateSelection();
changeHandlerRegistration =
listBox.addChangeHandler
(new ChangeHandler()
{
public void onChange(ChangeEvent event)
{
updateSelection();
}
});
}
void updateSelection()
{
int selectedIndex = listBox.getSelectedIndex();
setSelection(selectedIndex == -1 || selectedIndex >= values.size() ? null : values.get(selectedIndex));
}
});
}
protected void setSelection(Object object)
{
if (object != selection)
{
selection = object;
navigateButton.setEnabled(selection != null);
}
}
}
final NavigationListener navigationListener = new NavigationListener();
treeSelection.addSelectionChangeHandler
(new SelectionChangeEvent.Handler()
{
protected Object oldSelection;
public void onSelectionChange(SelectionChangeEvent event)
{
final Object object = treeSelection.getSelectedObject();
deleteCommandHandler.setSelection(object);
cutCommandHandler.setSelection(object);
pasteCommandHandler.setSelection(object);
copyCommandHandler.setSelection(object);
upCommandHandler.setSelection(object);
downCommandHandler.setSelection(object);
createButton.setEnabled
(object instanceof Resource ||
object instanceof ResourceSet ||
!editingDomain.getNewChildDescriptors(object, null).isEmpty());
if (oldSelection == object)
{
for (Runnable runnable : propertyUpdater)
{
runnable.run();
}
}
else
{
navigationListener.setSelection(null);
oldSelection = object;
List<IItemPropertyDescriptor> propertyDescriptors = itemDelegator.getPropertyDescriptors(object);
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(object));
Widget widget = null;
final IItemLabelProvider itemLabelProvider = propertyDescriptor.getLabelProvider(object);
final Object feature = propertyDescriptor.getFeature(object);
if (feature instanceof EReference[])
{
final ItemPropertyDescriptorFeatureEditor dialog =
new ItemPropertyDescriptorFeatureEditor(object, true, propertyDescriptor)
{
@Override
protected void hook(ListBox listBox, List<?> values)
{
navigationListener.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(object);
if (choiceOfValues != null)
{
final List<?> listOfValues = new ArrayList<Object>(propertyDescriptor.getChoiceOfValues(object));
if (propertyDescriptor.isMany(object))
{
boolean valid = true;
for (Object choice : choiceOfValues)
{
if (!eType.isInstance(choice))
{
valid = false;
break;
}
}
if (valid)
{
final ItemPropertyDescriptorFeatureEditor dialog =
new ItemPropertyDescriptorFeatureEditor(object, true, propertyDescriptor)
{
@Override
protected void hook(ListBox listBox, List<?> values)
{
navigationListener.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();
navigationListener.listenTo(listBox, listOfValues);
Object propertyValue = itemDelegator.getEditableValue(propertyDescriptor.getPropertyValue(object));
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(object, value);
}
});
runnable.run();
propertyUpdater.add(runnable);
}
}
else if (eType instanceof EDataType)
{
final EDataType eDataType = (EDataType)eType;
if (eDataType.isSerializable())
{
if (propertyDescriptor.isMany(object))
{
final ItemPropertyDescriptorFeatureEditor dialog =
new ItemPropertyDescriptorFeatureEditor(object, propertyDescriptor)
{
@Override
protected void hook(ListBox listBox, List<?> values)
{
navigationListener.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 = itemDelegator.getEditableValue(propertyDescriptor.getPropertyValue(object));
dateBox.setValue((Date)propertyValue);
}
};
dateBox.addValueChangeHandler
(new ValueChangeHandler<Date>()
{
public void onValueChange(ValueChangeEvent<Date> event)
{
propertyDescriptor.setPropertyValue(object, 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 = itemDelegator.getEditableValue(propertyDescriptor.getPropertyValue(object));
checkBox.setValue(Boolean.TRUE.equals(propertyValue));
}
};
checkBox.addValueChangeHandler
(new ValueChangeHandler<Boolean>()
{
public void onValueChange(ValueChangeEvent<Boolean> event)
{
propertyDescriptor.setPropertyValue(object, event.getValue());
}
});
runnable.run();
propertyUpdater.add(runnable);
}
else if (propertyDescriptor.isMultiLine(object))
{
final TextArea textArea = new TextArea();
widget = textArea;
Runnable runnable =
new Runnable()
{
public void run()
{
Object propertyValue = itemDelegator.getEditableValue(propertyDescriptor.getPropertyValue(object));
textArea.setText(EcoreUtil.convertToString(eDataType, propertyValue));
}
};
textArea.addValueChangeHandler
(new ValueChangeHandler<String>()
{
public void onValueChange(ValueChangeEvent<String> event)
{
propertyDescriptor.setPropertyValue(object, 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(object, 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 = itemDelegator.getEditableValue(propertyDescriptor.getPropertyValue(object));
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(object, value);
}
});
Runnable runnable =
new Runnable()
{
public void run()
{
Object propertyValue = itemDelegator.getEditableValue(propertyDescriptor.getPropertyValue(object));
String stringValue =
propertyValue == null ?
null :
propertyDescriptor.getLabelProvider(object).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(object) && widget instanceof FocusWidget)
{
((FocusWidget)widget).setEnabled(false);
}
}
}
}
}
}
});
contentPanel.addWest(treeScrollPanel, 400);
contentPanel.add(propertiesPanel);
bodyPanel.addNorth(toolBar, 28.0);
bodyPanel.add(contentPanel);
RootPanel.get("main").add(mainPanel);
createButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
Object selection= treeSelection.getSelectedObject();
if (selection instanceof ResourceSet)
{
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Create Resource");
final Button okButton = new Button("OK");
final Button cancelButton = new Button("Cancel");
VerticalPanel verticalPanel = new VerticalPanel();
Grid grid = new Grid();
grid.setWidth("50em");
grid.resize(3, 2);
grid.getColumnFormatter().setWidth(0, "15%");
grid.getColumnFormatter().setWidth(1, "85%");
Label uriLabel = new Label();
uriLabel.setText("URI");
final TextBox uriText = new TextBox();
uriText.setWidth("90%");
int count = 1;
while (resourceSet.getResource(URI.createURI("datastore:/resource" + count), false) != null)
{
++count;
}
uriText.setValue("datastore:/resource" + count);
uriText.selectAll();
final Label message = new Label();
uriText.addValueChangeHandler
(new ValueChangeHandler<String>()
{
public void onValueChange(ValueChangeEvent<String> event)
{
String value = event.getValue();
try
{
if (resourceSet.getResource(URI.createURI(value), false) != null)
{
message.setText("This URI a duplicate");
okButton.setEnabled(false);
}
else
{
message.setText("");
okButton.setEnabled(true);
}
}
catch (RuntimeException exception)
{
message.setText("This URI is not a well formed");
okButton.setEnabled(false);
}
}
});
grid.setWidget(0, 0, uriLabel);
grid.setWidget(0, 1, uriText);
verticalPanel.add(grid);
grid.setWidget(1, 1, message);
grid.setWidget(2, 0, okButton);
grid.setWidget(2, 1, cancelButton);
dialogBox.setWidget(verticalPanel);
dialogBox.show();
uriText.setFocus(true);
// dialogBox.setWidth("50em");
okButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
commandStack.execute
(new AbstractCommand()
{
Collection<?> affectedObjects;
Resource resource;
@Override
protected boolean prepare()
{
return true;
}
public void redo()
{
resourceSet.getResources().add(resource);
affectedObjects = Collections.singleton(resource);
}
@Override
public void undo()
{
resourceSet.getResources().remove(resource);
affectedObjects = Collections.singleton(resourceSet);
}
public void execute()
{
resource = resourceSet.createResource(URI.createURI(uriText.getValue()));
resource.getContents().clear();
affectedObjects = Collections.singleton(resource);
}
@Override
public Collection<?> getAffectedObjects()
{
return affectedObjects;
}
});
}
});
cancelButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
}
});
}
else if (selection instanceof Resource)
{
final Resource resource = (Resource)selection;
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Create Object");
final ListBox listBox = new ListBox();
listBox.setVisibleItemCount(1);
Registry packageRegistry = resourceSet.getPackageRegistry();
for (String nsURI : packageRegistry.keySet())
{
EPackage ePackage = packageRegistry.getEPackage(nsURI);
for (EClassifier eClassifier : ePackage.getEClassifiers())
{
if (eClassifier instanceof EClass)
{
EClass eClass = (EClass)eClassifier;
if (!eClass.isAbstract())
{
EObject eObject = EcoreUtil.create(eClass);
listBox.addItem("New " + itemDelegator.getText(eObject), EcoreUtil.getURI(eClass).toString());
}
}
}
}
final Button okButton = new Button("OK");
final Button cancelButton = new Button("Cancel");
VerticalPanel verticalPanel = new VerticalPanel();
Grid grid = new Grid();
grid.setWidth("50em");
grid.resize(2, 2);
grid.getColumnFormatter().setWidth(0, "15%");
grid.getColumnFormatter().setWidth(1, "85%");
Label classLabel = new Label();
classLabel.setText("Class");
grid.setWidget(0, 0, classLabel);
grid.setWidget(0, 1, listBox);
verticalPanel.add(grid);
// verticalPanel.add(okButton);
grid.setWidget(1, 0, okButton);
grid.setWidget(1, 1, cancelButton);
dialogBox.setWidget(verticalPanel);
dialogBox.show();
listBox.setFocus(true);
// dialogBox.setWidth("50em");
okButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
commandStack.execute
(new AbstractCommand()
{
EObject eObject;
Collection<?> affectedObjects;
@Override
protected boolean prepare()
{
return true;
}
public void redo()
{
resource.getContents().add(eObject);
affectedObjects = Collections.singleton(eObject);
}
@Override
public void undo()
{
resource.getContents().remove(eObject);
affectedObjects = Collections.singleton(resource);
}
public void execute()
{
eObject = EcoreUtil.create((EClass)resourceSet.getEObject(URI.createURI(listBox.getValue(listBox.getSelectedIndex())), false));
resource.getContents().add(eObject);
affectedObjects = Collections.singleton(eObject);
}
@Override
public Collection<?> getAffectedObjects()
{
return affectedObjects;
}
});
}
});
cancelButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
}
});
}
else
{
Collection<?> newChildDescriptors = editingDomain.getNewChildDescriptors(selection, null);
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Create Object");
final ListBox listBox = new ListBox();
final List<Command> commands = new ArrayList<Command>();
listBox.setVisibleItemCount(1);
for (Object descriptor : newChildDescriptors)
{
Command command = CreateChildCommand.create(editingDomain, selection, descriptor, Collections.singleton(selection));
commands.add(command);
listBox.addItem(command.getLabel());
}
final Button okButton = new Button("OK");
final Button cancelButton = new Button("Cancel");
VerticalPanel verticalPanel = new VerticalPanel();
Grid grid = new Grid();
grid.setWidth("50em");
grid.resize(2, 2);
grid.getColumnFormatter().setWidth(0, "15%");
grid.getColumnFormatter().setWidth(1, "85%");
Label classLabel = new Label();
classLabel.setText("Class");
grid.setWidget(0, 0, classLabel);
grid.setWidget(0, 1, listBox);
verticalPanel.add(grid);
// verticalPanel.add(okButton);
grid.setWidget(1, 0, okButton);
grid.setWidget(1, 1, cancelButton);
dialogBox.setWidget(verticalPanel);
dialogBox.show();
listBox.setFocus(true);
// dialogBox.setWidth("50em");
okButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
commandStack.execute(commands.get(listBox.getSelectedIndex()));
}
});
cancelButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
}
});
}
}
});
saveButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
EList<Resource> resources = resourceSet.getResources();
for (Resource resource : resources)
{
try
{
if (resource.isLoaded())
{
Map<String, Object> options = null;
if (originalResources.contains(resource))
{
options = new HashMap<String, Object>();
options.put(URIConverter.OPTION_UPDATE_ONLY_IF_TIME_STAMP_MATCHES, resource.getTimeStamp());
}
resource.save
(options,
new Callback<Resource>()
{
public void onFailure(Throwable caught)
{
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Save conflict");
final Button okButton = new Button("OK");
final Tree tree = new Tree();
tree.addItem(SafeHtmlUtils.fromString(caught.getLocalizedMessage()));
Grid grid = new Grid();
grid.setWidth("150em");
grid.resize(2, 1);
grid.setWidget(0, 0, tree);
grid.setWidget(1, 0, okButton);
dialogBox.setWidget(grid);
dialogBox.show();
okButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
}
});
}
public void onSuccess(Resource result)
{
// TODO Auto-generated method stub
}
});
}
}
catch (IOException exception)
{
EMFEditUIPlugin.INSTANCE.log(exception);
}
}
for (Resource resource : originalResources)
{
if (!resources.contains(resource))
{
Map<String, Object> options = null;
if (resource.isLoaded())
{
options = new HashMap<String, Object>();
options.put(URIConverter.OPTION_UPDATE_ONLY_IF_TIME_STAMP_MATCHES, resource.getTimeStamp());
}
resourceSet.getURIConverter().delete
(resource.getURI(),
options,
new Callback<Map<?, ?>>()
{
public void onFailure(Throwable caught)
{
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Delete conflict");
final Button okButton = new Button("OK");
final Tree tree = new Tree();
tree.addItem(SafeHtmlUtils.fromString(caught.getLocalizedMessage()));
Grid grid = new Grid();
grid.setWidth("150em");
grid.resize(2, 1);
grid.setWidget(0, 0, tree);
grid.setWidget(1, 0, okButton);
dialogBox.setWidget(grid);
dialogBox.show();
okButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
dialogBox.hide();
}
});
}
public void onSuccess(Map<?, ?> result)
{
// TODO Auto-generated method stub
}
});
}
}
originalResources.clear();
originalResources.addAll(resources);
commandStack.saveIsDone();
saveButton.setEnabled(false);
}
});
validateButton.addClickHandler
(new ClickHandler()
{
protected TreeItem createTreeItems(Diagnostic diagnostic)
{
TreeItem treeItem = new TreeItem(SafeHtmlUtils.fromString(diagnostic.getMessage()));
List<?> data = diagnostic.getData();
if (!data.isEmpty())
{
treeItem.setUserObject(data.get(0));
}
for (Diagnostic child : diagnostic.getChildren())
{
treeItem.addItem(createTreeItems(child));
}
return treeItem;
}
public void onClick(ClickEvent event)
{
Diagnostician diagnostician =
new Diagnostician()
{
@Override
public String getObjectLabel(EObject eObject)
{
return !eObject.eIsProxy() ? itemDelegator.getText(eObject) : super.getObjectLabel(eObject);
}
};
Map<Object, Object> context = diagnostician.createDefaultContext();
EList<Resource> resources = resourceSet.getResources();
BasicDiagnostic diagnostics = new BasicDiagnostic();
for (Resource resource : resources)
{
if (resource.isLoaded())
{
for (EObject eObject : resource.getContents())
{
diagnostician.validate(eObject, diagnostics, context);
}
}
}
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Problems");
final Button okButton = new Button("OK");
final Tree tree = new Tree();
if (diagnostics.getSeverity() == Diagnostic.OK)
{
tree.addItem(SafeHtmlUtils.fromString("No problems detected"));
}
else
{
for (Diagnostic child : diagnostics.getChildren())
{
tree.addItem(createTreeItems(child));
}
}
Grid grid = new Grid();
grid.setWidth("150em");
grid.resize(2, 1);
grid.setWidget(0, 0, tree);
grid.setWidget(1, 0, okButton);
dialogBox.setWidget(grid);
dialogBox.show();
okButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
TreeItem treeItem = tree.getSelectedItem();
if (treeItem != null)
{
Object newSelection = treeItem.getUserObject();
if (newSelection != null)
{
cellTree.expand(editingDomain.getTreePath(editingDomain.getParent(newSelection)));
treeSelection.setSelected(newSelection, true);
}
}
dialogBox.hide();
}
});
}
});
saveButton.setEnabled(false);
undoButton.setEnabled(false);
redoButton.setEnabled(false);
commandStack.addCommandStackListener
(new CommandStackListener()
{
public void commandStackChanged(EventObject event)
{
saveButton.setEnabled(commandStack.isSaveNeeded());
undoButton.setEnabled(commandStack.canUndo());
redoButton.setEnabled(commandStack.canRedo());
Command mostRecentCommand = ((CommandStack)event.getSource()).getMostRecentCommand();
if (mostRecentCommand != null)
{
Collection<?> affectedObjects = mostRecentCommand.getAffectedObjects();
if (!affectedObjects.isEmpty())
{
Object newSelection = affectedObjects.iterator().next();
cellTree.expand(editingDomain.getTreePath(editingDomain.getParent(newSelection)));
if (treeSelection.getSelectedObject() == newSelection)
{
for (Runnable runnable : propertyUpdater)
{
runnable.run();
}
}
else
{
treeSelection.setSelected(newSelection, true);
}
}
}
}
});
undoButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
commandStack.undo();
}
});
redoButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
commandStack.redo();
}
});
}
protected abstract void registerPackages(EPackage.Registry ePackageRegistry);
protected void configureItemProviderAdapterFactories(ComposedAdapterFactory adapterFactory)
{
// Do nothing.
}
protected abstract String getApplicationTitle();
public static class ImageData
{
public int width;
public int height;
}
protected ImageData getImageData(Object image)
{
ImageData imageData = new ImageData();
if (image instanceof ImageResource)
{
ImageResource imageResource = (ImageResource)image;
imageData.height = imageResource.getHeight();
imageData.width = imageResource.getWidth();
}
else if (image instanceof ComposedImage)
{
ComposedImage composedImage = (ComposedImage)image;
List<ComposedImage.Size> sizes = new ArrayList<ComposedImage.Size>();
List<Object> images = new ArrayList<Object>(composedImage.getImages());
List<ImageData> nestedImagesData = new ArrayList<ImageData>();
for (Object nestedImage : images)
{
ImageData nestedImageData = getImageData(nestedImage);
ComposedImage.Size size = new ComposedImage.Size();
size.height = nestedImageData.height;
size.width = nestedImageData.width;
sizes.add(size);
nestedImagesData.add(nestedImageData);
}
}
return imageData;
}
public abstract static class FeatureEditor extends Composite
{
protected Object object;
protected boolean isSortChoices;
protected List<?> values;
protected List<?> choiceOfValues;
protected ListBox valueBox;
protected ListBox choiceBox;
protected EDataType eDataType;
protected TextBox textBox;
protected FeatureEditor(Object object, boolean isSortChoices, final EDataType eDataType)
{
this.object = object;
this.isSortChoices = isSortChoices;
this.eDataType = eDataType;
Grid grid = new Grid();
grid.resize(1, 3);
grid.getColumnFormatter().setWidth(0, "40%");
grid.getColumnFormatter().setWidth(1, "20%");
grid.getColumnFormatter().setWidth(2, "40%");
valueBox = new ListBox();
valueBox.setMultipleSelect(true);
valueBox.setVisibleItemCount(4);
valueBox.setWidth("100%");
grid.setWidget(0, 0, valueBox);
Grid buttonGrid = new Grid();
buttonGrid.resize(2, 2);
Button upButton = new Button("Up ^");
buttonGrid.setWidget(0, 0, upButton);
Button downButton = new Button("Down v");
buttonGrid.setWidget(1, 0, downButton);
Button addButton = new Button("< Add");
buttonGrid.setWidget(0, 1, addButton);
Button removeButton = new Button("Remove >");
buttonGrid.setWidget(1, 1, removeButton);
grid.setWidget(0, 1, buttonGrid);
if (eDataType != null)
{
textBox = new TextBox();
textBox.setWidth("100%");
grid.setWidget(0, 2, textBox);
/*
textBox.addValueChangeHandler
(new ValueChangeHandler<String>()
{
public void onValueChange(ValueChangeEvent<String> event)
{
List<Object> result = isUnique() ? new UniqueEList<Object>(values) : new ArrayList<Object>(values);
try
{
Object value = EcoreUtil.createFromString(eDataType, event.getValue());
result.add(value);
setValue(result);
}
catch (RuntimeException exception)
{
// Ignore for now
}
}
});
*/
}
else
{
choiceBox = new ListBox();
choiceBox.setMultipleSelect(true);
choiceBox.setVisibleItemCount(4);
choiceBox.setWidth("100%");
grid.setWidget(0, 2, choiceBox);
}
addButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
List<Object> result = isUnique() ? new UniqueEList<Object>(values) : new ArrayList<Object>(values);
if (eDataType != null)
{
try
{
Object value = EcoreUtil.createFromString(eDataType, textBox.getValue());
result.add(value);
}
catch (RuntimeException exception)
{
// Ignore for now
}
}
else
{
for (int i = 0, size = choiceBox.getItemCount(); i < size; ++i)
{
if (choiceBox.isItemSelected(i))
{
result.add(choiceOfValues.get(i));
}
}
}
setValue(result);
}
});
removeButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
List<Object> result = isUnique() ? new UniqueEList<Object>(values) : new ArrayList<Object>(values);
for (int i = 0, size = valueBox.getItemCount(); i < size; ++i)
{
if (valueBox.isItemSelected(i))
{
result.remove(values.get(i));
}
}
setValue(result);
}
});
upButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
EList<Object> result = new BasicEList<Object>(values);
for (int i = 0, size = valueBox.getItemCount(); i < size; ++i)
{
if (valueBox.isItemSelected(i))
{
if (i != 0)
{
result.move(i, i - 1);
}
}
}
setValue(result);
}
});
downButton.addClickHandler
(new ClickHandler()
{
public void onClick(ClickEvent event)
{
EList<Object> result = new BasicEList<Object>(values);
for (int i = 0, size = valueBox.getItemCount(); i < size; ++i)
{
if (valueBox.isItemSelected(i))
{
if (i + 1 < size)
{
result.move(i, i + 1);
}
}
}
setValue(result);
}
});
initWidget(grid);
}
protected void hook(ListBox listBox, List<?> values)
{
// Do nothing.
}
public void update()
{
IItemLabelProvider labelProvider = getLabelProvider();
List<?> oldValues = values;
values = new ArrayList<Object>(getValues());
List<Object> oldValueSelection = new ArrayList<Object>();
int valueBoxItemCount = valueBox.getItemCount();
if (valueBoxItemCount != 0)
{
for (int i = 0; i < valueBoxItemCount; ++i)
{
if (valueBox.isItemSelected(i))
{
oldValueSelection.add(oldValues.get(i));
}
}
valueBox.clear();
}
for (Object value : values)
{
valueBox.addItem(labelProvider.getText(value));
if (oldValueSelection.contains(value) || oldValues != null && !oldValues.contains(value))
{
valueBox.setItemSelected(valueBox.getItemCount() - 1, true);
}
}
hook(valueBox, values);
if (eDataType != null)
{
textBox.setValue("");
}
else
{
List<Object> oldChoiceSelection = new ArrayList<Object>();
int choiceBoxItemCount = choiceBox.getItemCount();
if (choiceBoxItemCount != 0)
{
for (int i = 0; i < choiceBoxItemCount; ++i)
{
if (choiceBox.isItemSelected(i))
{
oldChoiceSelection.add(choiceOfValues.get(i));
}
}
choiceBox.clear();
}
Collection<?> basicChoices = getChoiceOfValues();
if (basicChoices == null)
{
choiceOfValues = null;
}
else
{
choiceOfValues = new ArrayList<Object>(basicChoices);
if (isSortChoices)
{
createItems(choiceOfValues, labelProvider, null, true);
}
for (Object value : choiceOfValues)
{
choiceBox.addItem(labelProvider.getText(value));
if (oldChoiceSelection.contains(value) || oldValues != null && oldValues.contains(value) && !values.contains(value))
{
choiceBox.setItemSelected(choiceBox.getItemCount() - 1, true);
}
}
hook(choiceBox, choiceOfValues);
}
}
}
protected abstract IItemLabelProvider getLabelProvider();
protected abstract List<?> getValues();
protected abstract Collection<?> getChoiceOfValues();
protected abstract boolean isMultiLine();
protected abstract boolean isUnique();
protected abstract void setValue(Object value);
}
public static class ItemPropertyDescriptorFeatureEditor extends FeatureEditor
{
protected IItemPropertyDescriptor propertyDescriptor;
public ItemPropertyDescriptorFeatureEditor(Object object, IItemPropertyDescriptor propertyDescriptor)
{
super(object, false, ((EAttribute)propertyDescriptor.getFeature(object)).getEAttributeType());
this.propertyDescriptor = propertyDescriptor;
}
public ItemPropertyDescriptorFeatureEditor(Object object, boolean isSortChoices, IItemPropertyDescriptor propertyDescriptor)
{
super(object, isSortChoices, null);
this.propertyDescriptor = propertyDescriptor;
}
@Override
protected IItemLabelProvider getLabelProvider()
{
return propertyDescriptor.getLabelProvider(object);
}
@Override
protected List<?> getValues()
{
Object propertyValue = propertyDescriptor.getPropertyValue(object);
if (propertyValue instanceof IItemPropertySource)
{
propertyValue = ((IItemPropertySource)propertyValue).getEditableValue(propertyValue);
}
return (List<?>)propertyValue;
}
@Override
protected Collection<?> getChoiceOfValues()
{
return propertyDescriptor.getChoiceOfValues(object);
}
@Override
protected boolean isMultiLine()
{
return propertyDescriptor.isMultiLine(object);
}
@Override
protected boolean isUnique()
{
Object feature = propertyDescriptor.getFeature(object);
return !(feature instanceof EStructuralFeature) || ((EStructuralFeature)feature).isUnique();
}
@Override
protected void setValue(Object value)
{
propertyDescriptor.setPropertyValue(object, value);
}
}
private static class StringPositionPair implements Comparable<StringPositionPair>
{
public String key;
public int position;
StringPositionPair(String key, int position)
{
this.key = key;
this.position = position;
}
public int compareTo(StringPositionPair object)
{
if (object == this || key == object.key)
{
return 0;
}
else if (key == null)
{
return -1;
}
else
{
return key.compareTo(object.key);
}
}
}
public static <T> String[] createItems(List<T> list, IItemLabelProvider labelProvider, String filter, boolean sorted)
{
String[] result;
if (filter != null && filter.length() > 0)
{
sorted = true;
}
// If there are objects to populate...
//
if (list != null && list.size() > 0)
{
if (sorted)
{
List<T> unsortedList = new ArrayList<T>(list.size());
if (filter != null && filter.length() > 0)
{
for (int i = 0; i < list.size(); i++)
{
if (select(filter, labelProvider.getText(list.get(i))))
{
unsortedList.add(list.get(i));
}
}
}
else
{
unsortedList.addAll(list);
}
list.clear();
StringPositionPair[] pairs = new StringPositionPair [unsortedList.size()];
for (int i = 0, size = unsortedList.size(); i < size; ++i)
{
Object object = unsortedList.get(i);
pairs[i] = new StringPositionPair(labelProvider.getText(object), i);
}
Arrays.sort(pairs);
// Create a new array.
//
result = new String [unsortedList.size()];
// Fill in the result array with labels and re-populate the original list in order.
//
for (int i = 0, size = unsortedList.size(); i < size; ++i)
{
result[i] = pairs[i].key;
list.add(unsortedList.get(pairs[i].position));
}
}
else
{
// Create a new array.
//
result = new String [list.size()];
// Fill in the array with labels.
//
for (int i = 0, size = list.size(); i < size; ++i)
{
Object object = list.get(i);
result[i] = labelProvider.getText(object);
}
}
}
else
{
result = new String [] { "" };
}
return result;
}
public static boolean select(String filter, String labelValue)
{
if (filter != null && filter.length() > 0)
{
if (filter.length() > labelValue.length())
{
return false;
}
for (int i = 0; i < filter.length(); i++)
{
if (Character.toLowerCase(filter.charAt(i)) != Character.toLowerCase(labelValue.charAt(i)))
{
return false;
}
}
}
return true;
}
static class MyCellTree extends CellTree
{
public <T> MyCellTree(TreeViewModel viewModel, T rootValue)
{
super(viewModel, rootValue, (Resources)GWT.create(CellTree.BasicResources.class));
}
public void expand(List<?> path)
{
TreeNode node = getRootTreeNode();
if (node != null)
{
LOOP:
for (int i = 0, size = path.size(); i < size; ++i)
{
Object segment = path.get(i);
for (int j = 0, count = node.getChildCount(); j < count; ++j)
{
Object childValue = node.getChildValue(j);
if (childValue.equals(segment))
{
node = node.setChildOpen(j, true);
continue LOOP;
}
}
break;
}
}
}
}
}