/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.views.properties.xwt; import java.util.HashSet; import java.util.Set; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.papyrus.infra.constraints.ConstraintDescriptor; import org.eclipse.papyrus.infra.constraints.constraints.Constraint; import org.eclipse.papyrus.infra.constraints.runtime.ConstraintFactory; import org.eclipse.papyrus.views.properties.Activator; import org.eclipse.papyrus.views.properties.contexts.Section; import org.eclipse.papyrus.views.properties.contexts.View; import org.eclipse.papyrus.views.properties.modelelement.DataSource; import org.eclipse.papyrus.views.properties.modelelement.DataSourceFactory; import org.eclipse.papyrus.views.properties.runtime.DisplayEngine; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection; import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; /** * An Implementation of ISection for the TabbedPropertyView framework. * The XWTSection uses an XWT File to display the SWT Controls, and * a DataSource for DataBinding * * @author Camille Letavernier */ public class XWTSection extends AbstractPropertySection implements IChangeListener { private Section section; private DataSource source; private View view; private Composite self; private DisplayEngine display; private Set<Constraint> constraints; /** * Constructor. * * @param section * The Section object containing the Metadata for the XWTSection * @param view * The view this section belongs to * @param display * The display engine that will generate the SWT Controls */ public XWTSection(Section section, View view, DisplayEngine display) { this.section = section; this.view = view; this.display = display; } @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { self = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(1, false); layout.marginHeight = 0; layout.marginWidth = 0; self.setLayout(layout); layout = new GridLayout(1, false); layout.verticalSpacing = 0; layout.marginHeight = 0; layout.marginWidth = 5; parent.setLayout(layout); GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); self.setLayoutData(data); self.setBackground(parent.getBackground()); self.setBackgroundMode(SWT.INHERIT_DEFAULT); } @Override public void setInput(IWorkbenchPart part, ISelection selection) { if(selection == getSelection()) { return; } //Sets the initial input, *or* changes the input for the same view : we need to clean the cache DataSourceFactory.instance.removeFromCache(getSelection(), view); super.setInput(part, selection); if(selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection)selection; setSource(DataSourceFactory.instance.createDataSourceFromSelection(structuredSelection, view)); } } private void setSource(DataSource source) { if(this.source != null) { this.source.removeChangeListener(this); this.source.dispose(); } this.source = source; if(section.getConstraints().size() > 0) { source.addChangeListener(this); } } /** * Displays the section * * @param refresh * If true, and the section has already been displayed, the controls will be * regenerated. If false, the section will only be displayed if it hasn't been * displayed yet, or if the display engine allows duplication of sections */ public void display(boolean refresh) { if(self.isDisposed()) { Activator.log.debug("Error : widget is disposed"); //$NON-NLS-1$ dispose(); return; } if(!isApplied()) { hide(); return; } if(refresh) { display.refreshSection(self, section, source); } else { display.createSection(self, section, source); } } private void hide() { display.removeSection(self); } @Override public void refresh() { display(false); } /** * Tests if this section is applied. A section is applied if it doesn't have * any constraint, or if at least one of its constraints match the current selection * * @return * True if the section should be displayed */ protected boolean isApplied() { if(getConstraints().isEmpty()) { return true; } ISelection selection = getSelection(); //Return true only if at least one constraint matches the selection for(Constraint constraint : getConstraints()) { if(constraint.match((IStructuredSelection)selection)) { return true; } } return false; } protected Set<Constraint> getConstraints() { if(constraints == null) { constraints = new HashSet<Constraint>(); for(ConstraintDescriptor constraintDescriptor : section.getConstraints()) { Constraint constraint = ConstraintFactory.getInstance().createFromModel(constraintDescriptor); if(constraint != null) { constraints.add(constraint); } } } return constraints; } @Override public void dispose() { //Dispose the DataSource if(source != null) { source.removeChangeListener(this); source.dispose(); } //Dispose the SWT Composite if(self != null) { self.dispose(); } //Clean the DataSource cache DataSourceFactory.instance.removeFromCache(getSelection(), view); super.dispose(); } @Override public IStructuredSelection getSelection() { return (IStructuredSelection)super.getSelection(); } @Override public String toString() { return "XWTSection : " + section.getName(); //$NON-NLS-1$ } public void handleChange(ChangeEvent event) { display(true); } }