/******************************************************************************* * Copyright (c) 2008 Hallvard Traetteberg. * 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: * Hallvard Traetteberg - initial API and implementation ******************************************************************************/ package org.eclipse.e4.tm.ui.editor; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.StringTokenizer; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.e4.tm.ui.Activator; import org.eclipse.e4.tm.ui.EcorePaletteView; import org.eclipse.e4.tm.ui.EditorPartModelContext; import org.eclipse.e4.tm.ui.ModelPartContent; import org.eclipse.e4.tm.ui.TmLabelProvider; import org.eclipse.e4.tm.ui.TmPartStyle; import org.eclipse.e4.tm.widgets.Control; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.presentation.EcoreEditor; 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.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter; import org.eclipse.emf.edit.ui.dnd.LocalTransfer; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.swt.SWTError; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorInput; public class TmEcoreEditor extends EcoreEditor { protected ModelPartContent modelContent; private TmPartStyle partStyle = new TmPartStyle.SashStyle(); protected Composite createPageContainer(Composite parent) { partStyle.createPageContainer(parent); partStyle.addTmComposite(this); return partStyle.getTreeParent(); } private boolean autoLoadToolkitModels = true; private IPostProcessor[] postProcessors; public void createPages() { postProcessors = Activator.getDefault().getPostProcessors(); super.createPages(); selectionViewer.setLabelProvider(new TmLabelProvider((ILabelProvider)selectionViewer.getLabelProvider())); modelContent = new ModelPartContent(partStyle.getTmComposite(this)) { protected void buildModel(EObject model) { super.buildModel(model); for (IPostProcessor postProcessor: postProcessors) { postProcessor.postBuildModel(model, this.getBuilder(), new IAdaptable(){ public Object getAdapter(Class key) { if (key.equals(Composite.class)) { return getModelComposite(); } return TmEcoreEditor.this.getAdapter(key); } }); } EList<Resource> resources = getEditingDomain().getResourceSet().getResources(); if (resources.size() > 0) { Resource resource = resources.get(0); if ("xmi".equals(resource.getURI().fileExtension()) && resource.getContents().size() > 0) { ((Control)model).setDataObject(resource.getContents().get(0)); } } } }; if (autoLoadToolkitModels) { loadToolkitModel(); } for (IPostProcessor postProcessor: postProcessors) { postProcessor.postLoadModel(this); } modelContent.setModelContext(new EditorPartModelContext(this)); } public Object getAdapter(Class key) { if (key.equals(EditingDomain.class)) { return getEditingDomain(); } else if (key.equals(URIConverter.class)) { return getEditingDomain().getResourceSet().getURIConverter(); } else if (key.equals(Composite.class)) { return getContainer(); } else if (IEditorInput.class.isAssignableFrom(key) && key.isInstance(getEditorInput())) { return getEditorInput(); } for (IPostProcessor postProcessor: postProcessors) { Object adapted = postProcessor.getAdapter(key); if (key.isInstance(adapted)) { return adapted; } } return super.getAdapter(key); } public final static String TM_FILE_EXTENSION = "tm"; private void loadToolkitModel() { ResourceSet resSet = getEditingDomain().getResourceSet(); List<Resource> resources = resSet.getResources(); Resource tmResource = null; for (Resource res: resources.toArray(new Resource[resources.size()])) { URI uri = res.getURI(); URI tmUri = uri.trimFileExtension().appendFileExtension(TM_FILE_EXTENSION); if ("xmi".equals(uri.fileExtension()) && resSet.getURIConverter().exists(tmUri, null)) { try { tmResource = resSet.getResource(tmUri, true); break; } catch (RuntimeException re) { } } } } protected void createContextMenuForGen(StructuredViewer viewer) { Transfer[] transferTypes = new Transfer[]{ TextTransfer.getInstance(), LocalTransfer.getInstance() }; viewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE, transferTypes, new EditingDomainViewerDropAdapter(getEditingDomain(), viewer) { private boolean isTransfer(Transfer transfer, DropTargetEvent event) { for (int i = 0; i < event.dataTypes.length; i++) { if (transfer.isSupportedType(event.dataTypes[i])) { return true; } } return false; } protected void helper(DropTargetEvent event) { if (isTransfer(TextTransfer.getInstance(), event)) { event.feedback = DND.FEEDBACK_SELECT | getAutoFeedback(); originalOperation = DND.DROP_COPY; event.detail = DND.DROP_COPY; } else { super.helper(event); } } protected Collection<?> getDragSource(DropTargetEvent event) { if (isTransfer(TextTransfer.getInstance(), event)) { return null; } return super.getDragSource(event); } protected Collection<?> extractDragSource(Object object) { if (object instanceof String) { return TmEcoreEditor.this.getDragSource((String)object); } return super.extractDragSource(object); } }); try { super.createContextMenuForGen(viewer); } catch (SWTError swtError) { // this is expected, since we have already added our own, hacked drop support if (swtError.code != DND.ERROR_CANNOT_INIT_DROP) { throw swtError; } } } private Collection<EObject> getDragSource(String uris) { Collection<EObject> eObjects = new ArrayList<EObject>(); ResourceSet resSet = new ResourceSetImpl(); StringTokenizer tokens = new StringTokenizer(uris); while (tokens.hasMoreTokens()) { String uri = tokens.nextToken(); int pos = uri.indexOf(EcorePaletteView.FRAGMENT_SEPARATOR); if (pos > 0) { Resource res = resSet.getResource(URI.createURI(uri.substring(0, pos)), true); EObject eObject = res.getEObject(uri.substring(pos + EcorePaletteView.FRAGMENT_SEPARATOR.length())); if (eObject != null) { eObjects.add(EcoreUtil.copy(eObject)); } } } return eObjects; } }