| /** |
| * <copyright> |
| * Copyright (c) 2009 Thales Corporate Services S.A.S. |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-v2.0.
|
| *
|
| * SPDX-License-Identifier: EPL-2.0
|
| * Contributors: |
| * Thales Corporate Services S.A.S - initial API and implementation |
| * </copyright> |
| */ |
| |
| package org.eclipse.egf.pattern.ui.editors; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.core.commands.operations.IOperationHistory; |
| import org.eclipse.core.commands.operations.ObjectUndoContext; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.egf.core.domain.PlatformResourceLoadedListener; |
| import org.eclipse.egf.core.domain.PlatformResourceLoadedListener.ResourceListener; |
| import org.eclipse.egf.core.domain.PlatformResourceLoadedListener.ResourceUser; |
| import org.eclipse.egf.model.fcore.FcorePackage; |
| import org.eclipse.egf.model.pattern.Pattern; |
| import org.eclipse.egf.model.pattern.PatternMethod; |
| import org.eclipse.egf.model.pattern.PatternPackage; |
| import org.eclipse.egf.pattern.ui.Activator; |
| import org.eclipse.egf.pattern.ui.Messages; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.editors.text.FileDocumentProvider; |
| import org.eclipse.ui.editors.text.StorageDocumentProvider; |
| import org.eclipse.ui.editors.text.TextEditor; |
| import org.eclipse.ui.part.MultiPageEditorPart; |
| |
| /** |
| * @author Thomas Guiu |
| */ |
| public class PatternTemplateEditor extends MultiPageEditorPart implements ResourceUser { |
| |
| public static final String ID = "org.eclipse.egf.pattern.ui.pattern.template.editor.id"; //$NON-NLS-1$ |
| |
| // method adapter |
| private final AdapterImpl methodAdapter = new AdapterImpl() { |
| |
| @Override |
| public void notifyChanged(Notification msg) { |
| if (FcorePackage.Literals.NAMED_MODEL_ELEMENT__NAME.equals(msg.getFeature()) && msg.getNotifier() instanceof PatternMethod) { |
| executeMethodEditorRename((PatternMethod) msg.getNotifier()); |
| } |
| } |
| |
| }; |
| |
| // The current pattern adapter |
| private final AdapterImpl patternAdapter = new AdapterImpl() { |
| |
| @Override |
| public void notifyChanged(final Notification msg) { |
| if (FcorePackage.Literals.NAMED_MODEL_ELEMENT__NAME.equals(msg.getFeature()) && msg.getNotifier() instanceof Pattern) { |
| // Title update |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| setPartName((String) msg.getNewValue()); |
| } |
| |
| }); |
| |
| } else if (PatternPackage.Literals.PATTERN_LIBRARY.equals(msg.getFeature()) && msg.getNewValue() == null) { |
| // Removed Pattern |
| // just close now without prompt |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| getSite().getPage().closeEditor(PatternTemplateEditor.this, false); |
| } |
| |
| }); |
| |
| } else if (PatternPackage.Literals.PATTERN__METHODS.equals(msg.getFeature())) { |
| refreshTemplateEditor(msg); |
| } |
| |
| } |
| |
| }; |
| |
| private final Map<String, TextEditor> editors = new HashMap<String, TextEditor>(); |
| |
| /** |
| * Domain resource listener |
| */ |
| private boolean patternInWorkspace = false; |
| |
| /** |
| * Current pattern |
| */ |
| private Pattern pattern; |
| |
| /** |
| * Domain resource listener |
| */ |
| private final ResourceListener resourceListener = new ResourceListener() { |
| |
| public void resourceMoved(final Resource movedResource, final URI oldURI) { |
| if (movedResource == getResource()) { |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| setInputWithNotify(new PatternEditorInput(movedResource, ((PatternEditorInput) getEditorInput()).getID())); |
| firePropertyChange(PROP_TITLE); |
| } |
| |
| }); |
| } |
| } |
| |
| public void resourceDeleted(final Resource deletedResource) { |
| if ((deletedResource == getResource())) { |
| // just close now without prompt |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| getSite().getPage().closeEditor(PatternTemplateEditor.this, false); |
| } |
| |
| }); |
| } |
| } |
| |
| public void resourceReloaded(final Resource reloadedResource) { |
| |
| if (reloadedResource == getResource()) { |
| |
| // Create a new input |
| final PatternEditorInput newEditorInput = new PatternEditorInput(reloadedResource, ((PatternEditorInput) getEditorInput()).getID()); |
| |
| // Check whether or not this pattern is still alive |
| if (newEditorInput.getPattern() != null) { |
| |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| |
| // Do we have something to do |
| if (pattern != newEditorInput.getPattern()) { |
| |
| // Remove previous adapters |
| removePatternChangeAdapter(); |
| // Store reloaded pattern |
| pattern = newEditorInput.getPattern(); |
| // Add new adapters |
| addPatternChangeAdapter(); |
| |
| // Should we update this template editor |
| if ((newEditorInput.getFile() == null && patternInWorkspace) || (newEditorInput.getFile() != null && patternInWorkspace == false)) { |
| // Remove pages |
| for (int i = getPageCount() - 1; i != -1; i--) { |
| removePage(i); |
| } |
| // Update |
| patternInWorkspace = newEditorInput.getFile() != null; |
| // Create pages |
| createPages(); |
| // Activate |
| if (getPageCount() != 0) { |
| setActivePage(0); |
| } |
| // Update editorInput |
| setInputWithNotify(newEditorInput); |
| } else { |
| // Pattern method analysis |
| } |
| |
| // Update title |
| firePropertyChange(PROP_TITLE); |
| |
| } |
| } |
| |
| }); |
| |
| } else { |
| |
| // just close now without prompt |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| getSite().getPage().closeEditor(PatternTemplateEditor.this, false); |
| } |
| |
| }); |
| |
| } |
| |
| } |
| |
| } |
| |
| public void externalUpdate(final Resource changedResource) { |
| if (changedResource == getResource()) { |
| // Wait until we are notified, this couldn't happen though |
| // if we are the latest opened editor in our editing domain |
| // anyway we don't how to deal with this situation yet |
| } |
| } |
| |
| public void internalUpdate(final Resource changedResource) { |
| if (changedResource == getResource()) { |
| // Nothing to do |
| } |
| } |
| |
| }; |
| |
| public PatternTemplateEditor() { |
| super(); |
| } |
| |
| /** |
| * Refresh the template editor while user change the content of pattern's |
| * methods. |
| */ |
| private void refreshTemplateEditor(Notification msg) { |
| Object newValue = msg.getNewValue(); |
| Object oldValue = msg.getOldValue(); |
| int eventType = msg.getEventType(); |
| if ((newValue != null && newValue instanceof PatternMethod) || (newValue == null && oldValue instanceof PatternMethod)) { |
| switch (eventType) { |
| case Notification.ADD: |
| executeMethodEditorAdd((PatternMethod) newValue); |
| break; |
| case Notification.REMOVE: |
| executeMethodEditorRemove((PatternMethod) oldValue); |
| break; |
| // case Notification.MOVE: |
| // executeMethodEditorsReorder((PatternMethod) newValue, oldValue); |
| // break; |
| default: |
| return; |
| } |
| } |
| } |
| |
| private void executeMethodEditorRename(PatternMethod patternMethod) { |
| IEditorPart editorPart = getEditorPart(patternMethod.getID()); |
| if (editorPart != null) { |
| for (int i = 0; i < getPageCount(); i++) { |
| if (editorPart.equals(getEditor(i))) { |
| setPageText(i, patternMethod.getName()); |
| } |
| } |
| } |
| } |
| |
| private void executeMethodEditorRemove(PatternMethod deleteMethod) { |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| for (int i = 0; i < getPageCount(); i++) { |
| IEditorPart editor = getEditor(i); |
| AbstractPatternMethodEditorInput input = (AbstractPatternMethodEditorInput) editor.getEditorInput(); |
| PatternMethod patternMethod = input.getPatternMethod(); |
| if (patternMethod == null) { |
| removePage(i); |
| } |
| } |
| } |
| |
| }); |
| |
| } |
| |
| protected void executeMethodEditorAdd(final PatternMethod addMethod) { |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| createPage(addMethod); |
| } |
| |
| }); |
| addMethodChangeAdapter(addMethod); |
| } |
| |
| /** |
| * Add method adapters |
| */ |
| protected void addMethodChangeAdapter(PatternMethod method) { |
| if (method != null && method.eAdapters().contains(methodAdapter) == false) { |
| method.eAdapters().add(methodAdapter); |
| } |
| } |
| |
| /** |
| * Remove method adapters |
| */ |
| protected void removeMethodChangeAdapter(PatternMethod method) { |
| if (method != null && method.eAdapters().contains(methodAdapter)) { |
| method.eAdapters().remove(methodAdapter); |
| } |
| } |
| |
| /** |
| * Add pattern and methods adapters |
| */ |
| private void addPatternChangeAdapter() { |
| if (pattern != null && pattern.eAdapters().contains(patternAdapter) == false) { |
| pattern.eAdapters().add(patternAdapter); |
| EList<PatternMethod> methods = pattern.getMethods(); |
| for (PatternMethod method : methods) { |
| addMethodChangeAdapter(method); |
| } |
| } |
| } |
| |
| /** |
| * Remove pattern and methods adapters |
| */ |
| protected void removePatternChangeAdapter() { |
| if (pattern != null && pattern.eAdapters().contains(patternAdapter)) { |
| pattern.eAdapters().remove(patternAdapter); |
| } |
| EList<PatternMethod> methods = pattern.getMethods(); |
| for (PatternMethod method : methods) { |
| removeMethodChangeAdapter(method); |
| } |
| } |
| |
| void createPage(PatternMethod method) { |
| try { |
| TextEditor editor = new TextEditor() { |
| |
| { |
| setDocumentProvider(patternInWorkspace ? new FileDocumentProvider() : new StorageDocumentProvider()); |
| } |
| |
| }; |
| AbstractPatternMethodEditorInput input = null; |
| if (patternInWorkspace) { |
| input = new WorkspacePatternMethodEditorInput(method.eResource(), method.getID()); |
| } else { |
| input = new RuntimePatternMethodEditorInput(method.eResource(), method.getID()); |
| } |
| int index = addPage(editor, input); |
| setPageText(index, method.getName()); |
| editors.put(method.getID(), editor); |
| } catch (PartInitException e) { |
| ErrorDialog.openError(getSite().getShell(), "Error creating nested text editor", null, e.getStatus()); //$NON-NLS-1$ |
| Activator.getDefault().logError(e); |
| } |
| } |
| |
| @Override |
| protected void createPages() { |
| for (PatternMethod method : pattern.getMethods()) { |
| createPage(method); |
| } |
| } |
| |
| public IEditorPart getEditorPart(String methodId) { |
| return editors.get(methodId); |
| } |
| |
| @Override |
| public void doSave(IProgressMonitor monitor) { |
| for (int i = 0; i < getPageCount(); i++) { |
| getEditor(i).doSave(monitor); |
| } |
| } |
| |
| @Override |
| public void doSaveAs() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /** |
| * The <code>MultiPageEditorExample</code> implementation of this method |
| * checks that the input is an instance of <code>IFileEditorInput</code>. |
| */ |
| @Override |
| public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException { |
| if (editorInput instanceof PatternEditorInput == false) { |
| throw new PartInitException(Messages.Editor_wrong_input); |
| } |
| super.init(site, editorInput); |
| patternInWorkspace = ((PatternEditorInput) getEditorInput()).getFile() != null; |
| pattern = ((PatternEditorInput) getEditorInput()).getPattern(); |
| PlatformResourceLoadedListener.getResourceManager().addObserver(this); |
| addPatternChangeAdapter(); |
| setPartName(pattern.getName()); |
| } |
| |
| @Override |
| public void dispose() { |
| // if init failed, dispose should not called this |
| if (getEditorInput() != null && getEditorInput() instanceof PatternEditorInput) { |
| removePatternChangeAdapter(); |
| } |
| PlatformResourceLoadedListener.getResourceManager().removeObserver(this); |
| super.dispose(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * Method declared on IEditorPart. |
| */ |
| @Override |
| public boolean isSaveAsAllowed() { |
| return false; |
| } |
| |
| public Resource getResource() { |
| PatternEditorInput input = (PatternEditorInput) getEditorInput(); |
| if (input == null) |
| throw new IllegalStateException(); |
| return input.getResource(); |
| } |
| |
| public void setActiveEditor(String methodId) { |
| IEditorPart editorPart = getEditorPart(methodId); |
| if (editorPart != null) { |
| super.setActiveEditor(editorPart); |
| } |
| } |
| |
| public ResourceListener getListener() { |
| return resourceListener; |
| } |
| |
| public IOperationHistory getOperationHistory() { |
| return null; |
| } |
| |
| public ObjectUndoContext getUndoContext() { |
| return null; |
| } |
| |
| public boolean userHasSavedResource() { |
| return false; |
| } |
| |
| public boolean resourceHasBeenExternallyChanged() { |
| return false; |
| } |
| |
| } |