blob: ee8a6c172b3585d9f6b233eb0b293462e80e3822 [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 v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
******************************************************************************/
package org.eclipse.emf.ecp.editor.mecontrols.melinkcontrol.associationclasscontrol;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecp.common.commands.ECPCommand;
import org.eclipse.emf.ecp.editor.mecontrols.AbstractMEControl;
import org.eclipse.emf.ecp.editor.mecontrols.melinkcontrol.MELinkControl;
import org.eclipse.emf.ecp.editor.mecontrols.melinkcontrol.MELinkControlFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
/**
* The GUI control for AssociationClassElements.
*
* @author Michael Haeger
*/
public class AssociationClassControl extends AbstractMEControl {
/**
* Command to rebuild the links.
*
* @author Michael Haeger
*/
private final class RebuildLinksCommand extends ECPCommand {
private int sizeLimit;
public RebuildLinksCommand(EObject eObject) {
super(eObject);
}
public RebuildLinksCommand(EObject eObject, int sizeLimit) {
this(eObject);
this.sizeLimit = sizeLimit;
}
@Override
protected void doRun() {
Object evaluatedFeature = getModelElement().eGet(eReference);
LinkedList<Object> associations = new LinkedList<Object>();
if (eReference.isMany()) {
associations.addAll((List<?>) evaluatedFeature);
} else {
associations.add(evaluatedFeature);
}
if (associations.size() <= sizeLimit) {
linkArea = getToolkit().createComposite(composite, style);
linkArea.setLayout(tableLayout);
linkArea.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
} else {
scrollPane = new ScrolledComposite(composite, SWT.V_SCROLL | SWT.H_SCROLL);
scrollPane.setBackgroundMode(SWT.INHERIT_FORCE);
scrollClient = new Composite(scrollPane, style);
scrollPane.setContent(scrollClient);
getToolkit().getColors().createColor("white", 255, 255, 255);
scrollClient.setBackground(getToolkit().getColors().getColor("white"));
scrollPane.setExpandVertical(true);
scrollPane.setExpandHorizontal(true);
RowLayout layout = new RowLayout(SWT.VERTICAL);
layout.wrap = true;
scrollClient.setLayout(layout);
GridData spec = new GridData(400, 150);
spec.horizontalAlignment = GridData.FILL;
spec.grabExcessHorizontalSpace = true;
scrollPane.setLayoutData(spec);
scrollPane.setMinSize(150, 150);
}
for (Object association : associations) {
MELinkControlFactory controlFactory = new MELinkControlFactory();
MELinkControl meControl = controlFactory.createMELinkControl(getItemPropertyDescriptor(),
(EObject) association, getModelElement(), getContext());
meControl.createControl((associations.size() <= sizeLimit ? linkArea : scrollClient), style,
getItemPropertyDescriptor(), (EObject) association, getModelElement(), getToolkit(), getContext());
linkControls.add(meControl);
}
if (scrollPane != null && !scrollPane.isDisposed()) {
scrollPane.setMinSize(scrollClient.computeSize(SWT.DEFAULT, SWT.DEFAULT));
scrollClient.layout();
scrollPane.layout();
} else {
linkArea.layout();
}
if (associations.size() > 0) {
section.setExpanded(false);
section.setExpanded(true);
}
}
}
private static final int PRIORITY = 2;
private EReference eReference;
private int style;
private ScrolledComposite scrollPane;
private Section section;
private Composite linkArea;
private Composite composite;
private Composite scrollClient;
private GridLayout tableLayout;
private org.eclipse.emf.ecp.editor.ModelElementChangeListener modelElementChangeListener;
private ArrayList<MELinkControl> linkControls;
/**
* {@inheritDoc}
*/
@Override
public int canRender(IItemPropertyDescriptor itemPropertyDescriptor, EObject modelElement) {
Object feature = itemPropertyDescriptor.getFeature(modelElement);
if (getContext() != null
&& feature instanceof EReference
&& getContext().getMetaModelElementContext().isAssociationClassElement(
((EReference) feature).getEReferenceType())) {
return PRIORITY;
}
return AbstractMEControl.DO_NOT_RENDER;
}
/**
* {@inheritDoc}
*/
@Override
public void dispose() {
modelElementChangeListener.remove();
for (MELinkControl link : linkControls) {
link.dispose();
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.ecp.editor.mecontrols.AbstractMEControl#createControl(org.eclipse.swt.widgets.Composite,
* int)
*/
@Override
protected Control createControl(Composite parent, int style) {
linkControls = new ArrayList<MELinkControl>();
eReference = (EReference) getItemPropertyDescriptor().getFeature(getModelElement());
modelElementChangeListener = new org.eclipse.emf.ecp.editor.ModelElementChangeListener(getModelElement()) {
@Override
public void onChange(Notification notification) {
if ((notification.getEventType() != Notification.RESOLVE)
&& (notification.getFeature().equals(eReference))) {
rebuildLinkSection();
}
}
};
this.style = style;
tableLayout = new GridLayout(1, false);
section = getToolkit().createSection(parent, Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED);
section.setText(getItemPropertyDescriptor().getDisplayName(getModelElement()));
createSectionToolbar(section, getToolkit());
composite = getToolkit().createComposite(section, style);
composite.setLayout(tableLayout);
rebuildLinkSection();
section.setClient(composite);
return section;
}
private void createSectionToolbar(Section section, FormToolkit toolkit) {
ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
ToolBar toolbar = toolBarManager.createControl(section);
final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
toolbar.setCursor(handCursor);
// Cursor needs to be explicitly disposed
toolbar.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (!handCursor.isDisposed()) {
handCursor.dispose();
}
}
});
toolBarManager.add(new AddAssociationClassAction(getModelElement(), eReference, getItemPropertyDescriptor(),
getContext()));
toolBarManager.add(new NewAssociationClassAction(getModelElement(), eReference, getItemPropertyDescriptor(),
getContext()));
toolBarManager.update(true);
section.setTextClient(toolbar);
}
private void rebuildLinkSection() {
final int sizeLimit = 5;
for (MELinkControl link : linkControls) {
link.dispose();
}
if (scrollPane != null) {
scrollPane.dispose();
}
if (linkArea != null) {
linkArea.dispose();
}
linkControls.clear();
new RebuildLinksCommand(getModelElement(), sizeLimit).run(true);
}
}