| /** |
| * 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; |
| } |
| } |
| } |
| } |
| |
| } |