blob: 2616bf1d02dfb4e20675eb1cfbe53d08be2d40de [file] [log] [blame]
/*******************************************************************************
* <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();
}
}