/******************************************************************************* | |
* <copyright> | |
* | |
* Copyright (c) 2013, 2013 SAP AG. | |
* 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: | |
* SAP AG - initial API, implementation and documentation | |
* | |
* </copyright> | |
* | |
*******************************************************************************/ | |
package org.eclipse.fmc.blockdiagram.editor.property; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import org.eclipse.core.runtime.IAdaptable; | |
import org.eclipse.emf.common.notify.AdapterFactory; | |
import org.eclipse.emf.common.notify.Notification; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.emf.ecore.EStructuralFeature; | |
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; | |
import org.eclipse.emf.edit.domain.IEditingDomainProvider; | |
import org.eclipse.emf.edit.provider.IItemPropertySource; | |
import org.eclipse.emf.edit.ui.provider.PropertySource; | |
import org.eclipse.emf.transaction.DemultiplexingListener; | |
import org.eclipse.emf.transaction.NotificationFilter; | |
import org.eclipse.emf.transaction.RecordingCommand; | |
import org.eclipse.emf.transaction.TransactionalEditingDomain; | |
import org.eclipse.fmc.blockdiagram.editor.util.FMCUtil; | |
import org.eclipse.gef.GraphicalEditPart; | |
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; | |
import org.eclipse.graphiti.mm.pictograms.PictogramElement; | |
import org.eclipse.graphiti.services.Graphiti; | |
import org.eclipse.graphiti.ui.editor.DiagramEditor; | |
import org.eclipse.jface.viewers.ISelection; | |
import org.eclipse.jface.viewers.IStructuredSelection; | |
import org.eclipse.jface.viewers.StructuredSelection; | |
import org.eclipse.swt.widgets.Composite; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.ui.IActionBars; | |
import org.eclipse.ui.IWorkbenchPart; | |
import org.eclipse.ui.views.properties.IPropertySource; | |
import org.eclipse.ui.views.properties.IPropertySourceProvider; | |
import org.eclipse.ui.views.properties.tabbed.AdvancedPropertySection; | |
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; | |
/** | |
* Default implementation of a table based property sheet that lets you change | |
* every property of the selected EObject. | |
* | |
* @author Rainer Thome | |
* | |
*/ | |
public class DefaultPropertySection extends AdvancedPropertySection implements | |
IPropertySourceProvider { | |
protected TransactionalEditingDomain editingDomain; | |
private DemultiplexingListener eventListener = new DemultiplexingListener( | |
getFilter()) { | |
protected void handleNotification(TransactionalEditingDomain domain, | |
Notification notification) { | |
update(notification); | |
} | |
}; | |
protected boolean disposed; | |
public IPropertySource getPropertySource(Object object) { | |
if (object instanceof IPropertySource) { | |
return (IPropertySource) object; | |
} | |
AdapterFactory adapterFactory = getAdapterFactory(object); | |
if (adapterFactory != null) { | |
IItemPropertySource itemPropertySource = (IItemPropertySource) adapterFactory | |
.adapt(object, IItemPropertySource.class); | |
if (itemPropertySource != null) { | |
return new PropertySource(object, itemPropertySource); | |
} | |
} | |
if (object instanceof IAdaptable) { | |
return (IPropertySource) ((IAdaptable) object) | |
.getAdapter(IPropertySource.class); | |
} | |
return null; | |
} | |
private IPropertySourceProvider getPropertySourceProvider() { | |
return this; | |
} | |
private AdapterFactory getAdapterFactory(Object object) { | |
if (getEditingDomain() instanceof AdapterFactoryEditingDomain) { | |
return ((AdapterFactoryEditingDomain) getEditingDomain()) | |
.getAdapterFactory(); | |
} | |
return null; | |
} | |
private void setActionBars(IActionBars actionBars) { | |
if (actionBars != null) { | |
actionBars.getMenuManager().removeAll(); | |
actionBars.getToolBarManager().removeAll(); | |
actionBars.getStatusLineManager().removeAll(); | |
page.makeContributions(actionBars.getMenuManager(), | |
actionBars.getToolBarManager(), | |
actionBars.getStatusLineManager()); | |
actionBars.getToolBarManager().update(true); | |
} | |
} | |
@Override | |
public void createControls(final Composite parent, | |
TabbedPropertySheetPage aTabbedPropertySheetPage) { | |
super.createControls(parent, aTabbedPropertySheetPage); | |
page.setPropertySourceProvider(getPropertySourceProvider()); | |
setActionBars(aTabbedPropertySheetPage.getSite().getActionBars()); | |
} | |
@Override | |
public void setInput(IWorkbenchPart part, ISelection selection) { | |
// set the current editing domain | |
IEditingDomainProvider provider = (IEditingDomainProvider) part | |
.getAdapter(IEditingDomainProvider.class); | |
assert provider.getEditingDomain() instanceof TransactionalEditingDomain; | |
editingDomain = (TransactionalEditingDomain) provider | |
.getEditingDomain(); | |
// transform the selection | |
List<Object> objects = new ArrayList<Object>(); | |
if (selection instanceof IStructuredSelection) { | |
Iterator<?> it = ((IStructuredSelection) selection).iterator(); | |
while (it.hasNext()) { | |
Object next = it.next(); | |
if (next instanceof GraphicalEditPart) { | |
GraphicalEditPart editPart = (GraphicalEditPart) next; | |
PictogramElement pe = (PictogramElement) editPart | |
.getModel(); | |
Object modelObj = Graphiti.getLinkService() | |
.getBusinessObjectForLinkedPictogramElement(pe); | |
objects.add(modelObj); | |
} else if (next instanceof EObject) { | |
objects.add(next); | |
} | |
} | |
} | |
StructuredSelection newSelection = new StructuredSelection(objects); | |
super.setInput(part, newSelection); | |
} | |
public NotificationFilter getFilter() { | |
return NotificationFilter | |
.createEventTypeFilter(Notification.SET) | |
.or(NotificationFilter | |
.createEventTypeFilter(Notification.UNSET)) | |
.and(NotificationFilter.createNotifierTypeFilter(EObject.class)); | |
} | |
@Override | |
public void aboutToBeHidden() { | |
if (getEditingDomain() != null) { | |
getEditingDomain().removeResourceSetListener(getEventListener()); | |
} | |
super.aboutToBeHidden(); | |
} | |
@Override | |
public void aboutToBeShown() { | |
super.aboutToBeShown(); | |
if (getEditingDomain() != null) { | |
getEditingDomain().addResourceSetListener(getEventListener()); | |
} | |
} | |
private DemultiplexingListener getEventListener() { | |
return eventListener; | |
} | |
private TransactionalEditingDomain getEditingDomain() { | |
return editingDomain; | |
} | |
public void update(final Notification notification) { | |
final EObject eObject = (EObject) notification.getNotifier(); | |
if (!isDisposed() && isSelection(eObject) && !isDeleted(eObject)) { | |
getDisplay().asyncExec(new Runnable() { | |
public void run() { | |
if (!isDisposed() && isSelection(eObject) | |
&& !isDeleted(eObject)) | |
refresh(); | |
DiagramEditor editor = (DiagramEditor) FMCUtil | |
.getActiveEditor(); | |
TransactionalEditingDomain domain = editor | |
.getEditingDomain(); | |
final PictogramElement pe = editor | |
.getSelectedPictogramElements()[0]; | |
Map<EStructuralFeature, GraphicsAlgorithm> map = FMCUtil | |
.getLinkedFeaturesMap(pe, eObject); | |
final GraphicsAlgorithm algo; | |
if (map != null) { | |
algo = map.get(notification.getFeature()); | |
domain.getCommandStack().execute( | |
new RecordingCommand(domain) { | |
@Override | |
protected void doExecute() { | |
if (algo != null | |
&& algo instanceof org.eclipse.graphiti.mm.algorithms.AbstractText) | |
((org.eclipse.graphiti.mm.algorithms.AbstractText) algo).setValue(notification | |
.getNewStringValue()); | |
} | |
}); | |
editor.getDiagramBehavior().refresh(); | |
} | |
} | |
}); | |
} | |
} | |
@Override | |
public void dispose() { | |
super.dispose(); | |
this.disposed = true; | |
} | |
protected boolean isDisposed() { | |
return this.disposed; | |
} | |
protected boolean isSelection(EObject eObject) { | |
ISelection selection = getSelection(); | |
if (selection == null) { | |
return false; | |
} | |
IStructuredSelection s = (IStructuredSelection) selection; | |
if (s.size() > 1) { | |
return false; | |
} | |
for (Iterator<?> it = s.iterator(); it.hasNext();) { | |
if (eObject == it.next()) { | |
return true; | |
} | |
} | |
return false; | |
} | |
protected boolean isDeleted(EObject eObject) { | |
return eObject.eResource() == null; | |
} | |
protected Display getDisplay() { | |
return getPart().getSite().getShell().getDisplay(); | |
} | |
} |