blob: 08f02af2811b289a0d8b53e86f207abab1e318c4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2011 Chair for Applied Software Engineering,
* Technische Universitaet Muenchen.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
******************************************************************************/
package org.eclipse.emf.ecp.editor.internal.e3;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecp.edit.spi.ECPContextDisposedListener;
import org.eclipse.emf.ecp.edit.spi.util.ECPModelElementChangeListener;
import org.eclipse.emf.ecp.editor.e3.AbstractMEEditorPage;
import org.eclipse.emf.ecp.editor.e3.ECPEditorContext;
import org.eclipse.emf.ecp.editor.e3.MEEditorInput;
import org.eclipse.emf.ecp.editor.e3.StatusMessageProvider;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.editor.SharedHeaderFormEditor;
/**
* GUI view for editing MEs.
*
* @author helming
* @author naughton
*/
public class MEEditor extends SharedHeaderFormEditor {
private static final String STATUS_EXTENSIONPOINT_ID = "org.eclipse.emf.ecp.editor.statusmessage"; //$NON-NLS-1$
private static final String DEFAULT_PAGE_ID = "Edit"; //$NON-NLS-1$
private static final String REPLACE_ATTRIBUTE = "replace"; //$NON-NLS-1$
private static final String EDITOR_PAGES_EXTENSIONPOINT_ID = "org.eclipse.emf.ecp.editor.pages"; //$NON-NLS-1$
/**
* The Id for MEEditor. We need this to open a model element.
*/
public static final String ID = "org.eclipse.emf.ecp.editor.internal.e3"; //$NON-NLS-1$
private MEEditorPage mePage;
private StatusMessageProvider statusMessageProvider;
private ECPModelElementChangeListener modelElementChangeListener;
private ECPEditorContext modelElementContext;
private ECPContextDisposedListener modelElementContextListener;
private MEEditorInput meInput;
private ShortLabelProvider shortLabelProvider;
private ComposedAdapterFactory composedAdapterFactory;
/**
* Default constructor.
*/
public MEEditor() {
}
/**
* {@inheritDoc}
*/
@Override
protected void addPages() {
final String editorID = DEFAULT_PAGE_ID;
final String editorDesc = Messages.MEEditor_Standard_View_Name;
final MEEditorInput editorInput = (MEEditorInput) getEditorInput();
// add pages from the extension point
final IConfigurationElement[] configTemp = Platform.getExtensionRegistry().getConfigurationElementsFor(
EDITOR_PAGES_EXTENSIONPOINT_ID);
IConfigurationElement[] configIn = null;
boolean replaceMEEditor = false;
int counter = 0;
for (int i = 0; i < configTemp.length; i++) {
if (configTemp[i].getAttribute(REPLACE_ATTRIBUTE) != null
&& configTemp[i].getAttribute(REPLACE_ATTRIBUTE).equals(editorID)) {
// if a replacement is found, create this page, so it becomes the first one
replaceMEEditor = true;
AbstractMEEditorPage newPage;
try {
newPage = (AbstractMEEditorPage) configTemp[i].createExecutableExtension("class"); //$NON-NLS-1$
final FormPage createPage = newPage.createPage(this, modelElementContext);
if (createPage != null) {
addPage(createPage);
}
} catch (final CoreException e1) {
Activator.logException(e1);
}
// put remaining pages into the original configIn array
configIn = new IConfigurationElement[configTemp.length - 1];
for (int j = 0, k = 0; j < configTemp.length - 1; j++, k++) {
if (counter == j) {
j--;
} else {
configIn[j] = configTemp[k];
}
}
break;
}
counter++;
}
// create original MEEditor standard view if no replacement exists
// and put remaining pages into the original configIn array
if (!replaceMEEditor) {
try {
if (editorInput.getProblemFeature() != null) {
mePage = new MEEditorPage(this, editorID, editorDesc, modelElementContext,
modelElementContext.getDomainObject(), editorInput.getProblemFeature());
} else {
mePage = new MEEditorPage(this, editorID, editorDesc, modelElementContext,
modelElementContext.getDomainObject());
}
addPage(mePage);
configIn = configTemp;
} catch (final PartInitException e) {
// JH Auto-generated catch block
Activator.logException(e);
}
}
// Sort the pages by the "after" attribute and omit replaced pages
final List<IConfigurationElement> config = PageCandidate.getPages(configIn);
for (final IConfigurationElement e : config) {
try {
final AbstractMEEditorPage newPage = (AbstractMEEditorPage) e.createExecutableExtension("class"); //$NON-NLS-1$
final FormPage createPage = newPage.createPage(this, modelElementContext);
if (createPage != null) {
addPage(createPage);
}
} catch (final CoreException e1) {
Activator.logException(e1);
}
}
}
/**
* {@inheritDoc}
*/
@Override
public void doSave(IProgressMonitor monitor) {
firePropertyChange(IEditorPart.PROP_DIRTY);
}
/**
* {@inheritDoc}
*/
@Override
public void doSaveAs() {
}
/**
* Save is not allowed as the editor can only modify model elements.
*
* @return false
*/
@Override
public boolean isSaveAsAllowed() {
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void init(IEditorSite site, final IEditorInput input) throws PartInitException {
super.init(site, input);
if (input instanceof MEEditorInput) {
setInput(input);
meInput = (MEEditorInput) input;
modelElementContext = meInput.getModelElementContext();
composedAdapterFactory = new ComposedAdapterFactory(new AdapterFactory[] {
new ReflectiveItemProviderAdapterFactory(),
new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) });
shortLabelProvider = new ShortLabelProvider(composedAdapterFactory);
setPartName(shortLabelProvider.getText(modelElementContext.getDomainObject()));
setTitleImage(shortLabelProvider.getImage(modelElementContext.getDomainObject()));
modelElementContextListener = new ECPContextDisposedListener() {
@Override
public void contextDisposed() {
close(false);
}
};
modelElementContext.addECPContextDisposeListener(modelElementContextListener);
modelElementChangeListener = new ECPModelElementChangeListener(modelElementContext.getDomainObject()) {
@Override
public void onChange(Notification notification) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
updateIcon();
setPartName(shortLabelProvider.getText(modelElementContext.getDomainObject()));
if (mePage != null) {
mePage.updateSectionTitle();
// mePage.updateLiveValidation();
}
updateStatusMessage();
}
});
}
};
initStatusProvider();
updateStatusMessage();
// labelProviderListener = new ILabelProviderListener() {
// public void labelProviderChanged(LabelProviderChangedEvent event) {
// if(!titleImage.isDisposed())
// titleImage.dispose();
// titleImage=meInput.getImageDescriptor().createImage();
// updateIcon();
// }
// };
// meInput.getLabelProvider().addListener(labelProviderListener);
} else {
throw new PartInitException("MEEditor is only appliable for MEEditorInputs"); //$NON-NLS-1$
}
}
private void initStatusProvider() {
final IConfigurationElement[] configurationElements = Platform.getExtensionRegistry()
.getConfigurationElementsFor(
STATUS_EXTENSIONPOINT_ID);
final ArrayList<IConfigurationElement> provider = new ArrayList<IConfigurationElement>();
provider.addAll(Arrays.asList(configurationElements));
int priority = 0;
for (final IConfigurationElement e : provider) {
try {
final StatusMessageProvider statusMessageProvider = (StatusMessageProvider) e
.createExecutableExtension("class"); //$NON-NLS-1$
final int newpriority = statusMessageProvider.canRender(modelElementContext.getDomainObject());
if (newpriority > priority) {
priority = newpriority;
this.statusMessageProvider = statusMessageProvider;
}
} catch (final CoreException e1) {
Activator.logException(e1);
}
}
}
private void updateStatusMessage() {
if (statusMessageProvider != null) {
getEditorSite().getActionBars().getStatusLineManager()
.setMessage(statusMessageProvider.getMessage(modelElementContext.getDomainObject()));
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isDirty() {
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void setFocus() {
super.setFocus();
if (mePage != null) {
mePage.setFocus();
}
updateStatusMessage();
}
/**
* {@inheritDoc}
*/
@Override
public void dispose() {
modelElementChangeListener.remove();
modelElementContext.dispose();
meInput.dispose();
// ((MEEditorInput) getEditorInput()).getLabelProvider().removeListener(labelProviderListener);
composedAdapterFactory.dispose();
shortLabelProvider.dispose();
// meInput.dispose();
getSite().setSelectionProvider(null);
super.dispose();
}
private void updateIcon() {
setTitleImage(shortLabelProvider.getImage(modelElementContext.getDomainObject()));
// TODO AS: Debug why sometimes the page is null - not disposed Adapter?
if (mePage != null) {
try {
mePage.getManagedForm().getForm()
.setImage(shortLabelProvider.getImage(modelElementContext.getDomainObject()));
} catch (final SWTException e) {
// Catch in case Editor is directly closed after change.
}
}
}
}