Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus')
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/Activator.java90
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/GeneratorExtensionPoint.java48
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/LayoutExtensionPoint.java47
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/AbstractQVTGenerator.java162
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EcoreGenerator.java244
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EditContextGenerator.java87
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/IGenerator.java122
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/ProfileGenerator.java223
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/ILayoutGenerator.java46
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/StandardLayoutGenerator.java218
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/Messages.java86
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/messages.properties30
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/AbstractCreateContextPage.java57
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextMainPage.java73
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextWizard.java342
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/GeneratorPage.java126
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/SelectFieldsPage.java271
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/ExtensionFilter.java61
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/FileChooser.java144
-rw-r--r--sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/TernaryButton.java218
20 files changed, 2695 insertions, 0 deletions
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/Activator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/Activator.java
new file mode 100644
index 00000000000..351af5b163f
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/Activator.java
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * 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.properties.generation;
+
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.papyrus.log.LogHelper;
+import org.eclipse.papyrus.properties.generation.extensionpoint.GeneratorExtensionPoint;
+import org.eclipse.papyrus.properties.generation.extensionpoint.LayoutExtensionPoint;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/** The activator class controls the plug-in life cycle */
+public class Activator extends AbstractUIPlugin {
+
+ /** the plug-in's logger */
+ public static LogHelper log;
+
+ /** The plug-in ID */
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.properties.generation"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ @Override
+ public void start(final BundleContext context) throws Exception {
+ super.start(context);
+ Activator.plugin = this;
+ log = new LogHelper(plugin);
+
+ new GeneratorExtensionPoint();
+ new LayoutExtensionPoint();
+ }
+
+ @Override
+ public void stop(final BundleContext context) throws Exception {
+ Activator.plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return Activator.plugin;
+ }
+
+ /**
+ * Returns the image at the given path from this plugin
+ *
+ * @param path
+ * the path of the image to be displayed
+ * @return The Image at the given location, or null if it couldn't be found
+ */
+ public Image getImage(String path) {
+ return getImage(PLUGIN_ID, path);
+ }
+
+ /**
+ * Returns the image from the given image descriptor
+ *
+ * @param pluginId
+ * The plugin in which the image is located
+ * @param path
+ * The path to the image from the plugin
+ * @return
+ * The Image at the given location, or null if it couldn't be found
+ */
+ public Image getImage(String pluginId, String path) {
+ final ImageRegistry registry = getImageRegistry();
+ String key = pluginId + "/" + path; //$NON-NLS-1$
+ Image image = registry.get(key);
+ if(image == null) {
+ registry.put(key, AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, path));
+ image = registry.get(key);
+ }
+ return image;
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/GeneratorExtensionPoint.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/GeneratorExtensionPoint.java
new file mode 100644
index 00000000000..7b86ddf6942
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/GeneratorExtensionPoint.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * 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.properties.generation.extensionpoint;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.generation.generators.IGenerator;
+import org.eclipse.papyrus.properties.generation.wizard.CreateContextWizard;
+
+/**
+ * Handles the extension point org.eclipse.papyrus.properties.generation.generator
+ * Registers the given Generator to the Property view generation wizard
+ *
+ * @author Camille Letavernier
+ */
+public class GeneratorExtensionPoint {
+
+ private final String EXTENSION_ID = "org.eclipse.papyrus.properties.generation.generator"; //$NON-NLS-1$
+
+ /**
+ * Constructor.
+ */
+ public GeneratorExtensionPoint() {
+
+ IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID);
+
+ for(IConfigurationElement e : config) {
+ String generatorClassName = e.getAttribute("generator"); //$NON-NLS-1$
+ try {
+ Class<? extends IGenerator> generatorClass = Class.forName(generatorClassName).asSubclass(IGenerator.class);
+ IGenerator generator = generatorClass.newInstance();
+ CreateContextWizard.addGenerator(generator);
+ } catch (Exception ex) {
+ Activator.log.error("Cannot instantiate the generator : " + generatorClassName, ex); //$NON-NLS-1$
+ }
+ }
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/LayoutExtensionPoint.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/LayoutExtensionPoint.java
new file mode 100644
index 00000000000..7792d42025f
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/extensionpoint/LayoutExtensionPoint.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * 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.properties.generation.extensionpoint;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.generation.layout.ILayoutGenerator;
+import org.eclipse.papyrus.properties.generation.wizard.CreateContextWizard;
+
+/**
+ * Handles the extension point org.eclipse.papyrus.properties.generation.layout
+ * Registers the given layout Generator to the Property view generation wizard
+ *
+ * @author Camille Letavernier
+ */
+public class LayoutExtensionPoint {
+
+ private final String EXTENSION_ID = "org.eclipse.papyrus.properties.generation.layout"; //$NON-NLS-1$
+
+ /**
+ * Constructor.
+ */
+ public LayoutExtensionPoint() {
+ IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID);
+
+ for(IConfigurationElement e : config) {
+ String generatorClassName = e.getAttribute("generator"); //$NON-NLS-1$
+ try {
+ Class<? extends ILayoutGenerator> generatorClass = Class.forName(generatorClassName).asSubclass(ILayoutGenerator.class);
+ ILayoutGenerator generator = generatorClass.newInstance();
+ CreateContextWizard.addLayoutGenerator(generator);
+ } catch (Exception ex) {
+ Activator.log.error("Cannot instantiate the layout generator : " + generatorClassName, ex); //$NON-NLS-1$
+ }
+ }
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/AbstractQVTGenerator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/AbstractQVTGenerator.java
new file mode 100644
index 00000000000..e3c6e4c6b96
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/AbstractQVTGenerator.java
@@ -0,0 +1,162 @@
+/*****************************************************************************
+ * 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.properties.generation.generators;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.m2m.qvt.oml.BasicModelExtent;
+import org.eclipse.m2m.qvt.oml.ExecutionContextImpl;
+import org.eclipse.m2m.qvt.oml.ExecutionDiagnostic;
+import org.eclipse.m2m.qvt.oml.ModelExtent;
+import org.eclipse.m2m.qvt.oml.TransformationExecutor;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.generation.Activator;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * An Abstract generator based on QVTO transformations.
+ * Subclasses should specify the .qvto file and ModelExtents, as well as the
+ * SWT widgets allowing the user to chose the input models.
+ *
+ * @author Camille Letavernier
+ */
+public abstract class AbstractQVTGenerator implements IGenerator, Listener {
+
+ /**
+ * The Context created by the transformation.
+ */
+ protected Context generatedContext;
+
+ /**
+ * The output ModelExtent
+ */
+ protected ModelExtent out;
+
+ private Set<Listener> listeners = new HashSet<Listener>();
+
+ public Context generate(URI targetURI) {
+
+ URI transformationURI = getTransformationURI();
+ TransformationExecutor executor = new TransformationExecutor(transformationURI);
+
+ List<ModelExtent> extents = getModelExtents();
+
+ ExecutionContextImpl context = new ExecutionContextImpl();
+ context.setConfigProperty("keepModeling", true); //$NON-NLS-1$
+ //context.setLog(new WriterLog(new OutputStreamWriter(System.out)));
+
+ ExecutionDiagnostic result = executor.execute(context, extents.toArray(new ModelExtent[0]));
+
+ if(result.getSeverity() == org.eclipse.emf.common.util.Diagnostic.OK) {
+ List<EObject> outObjects = getOutContextExtent().getContents();
+ Object objectResult = outObjects.get(0);
+ if(!(objectResult instanceof Context)) {
+ return null;
+ }
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ Resource contextResource = resourceSet.createResource(targetURI);
+ contextResource.getContents().addAll(outObjects);
+
+ return generatedContext = getContext(outObjects);
+ } else {
+ IStatus status = BasicDiagnostic.toIStatus(result);
+ Activator.getDefault().getLog().log(status);
+ }
+ return generatedContext = null;
+ }
+
+ /**
+ * @return the list of in/out/inout ModelExtents (including the OutContextExtent)
+ * Implementors should ensure they add the outContextExtent to the list.
+ */
+ abstract protected List<ModelExtent> getModelExtents();
+
+ /**
+ * @return the ModelExtent containing the generated context
+ */
+ protected ModelExtent getOutContextExtent() {
+ if(out == null) {
+ out = new BasicModelExtent();
+ }
+
+ return out;
+ }
+
+ /**
+ * @return the URI of the QVTO transformation file.
+ */
+ abstract protected URI getTransformationURI();
+
+ /**
+ * Loads the EObject from the given URI.
+ *
+ * @param uri
+ * The URI from which the EObject is loaded
+ * @return
+ * The loaded EObject, or null if an error occured
+ * @throws IOException
+ * If the URI isn't a valid EObject
+ */
+ protected EObject loadEMFModel(URI uri) throws IOException {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ try {
+ Resource resource = resourceSet.getResource(uri, true);
+ if(resource != null) {
+ if(!resource.getContents().isEmpty()) {
+ return resource.getContents().get(0);
+ }
+ }
+ } catch (Exception ex) {
+ throw new IOException(ex.toString());
+ }
+
+ return null;
+ }
+
+ public void addListener(Listener listener) {
+ listeners.add(listener);
+ }
+
+ public void handleEvent(Event event) {
+ for(Listener listener : listeners) {
+ listener.handleEvent(event);
+ }
+ }
+
+ /**
+ * Return the generated Context from a list of EObjects
+ *
+ * @param outObjects
+ * The list of EObjects from which the context will be retrieved
+ * @return
+ * The main generated context
+ */
+ protected Context getContext(List<EObject> outObjects) {
+ Object objectResult = outObjects.get(0);
+ if(!(objectResult instanceof Context)) {
+ return null;
+ }
+ return (Context)objectResult;
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EcoreGenerator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EcoreGenerator.java
new file mode 100644
index 00000000000..8618a2a3ae0
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EcoreGenerator.java
@@ -0,0 +1,244 @@
+/*****************************************************************************
+ * 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.properties.generation.generators;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.m2m.qvt.oml.BasicModelExtent;
+import org.eclipse.m2m.qvt.oml.ModelExtent;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.papyrus.properties.generation.wizard.widget.FileChooser;
+import org.eclipse.papyrus.properties.root.PropertiesRoot;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+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.swt.widgets.Label;
+
+/**
+ * An IGenerator to create Property view contexts from an Ecore metamodel
+ * FIXME : The generator doesn't seem to keep the Metaclass inheritance
+ *
+ * @author Camille Letavernier
+ */
+public class EcoreGenerator extends AbstractQVTGenerator {
+
+ private FileChooser sourceFileChooser;
+
+ private EPackage ecorePackage;
+
+ public void createControls(Composite parent) {
+ Composite root = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ root.setLayout(layout);
+
+ Label sourceLabel = new Label(root, SWT.NONE);
+ sourceLabel.setText(Messages.EcoreGenerator_source);
+ GridData data = new GridData();
+ data.widthHint = 100;
+ sourceLabel.setLayoutData(data);
+
+ sourceFileChooser = new FileChooser(root, false);
+ sourceFileChooser.setFilterExtensions(new String[]{ "ecore" }); //$NON-NLS-1$
+ sourceFileChooser.addListener(this);
+ }
+
+ public String getDescription() {
+ return Messages.EcoreGenerator_ecoreGeneratorDescription;
+ }
+
+ public boolean isReady() {
+ return sourceFileChooser.getFilePath() != null;
+ }
+
+ public String getName() {
+ return Messages.EcoreGenerator_ecoreGeneratorName;
+ }
+
+ public boolean isSelectedSingle(Property property) {
+ EStructuralFeature feature = getFeature(property);
+ if(feature.isDerived()) {
+ return false;
+ }
+
+ if(!feature.isChangeable()) {
+ return false;
+ }
+
+ if(feature instanceof EReference) {
+ EReference reference = (EReference)feature;
+ if(reference.isContainer() || reference.isContainment())
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Retrieve the EStructuralFeature corresponding to the given property
+ *
+ * @param property
+ * @return
+ * The EStructuralFeature corresponding to the given property
+ */
+ protected EStructuralFeature getFeature(Property property) {
+ List<String> path = getPath(property);
+ path.remove(0); //Root = EPackage
+
+ EPackage currentPackage = ecorePackage;
+
+ EClassifier classifier = findClassifier(path, currentPackage);
+ if(classifier == null) {
+ return null;
+ }
+
+ if(!(classifier instanceof EClass)) {
+ return null;
+ }
+
+ EClass eClass = (EClass)classifier;
+ return eClass.getEStructuralFeature(property.getName());
+ }
+
+ /**
+ * Retrieve the Classifier corresponding to the given path, in the given EPackage
+ *
+ * @param path
+ * The list of package and subpackages names, and the classifier name, i.e.
+ * the list of segments in the classifier's qualified name
+ * @param source
+ * The root EPackage in which the classifier should be retrieved
+ * @return
+ * The corresponding EClassifier, or null if it couldn't be retrieved
+ */
+ protected EClassifier findClassifier(List<String> path, EPackage source) {
+ String qualifier = path.get(0);
+ EClassifier classifier = source.getEClassifier(qualifier);
+ if(classifier == null) {
+ source = findSubPackage(source, qualifier);
+ if(source == null) {
+ return null;
+ }
+ path.remove(0);
+ return findClassifier(path, source);
+ } else {
+ return classifier;
+ }
+ }
+
+ /**
+ * Retrieve the subpackage corresponding to the given packageName, in the given
+ * package
+ *
+ * @param currentPackage
+ * The EPackage in which the subpackage should be found
+ * @param packageName
+ * The name of the EPackage to find
+ * @return
+ * The corresponding EPackage, or null if it couldn't be found
+ */
+ protected EPackage findSubPackage(EPackage currentPackage, String packageName) {
+ for(EPackage pack : currentPackage.getESubpackages()) {
+ if(pack.getName().equals(packageName))
+ return pack;
+ }
+ return null;
+ }
+
+ private List<String> getPath(Property property) {
+ List<String> result = getPath(property.getContextElement());
+ return result;
+ }
+
+ private List<String> getPath(DataContextElement element) {
+ List<String> result;
+ if(element.getPackage() == null) {
+ result = new LinkedList<String>();
+ } else {
+ result = getPath(element.getPackage());
+ }
+
+ result.add(element.getName());
+ return result;
+ }
+
+ public boolean isSelectedMultiple(Property property) {
+ if(!isSelectedSingle(property)) {
+ return false;
+ }
+
+ EStructuralFeature feature = getFeature(property);
+
+ Set<String> validDataTypes = new HashSet<String>(Arrays.asList(new String[]{ "int", "boolean", "float", "double" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ if(feature.getEType() instanceof EDataType) {
+ if(validDataTypes.contains(((EDataType)feature.getEType()).getInstanceTypeName()))
+ return true;
+ }
+
+ if(feature.getEType() instanceof EEnum) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean isSelectedSingle(Property property, DataContextElement element) {
+ return isSelectedSingle(property);
+ }
+
+ public boolean isSelectedMultiple(Property property, DataContextElement element) {
+ return isSelectedMultiple(property);
+ }
+
+ @Override
+ protected URI getTransformationURI() {
+ return URI.createPlatformPluginURI("org.eclipse.papyrus.properties.generation/transforms/ecore2datacontext.qvto", true); //$NON-NLS-1$
+ }
+
+ @Override
+ protected List<ModelExtent> getModelExtents() {
+ try {
+ URI packageURI = URI.createPlatformResourceURI(sourceFileChooser.getFilePath(), true);
+ ecorePackage = (EPackage)loadEMFModel(packageURI);
+ ModelExtent inPackage = new BasicModelExtent(Collections.singletonList(ecorePackage));
+
+ PropertiesRoot root = ConfigurationManager.instance.getPropertiesRoot();
+ ModelExtent inRoot = new BasicModelExtent(Collections.singletonList(root));
+
+ LinkedList<ModelExtent> result = new LinkedList<ModelExtent>();
+ result.add(inPackage);
+ result.add(inRoot);
+ result.add(getOutContextExtent());
+ return result;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EditContextGenerator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EditContextGenerator.java
new file mode 100644
index 00000000000..c1379bcf052
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/EditContextGenerator.java
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ * 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.properties.generation.generators;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * Incubation
+ *
+ * An implementation of IGenerator used to re-generate a Context from an existing one
+ *
+ * @author Camille Letavernier
+ */
+public class EditContextGenerator implements IGenerator {
+
+ public Context generate(URI targetURI) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void createControls(Composite parent) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public String getDescription() {
+ return Messages.EditContextGenerator_generateNewContext;
+ }
+
+ public boolean isReady() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public String getName() {
+ return Messages.EditContextGenerator_importExistingContext;
+ }
+
+ public boolean isSelectedSingle(Property property) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isSelectedMultiple(Property property) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isSelectedSingle(Property property, DataContextElement element) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isSelectedMultiple(Property property, DataContextElement element) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void addListener(Listener listener) {
+ // TODO Auto-generated method stub
+ }
+
+ public List<DataContextElement> getContextElementsFor(Collection<Context> contexts, View view) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/IGenerator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/IGenerator.java
new file mode 100644
index 00000000000..0384cde276a
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/IGenerator.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * 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.properties.generation.generators;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * A Generator is intended to output a partial Context model.
+ * This context model should only contain DataContextElements and Properties
+ * (i.e. it should not contain any View or Tabs)
+ * The Generator should also implement an heuristic, which will determine
+ * for each Property if it should be displayed in the Property view or not,
+ * for both Single and Multiple selection
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface IGenerator {
+
+ /**
+ * Generates the partial context, and persists it to the given target URI
+ *
+ * @param targetURI
+ * @return The generated Context
+ */
+ public Context generate(URI targetURI);
+
+ /**
+ * Creates the controls for this Generator. The generator is responsible
+ * for displaying any Control useful for editing its options, and listening
+ * for changes on them.
+ *
+ * @param parent
+ * The Composite in which the controls will be displayed
+ */
+ public void createControls(Composite parent);
+
+ /**
+ * Gets the description for this Generator
+ *
+ * @return The description
+ */
+ public String getDescription();
+
+ /**
+ * Tests if this Generator's settings are all set and valid
+ *
+ * @return true if all options are set and valid
+ */
+ public boolean isReady();
+
+ /**
+ * Gets the name for this Generator
+ *
+ * @return The name
+ */
+ public String getName();
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * exactly one instance of this property's parent element is selected.
+ *
+ * @param property
+ * @return
+ */
+ public boolean isSelectedSingle(Property property);
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * at least two instances of this property's parent element are selected.
+ *
+ * @param property
+ * @return
+ */
+ public boolean isSelectedMultiple(Property property);
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * exactly one instance of the given element is selected. The difference
+ * with {@link #isSelectedSingle(Property)} is that this method takes the inheritance
+ * into account, i.e. the property belongs to a Superclass of the given DataContextElement
+ *
+ * @param property
+ * @param element
+ * @return
+ */
+ public boolean isSelectedSingle(Property property, DataContextElement element);
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * at least two instances of the given element are selected. The difference
+ * with {@link #isSelectedMultiple(Property)} is that this method takes the inheritance
+ * into account, i.e. the property belongs to a Superclass of the given DataContextElement
+ *
+ * @param property
+ * @param element
+ * @return
+ */
+ public boolean isSelectedMultiple(Property property, DataContextElement element);
+
+ /**
+ * Adds a Change Listener to this generator. The Listener should be notified
+ * each time the generator's {@link #isReady()} value changes
+ *
+ * @param listener
+ */
+ public void addListener(Listener listener);
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/ProfileGenerator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/ProfileGenerator.java
new file mode 100644
index 00000000000..84129cc1c35
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/generators/ProfileGenerator.java
@@ -0,0 +1,223 @@
+/*****************************************************************************
+ * 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.properties.generation.generators;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.m2m.qvt.oml.BasicModelExtent;
+import org.eclipse.m2m.qvt.oml.ModelExtent;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.generation.Activator;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.papyrus.properties.generation.wizard.widget.FileChooser;
+import org.eclipse.papyrus.properties.root.PropertiesRoot;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+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.swt.widgets.Label;
+import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Profile;
+import org.eclipse.uml2.uml.Stereotype;
+
+/**
+ * An IGenerator for building Contexts from a UML Profile
+ *
+ * @author Camille Letavernier
+ */
+public class ProfileGenerator extends AbstractQVTGenerator {
+
+ private FileChooser sourceFileChooser;
+
+ private Profile umlProfile;
+
+ public void createControls(Composite parent) {
+ Composite root = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ root.setLayout(layout);
+
+ Label sourceLabel = new Label(root, SWT.NONE);
+ sourceLabel.setText(Messages.ProfileGenerator_source);
+ GridData data = new GridData();
+ data.widthHint = 100;
+ sourceLabel.setLayoutData(data);
+
+ sourceFileChooser = new FileChooser(root, false);
+ sourceFileChooser.setFilterExtensions(new String[]{ "profile.uml" }); //$NON-NLS-1$
+ sourceFileChooser.addListener(this);
+ }
+
+ public String getDescription() {
+ return Messages.ProfileGenerator_description;
+ }
+
+ public boolean isReady() {
+ return sourceFileChooser.getFilePath() != null;
+ }
+
+ public String getName() {
+ return Messages.ProfileGenerator_name;
+ }
+
+ @Override
+ protected List<ModelExtent> getModelExtents() {
+ try {
+ URI profileURI = URI.createPlatformResourceURI(sourceFileChooser.getFilePath(), true);
+ umlProfile = (Profile)loadEMFModel(profileURI);
+ ModelExtent inPackage = new BasicModelExtent(Collections.singletonList(umlProfile));
+
+ EPackage umlPackage = EPackage.Registry.INSTANCE.getEPackage("http://www.eclipse.org/uml2/3.0.0/UML"); //$NON-NLS-1$
+ ModelExtent inUml = new BasicModelExtent(Collections.singletonList(umlPackage));
+
+ PropertiesRoot root = ConfigurationManager.instance.getPropertiesRoot();
+ ModelExtent inRoot = new BasicModelExtent(Collections.singletonList(root));
+
+ LinkedList<ModelExtent> result = new LinkedList<ModelExtent>();
+ result.add(inPackage);
+ result.add(getOutContextExtent());
+ result.add(inUml);
+ result.add(inRoot);
+
+ return result;
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ }
+
+ return null;
+ }
+
+ @Override
+ protected URI getTransformationURI() {
+ return URI.createPlatformPluginURI("org.eclipse.papyrus.properties.generation/transforms/profile2datacontext.qvto", true); //$NON-NLS-1$
+ }
+
+ /**
+ * Retrieve the Stereotype corresponding to the given path, in the given Package
+ *
+ * @param path
+ * The list of package and subpackages names, and the stereotype name, i.e.
+ * the list of segments in the stereotype's qualified name
+ * e.g. : SysML::Blocks::Block : ["SysML", "Blocks", "Block"]
+ * @param profilePackage
+ * The root Package in which the stereotype should be retrieved
+ * @return
+ * The corresponding Stereotype, or null if it couldn't be retrieved
+ */
+ protected Stereotype findStereotype(List<String> path, Package profilePackage) {
+ NamedElement element = profilePackage.getOwnedMember(path.get(0));
+ path.remove(0);
+ if(path.size() == 0) {
+ if(element instanceof Stereotype) {
+ return (Stereotype)element;
+ }
+ } else {
+ if(element instanceof Package) {
+ return findStereotype(path, (Package)element);
+ }
+ }
+ return null;
+ }
+
+ private List<String> getPath(Property property) {
+ List<String> result = getPath(property.getContextElement());
+ return result;
+ }
+
+ private List<String> getPath(DataContextElement element) {
+ List<String> result;
+ if(element.getPackage() == null) {
+ result = new LinkedList<String>();
+ } else {
+ result = getPath(element.getPackage());
+ }
+
+ result.add(element.getName());
+ return result;
+ }
+
+ /**
+ * Retrieve the UML Property corresponding to the given Property view context Property
+ *
+ * @param property
+ * @return
+ */
+ protected org.eclipse.uml2.uml.Property getAttribute(Property property) {
+ List<String> path = getPath(property);
+ path.remove(0); //The first path element corresponds to this.umlProfile
+ Stereotype stereotype = findStereotype(path, umlProfile);
+ if(stereotype == null)
+ return null;
+
+ org.eclipse.uml2.uml.Property attribute = stereotype.getOwnedAttribute(property.getName(), null);
+ return attribute;
+ }
+
+ public boolean isSelectedSingle(Property property) {
+ org.eclipse.uml2.uml.Property attribute = getAttribute(property);
+ if(attribute == null) {
+ Activator.log.warn("Cannot find the Property corresponding to " + getPath(property)); //$NON-NLS-1$
+ return false;
+ }
+
+ if(attribute.isDerived()) {
+ return false;
+ }
+
+ if(attribute.isReadOnly()) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public boolean isSelectedMultiple(Property property) {
+ if(!isSelectedSingle(property)) {
+ return false;
+ }
+
+ org.eclipse.uml2.uml.Property attribute = getAttribute(property);
+
+ Set<String> validDataTypes = new HashSet<String>(Arrays.asList(new String[]{ "Integer", "Boolean", "Float", "Double" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ if(attribute.getType() instanceof DataType) {
+ if(validDataTypes.contains(((DataType)attribute.getType()).getName()))
+ return true;
+ }
+
+ if(attribute.getType() instanceof Enumeration) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean isSelectedSingle(Property property, DataContextElement element) {
+ return isSelectedSingle(property);
+ }
+
+ public boolean isSelectedMultiple(Property property, DataContextElement element) {
+ return isSelectedMultiple(property);
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/ILayoutGenerator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/ILayoutGenerator.java
new file mode 100644
index 00000000000..4ab67cb1c78
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/ILayoutGenerator.java
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * 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.properties.generation.layout;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.contexts.Section;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.ui.PropertyEditor;
+
+/**
+ * An interface for defining Layout generators.
+ * Layout generators are responsible for building a List of sections from a list
+ * of Property editors.
+ *
+ * @author Camille Letavernier
+ */
+public interface ILayoutGenerator {
+
+ /**
+ * Return a list of Sections from a list of property editors.
+ * Each section should be placed in the parent's resourceSet
+ *
+ * @param editors
+ * The list of editors to layout
+ * @param parent
+ * The view owning the resulting list of sections
+ * @return
+ * The list of sections owning the input editors
+ */
+ public List<Section> layoutElements(List<PropertyEditor> editors, View parent);
+
+ /**
+ * @return the name of the Layout generator
+ */
+ public String getName();
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/StandardLayoutGenerator.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/StandardLayoutGenerator.java
new file mode 100644
index 00000000000..49cc93bd6a4
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/layout/StandardLayoutGenerator.java
@@ -0,0 +1,218 @@
+/*****************************************************************************
+ * 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.properties.generation.layout;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrus.properties.contexts.ContextsFactory;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.contexts.Section;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.environment.CompositeWidgetType;
+import org.eclipse.papyrus.properties.environment.LayoutType;
+import org.eclipse.papyrus.properties.environment.Namespace;
+import org.eclipse.papyrus.properties.environment.Type;
+import org.eclipse.papyrus.properties.generation.Activator;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+import org.eclipse.papyrus.properties.ui.CompositeWidget;
+import org.eclipse.papyrus.properties.ui.Layout;
+import org.eclipse.papyrus.properties.ui.PropertyEditor;
+import org.eclipse.papyrus.properties.ui.UiFactory;
+import org.eclipse.papyrus.properties.ui.ValueAttribute;
+import org.eclipse.papyrus.properties.util.Util;
+
+/**
+ * Default implementation for ILayoutGenerator
+ * PropertyEditors are grouped by their property type (Strings, booleans, ...)
+ * Boolean and integer sections have two columns, while the other ones have only one columns
+ *
+ * All multiple value editors are displayed after all the single value editors.
+ *
+ * @author Camille Letavernier
+ */
+public class StandardLayoutGenerator implements ILayoutGenerator {
+
+ private TreeMap<Category, List<PropertyEditor>> editorsByCategory = new TreeMap<Category, List<PropertyEditor>>();
+
+ public List<Section> layoutElements(List<PropertyEditor> editors, View parent) {
+
+ editorsByCategory.clear();
+
+ Set<Namespace> namespaces = new HashSet<Namespace>(ConfigurationManager.instance.getBaseNamespaces());
+
+ for(PropertyEditor editor : editors) {
+ Category category = new Category(editor.getProperty());
+ getByCategory(category).add(editor);
+ if(editor.getWidgetType() == null) {
+ Activator.log.warn("Editor for property " + editor.getProperty().getName() + " doesn't have a WidgetType"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ namespaces.add(editor.getWidgetType().getNamespace());
+ }
+ }
+
+ ConfigurationManager configManager = ConfigurationManager.instance;
+
+ Section section = ContextsFactory.eINSTANCE.createSection();
+ section.setName(parent.getName());
+ section.setSectionFile("ui/" + section.getName().replaceAll(" ", "") + ".xwt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ URI compositeURI = URI.createURI(section.getSectionFile());
+ compositeURI = compositeURI.resolve(parent.eResource().getURI());
+ Resource resource = parent.eResource().getResourceSet().createResource(compositeURI);
+
+ CompositeWidgetType compositeType = configManager.getDefaultCompositeType();
+ namespaces.add(compositeType.getNamespace());
+ LayoutType propertiesLayoutType = configManager.getDefaultLayoutType();
+ namespaces.add(propertiesLayoutType.getNamespace());
+
+ CompositeWidget sectionRoot = UiFactory.eINSTANCE.createCompositeWidget();
+ sectionRoot.setWidgetType(compositeType);
+ Layout layout = UiFactory.eINSTANCE.createLayout();
+ layout.setLayoutType(propertiesLayoutType);
+ sectionRoot.setLayout(layout);
+ sectionRoot.getAttributes().addAll(createNamespaces(namespaces));
+
+ section.setWidget(sectionRoot);
+
+ resource.getContents().add(sectionRoot);
+
+ for(Map.Entry<Category, List<PropertyEditor>> mapping : editorsByCategory.entrySet()) {
+ Category category = mapping.getKey();
+ List<PropertyEditor> categorizedEditors = mapping.getValue();
+
+ CompositeWidget container = UiFactory.eINSTANCE.createCompositeWidget();
+ container.setWidgetType(compositeType);
+ layout = UiFactory.eINSTANCE.createLayout();
+ container.setLayout(layout);
+ ValueAttribute numColumns = UiFactory.eINSTANCE.createValueAttribute();
+ numColumns.setName("numColumns"); //$NON-NLS-1$
+ numColumns.setValue(category.getNumColumns().toString());
+ layout.getAttributes().add(numColumns);
+ layout.setLayoutType(propertiesLayoutType);
+ container.getWidgets().addAll(categorizedEditors);
+ sectionRoot.getWidgets().add(container);
+ }
+
+ return Collections.singletonList(section);
+ }
+
+ private List<ValueAttribute> createNamespaces(Collection<Namespace> namespaces) {
+ List<ValueAttribute> xmlNamespaces = new LinkedList<ValueAttribute>();
+ for(Namespace namespace : namespaces) {
+ if(namespace == null)
+ continue;
+
+ ValueAttribute attribute = UiFactory.eINSTANCE.createValueAttribute();
+ attribute.setName(Util.getQualifiedName(namespace));
+ attribute.setValue(Util.getPrefixedValue(namespace));
+ xmlNamespaces.add(attribute);
+ }
+ return xmlNamespaces;
+ }
+
+ private List<PropertyEditor> getByCategory(Category category) {
+ if(!editorsByCategory.containsKey(category)) {
+ editorsByCategory.put(category, new LinkedList<PropertyEditor>());
+ }
+ return editorsByCategory.get(category);
+ }
+
+ private class Category implements Comparable<Category> {
+
+ public Type editorType;
+
+ public int multiplicity;
+
+ public Integer getNumColumns() {
+ switch(editorType) {
+ case BOOLEAN:
+ return 2;
+ case ENUMERATION:
+ return 1;
+ case INTEGER:
+ return 2;
+ case REFERENCE:
+ return 1;
+ case STRING:
+ return 1;
+ }
+ return 1; //Cannot happen
+ }
+
+ public Category(Property property) {
+ this.editorType = property.getType();
+ this.multiplicity = property.getMultiplicity();
+ }
+
+ @Override
+ public int hashCode() {
+ return editorType.hashCode() * multiplicity;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if(o == null)
+ return false;
+ if(!(o instanceof Category))
+ return false;
+
+ Category category = (Category)o;
+ return category.editorType == editorType && category.multiplicity == multiplicity;
+ }
+
+ public int compareTo(Category category) {
+ if(category == null)
+ return -1;
+
+ if(category.multiplicity != multiplicity) {
+ return multiplicity == 1 ? -1 : 1;
+ }
+
+ int result = getTypeIndex().compareTo(category.getTypeIndex());
+ return result;
+ }
+
+ public Integer getTypeIndex() {
+ int i = 0;
+ for(Type type : orderedTypes) {
+ if(type == editorType)
+ return i;
+ i++;
+ }
+ return orderedTypes.length;
+ }
+
+ @Override
+ public String toString() {
+ return (multiplicity == 1 ? "Single" : "Multiple") + editorType.toString(); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * The order in which the types are displayed
+ */
+ public static Type[] orderedTypes = new Type[]{ Type.STRING, Type.BOOLEAN, Type.INTEGER, Type.ENUMERATION, Type.REFERENCE };
+
+ public String getName() {
+ return Messages.StandardLayoutGenerator_name;
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/Messages.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/Messages.java
new file mode 100644
index 00000000000..30f54286308
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/Messages.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * Copyright (c) 2011 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.properties.generation.messages;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.properties.generation.messages.messages"; //$NON-NLS-1$
+
+ public static String EcoreGenerator_ecoreGeneratorDescription;
+
+ public static String EcoreGenerator_ecoreGeneratorName;
+
+ public static String EcoreGenerator_source;
+
+ public static String EditContextGenerator_generateNewContext;
+
+ public static String EditContextGenerator_importExistingContext;
+
+ public static String ProfileGenerator_description;
+
+ public static String ProfileGenerator_name;
+
+ public static String ProfileGenerator_source;
+
+ public static String StandardLayoutGenerator_name;
+
+ public static String CreateContextMainPage_description;
+
+ public static String CreateContextMainPage_title;
+
+ public static String CreateContextWizard_pageTitle;
+
+ public static String CreateContextWizard_propertyViewGenerationError;
+
+ public static String CreateContextWizard_propertyViewGenerationJobName;
+
+ public static String GeneratorPage_layoutGenerator;
+
+ public static String GeneratorPage_target;
+
+ public static String GeneratorPage_title;
+
+ public static String SelectFieldsPage_availableFields;
+
+ public static String SelectFieldsPage_description;
+
+ public static String SelectFieldsPage_descriptionNotAvailable;
+
+ public static String SelectFieldsPage_displayMultiple;
+
+ public static String SelectFieldsPage_displaySingle;
+
+ public static String SelectFieldsPage_field;
+
+ public static String SelectFieldsPage_selectFields;
+
+ public static String SelectFieldsPage_title;
+
+ public static String FileChooser_browseWorkspace;
+
+ public static String TernaryButton_defaultFalse;
+
+ public static String TernaryButton_defaultTrue;
+
+ public static String TernaryButton_false;
+
+ public static String TernaryButton_true;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/messages.properties b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/messages.properties
new file mode 100644
index 00000000000..1663dcd16d1
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/messages/messages.properties
@@ -0,0 +1,30 @@
+EcoreGenerator_ecoreGeneratorDescription=Generate a new Property View context from an Ecore Metamodel\nChose the Ecore file corresponding to your metamodel
+EcoreGenerator_ecoreGeneratorName=Create from Ecore Metamodel
+EcoreGenerator_source=Source :
+EditContextGenerator_generateNewContext=Generates a new context from an existing one
+EditContextGenerator_importExistingContext=Import existing context
+ProfileGenerator_description=Generate a new Property View context from a UML Profile\nChose the UML Profile corresponding to your metamodel
+ProfileGenerator_name=Create from UML Profile
+ProfileGenerator_source=Source :
+StandardLayoutGenerator_name=Standard layout generator
+CreateContextMainPage_description=Generate a new Property View context from a Metamodel
+CreateContextMainPage_title=Create context
+CreateContextWizard_pageTitle=New Property view Context
+CreateContextWizard_propertyViewGenerationError=An error occured while generating the property view for
+CreateContextWizard_propertyViewGenerationJobName=Property View Generation for
+GeneratorPage_layoutGenerator=Layout generator :
+GeneratorPage_target=Target :
+GeneratorPage_title=Generator page
+SelectFieldsPage_availableFields=Available fields :
+SelectFieldsPage_description=Description
+SelectFieldsPage_descriptionNotAvailable=N/A
+SelectFieldsPage_displayMultiple=Display multiple
+SelectFieldsPage_displaySingle=Display single
+SelectFieldsPage_field=Field
+SelectFieldsPage_selectFields=Select the fields you want to be displayed in the Property view
+SelectFieldsPage_title=Select fields
+FileChooser_browseWorkspace=Browse workspace...
+TernaryButton_defaultFalse=Default (False)
+TernaryButton_defaultTrue=Default (True)
+TernaryButton_false=False
+TernaryButton_true=True
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/AbstractCreateContextPage.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/AbstractCreateContextPage.java
new file mode 100644
index 00000000000..35ee374bdc6
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/AbstractCreateContextPage.java
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.wizard.WizardPage;
+
+/**
+ * An abstract WizardPage for the CreateContext wizard, providing helper
+ * methods to its implementers
+ *
+ * @author Camille Letavernier
+ */
+public abstract class AbstractCreateContextPage extends WizardPage {
+
+ /**
+ * Builds a new WizardPage with the given pageName
+ * Constructor.
+ *
+ * @param pageName
+ * The name of this wizard page
+ */
+ public AbstractCreateContextPage(String pageName) {
+ super(pageName);
+ }
+
+ /**
+ *
+ * Builds a new WizardPage with the given pageName, title and image
+ *
+ * @param pageName
+ * the name of the page
+ * @param title
+ * the title for this wizard page, or <code>null</code> if none
+ * @param titleImage
+ * the image descriptor for the title of this wizard page,
+ * or <code>null</code> if none
+ */
+ public AbstractCreateContextPage(String pageName, String title, ImageDescriptor titleImage) {
+ super(pageName, title, titleImage);
+ }
+
+ @Override
+ public CreateContextWizard getWizard() {
+ return (CreateContextWizard)super.getWizard();
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextMainPage.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextMainPage.java
new file mode 100644
index 00000000000..1d7a543e6c6
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextMainPage.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.papyrus.properties.generation.generators.IGenerator;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * A WizardPage for selecting the method of generation (e.g. from Ecore
+ * Metamodel or from Profile model)
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class CreateContextMainPage extends AbstractCreateContextPage implements Listener {
+
+ private CCombo combo;
+
+ /**
+ * Constructor
+ */
+ public CreateContextMainPage() {
+ super(Messages.CreateContextMainPage_title);
+ }
+
+ public void createControl(Composite parent) {
+ Composite root = new Composite(parent, SWT.NONE);
+ root.setLayout(new GridLayout(1, false));
+
+ combo = new CCombo(root, SWT.BORDER);
+ for(IGenerator generator : CreateContextWizard.contextGenerators) {
+ combo.add(generator.getName());
+ }
+ combo.setEditable(false);
+ combo.setBackground(new Color(combo.getDisplay(), 255, 255, 255));
+ combo.select(0);
+ combo.addListener(SWT.Selection, this);
+ combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ setControl(root);
+ setDescription(Messages.CreateContextMainPage_description);
+ }
+
+ @Override
+ public IWizardPage getNextPage() {
+ int selection = combo.getSelectionIndex();
+ getWizard().setGenerator(CreateContextWizard.contextGenerators.get(selection));
+ return getWizard().generatorPage;
+ }
+
+ public void handleEvent(Event event) {
+ super.setPageComplete(true);
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextWizard.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextWizard.java
new file mode 100644
index 00000000000..f36b09e3f31
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/CreateContextWizard.java
@@ -0,0 +1,342 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.ContextsFactory;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.contexts.Section;
+import org.eclipse.papyrus.properties.contexts.Tab;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.generation.Activator;
+import org.eclipse.papyrus.properties.generation.fieldselection.ContextElement;
+import org.eclipse.papyrus.properties.generation.fieldselection.FieldSelection;
+import org.eclipse.papyrus.properties.generation.fieldselection.PropertyDefinition;
+import org.eclipse.papyrus.properties.generation.generators.IGenerator;
+import org.eclipse.papyrus.properties.generation.layout.ILayoutGenerator;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.papyrus.properties.generation.wizard.widget.TernaryButton;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+import org.eclipse.papyrus.properties.ui.PropertyEditor;
+import org.eclipse.papyrus.properties.ui.UiFactory;
+import org.eclipse.papyrus.properties.ui.ValueAttribute;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+
+/**
+ * A Wizard for generating Property view contexts
+ *
+ * @author Camille Letavernier
+ */
+public class CreateContextWizard extends Wizard implements INewWizard {
+
+ CreateContextMainPage mainPage;
+
+ GeneratorPage generatorPage;
+
+ //protected LayoutPage layout;
+
+ SelectFieldsPage selectFieldsPage;
+
+ /**
+ * All available context generators
+ */
+ protected static List<IGenerator> contextGenerators = new LinkedList<IGenerator>();
+
+ /**
+ * All available layout generators
+ */
+ protected static List<ILayoutGenerator> layoutGenerators = new LinkedList<ILayoutGenerator>();
+
+ /**
+ * The generated context
+ */
+ protected Context context;
+
+ /**
+ * The IGenerator used to generate the context
+ */
+ protected IGenerator generator;
+
+ /**
+ * The ILayoutGenerator used to layout the context's sections
+ */
+ protected ILayoutGenerator layoutGenerator;
+
+ @Override
+ public boolean performFinish() {
+ if(generator == null || context == null) {
+ return false;
+ }
+
+ ConfigurationManager configManager = ConfigurationManager.instance;
+
+ Tab defaultTab = ContextsFactory.eINSTANCE.createTab();
+ defaultTab.setCategory("default"); //$NON-NLS-1$
+ defaultTab.setId("default"); //$NON-NLS-1$
+ defaultTab.setLabel("Default"); //$NON-NLS-1$
+ context.getTabs().add(defaultTab);
+
+ FieldSelection fieldSelection = selectFieldsPage.getFieldSelection();
+
+ URI contextURI = context.eResource().getURI();
+ Resource selectionResource = context.eResource().getResourceSet().createResource(URI.createURI(context.getName() + "FieldSelection.xmi").resolve(contextURI)); //$NON-NLS-1$
+ selectionResource.getContents().add(fieldSelection);
+ try {
+ selectionResource.save(null);
+ } catch (IOException ex) {
+ Activator.log.error("Couldn't persist the field selection model", ex); //$NON-NLS-1$
+ }
+
+ layoutGenerator = layoutGenerators.get(0); //TODO : Use the layoutGenerator combo
+
+ for(View view : context.getViews()) {
+ if(view.getConstraints().size() == 0) //TODO : Problem with external resource references
+ continue;
+
+ List<PropertyEditor> editors = new LinkedList<PropertyEditor>();
+
+ for(DataContextElement element : getAllContextElements(view.getDatacontexts())) {
+ for(Property property : element.getProperties()) {
+ if(isSelected(fieldSelection, property, view.getElementMultiplicity() != 1)) {
+ PropertyEditor editor = UiFactory.eINSTANCE.createPropertyEditor();
+ editor.setProperty(property);
+ editor.setWidgetType(configManager.getDefaultEditorType(property));
+ editors.add(editor);
+ ValueAttribute input = UiFactory.eINSTANCE.createValueAttribute();
+ input.setName("input"); //$NON-NLS-1$
+ input.setValue("{Binding}"); //$NON-NLS-1$
+ editor.getAttributes().add(input);
+ }
+ }
+ }
+
+ List<Section> generatedSections = layoutGenerator.layoutElements(editors, view);
+ defaultTab.getSections().addAll(generatedSections);
+ view.getSections().addAll(generatedSections);
+ context.getViews().add(view);
+ }
+
+ int i = 1;
+ for(Tab tab : context.getTabs()) {
+ i += tab.getSections().size();
+ }
+ final int numberOfSections = i;
+ try {
+ setNeedsProgressMonitor(true);
+ getContainer().run(true, true, new IRunnableWithProgress() {
+
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ monitor.beginTask(Messages.CreateContextWizard_propertyViewGenerationJobName + context.getName(), numberOfSections + 1);
+ monitor.worked(1);
+
+ try {
+ context.eResource().save(Collections.EMPTY_MAP);
+
+ monitor.worked(1);
+ for(Tab tab : context.getTabs()) {
+ for(Section section : tab.getSections()) {
+ if(monitor.isCanceled()) {
+ return;
+ }
+ section.getWidget().eResource().save(Collections.EMPTY_MAP);
+ monitor.worked(1);
+ }
+ }
+ } catch (IOException ex) {
+ Activator.log.error(ex);
+ return;
+ }
+ monitor.done();
+ }
+
+ });
+ } catch (InvocationTargetException ex) {
+ Activator.log.error(ex);
+ } catch (InterruptedException ex) {
+ Activator.log.error(ex);
+ }
+ // Job job = new Job(Messages.CreateContextWizard_propertyViewGenerationJobName + context.getName()) {
+ //
+ // @Override
+ // protected IStatus run(IProgressMonitor monitor) {
+ // monitor.beginTask(getName(), numberOfSections);
+ //
+ // try {
+ // context.eResource().save(Collections.EMPTY_MAP);
+ //
+ // monitor.worked(1);
+ // for(Tab tab : context.getTabs()) {
+ // for(Section section : tab.getSections()) {
+ // if(monitor.isCanceled()) {
+ // return Status.CANCEL_STATUS;
+ // }
+ // section.getWidget().eResource().save(Collections.EMPTY_MAP);
+ // monitor.worked(1);
+ // }
+ // }
+ // } catch (IOException ex) {
+ // Activator.log.error(ex);
+ // return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CreateContextWizard_propertyViewGenerationError + context.getName(), ex);
+ // }
+ // return Status.OK_STATUS;
+ // }
+ // };
+ // job.setPriority(Job.INTERACTIVE);
+ // job.setUser(true);
+ // job.schedule();
+
+ return true;
+ }
+
+ private boolean isSelected(FieldSelection fieldSelection, Property property, boolean multiple) {
+ PropertyDefinition definition = getPropertyDefinition(fieldSelection, property);
+ if(definition == null) {
+ return false;
+ }
+ TernaryButton.State value = multiple ? definition.getValueMultiple() : definition.getValueSingle();
+ switch(value) {
+ case TRUE:
+ return true;
+ case FALSE:
+ return false;
+ case DEFAULT:
+ return multiple ? generator.isSelectedMultiple(property) : generator.isSelectedSingle(property);
+ }
+
+ return false;
+ }
+
+ PropertyDefinition getPropertyDefinition(FieldSelection fieldSelection, Property property) {
+ List<String> propertyPath = getPropertyPath(property.getContextElement());
+ if(propertyPath.isEmpty()) {
+ return null;
+ }
+
+ ContextElement currentElement = null;
+ for(ContextElement contextRoot : fieldSelection.getContextElements()) {
+ if(contextRoot.getName().equals(propertyPath.get(0))) {
+ currentElement = contextRoot;
+ }
+ }
+ propertyPath.remove(0);
+ if(currentElement == null)
+ return null;
+
+ while(propertyPath.size() > 0) {
+ String name = propertyPath.get(0);
+ propertyPath.remove(0);
+ currentElement = findByName(currentElement, name);
+ }
+
+ for(PropertyDefinition definition : currentElement.getProperties()) {
+ if(definition.getName().equals(property.getName())) {
+ return definition;
+ }
+ }
+
+ return null;
+ }
+
+ ContextElement findByName(ContextElement source, String name) {
+ for(ContextElement element : source.getElements()) {
+ if(element.getName().equals(name))
+ return element;
+ }
+ return null;
+ }
+
+ List<String> getPropertyPath(DataContextElement element) {
+ List<String> result;
+ if(element.getPackage() == null) {
+ result = new LinkedList<String>();
+ } else {
+ result = getPropertyPath(element.getPackage());
+ }
+ result.add(element.getName());
+ return result;
+ }
+
+ private Set<DataContextElement> getAllContextElements(Collection<DataContextElement> source) {
+ Set<DataContextElement> result = new HashSet<DataContextElement>();
+ for(DataContextElement element : source) {
+ getAllContextElements(element, result);
+ }
+ return result;
+ }
+
+ private void getAllContextElements(DataContextElement source, Set<DataContextElement> result) {
+ if(result.contains(source))
+ return;
+
+ result.add(source);
+ for(DataContextElement element : source.getSupertypes()) {
+ getAllContextElements(element, result);
+ }
+ }
+
+ public void init(IWorkbench workbench, IStructuredSelection selection) {
+ addPage(mainPage = new CreateContextMainPage());
+ addPage(generatorPage = new GeneratorPage());
+ addPage(selectFieldsPage = new SelectFieldsPage());
+ //addPage(layout = new LayoutPage());
+
+ setWindowTitle(Messages.CreateContextWizard_pageTitle);
+
+ }
+
+ void setGenerator(IGenerator generator) {
+ this.generator = generator;
+ generatorPage.setGenerator(generator);
+ }
+
+ void setContext(Context context) {
+ this.context = context;
+ }
+
+ /**
+ * Registers a new context Generator for the CreateContextWizard
+ *
+ * @param generator
+ * The IGenerator to register
+ */
+ public static void addGenerator(IGenerator generator) {
+ contextGenerators.add(generator);
+ }
+
+ /**
+ * Registers a new Layout Generator for the CreateContextWizard
+ *
+ * @param generator
+ * The ILayoutGenerator to register
+ */
+ public static void addLayoutGenerator(ILayoutGenerator generator) {
+ layoutGenerators.add(generator);
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/GeneratorPage.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/GeneratorPage.java
new file mode 100644
index 00000000000..46972af29c4
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/GeneratorPage.java
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.properties.generation.generators.IGenerator;
+import org.eclipse.papyrus.properties.generation.layout.ILayoutGenerator;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.papyrus.properties.generation.wizard.widget.FileChooser;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * A WizardPage to display the selected generator's options, as well as the context's
+ * target file. The options depend on the selected generator.
+ *
+ * @author Camille Letavernier
+ */
+public class GeneratorPage extends AbstractCreateContextPage implements Listener {
+
+ private IGenerator generator;
+
+ private Composite root, generatorControl;
+
+ private FileChooser targetFileChooser;
+
+ /**
+ * Constructor.
+ */
+ public GeneratorPage() {
+ super(Messages.GeneratorPage_title);
+ }
+
+ /**
+ * Sets the IGenerator for this wizard, and displays its controls in the
+ * page.
+ *
+ * @param generator
+ */
+ public void setGenerator(IGenerator generator) {
+ cleanGeneratorControl();
+ generator.addListener(this);
+
+ setDescription(generator.getDescription());
+ this.generator = generator;
+ generator.createControls(generatorControl);
+ generatorControl.layout();
+ root.layout();
+ }
+
+ @Override
+ public boolean isPageComplete() {
+ return targetFileChooser.getFilePath() != null && (generator != null && generator.isReady());
+ }
+
+ private void cleanGeneratorControl() {
+ for(Control control : generatorControl.getChildren()) {
+ control.dispose();
+ }
+ }
+
+ public void createControl(Composite parent) {
+ root = new Composite(parent, SWT.NONE);
+ root.setLayout(new GridLayout(2, false));
+ root.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ generatorControl = new Composite(root, SWT.NONE);
+ generatorControl.setLayout(new FillLayout());
+ generatorControl.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 2, 1));
+
+
+ Label layoutGeneratorLabel = new Label(root, SWT.NONE);
+ layoutGeneratorLabel.setText(Messages.GeneratorPage_layoutGenerator);
+ GridData data = new GridData();
+ data.widthHint = 100;
+ layoutGeneratorLabel.setLayoutData(data);
+
+ CCombo layoutGeneratorCombo = new CCombo(root, SWT.BORDER);
+ layoutGeneratorCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ layoutGeneratorCombo.setEditable(false);
+ layoutGeneratorCombo.setBackground(new Color(layoutGeneratorCombo.getDisplay(), 255, 255, 255));
+ for(ILayoutGenerator layoutGenerator : CreateContextWizard.layoutGenerators) {
+ layoutGeneratorCombo.add(layoutGenerator.getName());
+ }
+ layoutGeneratorCombo.select(0);
+
+ Label targetLabel = new Label(root, SWT.NONE);
+ targetLabel.setText(Messages.GeneratorPage_target);
+ data = new GridData();
+ data.widthHint = 100;
+ targetLabel.setLayoutData(data);
+
+ targetFileChooser = new FileChooser(root, true);
+ targetFileChooser.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ targetFileChooser.addListener(this);
+
+ setControl(root);
+ }
+
+ public void handleEvent(Event event) {
+ String filePath = targetFileChooser.getFilePath();
+ if(filePath != null) {
+ getWizard().selectFieldsPage.setTargetURI(URI.createPlatformResourceURI(targetFileChooser.getFilePath(), true));
+ }
+ super.getContainer().updateButtons();
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/SelectFieldsPage.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/SelectFieldsPage.java
new file mode 100644
index 00000000000..54f79d74fb3
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/SelectFieldsPage.java
@@ -0,0 +1,271 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.databinding.EMFProperties;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.contexts.DataContextPackage;
+import org.eclipse.papyrus.properties.contexts.DataContextRoot;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.generation.Activator;
+import org.eclipse.papyrus.properties.generation.fieldselection.ContextElement;
+import org.eclipse.papyrus.properties.generation.fieldselection.FieldSelection;
+import org.eclipse.papyrus.properties.generation.fieldselection.FieldSelectionFactory;
+import org.eclipse.papyrus.properties.generation.fieldselection.FieldSelectionPackage;
+import org.eclipse.papyrus.properties.generation.fieldselection.PropertyDefinition;
+import org.eclipse.papyrus.properties.generation.generators.IGenerator;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.papyrus.properties.generation.wizard.widget.TernaryButton;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * A WizardPage to choose the fields that will be displayed in the Property view.
+ * For each property, the choice can be either "True", "False" or "Default".
+ * The visibility of properties marked as Default is decided by the Generator.
+ * When the context is regenerated, the visibility of properties marked as default
+ * may change (If the generator is changed)
+ *
+ * @author Camille Letavernier
+ */
+public class SelectFieldsPage extends AbstractCreateContextPage {
+
+ private URI targetURI;
+
+ private Context context;
+
+ private Composite root;
+
+ private Composite fields;
+
+ private FieldSelection fieldSelection;
+
+ /**
+ * Constructor.
+ */
+ protected SelectFieldsPage() {
+ super(Messages.SelectFieldsPage_title);
+ }
+
+ public void createControl(Composite parent) {
+ root = new Composite(parent, SWT.NONE);
+ root.setLayout(new GridLayout(1, true));
+
+ setControl(root);
+ setPageComplete(false);
+
+ setDescription(Messages.SelectFieldsPage_selectFields);
+ }
+
+ /**
+ * Sets the generated partial context
+ *
+ * @param context
+ * The partially generated context
+ */
+ public void setContext(Context context) {
+ if(context == null) {
+ Activator.log.warn("Generated context is null"); //$NON-NLS-1$
+ return;
+ }
+
+ this.context = context;
+
+ fieldSelection = createNewFieldSelection();
+
+ getWizard().setContext(context);
+
+ Label label = new Label(root, SWT.NONE);
+ label.setText(Messages.SelectFieldsPage_availableFields);
+
+ ScrolledComposite scrollableFields = new ScrolledComposite(root, SWT.V_SCROLL | SWT.H_SCROLL);
+ scrollableFields.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ scrollableFields.getVerticalBar().setIncrement(10);
+
+ fields = new Composite(scrollableFields, SWT.NONE);
+ scrollableFields.setContent(fields);
+
+ fields.setLayout(new GridLayout(4, false));
+
+ Label fieldLabel = new Label(fields, SWT.NONE);
+ Label selectionSingle = new Label(fields, SWT.NONE);
+ Label selectionMultiple = new Label(fields, SWT.NONE);
+ Label descriptionLabel = new Label(fields, SWT.NONE);
+
+ selectionSingle.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ selectionMultiple.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+ descriptionLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+
+ fieldLabel.setText(Messages.SelectFieldsPage_field);
+ selectionSingle.setText(Messages.SelectFieldsPage_displaySingle);
+ selectionMultiple.setText(Messages.SelectFieldsPage_displayMultiple);
+ descriptionLabel.setText(Messages.SelectFieldsPage_description);
+
+ for(DataContextRoot dataContextRoot : context.getDataContexts()) {
+ displayFields(dataContextRoot);
+ }
+
+ fields.setSize(fields.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+
+ root.layout();
+ fields.layout();
+ scrollableFields.layout();
+ }
+
+ private FieldSelection createNewFieldSelection() {
+ FieldSelection selection = FieldSelectionFactory.eINSTANCE.createFieldSelection();
+
+ for(DataContextRoot dataContextRoot : context.getDataContexts()) {
+ ContextElement definition = createContextPackage(dataContextRoot);
+ selection.getContextElements().add(definition);
+ }
+
+ return selection;
+ }
+
+ private ContextElement createContextPackage(DataContextPackage sourcePackage) {
+ ContextElement element = createContextElement(sourcePackage);
+
+ for(DataContextElement sourceElement : sourcePackage.getElements()) {
+ ContextElement subElement;
+ if(sourceElement instanceof DataContextPackage) {
+ subElement = createContextPackage((DataContextPackage)sourceElement);
+ } else {
+ subElement = createContextElement(sourceElement);
+ }
+ element.getElements().add(subElement);
+ }
+ return element;
+ }
+
+ private ContextElement createContextElement(DataContextElement sourceElement) {
+ ContextElement element = FieldSelectionFactory.eINSTANCE.createContextElement();
+ element.setName(sourceElement.getName());
+
+ for(Property property : sourceElement.getProperties()) {
+ PropertyDefinition propertyDefinition = FieldSelectionFactory.eINSTANCE.createPropertyDefinition();
+ propertyDefinition.setName(property.getName());
+ propertyDefinition.setValueSingle(TernaryButton.State.DEFAULT);
+ propertyDefinition.setValueMultiple(TernaryButton.State.DEFAULT);
+ element.getProperties().add(propertyDefinition);
+ }
+
+ return element;
+ }
+
+ private void displayFields(DataContextElement contextElement) {
+
+ if(contextElement.getProperties().size() > 0) {
+
+ Label separator = new Label(fields, SWT.SEPARATOR | SWT.HORIZONTAL);
+ GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
+ separator.setLayoutData(data);
+
+ Label elementName = new Label(fields, SWT.NONE);
+ elementName.setText(contextElement.getName());
+ FontData[] fontDatas = elementName.getFont().getFontData();
+ for(FontData fontData : fontDatas) {
+ fontData.setStyle(SWT.BOLD);
+ // fontData.setHeight(fontData.getHeight() + 2);
+ }
+ elementName.setFont(new Font(elementName.getDisplay(), fontDatas));
+
+ data = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
+ elementName.setLayoutData(data);
+
+ Label separator2 = new Label(fields, SWT.SEPARATOR | SWT.HORIZONTAL);
+ data = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
+ separator2.setLayoutData(data);
+
+ for(Property property : contextElement.getProperties()) {
+ Label label = new Label(fields, SWT.NONE);
+ label.setText(property.getName());
+
+ TernaryButton showSingle = new TernaryButton(fields, getGenerator().isSelectedSingle(property));
+ TernaryButton showMultiple = new TernaryButton(fields, getGenerator().isSelectedMultiple(property));
+
+ PropertyDefinition propertyDefinition = getWizard().getPropertyDefinition(fieldSelection, property);
+
+ IObservableValue singleValue = EMFProperties.value(FieldSelectionPackage.eINSTANCE.getPropertyDefinition_ValueSingle()).observe(propertyDefinition);
+ IObservableValue multipleValue = EMFProperties.value(FieldSelectionPackage.eINSTANCE.getPropertyDefinition_ValueMultiple()).observe(propertyDefinition);
+
+ showSingle.setObservable(singleValue);
+ showMultiple.setObservable(multipleValue);
+
+ Label description = new Label(fields, SWT.WRAP);
+ String propertyDescription = "";// property.getTooltipText(); //$NON-NLS-1$
+ if(propertyDescription == null || propertyDescription.trim().equals("")) { //$NON-NLS-1$
+ propertyDescription = Messages.SelectFieldsPage_descriptionNotAvailable;
+ description.setAlignment(SWT.CENTER);
+ }
+ description.setText(propertyDescription);
+
+ data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ label.setLayoutData(data);
+ data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ showSingle.setLayoutData(data);
+ data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ showMultiple.setLayoutData(data);
+ data = new GridData(SWT.CENTER, SWT.CENTER, true, false);
+ data.widthHint = 500;
+ description.setLayoutData(data);
+ }
+ }
+
+ if(contextElement instanceof DataContextPackage) {
+ DataContextPackage contextPackage = (DataContextPackage)contextElement;
+ for(DataContextElement element : contextPackage.getElements()) {
+ displayFields(element);
+ }
+ }
+ }
+
+ private IGenerator getGenerator() {
+ return getWizard().generator;
+ }
+
+ /**
+ * Sets the URI of the generated context
+ *
+ * @param uri
+ * The URI of the generated context
+ */
+ public void setTargetURI(URI uri) {
+ this.targetURI = uri;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setPageComplete(true);
+ super.setVisible(visible);
+ if(context == null && visible) {
+ setContext(getWizard().generator.generate(targetURI));
+ }
+ }
+
+ /**
+ * @return the result of the user's field selection
+ */
+ public FieldSelection getFieldSelection() {
+ return fieldSelection;
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/ExtensionFilter.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/ExtensionFilter.java
new file mode 100644
index 00000000000..f5ed15912da
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/ExtensionFilter.java
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard.widget;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+/**
+ * A filter for file extensions
+ *
+ * @author Camille Letavernier
+ */
+public class ExtensionFilter extends ViewerFilter {
+
+ private Set<String> extensions;
+
+ /**
+ *
+ * Constructs a ViewerFilter that will only accept filenames with one of the
+ * given extensions
+ *
+ * @param extensions
+ * The authorized extensions
+ */
+ public ExtensionFilter(String[] extensions) {
+ this.extensions = new HashSet<String>(Arrays.asList(extensions));
+ }
+
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if(element instanceof IFile) {
+ IFile file = (IFile)element;
+ for(String ext : extensions) {
+ if(file.getFullPath().toString().endsWith(ext)) {
+ return true;
+ }
+ }
+ } else if(element instanceof IProject || element instanceof IFolder) {
+ return true;
+ }
+
+ return false;
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/FileChooser.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/FileChooser.java
new file mode 100644
index 00000000000..3f04db3b49b
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/FileChooser.java
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard.widget;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.common.ui.dialogs.WorkspaceResourceDialog;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A Widget for selecting or creating a file in the workspace
+ *
+ * @author Camille Letavernier
+ */
+public class FileChooser extends Composite implements SelectionListener, Listener {
+
+ private Text text;
+
+ private Button browse;
+
+ private IFile currentFile;
+
+ private List<ViewerFilter> filters;
+
+ private Set<Listener> listeners = new HashSet<Listener>();
+
+ private boolean newFile;
+
+ /**
+ * Constructs a new FileChooser in the given Composite
+ *
+ * @param parent
+ * The composite in which the FileChooser is created
+ * @param newFile
+ * True if the fileChooser allows the user to create a new file,
+ * false if he should select an existing one
+ */
+ public FileChooser(Composite parent, boolean newFile) {
+ super(parent, SWT.NONE);
+ setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ setLayout(layout);
+
+ text = new Text(this, SWT.BORDER);
+ text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ text.addListener(SWT.FocusOut, this);
+ browse = new Button(this, SWT.PUSH);
+ browse.setText(Messages.FileChooser_browseWorkspace);
+ browse.addSelectionListener(this);
+ filters = new LinkedList<ViewerFilter>();
+ this.newFile = newFile;
+ }
+
+ /**
+ * @return the selected file path
+ */
+ public String getFilePath() {
+ String path = text.getText();
+ if(path.trim().equals("")) { //$NON-NLS-1$
+ return null;
+ }
+ return path.trim();
+ }
+
+ /**
+ * Sets the file extensions that this FileChooser accepts
+ * Files that don't match one of these extensions will be hidden
+ *
+ * @param extensions
+ */
+ public void setFilterExtensions(String[] extensions) {
+ filters.clear();
+ ExtensionFilter filter = new ExtensionFilter(extensions);
+ filters.add(filter);
+ }
+
+ public void handleEvent(Event event) {
+ notifyChange();
+ }
+
+ /**
+ * Add a listener to this widget. The listener will be notified when the user
+ * choose a new file
+ *
+ * @param listener
+ */
+ public void addListener(Listener listener) {
+ listeners.add(listener);
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ IFile[] result = new IFile[0];
+
+ if(newFile) {
+ IFile file = WorkspaceResourceDialog.openNewFile(getShell(), null, null, null, filters);
+ if(file != null)
+ result = new IFile[]{ file };
+ } else {
+ result = WorkspaceResourceDialog.openFileSelection(getShell(), null, null, false, new Object[]{ currentFile }, filters);
+ }
+
+ if(result.length >= 1) {
+ currentFile = result[0];
+ text.setText(currentFile.getFullPath().toString());
+ notifyChange();
+ }
+ }
+
+ private void notifyChange() {
+ for(Listener listener : listeners) {
+ listener.handleEvent(null);
+ }
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ //Nothing
+ }
+
+}
diff --git a/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/TernaryButton.java b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/TernaryButton.java
new file mode 100644
index 00000000000..23253c8173a
--- /dev/null
+++ b/sandbox/org.eclipse.papyrus.properties.generation/src/org/eclipse/papyrus/properties/generation/wizard/widget/TernaryButton.java
@@ -0,0 +1,218 @@
+/*****************************************************************************
+ * 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.properties.generation.wizard.widget;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.properties.generation.Activator;
+import org.eclipse.papyrus.properties.generation.messages.Messages;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A 3-choices button. The three possible values are "True", "False" or "Default".
+ * When the choice is "Default", it can be either "Default (True)" or "Default (False)",
+ * depending on the default value assignated to the button.
+ *
+ * @see State
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class TernaryButton extends Composite implements SelectionListener {
+
+ private State state;
+
+ private Button button;
+
+ private boolean defaultValue;
+
+ private IObservableValue observable;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The parent in which the button is created
+ * @param defaultValue
+ * The value returned when the "default" value is selected
+ */
+ public TernaryButton(Composite parent, boolean defaultValue) {
+ super(parent, SWT.NONE);
+ button = new Button(this, SWT.PUSH);
+ setLayout(new FillLayout());
+ button.addSelectionListener(this);
+ this.defaultValue = defaultValue;
+ setState(State.DEFAULT);
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ switch(state) {
+ case DEFAULT:
+ setState(State.TRUE);
+ break;
+ case TRUE:
+ setState(State.FALSE);
+ break;
+ case FALSE:
+ setState(State.DEFAULT);
+ break;
+ }
+
+ observable.setValue(getState());
+ }
+
+ /**
+ * Sets the ObservableValue binded to this widget. The databinding
+ * is only one-way : modifications on the Observable value won't be
+ * reflected on the widget.
+ *
+ * @param value
+ * The Observable value to link to this widget
+ */
+ public void setObservable(IObservableValue value) {
+ this.observable = value;
+ }
+
+ /**
+ * Change this button's value
+ *
+ * @param state
+ * The new button's state
+ */
+ public void setState(State state) {
+ this.state = state;
+ button.setImage(state.getImage(defaultValue));
+ button.setText(state.getText(defaultValue));
+ }
+
+ /**
+ * @return the button's state
+ */
+ public State getState() {
+ return state;
+ }
+
+ /**
+ * @return the boolean value of this button. If the State is Default, then
+ * the button's default value will be returned.
+ */
+ public boolean getValue() {
+ return state.getValue(defaultValue);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ //Nothing
+ }
+
+ /**
+ * An enum representing the three possible states of the button :
+ * DEFAULT, TRUE, FALSE
+ *
+ * @author Camille Letavernier
+ *
+ */
+ public enum State {
+ /**
+ * The default value. The Button is responsible for providing
+ * a default value for this case (Either true or false)
+ */
+ DEFAULT,
+ /**
+ * The boolean True value
+ */
+ TRUE,
+ /**
+ * The boolean False value
+ */
+ FALSE;
+
+ /**
+ * @param defaultValue
+ * The value to return if the state is "Default"
+ * @return the boolean value of this button. If the State is Default, then
+ * the default value will be returned.
+ */
+ public boolean getValue(boolean defaultValue) {
+ switch(this) {
+ case DEFAULT:
+ return defaultValue;
+ case TRUE:
+ return true;
+ case FALSE:
+ return false;
+ }
+
+ //Cannot happen as the switch is exhaustive
+ throw new RuntimeException();
+ }
+
+ /**
+ * Return the image corresponding to the current state. If the state
+ * is "Default", the image will depend on the given defaultValue
+ *
+ * @param defaultValue
+ * The value to use if the State is "Default"
+ * @return
+ * The image corresponding to the current State
+ */
+ public Image getImage(boolean defaultValue) {
+ switch(this) {
+ case DEFAULT:
+ if(defaultValue) {
+ return Activator.getDefault().getImage("/icons/default_true.gif"); //$NON-NLS-1$
+ } else {
+ return Activator.getDefault().getImage("/icons/default_false.gif"); //$NON-NLS-1$
+ }
+ case TRUE:
+ return Activator.getDefault().getImage("/icons/true.gif"); //$NON-NLS-1$
+ case FALSE:
+ return Activator.getDefault().getImage("/icons/false.gif"); //$NON-NLS-1$
+ }
+
+ //Cannot happen as the switch is exhaustive
+ throw new RuntimeException();
+ }
+
+ /**
+ * Return the text corresponding to the current state. If the state
+ * is "Default", the text will depend on the given defaultValue
+ *
+ * @param defaultValue
+ * The value to use if the State is "Default"
+ * @return
+ * The text corresponding to the current State
+ */
+ public String getText(boolean defaultValue) {
+ switch(this) {
+ case DEFAULT:
+ if(defaultValue) {
+ return Messages.TernaryButton_defaultTrue;
+ } else {
+ return Messages.TernaryButton_defaultFalse;
+ }
+ case TRUE:
+ return Messages.TernaryButton_true;
+ case FALSE:
+ return Messages.TernaryButton_false;
+ }
+
+ //Cannot happen as the switch is exhaustive
+ throw new RuntimeException();
+ }
+ }
+}

Back to the top