| /******************************************************************************* |
| * Copyright (c) 2013 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.stem.model.ctdl.ui.embed; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.edit.command.SetCommand; |
| import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.edit.provider.IItemPropertySource; |
| import org.eclipse.emf.edit.provider.INotifyChangedListener; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.text.DocumentEvent; |
| import org.eclipse.stem.model.ctdl.ContextSensitiveResourceWrapper; |
| import org.eclipse.stem.model.ctdl.scoping.CTDLScopeProvider; |
| import org.eclipse.stem.model.ctdl.scoping.MetamodelContextLinker; |
| import org.eclipse.stem.model.ctdl.ui.internal.CTDLActivator; |
| import org.eclipse.stem.model.metamodel.MetamodelPackage; |
| import org.eclipse.stem.model.metamodel.Transition; |
| import org.eclipse.stem.model.metamodel.provider.TransitionItemProvider; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.StyledText; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.xtext.linking.ILinkingService; |
| import org.eclipse.xtext.linking.lazy.LazyLinkingResource; |
| import org.eclipse.xtext.resource.XtextResource; |
| import org.eclipse.xtext.resource.XtextResourceSet; |
| import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditor; |
| import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditorFactory; |
| import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditorModelAccess; |
| import org.eclipse.xtext.ui.editor.embedded.IEditedResourceProvider; |
| import org.eclipse.xtext.ui.editor.model.IXtextDocumentContentObserver; |
| import org.eclipse.xtext.ui.editor.model.IXtextModelListener; |
| import org.eclipse.xtext.ui.editor.model.XtextDocument; |
| import org.eclipse.xtext.ui.editor.validation.IValidationIssueProcessor; |
| import org.eclipse.xtext.validation.Issue; |
| |
| import com.google.inject.Injector; |
| |
| @SuppressWarnings("restriction") |
| public class EmbeddedExpressionEditorComposite extends Composite { |
| protected EmbeddedEditorFactory factory; |
| protected EmbeddedEditorFactory.Builder builder; |
| protected EmbeddedEditor embeddedEditor; |
| protected EmbeddedEditorModelAccess partialEditorModelAccess; |
| |
| // protected XtextResource resource; |
| // protected IEditedResourceProvider resourceProvider; |
| protected ILinkingService linker; |
| protected Injector injector; |
| |
| protected Transition transition; |
| protected EditingDomain editingDomain; |
| protected boolean edited = false; |
| // protected Button applyButton, revertButton; |
| // private boolean dirty = false; |
| protected TransitionItemProvider itemProvider; |
| |
| protected final IEditedResourceProvider resourceProvider = new IEditedResourceProvider() { |
| public XtextResource createResource() { |
| XtextResourceSet resourceSet = new XtextResourceSet(); |
| XtextResource resource = (XtextResource) resourceSet |
| .createResource(URI.createURI("empty.sctd")); |
| resourceSet.getResources().add(resource); |
| return resource; |
| } |
| }; |
| |
| protected final XtextResource emptyResource = resourceProvider |
| .createResource(); |
| |
| public EmbeddedExpressionEditorComposite(Composite parent, int style) { |
| super(parent, style); |
| setLayout(new GridLayout(2, false)); |
| setupEditor(); |
| // setupEditorButtons(); |
| } |
| |
| public void setTransition(Transition transition, EditingDomain editingDomain) { |
| if (this.transition == transition) { |
| return; |
| } |
| |
| if (transition == null) { |
| this.transition = null; |
| embeddedEditor.getDocument().setInput( |
| resourceProvider.createResource()); |
| embeddedEditor.getDocument().set(""); |
| embeddedEditor.getViewer().getTextWidget().setEditable(true); |
| } else { |
| this.transition = transition; |
| this.editingDomain = editingDomain; |
| |
| itemProvider = (TransitionItemProvider) ((AdapterFactoryEditingDomain) editingDomain) |
| .getAdapterFactory().adapt(transition, |
| IItemPropertySource.class); |
| |
| if (itemProvider != null) { |
| itemProvider.addListener(new INotifyChangedListener() { |
| |
| @Override |
| public void notifyChanged(final Notification notification) { |
| if (notification.getEventType() == Notification.SET |
| && notification.getFeature() == MetamodelPackage.Literals.TRANSITION__EXPRESSION) { |
| StyledText txt2 = embeddedEditor.getViewer() |
| .getTextWidget(); |
| if (txt2 != null && !txt2.isFocusControl()) { |
| |
| embeddedEditor.getDocument().set( |
| notification.getNewStringValue()); |
| } |
| |
| } |
| |
| } |
| }); |
| } |
| |
| XtextResource newResource = resourceProvider.createResource(); |
| |
| String expr = transition.getExpression(); |
| if (expr == null) { |
| expr = ""; |
| } |
| // if (!isNullOrEmpty(expr)) { |
| // //embeddedEditor.getDocument().set(""); |
| // //embeddedEditor.getDocument().set(expr); |
| // } else { |
| // //embeddedEditor.getDocument().set(""); |
| // } |
| |
| |
| ByteArrayInputStream bais = new ByteArrayInputStream(expr.getBytes()); |
| try { |
| newResource.load(bais,Collections.emptyMap()); |
| |
| } catch (IOException ioe) { |
| ioe.printStackTrace(); |
| } |
| |
| |
| transition.setExpressionResource(newResource); |
| |
| MetamodelContextLinker linker = (MetamodelContextLinker) ((LazyLinkingResource) newResource) |
| .getLinkingService(); |
| linker.setTransition(transition); |
| if (linker.getScopeProvider() instanceof CTDLScopeProvider) { |
| ((CTDLScopeProvider) linker.getScopeProvider()) |
| .setTransition(transition); |
| } |
| |
| if (newResource instanceof ContextSensitiveResourceWrapper) { |
| ((ContextSensitiveResourceWrapper) newResource) |
| .setTransition(transition); |
| } |
| |
| if (newResource != null |
| && newResource instanceof LazyLinkingResource |
| && ((LazyLinkingResource) newResource).getLinkingService() instanceof MetamodelContextLinker) { |
| |
| } |
| |
| embeddedEditor.getDocument(); |
| |
| embeddedEditor.getDocument().setInput(newResource); |
| embeddedEditor.getDocument().set(expr); |
| |
| embeddedEditor.getViewer().getTextWidget().setEditable(true); |
| flagDirty(false); |
| } |
| } |
| |
| public void setTransition(Transition transition) { |
| setTransition(transition, null); |
| } |
| |
| static boolean isNullOrEmpty(String s) { |
| return (s == null || "".equals(s.trim())); |
| } |
| |
| public void verifySaveChanges() { |
| if (isDirty()) { |
| if (MessageDialog.openConfirm(getShell(), "Sure?", |
| "Do you wish to save the current transition?")) { |
| applyChanges(); |
| } else { |
| revertChanges(); |
| } |
| } |
| } |
| |
| protected void applyChanges() { |
| final XtextDocument doc = getDocument(); |
| if (doc != null && transition != null) { |
| |
| if (editingDomain != null) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| editingDomain |
| .getCommandStack() |
| .execute( |
| SetCommand |
| .create(editingDomain, |
| transition, |
| MetamodelPackage.Literals.TRANSITION__EXPRESSION, |
| doc.get())); |
| |
| } |
| }); |
| |
| } else { |
| transition.setExpression(doc.get()); |
| } |
| } |
| flagDirty(false); |
| } |
| |
| protected void revertChanges() { |
| XtextDocument doc = getDocument(); |
| if (doc != null && transition != null) { |
| doc.set(transition.getExpression()); |
| } |
| flagDirty(false); |
| } |
| |
| |
| protected XtextDocument getDocument() { |
| return embeddedEditor.getDocument(); |
| } |
| |
| public boolean isDirty() { |
| return false; |
| } |
| |
| protected void flagDirty(boolean dirty) { |
| // this.dirty = dirty; |
| // if (dirty) { |
| // enableButtons(); |
| // } else { |
| // disableButtons(); |
| // } |
| } |
| |
| |
| protected void setupEditor() { |
| Composite editorCanvas = new Composite(this, SWT.NONE); |
| GridData canvasData = new GridData(GridData.FILL_BOTH); |
| canvasData.horizontalSpan = 2; |
| editorCanvas.setLayoutData(canvasData); |
| editorCanvas.setLayout(new GridLayout()); |
| CTDLActivator activator = CTDLActivator.getInstance(); |
| injector = activator |
| .getInjector(CTDLActivator.ORG_ECLIPSE_STEM_MODEL_CTDL_CTDL); |
| factory = injector.getInstance(EmbeddedEditorFactory.class); |
| |
| linker = (ILinkingService) injector.getInstance(ILinkingService.class); |
| builder = factory.newEditor(resourceProvider); |
| |
| embeddedEditor = builder |
| .processIssuesBy(new EmbeddedEditorIssueProcessor()) |
| .showErrorAndWarningAnnotations().withParent(editorCanvas); |
| partialEditorModelAccess = embeddedEditor.createPartialEditor(true); |
| |
| embeddedEditor.getDocument().addModelListener( |
| new IXtextModelListener() { |
| |
| @Override |
| public void modelChanged(XtextResource resource) { |
| if (edited) { |
| String contents = getDocument().get(); |
| if (contents != null |
| && !contents.equals(transition |
| .getExpression())) { |
| applyChanges(); |
| } |
| edited = false; |
| } |
| } |
| }); |
| |
| embeddedEditor.getDocument().addXtextDocumentContentObserver( |
| new IXtextDocumentContentObserver() { |
| |
| @Override |
| public void documentChanged(DocumentEvent event) { |
| // flagDirty(true); |
| edited = true; |
| } |
| |
| @Override |
| public void documentAboutToBeChanged(DocumentEvent event) { |
| } |
| |
| @Override |
| public boolean performNecessaryUpdates(Processor processor) { |
| return true; |
| } |
| |
| @Override |
| public boolean hasPendingUpdates() { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| }); |
| } |
| |
| private class EmbeddedEditorIssueProcessor implements |
| IValidationIssueProcessor { |
| |
| @Override |
| public void processIssues(List<Issue> issues, IProgressMonitor monitor) { |
| for (Issue issue : issues) { |
| System.err.println(issue.getMessage()); |
| } |
| |
| } |
| |
| } |
| } |