Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcletavernie2011-10-25 12:14:05 +0000
committercletavernie2011-10-25 12:14:05 +0000
commiteaf4d7c27f31095e986fdb19cf9c82651b0a4f69 (patch)
tree6ae770f52dc71da21d09d358c8c7957630a92b34 /plugins/views/properties
parentb6498085b422c97948ada677aadf5bb547a94aa1 (diff)
downloadorg.eclipse.papyrus-eaf4d7c27f31095e986fdb19cf9c82651b0a4f69.tar.gz
org.eclipse.papyrus-eaf4d7c27f31095e986fdb19cf9c82651b0a4f69.tar.xz
org.eclipse.papyrus-eaf4d7c27f31095e986fdb19cf9c82651b0a4f69.zip
359057: [Architecture - SVN - Build] The Papyrus architecture should be refactored
https://bugs.eclipse.org/bugs/show_bug.cgi?id=359057
Diffstat (limited to 'plugins/views/properties')
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/.classpath8
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/.project28
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.core.resources.prefs3
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/META-INF/MANIFEST.MF50
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/Properties.pdoc4
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/about.html28
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/build.properties12
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/icons/error.gifbin0 -> 353 bytes
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/model/Environment.xmi48
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.ecore15
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.genmodel19
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.ecore12
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.genmodel17
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/plugin.properties13
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/plugin.xml68
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/schema/context.exsd137
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/schema/environment.exsd125
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/schema/labelprovider.exsd109
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/PropertiesRoot.java68
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootFactory.java51
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootPackage.java201
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/PropertiesRootImpl.java186
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootFactoryImpl.java107
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootPackageImpl.java220
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootAdapterFactory.java135
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootSwitch.java139
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/ContextDescriptor.java87
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/Preferences.java47
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesFactory.java61
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesPackage.java280
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/ContextDescriptorImpl.java238
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesFactoryImpl.java120
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesImpl.java166
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesPackageImpl.java241
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesAdapterFactory.java156
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesSwitch.java164
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/Activator.java138
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesCatalog.java74
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesURIHandler.java191
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/AbstractConstraint.java184
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/CompoundConstraint.java107
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/Constraint.java75
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFInstanceOfConstraint.java107
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFQueryConstraint.java84
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaInstanceOf.java46
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQuery.java17
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQueryConstraint.java53
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/TrueConstraint.java31
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/CreateInDialog.java180
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EcorePropertyEditorFactory.java401
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EditionDialog.java249
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/PropertyEditorFactory.java176
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/AnnotationObservableValue.java133
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableList.java331
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableValue.java88
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservable.java34
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableList.java187
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableValue.java178
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/ContextExtensionPoint.java49
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/EnvironmentExtensionPoint.java51
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/Messages.java49
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/messages.properties9
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AbstractModelElement.java134
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElement.java66
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElementFactory.java44
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/CompositeModelElement.java188
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSource.java346
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSourceFactory.java240
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElement.java294
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElementFactory.java40
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElement.java155
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElementFactory.java42
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/preferences/Preferences.java171
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/ContainerContentProvider.java67
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/CreateInFeatureContentProvider.java27
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectFilteredLabelProvider.java51
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectLabelProvider.java206
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreEnumeratorContentProvider.java66
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreReferenceContentProvider.java88
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedComboViewer.java47
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedViewerFilter.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/FeatureContentProvider.java67
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/IFilteredLabelProvider.java21
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/SelectionLabelProvider.java93
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProvider.java31
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProviderListener.java23
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationConflict.java69
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationManager.java672
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintEngine.java56
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintFactory.java84
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultConstraintEngine.java155
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultDisplayEngine.java233
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DisplayEngine.java102
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/EmbeddedDisplayEngine.java239
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/ClassLoader.java134
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EClassNameComparator.java35
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EMFHelper.java380
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/Util.java288
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/AbstractPropertyEditor.java497
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCheckbox.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCombo.java37
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanRadio.java38
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanToggle.java85
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumCombo.java58
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumRadio.java76
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerEditor.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerMask.java101
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerSpinner.java92
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/InvalidWidget.java49
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MaskProvider.java29
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiInteger.java56
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReference.java93
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferenceEditorWithPropertyView.java144
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferencePropertyEditorWithPropertyView.java49
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiString.java65
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceCombo.java69
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceDialog.java85
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceLabel.java50
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringCombo.java55
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringEditor.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringFileSelector.java126
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringLabel.java48
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringMultiline.java38
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ViewEditor.java238
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/GridData.java639
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/PropertiesLayout.java962
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/xwt/XWTSection.java235
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/xwt/XWTSectionDescriptor.java77
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/xwt/XWTTabDescriptor.java107
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/xwt/XWTTabDescriptorProvider.java241
131 files changed, 16130 insertions, 0 deletions
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/.classpath b/plugins/views/properties/org.eclipse.papyrus.properties/.classpath
new file mode 100644
index 00000000000..84853724f03
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="src-gen"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/.project b/plugins/views/properties/org.eclipse.papyrus.properties/.project
new file mode 100644
index 00000000000..32de1ef6467
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.papyrus.properties</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.core.resources.prefs b/plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 00000000000..79251c940f1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Fri Feb 11 15:34:17 CET 2011
+eclipse.preferences.version=1
+encoding//src/org/eclipse/papyrus/properties/messages/messages.properties=ISO-8859-1
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.jdt.core.prefs b/plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..10c4cbe2437
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Mon Jan 24 14:55:03 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/META-INF/MANIFEST.MF b/plugins/views/properties/org.eclipse.papyrus.properties/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..946a286b727
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/META-INF/MANIFEST.MF
@@ -0,0 +1,50 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.papyrus.properties;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-ClassPath: .,bin
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Localization: plugin
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: com.ibm.icu,
+ org.eclipse.emf;bundle-version="2.6.0",
+ org.eclipse.emf.ecore;bundle-version="2.6.0",
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.eclipse.emf.databinding;bundle-version="1.2.0",
+ org.eclipse.equinox.common;bundle-version="3.6.0",
+ org.eclipse.ui;bundle-version="3.6.0",
+ org.eclipse.osgi;bundle-version="3.6.0",
+ org.eclipse.core.runtime;bundle-version="3.6.0",
+ org.eclipse.core.resources;bundle-version="3.6.0",
+ org.eclipse.swt,
+ org.eclipse.jface,
+ org.eclipse.jface.databinding,
+ org.eclipse.core.databinding,
+ org.eclipse.core.databinding.property;bundle-version="1.3.0",
+ org.eclipse.e4.xwt;bundle-version="0.9.1",
+ org.eclipse.e4.xwt.pde;bundle-version="0.9.1",
+ org.eclipse.papyrus.properties.model;bundle-version="0.8.0",
+ org.eclipse.papyrus.service.edit;bundle-version="0.8.0",
+ org.eclipse.papyrus.widgets;bundle-version="0.8.0",
+ org.eclipse.core.databinding.beans;bundle-version="1.2.100",
+ org.eclipse.emf.facet.infra.query;bundle-version="0.1.0",
+ org.eclipse.emf.facet.infra.query.core;bundle-version="0.1.0",
+ org.eclipse.emf.facet.infra.common.core;bundle-version="0.1.0",
+ org.eclipse.papyrus.modelexplorer.widgets;bundle-version="0.9.0"
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.papyrus.properties.Activator
+Export-Package: org.eclipse.papyrus.properties,
+ org.eclipse.papyrus.properties.catalog,
+ org.eclipse.papyrus.properties.constraints,
+ org.eclipse.papyrus.properties.creation,
+ org.eclipse.papyrus.properties.databinding,
+ org.eclipse.papyrus.properties.modelelement,
+ org.eclipse.papyrus.properties.providers,
+ org.eclipse.papyrus.properties.root,
+ org.eclipse.papyrus.properties.runtime,
+ org.eclipse.papyrus.properties.util,
+ org.eclipse.papyrus.properties.widgets,
+ org.eclipse.papyrus.properties.widgets.layout,
+ org.eclipse.papyrus.properties.xwt
+Eclipse-BuddyPolicy: dependent
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/Properties.pdoc b/plugins/views/properties/org.eclipse.papyrus.properties/Properties.pdoc
new file mode 100644
index 00000000000..dec431836ed
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/Properties.pdoc
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<doc:Documentation xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:doc="http://www.eclipse.org/papyrus/documentation/plugin/documentation" description="This plug-in contains the runtime elements for the property view framework, as well as a set of basic tools: basic property editors, EMF Data manipulation, ...">
+ <referent firstName="Camille" lastName="Letavernier" eMail="camille.letavernier@cea.fr" currentCompany="CEA LIST"/>
+</doc:Documentation>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/about.html b/plugins/views/properties/org.eclipse.papyrus.properties/about.html
new file mode 100644
index 00000000000..82d49bf5f81
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 5, 2007</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/build.properties b/plugins/views/properties/org.eclipse.papyrus.properties/build.properties
new file mode 100644
index 00000000000..855deb90d24
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/build.properties
@@ -0,0 +1,12 @@
+#
+#Mon Sep 12 09:30:04 CEST 2011
+output..=bin/
+bin.includes=.,META-INF/,plugin.xml,plugin.properties,model/,schema/,about.html,icons/
+jars.compile.order=.
+src.includes = model/,\
+ schema/,\
+ about.html,\
+ icons/,\
+ Properties.pdoc
+source..=src/,src-gen/
+bin..=bin/
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/icons/error.gif b/plugins/views/properties/org.eclipse.papyrus.properties/icons/error.gif
new file mode 100644
index 00000000000..9b048d60532
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/icons/error.gif
Binary files differ
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/model/Environment.xmi b/plugins/views/properties/org.eclipse.papyrus.properties/model/Environment.xmi
new file mode 100644
index 00000000000..3083a59b680
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/model/Environment.xmi
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="ASCII"?>
+<environment:Environment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:environment="http://www.eclipse.org/papyrus/properties/environment">
+ <modelElementFactories name="EMF Factory" factoryClass="org.eclipse.papyrus.properties.modelelement.EMFModelElementFactory"/>
+ <modelElementFactories name="Annotation Factory" factoryClass="org.eclipse.papyrus.properties.modelelement.AnnotationModelElementFactory"/>
+ <constraintTypes label="EMF Instance Of" constraintClass="org.eclipse.papyrus.properties.constraints.EMFInstanceOfConstraint"/>
+ <constraintTypes label="True Constraint" constraintClass="org.eclipse.papyrus.properties.constraints.TrueConstraint"/>
+ <constraintTypes label="EMF Query" constraintClass="org.eclipse.papyrus.properties.constraints.EMFQueryConstraint"/>
+ <constraintTypes label="Java Instance Of" constraintClass="org.eclipse.papyrus.properties.constraints.JavaInstanceOf"/>
+ <constraintTypes label="Java Query" constraintClass="org.eclipse.papyrus.properties.constraints.JavaQueryConstraint"/>
+ <widgetTypes label="Label" widgetClass="Label"/>
+ <widgetTypes label="Text" widgetClass="Text"/>
+ <propertyEditorTypes label="StringEditor" widgetClass="StringEditor" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="StringMultiline" widgetClass="StringMultiline" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="StringLabel (Read-only)" widgetClass="StringLabel" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="StringCombo" widgetClass="StringCombo" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="FileSelector" widgetClass="StringFileSelector" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="BooleanCombo" widgetClass="BooleanCombo" namespace="//@namespaces.3" type="Boolean"/>
+ <propertyEditorTypes label="BooleanCheckbox" widgetClass="BooleanCheckbox" namespace="//@namespaces.3" type="Boolean"/>
+ <propertyEditorTypes label="BooleanRadio" widgetClass="BooleanRadio" namespace="//@namespaces.3" type="Boolean"/>
+ <propertyEditorTypes label="BooleanToggle" widgetClass="BooleanToggle" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="IntegerEditor" widgetClass="IntegerEditor" namespace="//@namespaces.3" type="Integer"/>
+ <propertyEditorTypes label="IntegerSpinner" widgetClass="IntegerSpinner" namespace="//@namespaces.3" type="Integer"/>
+ <propertyEditorTypes label="EnumCombo" widgetClass="EnumCombo" namespace="//@namespaces.3" type="Enumeration"/>
+ <propertyEditorTypes label="EnumRadio (No preview)" widgetClass="EnumRadio" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="ReferenceCombo" widgetClass="ReferenceCombo" namespace="//@namespaces.3" type="Reference"/>
+ <propertyEditorTypes label="ReferenceDialog" widgetClass="ReferenceDialog" namespace="//@namespaces.3" type="Reference"/>
+ <propertyEditorTypes label="ViewEditor" widgetClass="ViewEditor" namespace="//@namespaces.3" type="Reference" multiplicity="-1"/>
+ <propertyEditorTypes label="ReferenceLabel (Read-only)" widgetClass="ReferenceLabel" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="MultiReference" widgetClass="MultiReference" namespace="//@namespaces.3" type="Reference" multiplicity="-1"/>
+ <propertyEditorTypes label="MultiReferenceWithPropertyView" widgetClass="MultiReferencePropertyEditorWithPropertyView" namespace="//@namespaces.3"/>
+ <propertyEditorTypes label="MultiString" widgetClass="MultiString" namespace="//@namespaces.3" multiplicity="-1"/>
+ <propertyEditorTypes label="MultiInteger" widgetClass="MultiInteger" namespace="//@namespaces.3" type="Integer" multiplicity="-1"/>
+ <propertyEditorTypes label="InvalidWidget" widgetClass="InvalidWidget" namespace="//@namespaces.3"/>
+ <compositeWidgetTypes label="Composite" widgetClass="Composite"/>
+ <compositeWidgetTypes label="Group" widgetClass="Group"/>
+ <layoutTypes label="GridLayout" widgetClass="GridLayout"/>
+ <layoutTypes label="FillLayout" widgetClass="FillLayout"/>
+ <layoutTypes label="RowLayout" widgetClass="RowLayout"/>
+ <layoutTypes label="PropertiesLayout" widgetClass="PropertiesLayout" namespace="//@namespaces.4"/>
+ <namespaces prefix="" name="" value="http://www.eclipse.org/xwt/presentation"/>
+ <namespaces name="x" value="http://www.eclipse.org/xwt"/>
+ <namespaces prefix="clr-namespace" name="j" value="java.lang"/>
+ <namespaces prefix="clr-namespace" name="ppe" value="org.eclipse.papyrus.properties.widgets"/>
+ <namespaces prefix="clr-namespace" name="ppel" value="org.eclipse.papyrus.properties.widgets.layout"/>
+ <namespaces prefix="clr-namespace" name="ppec" value="org.eclipse.papyrus.properties.creation"/>
+ <miscClasses label="EMF object factory" class="EcorePropertyEditorFactory" namespace="//@namespaces.5"/>
+ <miscClasses label="Property view Edition factory" class="PropertyEditorFactory" namespace="//@namespaces.5"/>
+</environment:Environment>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.ecore b/plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.ecore
new file mode 100644
index 00000000000..b9d0f86df91
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.ecore
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="preferences"
+ nsURI="http://www.eclipse.org/papryus/properties/preferences" nsPrefix="pref">
+ <eClassifiers xsi:type="ecore:EClass" name="ContextDescriptor">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" lowerBound="1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="applied" lowerBound="1"
+ eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" defaultValueLiteral="true"/>
+ </eClassifiers>
+ <eClassifiers xsi:type="ecore:EClass" name="Preferences">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="contexts" upperBound="-1"
+ eType="#//ContextDescriptor" containment="true"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.genmodel b/plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.genmodel
new file mode 100644
index 00000000000..b2cd6f113b9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/model/Preferences.genmodel
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.papyrus.properties/src-gen"
+ editDirectory="/org.eclipse.papyrus.properties.edit/src-gen" editorDirectory="/org.eclipse.papyrus.properties.editor/src-gen"
+ modelPluginID="org.eclipse.papyrus.properties" modelName="Preferences" testsDirectory="/org.eclipse.papyrus.properties.tests/src-gen"
+ importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0" copyrightFields="false">
+ <foreignModel>Preferences.ecore</foreignModel>
+ <genPackages prefix="Preferences" basePackage="org.eclipse.papyrus.properties.runtime"
+ disposableProviderFactory="true" ecorePackage="Preferences.ecore#/">
+ <genClasses ecoreClass="Preferences.ecore#//ContextDescriptor">
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Preferences.ecore#//ContextDescriptor/name"/>
+ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Preferences.ecore#//ContextDescriptor/applied"/>
+ </genClasses>
+ <genClasses ecoreClass="Preferences.ecore#//Preferences">
+ <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Preferences.ecore#//Preferences/contexts"/>
+ </genClasses>
+ </genPackages>
+</genmodel:GenModel>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.ecore b/plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.ecore
new file mode 100644
index 00000000000..86c708091b9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.ecore
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="root"
+ nsURI="http://www.eclipse.org/papyrus/properties/root" nsPrefix="root">
+ <eClassifiers xsi:type="ecore:EClass" name="PropertiesRoot">
+ <eStructuralFeatures xsi:type="ecore:EReference" name="environments" upperBound="-1"
+ eType="ecore:EClass platform:/plugin/org.eclipse.papyrus.properties.model/Model/Properties.ecore#//environment/Environment"/>
+ <eStructuralFeatures xsi:type="ecore:EReference" name="contexts" upperBound="-1"
+ eType="ecore:EClass platform:/plugin/org.eclipse.papyrus.properties.model/Model/Properties.ecore#//contexts/Context"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.genmodel b/plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.genmodel
new file mode 100644
index 00000000000..5e625276908
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/model/PropertiesRoot.genmodel
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.papyrus.properties/src-gen"
+ editDirectory="/org.eclipse.papyrus.properties.edit/src-gen" editorDirectory="/org.eclipse.papyrus.properties.editor/src-gen"
+ modelPluginID="org.eclipse.papyrus.properties" modelName="PropertiesRoot" testsDirectory="/org.eclipse.papyrus.properties.tests/src-gen"
+ importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0" copyrightFields="false"
+ usedGenPackages="platform:/plugin/org.eclipse.papyrus.properties.model/Model/Properties.genmodel#//properties">
+ <foreignModel>PropertiesRoot.ecore</foreignModel>
+ <genPackages prefix="Root" basePackage="org.eclipse.papyrus.properties" disposableProviderFactory="true"
+ ecorePackage="PropertiesRoot.ecore#/">
+ <genClasses ecoreClass="PropertiesRoot.ecore#//PropertiesRoot">
+ <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PropertiesRoot.ecore#//PropertiesRoot/environments"/>
+ <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference PropertiesRoot.ecore#//PropertiesRoot/contexts"/>
+ </genClasses>
+ </genPackages>
+</genmodel:GenModel>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/plugin.properties b/plugins/views/properties/org.eclipse.papyrus.properties/plugin.properties
new file mode 100644
index 00000000000..cb3492bafd3
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/plugin.properties
@@ -0,0 +1,13 @@
+
+# <copyright>
+# </copyright>
+#
+# $Id$
+
+pluginName = Papyrus properties runtime (Incubation)
+providerName = Eclipse Modeling Project
+
+Bundle-Vendor = Eclipse Modeling Project
+page.name = Property views
+extension-point.context = Context
+extension-point.environment = Environment \ No newline at end of file
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/plugin.xml b/plugins/views/properties/org.eclipse.papyrus.properties/plugin.xml
new file mode 100644
index 00000000000..4b806121eb8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/plugin.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<!--
+ <copyright>
+ </copyright>
+
+ $Id$
+-->
+
+<plugin>
+ <extension-point id="context" name="%extension-point.context" schema="schema/context.exsd"/>
+ <extension-point id="environment" name="%extension-point.environment" schema="schema/environment.exsd"/>
+ <extension-point id="labelprovider" name="labelprovider" schema="schema/labelprovider.exsd"/>
+
+ <extension
+ point="org.eclipse.emf.ecore.generated_package">
+ <package
+ class="org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage"
+ genModel="Model/Preferences.genmodel"
+ uri="http://www.eclipse.org/papryus/properties/preferences">
+ </package>
+ </extension>
+ <extension
+ point="org.eclipse.emf.ecore.uri_mapping">
+ <mapping
+ source="pathmap://PPEResources/"
+ target="platform:/plugin/org.eclipse.papyrus.properties/model/">
+ </mapping>
+ </extension>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.eclipse.papyrus.preferences.generalcategory"
+ class="org.eclipse.papyrus.properties.preferences.Preferences"
+ id="org.eclipse.papyrus.properties.propertyview"
+ name="%page.name">
+ </page>
+ </extension>
+ <extension
+ point="org.eclipse.emf.ecore.generated_package">
+ <package
+ class="org.eclipse.papyrus.properties.root.RootPackage"
+ genModel="Model/PropertiesRoot.genmodel"
+ uri="http://www.eclipse.org/papyrus/properties/root">
+ </package>
+ </extension>
+ <extension
+ point="org.eclipse.papyrus.properties.environment">
+ <environment
+ environmentModel="model/Environment.xmi">
+ </environment>
+ </extension>
+ <extension
+ point="org.eclipse.emf.ecore.protocol_parser">
+ <parser
+ class="org.eclipse.papyrus.properties.catalog.PropertiesCatalog"
+ protocolName="ppe">
+ </parser>
+ </extension>
+ <extension
+ point="org.eclipse.papyrus.properties.labelprovider">
+ <labelProvider
+ labelProvider="org.eclipse.papyrus.properties.providers.EMFObjectFilteredLabelProvider"
+ priority="100">
+ </labelProvider>
+ </extension>
+</plugin>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/schema/context.exsd b/plugins/views/properties/org.eclipse.papyrus.properties/schema/context.exsd
new file mode 100644
index 00000000000..3dcdd57d811
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/schema/context.exsd
@@ -0,0 +1,137 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.properties" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.properties" id="Context" name="Context"/>
+ </appInfo>
+ <documentation>
+ Extension point used to provide new Contexts to the Papyrus Property View. A Context is an EMF Model conforming to http://www.eclipse.org/papyrus/properties (From org.eclipse.papyrus.properties.model), defining a set of Constraint descriptors, and the view to display for each.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="context" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="context">
+ <complexType>
+ <attribute name="contextModel" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="loadDefault" type="boolean" use="default" value="true">
+ <annotation>
+ <documentation>
+ If set to true, this context will be activated by default. Otherwise, the user will need to activate it manually through the preferences page (Preferences -&gt; Papyrus -&gt; Property views)
+
+Default is true.
+ </documentation>
+ <appInfo>
+ <meta.attribute deprecated="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 0.8.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ &lt;extension
+ point=&quot;org.eclipse.papyrus.properties.Context&quot;&gt;
+ &lt;context contextModel=&quot;Model/UML.xmi&quot;&gt;
+ &lt;/context&gt;
+&lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ There is no API associated with this extension point.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ Sample Implementation :
+org.eclipse.papyrus.properties.uml
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*****************************************************************************
+ * 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
+ *****************************************************************************/
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/schema/environment.exsd b/plugins/views/properties/org.eclipse.papyrus.properties/schema/environment.exsd
new file mode 100644
index 00000000000..06d69b73b1d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/schema/environment.exsd
@@ -0,0 +1,125 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.properties" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.properties" id="Environment" name="Environment"/>
+ </appInfo>
+ <documentation>
+ Extension point used to provide new Environment to the Papyrus Property View. An Environment is an EMF Model conforming to http://www.eclipse.org/papyrus/properties/environment (From org.eclipse.papyrus.properties.model), defining a set of element descriptors (Widgets, Factories, ...), which can be used by the different Contexts to define new property views.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="environment" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="environment">
+ <complexType>
+ <attribute name="environmentModel" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="resource"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 0.8.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ &lt;extension
+ point=&quot;org.eclipse.papyrus.properties.Environment&quot;&gt;
+ &lt;environment environmentModel=&quot;Model/Environment.xmi&quot;&gt;
+ &lt;/environment&gt;
+&lt;/extension&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ There is no API associated with this extension point.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ Sample Implementation :
+org.eclipse.papyrus.properties
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ /*****************************************************************************
+ * 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
+ *****************************************************************************/
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/schema/labelprovider.exsd b/plugins/views/properties/org.eclipse.papyrus.properties/schema/labelprovider.exsd
new file mode 100644
index 00000000000..6db00a591bc
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/schema/labelprovider.exsd
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.properties" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.papyrus.properties" id="labelprovider" name="labelprovider"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="labelProvider" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="labelProvider">
+ <complexType>
+ <attribute name="labelProvider" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.properties.providers.IFilteredLabelProvider"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="priority" type="string" use="default" value="10">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/PropertiesRoot.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/PropertiesRoot.java
new file mode 100644
index 00000000000..ff9562aec8b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/PropertiesRoot.java
@@ -0,0 +1,68 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.papyrus.properties.contexts.Context;
+
+import org.eclipse.papyrus.properties.environment.Environment;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Properties Root</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ * <li>{@link org.eclipse.papyrus.properties.root.PropertiesRoot#getEnvironments <em>Environments</em>}</li>
+ * <li>{@link org.eclipse.papyrus.properties.root.PropertiesRoot#getContexts <em>Contexts</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.papyrus.properties.root.RootPackage#getPropertiesRoot()
+ * @model
+ * @generated
+ */
+public interface PropertiesRoot extends EObject {
+
+ /**
+ * Returns the value of the '<em><b>Environments</b></em>' reference list.
+ * The list contents are of type {@link org.eclipse.papyrus.properties.environment.Environment}.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Environments</em>' reference list isn't clear, there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ *
+ * @return the value of the '<em>Environments</em>' reference list.
+ * @see org.eclipse.papyrus.properties.root.RootPackage#getPropertiesRoot_Environments()
+ * @model
+ * @generated
+ */
+ EList<Environment> getEnvironments();
+
+ /**
+ * Returns the value of the '<em><b>Contexts</b></em>' reference list.
+ * The list contents are of type {@link org.eclipse.papyrus.properties.contexts.Context}.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Contexts</em>' reference list isn't clear, there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ *
+ * @return the value of the '<em>Contexts</em>' reference list.
+ * @see org.eclipse.papyrus.properties.root.RootPackage#getPropertiesRoot_Contexts()
+ * @model
+ * @generated
+ */
+ EList<Context> getContexts();
+
+} // PropertiesRoot
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootFactory.java
new file mode 100644
index 00000000000..f377c4f75cb
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootFactory.java
@@ -0,0 +1,51 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root;
+
+import org.eclipse.emf.ecore.EFactory;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Factory</b> for the model.
+ * It provides a create method for each non-abstract class of the model.
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.root.RootPackage
+ * @generated
+ */
+public interface RootFactory extends EFactory {
+
+ /**
+ * The singleton instance of the factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ RootFactory eINSTANCE = org.eclipse.papyrus.properties.root.impl.RootFactoryImpl.init();
+
+ /**
+ * Returns a new object of class '<em>Properties Root</em>'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return a new object of class '<em>Properties Root</em>'.
+ * @generated
+ */
+ PropertiesRoot createPropertiesRoot();
+
+ /**
+ * Returns the package supported by this factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the package supported by this factory.
+ * @generated
+ */
+ RootPackage getRootPackage();
+
+} //RootFactory
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootPackage.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootPackage.java
new file mode 100644
index 00000000000..5148110b3af
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/RootPackage.java
@@ -0,0 +1,201 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Package</b> for the model.
+ * It contains accessors for the meta objects to represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.root.RootFactory
+ * @model kind="package"
+ * @generated
+ */
+public interface RootPackage extends EPackage {
+
+ /**
+ * The package name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ String eNAME = "root"; //$NON-NLS-1$
+
+ /**
+ * The package namespace URI.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ String eNS_URI = "http://www.eclipse.org/papyrus/properties/root"; //$NON-NLS-1$
+
+ /**
+ * The package namespace name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ String eNS_PREFIX = "root"; //$NON-NLS-1$
+
+ /**
+ * The singleton instance of the package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ RootPackage eINSTANCE = org.eclipse.papyrus.properties.root.impl.RootPackageImpl.init();
+
+ /**
+ * The meta object id for the '{@link org.eclipse.papyrus.properties.root.impl.PropertiesRootImpl <em>Properties Root</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.root.impl.PropertiesRootImpl
+ * @see org.eclipse.papyrus.properties.root.impl.RootPackageImpl#getPropertiesRoot()
+ * @generated
+ */
+ int PROPERTIES_ROOT = 0;
+
+ /**
+ * The feature id for the '<em><b>Environments</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int PROPERTIES_ROOT__ENVIRONMENTS = 0;
+
+ /**
+ * The feature id for the '<em><b>Contexts</b></em>' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int PROPERTIES_ROOT__CONTEXTS = 1;
+
+ /**
+ * The number of structural features of the '<em>Properties Root</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int PROPERTIES_ROOT_FEATURE_COUNT = 2;
+
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.papyrus.properties.root.PropertiesRoot <em>Properties Root</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for class '<em>Properties Root</em>'.
+ * @see org.eclipse.papyrus.properties.root.PropertiesRoot
+ * @generated
+ */
+ EClass getPropertiesRoot();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.papyrus.properties.root.PropertiesRoot#getEnvironments
+ * <em>Environments</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for the reference list '<em>Environments</em>'.
+ * @see org.eclipse.papyrus.properties.root.PropertiesRoot#getEnvironments()
+ * @see #getPropertiesRoot()
+ * @generated
+ */
+ EReference getPropertiesRoot_Environments();
+
+ /**
+ * Returns the meta object for the reference list '{@link org.eclipse.papyrus.properties.root.PropertiesRoot#getContexts <em>Contexts</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for the reference list '<em>Contexts</em>'.
+ * @see org.eclipse.papyrus.properties.root.PropertiesRoot#getContexts()
+ * @see #getPropertiesRoot()
+ * @generated
+ */
+ EReference getPropertiesRoot_Contexts();
+
+ /**
+ * Returns the factory that creates the instances of the model.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the factory that creates the instances of the model.
+ * @generated
+ */
+ RootFactory getRootFactory();
+
+ /**
+ * <!-- begin-user-doc -->
+ * Defines literals for the meta objects that represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ interface Literals {
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.papyrus.properties.root.impl.PropertiesRootImpl <em>Properties Root</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.root.impl.PropertiesRootImpl
+ * @see org.eclipse.papyrus.properties.root.impl.RootPackageImpl#getPropertiesRoot()
+ * @generated
+ */
+ EClass PROPERTIES_ROOT = eINSTANCE.getPropertiesRoot();
+
+ /**
+ * The meta object literal for the '<em><b>Environments</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ EReference PROPERTIES_ROOT__ENVIRONMENTS = eINSTANCE.getPropertiesRoot_Environments();
+
+ /**
+ * The meta object literal for the '<em><b>Contexts</b></em>' reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ EReference PROPERTIES_ROOT__CONTEXTS = eINSTANCE.getPropertiesRoot_Contexts();
+
+ }
+
+} //RootPackage
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/PropertiesRootImpl.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/PropertiesRootImpl.java
new file mode 100644
index 00000000000..88ff206f15c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/PropertiesRootImpl.java
@@ -0,0 +1,186 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root.impl;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.emf.ecore.EClass;
+
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+import org.eclipse.emf.ecore.util.EObjectResolvingEList;
+
+import org.eclipse.papyrus.properties.contexts.Context;
+
+import org.eclipse.papyrus.properties.environment.Environment;
+
+import org.eclipse.papyrus.properties.root.PropertiesRoot;
+import org.eclipse.papyrus.properties.root.RootPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Properties Root</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ * <li>{@link org.eclipse.papyrus.properties.root.impl.PropertiesRootImpl#getEnvironments <em>Environments</em>}</li>
+ * <li>{@link org.eclipse.papyrus.properties.root.impl.PropertiesRootImpl#getContexts <em>Contexts</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+public class PropertiesRootImpl extends EObjectImpl implements PropertiesRoot {
+
+ /**
+ * The cached value of the '{@link #getEnvironments() <em>Environments</em>}' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see #getEnvironments()
+ * @generated
+ * @ordered
+ */
+ protected EList<Environment> environments;
+
+ /**
+ * The cached value of the '{@link #getContexts() <em>Contexts</em>}' reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see #getContexts()
+ * @generated
+ * @ordered
+ */
+ protected EList<Context> contexts;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected PropertiesRootImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return RootPackage.Literals.PROPERTIES_ROOT;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EList<Environment> getEnvironments() {
+ if(environments == null) {
+ environments = new EObjectResolvingEList<Environment>(Environment.class, this, RootPackage.PROPERTIES_ROOT__ENVIRONMENTS);
+ }
+ return environments;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EList<Context> getContexts() {
+ if(contexts == null) {
+ contexts = new EObjectResolvingEList<Context>(Context.class, this, RootPackage.PROPERTIES_ROOT__CONTEXTS);
+ }
+ return contexts;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch(featureID) {
+ case RootPackage.PROPERTIES_ROOT__ENVIRONMENTS:
+ return getEnvironments();
+ case RootPackage.PROPERTIES_ROOT__CONTEXTS:
+ return getContexts();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch(featureID) {
+ case RootPackage.PROPERTIES_ROOT__ENVIRONMENTS:
+ getEnvironments().clear();
+ getEnvironments().addAll((Collection<? extends Environment>)newValue);
+ return;
+ case RootPackage.PROPERTIES_ROOT__CONTEXTS:
+ getContexts().clear();
+ getContexts().addAll((Collection<? extends Context>)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch(featureID) {
+ case RootPackage.PROPERTIES_ROOT__ENVIRONMENTS:
+ getEnvironments().clear();
+ return;
+ case RootPackage.PROPERTIES_ROOT__CONTEXTS:
+ getContexts().clear();
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch(featureID) {
+ case RootPackage.PROPERTIES_ROOT__ENVIRONMENTS:
+ return environments != null && !environments.isEmpty();
+ case RootPackage.PROPERTIES_ROOT__CONTEXTS:
+ return contexts != null && !contexts.isEmpty();
+ }
+ return super.eIsSet(featureID);
+ }
+
+} //PropertiesRootImpl
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootFactoryImpl.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootFactoryImpl.java
new file mode 100644
index 00000000000..0256b9d7430
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootFactoryImpl.java
@@ -0,0 +1,107 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root.impl;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+
+import org.eclipse.emf.ecore.impl.EFactoryImpl;
+
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+
+import org.eclipse.papyrus.properties.root.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Factory</b>.
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+public class RootFactoryImpl extends EFactoryImpl implements RootFactory {
+
+ /**
+ * Creates the default factory implementation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public static RootFactory init() {
+ try {
+ RootFactory theRootFactory = (RootFactory)EPackage.Registry.INSTANCE.getEFactory("http://www.eclipse.org/papyrus/properties/root"); //$NON-NLS-1$
+ if(theRootFactory != null) {
+ return theRootFactory;
+ }
+ } catch (Exception exception) {
+ EcorePlugin.INSTANCE.log(exception);
+ }
+ return new RootFactoryImpl();
+ }
+
+ /**
+ * Creates an instance of the factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public RootFactoryImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public EObject create(EClass eClass) {
+ switch(eClass.getClassifierID()) {
+ case RootPackage.PROPERTIES_ROOT:
+ return createPropertiesRoot();
+ default:
+ throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public PropertiesRoot createPropertiesRoot() {
+ PropertiesRootImpl propertiesRoot = new PropertiesRootImpl();
+ return propertiesRoot;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public RootPackage getRootPackage() {
+ return (RootPackage)getEPackage();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @deprecated
+ * @generated
+ */
+ @Deprecated
+ public static RootPackage getPackage() {
+ return RootPackage.eINSTANCE;
+ }
+
+} //RootFactoryImpl
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootPackageImpl.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootPackageImpl.java
new file mode 100644
index 00000000000..d5c38c2c5a2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/impl/RootPackageImpl.java
@@ -0,0 +1,220 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root.impl;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+
+import org.eclipse.papyrus.properties.contexts.ContextsPackage;
+
+import org.eclipse.papyrus.properties.environment.EnvironmentPackage;
+
+import org.eclipse.papyrus.properties.root.PropertiesRoot;
+import org.eclipse.papyrus.properties.root.RootFactory;
+import org.eclipse.papyrus.properties.root.RootPackage;
+
+import org.eclipse.papyrus.properties.ui.UiPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Package</b>.
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+public class RootPackageImpl extends EPackageImpl implements RootPackage {
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private EClass propertiesRootEClass = null;
+
+ /**
+ * Creates an instance of the model <b>Package</b>, registered with {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the
+ * package
+ * package URI value.
+ * <p>
+ * Note: the correct way to create the package is via the static factory method {@link #init init()}, which also performs initialization of the
+ * package, or returns the registered package, if one already exists. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @see org.eclipse.emf.ecore.EPackage.Registry
+ * @see org.eclipse.papyrus.properties.root.RootPackage#eNS_URI
+ * @see #init()
+ * @generated
+ */
+ private RootPackageImpl() {
+ super(eNS_URI, RootFactory.eINSTANCE);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private static boolean isInited = false;
+
+ /**
+ * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
+ *
+ * <p>
+ * This method is used to initialize {@link RootPackage#eINSTANCE} when that field is accessed. Clients should not invoke it directly. Instead,
+ * they should simply access that field to obtain the package. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @see #eNS_URI
+ * @see #createPackageContents()
+ * @see #initializePackageContents()
+ * @generated
+ */
+ public static RootPackage init() {
+ if(isInited)
+ return (RootPackage)EPackage.Registry.INSTANCE.getEPackage(RootPackage.eNS_URI);
+
+ // Obtain or create and register package
+ RootPackageImpl theRootPackage = (RootPackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof RootPackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new RootPackageImpl());
+
+ isInited = true;
+
+ // Initialize simple dependencies
+ EnvironmentPackage.eINSTANCE.eClass();
+ ContextsPackage.eINSTANCE.eClass();
+ UiPackage.eINSTANCE.eClass();
+
+ // Create package meta-data objects
+ theRootPackage.createPackageContents();
+
+ // Initialize created meta-data
+ theRootPackage.initializePackageContents();
+
+ // Mark meta-data to indicate it can't be changed
+ theRootPackage.freeze();
+
+
+ // Update the registry and return the package
+ EPackage.Registry.INSTANCE.put(RootPackage.eNS_URI, theRootPackage);
+ return theRootPackage;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EClass getPropertiesRoot() {
+ return propertiesRootEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EReference getPropertiesRoot_Environments() {
+ return (EReference)propertiesRootEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EReference getPropertiesRoot_Contexts() {
+ return (EReference)propertiesRootEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public RootFactory getRootFactory() {
+ return (RootFactory)getEFactoryInstance();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private boolean isCreated = false;
+
+ /**
+ * Creates the meta-model objects for the package. This method is
+ * guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public void createPackageContents() {
+ if(isCreated)
+ return;
+ isCreated = true;
+
+ // Create classes and their features
+ propertiesRootEClass = createEClass(PROPERTIES_ROOT);
+ createEReference(propertiesRootEClass, PROPERTIES_ROOT__ENVIRONMENTS);
+ createEReference(propertiesRootEClass, PROPERTIES_ROOT__CONTEXTS);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private boolean isInitialized = false;
+
+ /**
+ * Complete the initialization of the package and its meta-model. This
+ * method is guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public void initializePackageContents() {
+ if(isInitialized)
+ return;
+ isInitialized = true;
+
+ // Initialize package
+ setName(eNAME);
+ setNsPrefix(eNS_PREFIX);
+ setNsURI(eNS_URI);
+
+ // Obtain other dependent packages
+ EnvironmentPackage theEnvironmentPackage = (EnvironmentPackage)EPackage.Registry.INSTANCE.getEPackage(EnvironmentPackage.eNS_URI);
+ ContextsPackage theContextsPackage = (ContextsPackage)EPackage.Registry.INSTANCE.getEPackage(ContextsPackage.eNS_URI);
+
+ // Create type parameters
+
+ // Set bounds for type parameters
+
+ // Add supertypes to classes
+
+ // Initialize classes and features; add operations and parameters
+ initEClass(propertiesRootEClass, PropertiesRoot.class, "PropertiesRoot", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$
+ initEReference(getPropertiesRoot_Environments(), theEnvironmentPackage.getEnvironment(), null, "environments", null, 0, -1, PropertiesRoot.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+ initEReference(getPropertiesRoot_Contexts(), theContextsPackage.getContext(), null, "contexts", null, 0, -1, PropertiesRoot.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$
+
+ // Create resource
+ createResource(eNS_URI);
+ }
+
+} //RootPackageImpl
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootAdapterFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootAdapterFactory.java
new file mode 100644
index 00000000000..fa5363cd3fd
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootAdapterFactory.java
@@ -0,0 +1,135 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root.util;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.papyrus.properties.root.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Adapter Factory</b> for the model.
+ * It provides an adapter <code>createXXX</code> method for each class of the model.
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.root.RootPackage
+ * @generated
+ */
+public class RootAdapterFactory extends AdapterFactoryImpl {
+
+ /**
+ * The cached model package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected static RootPackage modelPackage;
+
+ /**
+ * Creates an instance of the adapter factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public RootAdapterFactory() {
+ if(modelPackage == null) {
+ modelPackage = RootPackage.eINSTANCE;
+ }
+ }
+
+ /**
+ * Returns whether this factory is applicable for the type of the object.
+ * <!-- begin-user-doc -->
+ * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model.
+ * <!-- end-user-doc -->
+ *
+ * @return whether this factory is applicable for the type of the object.
+ * @generated
+ */
+ @Override
+ public boolean isFactoryForType(Object object) {
+ if(object == modelPackage) {
+ return true;
+ }
+ if(object instanceof EObject) {
+ return ((EObject)object).eClass().getEPackage() == modelPackage;
+ }
+ return false;
+ }
+
+ /**
+ * The switch that delegates to the <code>createXXX</code> methods.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected RootSwitch<Adapter> modelSwitch = new RootSwitch<Adapter>() {
+
+ @Override
+ public Adapter casePropertiesRoot(PropertiesRoot object) {
+ return createPropertiesRootAdapter();
+ }
+
+ @Override
+ public Adapter defaultCase(EObject object) {
+ return createEObjectAdapter();
+ }
+ };
+
+ /**
+ * Creates an adapter for the <code>target</code>.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @param target
+ * the object to adapt.
+ * @return the adapter for the <code>target</code>.
+ * @generated
+ */
+ @Override
+ public Adapter createAdapter(Notifier target) {
+ return modelSwitch.doSwitch((EObject)target);
+ }
+
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.papyrus.properties.root.PropertiesRoot <em>Properties Root</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ *
+ * @return the new adapter.
+ * @see org.eclipse.papyrus.properties.root.PropertiesRoot
+ * @generated
+ */
+ public Adapter createPropertiesRootAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for the default case.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null.
+ * <!-- end-user-doc -->
+ *
+ * @return the new adapter.
+ * @generated
+ */
+ public Adapter createEObjectAdapter() {
+ return null;
+ }
+
+} //RootAdapterFactory
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootSwitch.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootSwitch.java
new file mode 100644
index 00000000000..98dc31a377c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/root/util/RootSwitch.java
@@ -0,0 +1,139 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.root.util;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.papyrus.properties.root.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Switch</b> for the model's inheritance hierarchy.
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)} to invoke the <code>caseXXX</code> method for each class of the model,
+ * starting with the actual class of the object
+ * and proceeding up the inheritance hierarchy
+ * until a non-null result is returned,
+ * which is the result of the switch.
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.root.RootPackage
+ * @generated
+ */
+public class RootSwitch<T> {
+
+ /**
+ * The cached model package
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected static RootPackage modelPackage;
+
+ /**
+ * Creates an instance of the switch.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public RootSwitch() {
+ if(modelPackage == null) {
+ modelPackage = RootPackage.eINSTANCE;
+ }
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ public T doSwitch(EObject theEObject) {
+ return doSwitch(theEObject.eClass(), theEObject);
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ protected T doSwitch(EClass theEClass, EObject theEObject) {
+ if(theEClass.eContainer() == modelPackage) {
+ return doSwitch(theEClass.getClassifierID(), theEObject);
+ } else {
+ List<EClass> eSuperTypes = theEClass.getESuperTypes();
+ return eSuperTypes.isEmpty() ? defaultCase(theEObject) : doSwitch(eSuperTypes.get(0), theEObject);
+ }
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ protected T doSwitch(int classifierID, EObject theEObject) {
+ switch(classifierID) {
+ case RootPackage.PROPERTIES_ROOT:
+ {
+ PropertiesRoot propertiesRoot = (PropertiesRoot)theEObject;
+ T result = casePropertiesRoot(propertiesRoot);
+ if(result == null)
+ result = defaultCase(theEObject);
+ return result;
+ }
+ default:
+ return defaultCase(theEObject);
+ }
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Properties Root</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ *
+ * @param object
+ * the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Properties Root</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T casePropertiesRoot(PropertiesRoot object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>EObject</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch, but this is the last case anyway.
+ * <!-- end-user-doc -->
+ *
+ * @param object
+ * the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>EObject</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject)
+ * @generated
+ */
+ public T defaultCase(EObject object) {
+ return null;
+ }
+
+} //RootSwitch
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/ContextDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/ContextDescriptor.java
new file mode 100644
index 00000000000..20e64a8bcc1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/ContextDescriptor.java
@@ -0,0 +1,87 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Context Descriptor</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ * <li>{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#getName <em>Name</em>}</li>
+ * <li>{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#isApplied <em>Applied</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage#getContextDescriptor()
+ * @model
+ * @generated
+ */
+public interface ContextDescriptor extends EObject {
+
+ /**
+ * Returns the value of the '<em><b>Name</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Name</em>' attribute isn't clear, there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ *
+ * @return the value of the '<em>Name</em>' attribute.
+ * @see #setName(String)
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage#getContextDescriptor_Name()
+ * @model required="true"
+ * @generated
+ */
+ String getName();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#getName <em>Name</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @param value
+ * the new value of the '<em>Name</em>' attribute.
+ * @see #getName()
+ * @generated
+ */
+ void setName(String value);
+
+ /**
+ * Returns the value of the '<em><b>Applied</b></em>' attribute.
+ * The default value is <code>"true"</code>.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Applied</em>' attribute isn't clear, there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ *
+ * @return the value of the '<em>Applied</em>' attribute.
+ * @see #setApplied(boolean)
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage#getContextDescriptor_Applied()
+ * @model default="true" required="true"
+ * @generated
+ */
+ boolean isApplied();
+
+ /**
+ * Sets the value of the '{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#isApplied <em>Applied</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @param value
+ * the new value of the '<em>Applied</em>' attribute.
+ * @see #isApplied()
+ * @generated
+ */
+ void setApplied(boolean value);
+
+} // ContextDescriptor
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/Preferences.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/Preferences.java
new file mode 100644
index 00000000000..31532c6c1c6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/Preferences.java
@@ -0,0 +1,47 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * <!-- begin-user-doc -->
+ * A representation of the model object '<em><b>Preferences</b></em>'.
+ * <!-- end-user-doc -->
+ *
+ * <p>
+ * The following features are supported:
+ * <ul>
+ * <li>{@link org.eclipse.papyrus.properties.runtime.preferences.Preferences#getContexts <em>Contexts</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage#getPreferences()
+ * @model
+ * @generated
+ */
+public interface Preferences extends EObject {
+
+ /**
+ * Returns the value of the '<em><b>Contexts</b></em>' containment reference list.
+ * The list contents are of type {@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor}.
+ * <!-- begin-user-doc -->
+ * <p>
+ * If the meaning of the '<em>Contexts</em>' containment reference list isn't clear, there really should be more of a description here...
+ * </p>
+ * <!-- end-user-doc -->
+ *
+ * @return the value of the '<em>Contexts</em>' containment reference list.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage#getPreferences_Contexts()
+ * @model containment="true"
+ * @generated
+ */
+ EList<ContextDescriptor> getContexts();
+
+} // Preferences
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesFactory.java
new file mode 100644
index 00000000000..9fbf35fd43b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesFactory.java
@@ -0,0 +1,61 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences;
+
+import org.eclipse.emf.ecore.EFactory;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Factory</b> for the model.
+ * It provides a create method for each non-abstract class of the model.
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage
+ * @generated
+ */
+public interface PreferencesFactory extends EFactory {
+
+ /**
+ * The singleton instance of the factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ PreferencesFactory eINSTANCE = org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesFactoryImpl.init();
+
+ /**
+ * Returns a new object of class '<em>Context Descriptor</em>'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return a new object of class '<em>Context Descriptor</em>'.
+ * @generated
+ */
+ ContextDescriptor createContextDescriptor();
+
+ /**
+ * Returns a new object of class '<em>Preferences</em>'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return a new object of class '<em>Preferences</em>'.
+ * @generated
+ */
+ Preferences createPreferences();
+
+ /**
+ * Returns the package supported by this factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the package supported by this factory.
+ * @generated
+ */
+ PreferencesPackage getPreferencesPackage();
+
+} //PreferencesFactory
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesPackage.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesPackage.java
new file mode 100644
index 00000000000..2737a847ed5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/PreferencesPackage.java
@@ -0,0 +1,280 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Package</b> for the model.
+ * It contains accessors for the meta objects to represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesFactory
+ * @model kind="package"
+ * @generated
+ */
+public interface PreferencesPackage extends EPackage {
+
+ /**
+ * The package name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ String eNAME = "preferences";
+
+ /**
+ * The package namespace URI.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ String eNS_URI = "http://www.eclipse.org/papryus/properties/preferences";
+
+ /**
+ * The package namespace name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ String eNS_PREFIX = "pref";
+
+ /**
+ * The singleton instance of the package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ PreferencesPackage eINSTANCE = org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesPackageImpl.init();
+
+ /**
+ * The meta object id for the '{@link org.eclipse.papyrus.properties.runtime.preferences.impl.ContextDescriptorImpl <em>Context Descriptor</em>}'
+ * class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.ContextDescriptorImpl
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesPackageImpl#getContextDescriptor()
+ * @generated
+ */
+ int CONTEXT_DESCRIPTOR = 0;
+
+ /**
+ * The feature id for the '<em><b>Name</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int CONTEXT_DESCRIPTOR__NAME = 0;
+
+ /**
+ * The feature id for the '<em><b>Applied</b></em>' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int CONTEXT_DESCRIPTOR__APPLIED = 1;
+
+ /**
+ * The number of structural features of the '<em>Context Descriptor</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int CONTEXT_DESCRIPTOR_FEATURE_COUNT = 2;
+
+ /**
+ * The meta object id for the '{@link org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesImpl <em>Preferences</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesImpl
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesPackageImpl#getPreferences()
+ * @generated
+ */
+ int PREFERENCES = 1;
+
+ /**
+ * The feature id for the '<em><b>Contexts</b></em>' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int PREFERENCES__CONTEXTS = 0;
+
+ /**
+ * The number of structural features of the '<em>Preferences</em>' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ * @ordered
+ */
+ int PREFERENCES_FEATURE_COUNT = 1;
+
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor <em>Context Descriptor</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for class '<em>Context Descriptor</em>'.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor
+ * @generated
+ */
+ EClass getContextDescriptor();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#getName <em>Name</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for the attribute '<em>Name</em>'.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#getName()
+ * @see #getContextDescriptor()
+ * @generated
+ */
+ EAttribute getContextDescriptor_Name();
+
+ /**
+ * Returns the meta object for the attribute '{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#isApplied
+ * <em>Applied</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for the attribute '<em>Applied</em>'.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor#isApplied()
+ * @see #getContextDescriptor()
+ * @generated
+ */
+ EAttribute getContextDescriptor_Applied();
+
+ /**
+ * Returns the meta object for class '{@link org.eclipse.papyrus.properties.runtime.preferences.Preferences <em>Preferences</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for class '<em>Preferences</em>'.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.Preferences
+ * @generated
+ */
+ EClass getPreferences();
+
+ /**
+ * Returns the meta object for the containment reference list '{@link org.eclipse.papyrus.properties.runtime.preferences.Preferences#getContexts
+ * <em>Contexts</em>}'.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the meta object for the containment reference list '<em>Contexts</em>'.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.Preferences#getContexts()
+ * @see #getPreferences()
+ * @generated
+ */
+ EReference getPreferences_Contexts();
+
+ /**
+ * Returns the factory that creates the instances of the model.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the factory that creates the instances of the model.
+ * @generated
+ */
+ PreferencesFactory getPreferencesFactory();
+
+ /**
+ * <!-- begin-user-doc -->
+ * Defines literals for the meta objects that represent
+ * <ul>
+ * <li>each class,</li>
+ * <li>each feature of each class,</li>
+ * <li>each enum,</li>
+ * <li>and each data type</li>
+ * </ul>
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ interface Literals {
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.papyrus.properties.runtime.preferences.impl.ContextDescriptorImpl
+ * <em>Context Descriptor</em>}' class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.ContextDescriptorImpl
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesPackageImpl#getContextDescriptor()
+ * @generated
+ */
+ EClass CONTEXT_DESCRIPTOR = eINSTANCE.getContextDescriptor();
+
+ /**
+ * The meta object literal for the '<em><b>Name</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ EAttribute CONTEXT_DESCRIPTOR__NAME = eINSTANCE.getContextDescriptor_Name();
+
+ /**
+ * The meta object literal for the '<em><b>Applied</b></em>' attribute feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ EAttribute CONTEXT_DESCRIPTOR__APPLIED = eINSTANCE.getContextDescriptor_Applied();
+
+ /**
+ * The meta object literal for the '{@link org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesImpl <em>Preferences</em>}'
+ * class.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesImpl
+ * @see org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesPackageImpl#getPreferences()
+ * @generated
+ */
+ EClass PREFERENCES = eINSTANCE.getPreferences();
+
+ /**
+ * The meta object literal for the '<em><b>Contexts</b></em>' containment reference list feature.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ EReference PREFERENCES__CONTEXTS = eINSTANCE.getPreferences_Contexts();
+
+ }
+
+} //PreferencesPackage
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/ContextDescriptorImpl.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/ContextDescriptorImpl.java
new file mode 100644
index 00000000000..0188e5e2ae3
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/ContextDescriptorImpl.java
@@ -0,0 +1,238 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences.impl;
+
+import org.eclipse.emf.common.notify.Notification;
+
+import org.eclipse.emf.ecore.EClass;
+
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+import org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor;
+import org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Context Descriptor</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ * <li>{@link org.eclipse.papyrus.properties.runtime.preferences.impl.ContextDescriptorImpl#getName <em>Name</em>}</li>
+ * <li>{@link org.eclipse.papyrus.properties.runtime.preferences.impl.ContextDescriptorImpl#isApplied <em>Applied</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+public class ContextDescriptorImpl extends EObjectImpl implements ContextDescriptor {
+
+ /**
+ * The default value of the '{@link #getName() <em>Name</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see #getName()
+ * @generated
+ * @ordered
+ */
+ protected static final String NAME_EDEFAULT = null;
+
+ /**
+ * The cached value of the '{@link #getName() <em>Name</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see #getName()
+ * @generated
+ * @ordered
+ */
+ protected String name = NAME_EDEFAULT;
+
+ /**
+ * The default value of the '{@link #isApplied() <em>Applied</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see #isApplied()
+ * @generated
+ * @ordered
+ */
+ protected static final boolean APPLIED_EDEFAULT = true;
+
+ /**
+ * The cached value of the '{@link #isApplied() <em>Applied</em>}' attribute.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see #isApplied()
+ * @generated
+ * @ordered
+ */
+ protected boolean applied = APPLIED_EDEFAULT;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected ContextDescriptorImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return PreferencesPackage.Literals.CONTEXT_DESCRIPTOR;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public void setName(String newName) {
+ String oldName = name;
+ name = newName;
+ if(eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, PreferencesPackage.CONTEXT_DESCRIPTOR__NAME, oldName, name));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public boolean isApplied() {
+ return applied;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public void setApplied(boolean newApplied) {
+ boolean oldApplied = applied;
+ applied = newApplied;
+ if(eNotificationRequired())
+ eNotify(new ENotificationImpl(this, Notification.SET, PreferencesPackage.CONTEXT_DESCRIPTOR__APPLIED, oldApplied, applied));
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch(featureID) {
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__NAME:
+ return getName();
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__APPLIED:
+ return isApplied();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch(featureID) {
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__NAME:
+ setName((String)newValue);
+ return;
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__APPLIED:
+ setApplied((Boolean)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch(featureID) {
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__NAME:
+ setName(NAME_EDEFAULT);
+ return;
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__APPLIED:
+ setApplied(APPLIED_EDEFAULT);
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch(featureID) {
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__NAME:
+ return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
+ case PreferencesPackage.CONTEXT_DESCRIPTOR__APPLIED:
+ return applied != APPLIED_EDEFAULT;
+ }
+ return super.eIsSet(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public String toString() {
+ if(eIsProxy())
+ return super.toString();
+
+ StringBuffer result = new StringBuffer(super.toString());
+ result.append(" (name: ");
+ result.append(name);
+ result.append(", applied: ");
+ result.append(applied);
+ result.append(')');
+ return result.toString();
+ }
+
+} //ContextDescriptorImpl
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesFactoryImpl.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesFactoryImpl.java
new file mode 100644
index 00000000000..8e472af4a5b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesFactoryImpl.java
@@ -0,0 +1,120 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences.impl;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+
+import org.eclipse.emf.ecore.impl.EFactoryImpl;
+
+import org.eclipse.emf.ecore.plugin.EcorePlugin;
+
+import org.eclipse.papyrus.properties.runtime.preferences.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Factory</b>.
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+public class PreferencesFactoryImpl extends EFactoryImpl implements PreferencesFactory {
+
+ /**
+ * Creates the default factory implementation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public static PreferencesFactory init() {
+ try {
+ PreferencesFactory thePreferencesFactory = (PreferencesFactory)EPackage.Registry.INSTANCE.getEFactory("http://www.eclipse.org/papryus/properties/preferences");
+ if(thePreferencesFactory != null) {
+ return thePreferencesFactory;
+ }
+ } catch (Exception exception) {
+ EcorePlugin.INSTANCE.log(exception);
+ }
+ return new PreferencesFactoryImpl();
+ }
+
+ /**
+ * Creates an instance of the factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public PreferencesFactoryImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public EObject create(EClass eClass) {
+ switch(eClass.getClassifierID()) {
+ case PreferencesPackage.CONTEXT_DESCRIPTOR:
+ return createContextDescriptor();
+ case PreferencesPackage.PREFERENCES:
+ return createPreferences();
+ default:
+ throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier");
+ }
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public ContextDescriptor createContextDescriptor() {
+ ContextDescriptorImpl contextDescriptor = new ContextDescriptorImpl();
+ return contextDescriptor;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public Preferences createPreferences() {
+ PreferencesImpl preferences = new PreferencesImpl();
+ return preferences;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public PreferencesPackage getPreferencesPackage() {
+ return (PreferencesPackage)getEPackage();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @deprecated
+ * @generated
+ */
+ @Deprecated
+ public static PreferencesPackage getPackage() {
+ return PreferencesPackage.eINSTANCE;
+ }
+
+} //PreferencesFactoryImpl
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesImpl.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesImpl.java
new file mode 100644
index 00000000000..721522fab30
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesImpl.java
@@ -0,0 +1,166 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences.impl;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.NotificationChain;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.InternalEObject;
+
+import org.eclipse.emf.ecore.impl.EObjectImpl;
+
+import org.eclipse.emf.ecore.util.EObjectContainmentEList;
+import org.eclipse.emf.ecore.util.InternalEList;
+
+import org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor;
+import org.eclipse.papyrus.properties.runtime.preferences.Preferences;
+import org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model object '<em><b>Preferences</b></em>'.
+ * <!-- end-user-doc -->
+ * <p>
+ * The following features are implemented:
+ * <ul>
+ * <li>{@link org.eclipse.papyrus.properties.runtime.preferences.impl.PreferencesImpl#getContexts <em>Contexts</em>}</li>
+ * </ul>
+ * </p>
+ *
+ * @generated
+ */
+public class PreferencesImpl extends EObjectImpl implements Preferences {
+
+ /**
+ * The cached value of the '{@link #getContexts() <em>Contexts</em>}' containment reference list.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @see #getContexts()
+ * @generated
+ * @ordered
+ */
+ protected EList<ContextDescriptor> contexts;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected PreferencesImpl() {
+ super();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ protected EClass eStaticClass() {
+ return PreferencesPackage.Literals.PREFERENCES;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EList<ContextDescriptor> getContexts() {
+ if(contexts == null) {
+ contexts = new EObjectContainmentEList<ContextDescriptor>(ContextDescriptor.class, this, PreferencesPackage.PREFERENCES__CONTEXTS);
+ }
+ return contexts;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
+ switch(featureID) {
+ case PreferencesPackage.PREFERENCES__CONTEXTS:
+ return ((InternalEList<?>)getContexts()).basicRemove(otherEnd, msgs);
+ }
+ return super.eInverseRemove(otherEnd, featureID, msgs);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public Object eGet(int featureID, boolean resolve, boolean coreType) {
+ switch(featureID) {
+ case PreferencesPackage.PREFERENCES__CONTEXTS:
+ return getContexts();
+ }
+ return super.eGet(featureID, resolve, coreType);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void eSet(int featureID, Object newValue) {
+ switch(featureID) {
+ case PreferencesPackage.PREFERENCES__CONTEXTS:
+ getContexts().clear();
+ getContexts().addAll((Collection<? extends ContextDescriptor>)newValue);
+ return;
+ }
+ super.eSet(featureID, newValue);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public void eUnset(int featureID) {
+ switch(featureID) {
+ case PreferencesPackage.PREFERENCES__CONTEXTS:
+ getContexts().clear();
+ return;
+ }
+ super.eUnset(featureID);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ @Override
+ public boolean eIsSet(int featureID) {
+ switch(featureID) {
+ case PreferencesPackage.PREFERENCES__CONTEXTS:
+ return contexts != null && !contexts.isEmpty();
+ }
+ return super.eIsSet(featureID);
+ }
+
+} //PreferencesImpl
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesPackageImpl.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesPackageImpl.java
new file mode 100644
index 00000000000..d2cc88a8d01
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/impl/PreferencesPackageImpl.java
@@ -0,0 +1,241 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences.impl;
+
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+
+import org.eclipse.emf.ecore.impl.EPackageImpl;
+
+import org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor;
+import org.eclipse.papyrus.properties.runtime.preferences.Preferences;
+import org.eclipse.papyrus.properties.runtime.preferences.PreferencesFactory;
+import org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage;
+
+/**
+ * <!-- begin-user-doc -->
+ * An implementation of the model <b>Package</b>.
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+public class PreferencesPackageImpl extends EPackageImpl implements PreferencesPackage {
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private EClass contextDescriptorEClass = null;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private EClass preferencesEClass = null;
+
+ /**
+ * Creates an instance of the model <b>Package</b>, registered with {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the
+ * package
+ * package URI value.
+ * <p>
+ * Note: the correct way to create the package is via the static factory method {@link #init init()}, which also performs initialization of the
+ * package, or returns the registered package, if one already exists. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @see org.eclipse.emf.ecore.EPackage.Registry
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage#eNS_URI
+ * @see #init()
+ * @generated
+ */
+ private PreferencesPackageImpl() {
+ super(eNS_URI, PreferencesFactory.eINSTANCE);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private static boolean isInited = false;
+
+ /**
+ * Creates, registers, and initializes the <b>Package</b> for this model, and for any others upon which it depends.
+ *
+ * <p>
+ * This method is used to initialize {@link PreferencesPackage#eINSTANCE} when that field is accessed. Clients should not invoke it directly.
+ * Instead, they should simply access that field to obtain the package. <!-- begin-user-doc --> <!-- end-user-doc -->
+ *
+ * @see #eNS_URI
+ * @see #createPackageContents()
+ * @see #initializePackageContents()
+ * @generated
+ */
+ public static PreferencesPackage init() {
+ if(isInited)
+ return (PreferencesPackage)EPackage.Registry.INSTANCE.getEPackage(PreferencesPackage.eNS_URI);
+
+ // Obtain or create and register package
+ PreferencesPackageImpl thePreferencesPackage = (PreferencesPackageImpl)(EPackage.Registry.INSTANCE.get(eNS_URI) instanceof PreferencesPackageImpl ? EPackage.Registry.INSTANCE.get(eNS_URI) : new PreferencesPackageImpl());
+
+ isInited = true;
+
+ // Create package meta-data objects
+ thePreferencesPackage.createPackageContents();
+
+ // Initialize created meta-data
+ thePreferencesPackage.initializePackageContents();
+
+ // Mark meta-data to indicate it can't be changed
+ thePreferencesPackage.freeze();
+
+
+ // Update the registry and return the package
+ EPackage.Registry.INSTANCE.put(PreferencesPackage.eNS_URI, thePreferencesPackage);
+ return thePreferencesPackage;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EClass getContextDescriptor() {
+ return contextDescriptorEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EAttribute getContextDescriptor_Name() {
+ return (EAttribute)contextDescriptorEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EAttribute getContextDescriptor_Applied() {
+ return (EAttribute)contextDescriptorEClass.getEStructuralFeatures().get(1);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EClass getPreferences() {
+ return preferencesEClass;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public EReference getPreferences_Contexts() {
+ return (EReference)preferencesEClass.getEStructuralFeatures().get(0);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public PreferencesFactory getPreferencesFactory() {
+ return (PreferencesFactory)getEFactoryInstance();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private boolean isCreated = false;
+
+ /**
+ * Creates the meta-model objects for the package. This method is
+ * guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public void createPackageContents() {
+ if(isCreated)
+ return;
+ isCreated = true;
+
+ // Create classes and their features
+ contextDescriptorEClass = createEClass(CONTEXT_DESCRIPTOR);
+ createEAttribute(contextDescriptorEClass, CONTEXT_DESCRIPTOR__NAME);
+ createEAttribute(contextDescriptorEClass, CONTEXT_DESCRIPTOR__APPLIED);
+
+ preferencesEClass = createEClass(PREFERENCES);
+ createEReference(preferencesEClass, PREFERENCES__CONTEXTS);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ private boolean isInitialized = false;
+
+ /**
+ * Complete the initialization of the package and its meta-model. This
+ * method is guarded to have no affect on any invocation but its first.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public void initializePackageContents() {
+ if(isInitialized)
+ return;
+ isInitialized = true;
+
+ // Initialize package
+ setName(eNAME);
+ setNsPrefix(eNS_PREFIX);
+ setNsURI(eNS_URI);
+
+ // Create type parameters
+
+ // Set bounds for type parameters
+
+ // Add supertypes to classes
+
+ // Initialize classes and features; add operations and parameters
+ initEClass(contextDescriptorEClass, ContextDescriptor.class, "ContextDescriptor", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+ initEAttribute(getContextDescriptor_Name(), ecorePackage.getEString(), "name", null, 1, 1, ContextDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+ initEAttribute(getContextDescriptor_Applied(), ecorePackage.getEBoolean(), "applied", "true", 1, 1, ContextDescriptor.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+ initEClass(preferencesEClass, Preferences.class, "Preferences", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
+ initEReference(getPreferences_Contexts(), this.getContextDescriptor(), null, "contexts", null, 0, -1, Preferences.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+
+ // Create resource
+ createResource(eNS_URI);
+ }
+
+} //PreferencesPackageImpl
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesAdapterFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesAdapterFactory.java
new file mode 100644
index 00000000000..fb6d605a2cb
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesAdapterFactory.java
@@ -0,0 +1,156 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences.util;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notifier;
+
+import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl;
+
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.papyrus.properties.runtime.preferences.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Adapter Factory</b> for the model.
+ * It provides an adapter <code>createXXX</code> method for each class of the model.
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage
+ * @generated
+ */
+public class PreferencesAdapterFactory extends AdapterFactoryImpl {
+
+ /**
+ * The cached model package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected static PreferencesPackage modelPackage;
+
+ /**
+ * Creates an instance of the adapter factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public PreferencesAdapterFactory() {
+ if(modelPackage == null) {
+ modelPackage = PreferencesPackage.eINSTANCE;
+ }
+ }
+
+ /**
+ * Returns whether this factory is applicable for the type of the object.
+ * <!-- begin-user-doc -->
+ * This implementation returns <code>true</code> if the object is either the model's package or is an instance object of the model.
+ * <!-- end-user-doc -->
+ *
+ * @return whether this factory is applicable for the type of the object.
+ * @generated
+ */
+ @Override
+ public boolean isFactoryForType(Object object) {
+ if(object == modelPackage) {
+ return true;
+ }
+ if(object instanceof EObject) {
+ return ((EObject)object).eClass().getEPackage() == modelPackage;
+ }
+ return false;
+ }
+
+ /**
+ * The switch that delegates to the <code>createXXX</code> methods.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected PreferencesSwitch<Adapter> modelSwitch = new PreferencesSwitch<Adapter>() {
+
+ @Override
+ public Adapter caseContextDescriptor(ContextDescriptor object) {
+ return createContextDescriptorAdapter();
+ }
+
+ @Override
+ public Adapter casePreferences(Preferences object) {
+ return createPreferencesAdapter();
+ }
+
+ @Override
+ public Adapter defaultCase(EObject object) {
+ return createEObjectAdapter();
+ }
+ };
+
+ /**
+ * Creates an adapter for the <code>target</code>.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @param target
+ * the object to adapt.
+ * @return the adapter for the <code>target</code>.
+ * @generated
+ */
+ @Override
+ public Adapter createAdapter(Notifier target) {
+ return modelSwitch.doSwitch((EObject)target);
+ }
+
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor
+ * <em>Context Descriptor</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ *
+ * @return the new adapter.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor
+ * @generated
+ */
+ public Adapter createContextDescriptorAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for an object of class '{@link org.eclipse.papyrus.properties.runtime.preferences.Preferences <em>Preferences</em>}'.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null so that we can easily ignore cases;
+ * it's useful to ignore a case when inheritance will catch all the cases anyway.
+ * <!-- end-user-doc -->
+ *
+ * @return the new adapter.
+ * @see org.eclipse.papyrus.properties.runtime.preferences.Preferences
+ * @generated
+ */
+ public Adapter createPreferencesAdapter() {
+ return null;
+ }
+
+ /**
+ * Creates a new adapter for the default case.
+ * <!-- begin-user-doc -->
+ * This default implementation returns null.
+ * <!-- end-user-doc -->
+ *
+ * @return the new adapter.
+ * @generated
+ */
+ public Adapter createEObjectAdapter() {
+ return null;
+ }
+
+} //PreferencesAdapterFactory
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesSwitch.java b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesSwitch.java
new file mode 100644
index 00000000000..84475e2c761
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src-gen/org/eclipse/papyrus/properties/runtime/preferences/util/PreferencesSwitch.java
@@ -0,0 +1,164 @@
+/**
+ * <copyright>
+ * </copyright>
+ *
+ * $Id$
+ */
+package org.eclipse.papyrus.properties.runtime.preferences.util;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+
+import org.eclipse.papyrus.properties.runtime.preferences.*;
+
+/**
+ * <!-- begin-user-doc -->
+ * The <b>Switch</b> for the model's inheritance hierarchy.
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)} to invoke the <code>caseXXX</code> method for each class of the model,
+ * starting with the actual class of the object
+ * and proceeding up the inheritance hierarchy
+ * until a non-null result is returned,
+ * which is the result of the switch.
+ * <!-- end-user-doc -->
+ *
+ * @see org.eclipse.papyrus.properties.runtime.preferences.PreferencesPackage
+ * @generated
+ */
+public class PreferencesSwitch<T> {
+
+ /**
+ * The cached model package
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ protected static PreferencesPackage modelPackage;
+
+ /**
+ * Creates an instance of the switch.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @generated
+ */
+ public PreferencesSwitch() {
+ if(modelPackage == null) {
+ modelPackage = PreferencesPackage.eINSTANCE;
+ }
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ public T doSwitch(EObject theEObject) {
+ return doSwitch(theEObject.eClass(), theEObject);
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ protected T doSwitch(EClass theEClass, EObject theEObject) {
+ if(theEClass.eContainer() == modelPackage) {
+ return doSwitch(theEClass.getClassifierID(), theEObject);
+ } else {
+ List<EClass> eSuperTypes = theEClass.getESuperTypes();
+ return eSuperTypes.isEmpty() ? defaultCase(theEObject) : doSwitch(eSuperTypes.get(0), theEObject);
+ }
+ }
+
+ /**
+ * Calls <code>caseXXX</code> for each class of the model until one returns a non null result; it yields that result.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ *
+ * @return the first non-null result returned by a <code>caseXXX</code> call.
+ * @generated
+ */
+ protected T doSwitch(int classifierID, EObject theEObject) {
+ switch(classifierID) {
+ case PreferencesPackage.CONTEXT_DESCRIPTOR:
+ {
+ ContextDescriptor contextDescriptor = (ContextDescriptor)theEObject;
+ T result = caseContextDescriptor(contextDescriptor);
+ if(result == null)
+ result = defaultCase(theEObject);
+ return result;
+ }
+ case PreferencesPackage.PREFERENCES:
+ {
+ Preferences preferences = (Preferences)theEObject;
+ T result = casePreferences(preferences);
+ if(result == null)
+ result = defaultCase(theEObject);
+ return result;
+ }
+ default:
+ return defaultCase(theEObject);
+ }
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Context Descriptor</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ *
+ * @param object
+ * the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Context Descriptor</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T caseContextDescriptor(ContextDescriptor object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>Preferences</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch.
+ * <!-- end-user-doc -->
+ *
+ * @param object
+ * the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>Preferences</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject)
+ * @generated
+ */
+ public T casePreferences(Preferences object) {
+ return null;
+ }
+
+ /**
+ * Returns the result of interpreting the object as an instance of '<em>EObject</em>'.
+ * <!-- begin-user-doc -->
+ * This implementation returns null;
+ * returning a non-null result will terminate the switch, but this is the last case anyway.
+ * <!-- end-user-doc -->
+ *
+ * @param object
+ * the target of the switch.
+ * @return the result of interpreting the object as an instance of '<em>EObject</em>'.
+ * @see #doSwitch(org.eclipse.emf.ecore.EObject)
+ * @generated
+ */
+ public T defaultCase(EObject object) {
+ return null;
+ }
+
+} //PreferencesSwitch
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/Activator.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/Activator.java
new file mode 100644
index 00000000000..8c6745c4ae2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/Activator.java
@@ -0,0 +1,138 @@
+/*****************************************************************************
+ * 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;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.papyrus.log.LogHelper;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+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 ID
+ */
+ public static final String PLUGIN_ID = "org.eclipse.papyrus.properties"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * Log
+ */
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(plugin);
+ ConfigurationManager.init();
+ }
+
+ /**
+ * @return The IPath representing the plugin's preferences folder location
+ */
+ public IPath getPreferencesPath() {
+ return getStateLocation();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return 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;
+ }
+
+ /**
+ * Returns the image from the given path
+ *
+ * @param imagePath
+ * The path of the image, in the form /<plug-in ID>/<path to the image>
+ * @return
+ * The Image at the given location, or null if none was found
+ */
+ public Image getImageFromPlugin(String imagePath) {
+ if(imagePath.startsWith("/")) { //$NON-NLS-1$
+ String pluginId, path;
+ imagePath = imagePath.substring(1, imagePath.length());
+ pluginId = imagePath.substring(0, imagePath.indexOf("/")); //$NON-NLS-1$
+ path = imagePath.substring(imagePath.indexOf("/"), imagePath.length()); //$NON-NLS-1$
+ return getImage(pluginId, path);
+ } else {
+ return getImage(imagePath);
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesCatalog.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesCatalog.java
new file mode 100644
index 00000000000..7600e175228
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesCatalog.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * 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.catalog;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.Resource.Factory;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
+
+/**
+ * A catalog for property view URIs
+ *
+ * Handles URIs with the ppe:/ scheme
+ *
+ * @author Camille Letavernier
+ */
+public class PropertiesCatalog implements Factory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public Resource createResource(URI sourceURI) {
+ return new PropertiesXMIResource(sourceURI);
+ }
+
+ /**
+ * An XMIResource with a specific URI Converter, for handling
+ * the ppe:/ scheme
+ *
+ * @author Camille Letavernier
+ */
+ //TODO : This class should encapsulate a resource, and not extend it
+ //Non-xmi resources which are relative to a XMI resource cannot be handled
+ //Typically, xwt files cannot be handled by an XMIResource
+ //Problem : local calls to getURIConverter will skip the encapsulation...
+ public class PropertiesXMIResource extends XMIResourceImpl {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param sourceURI
+ * The URI to associate to this resource
+ */
+ public PropertiesXMIResource(URI sourceURI) {
+ super(sourceURI);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public URIConverter getURIConverter() {
+ return new ExtensibleURIConverterImpl() {
+
+ @Override
+ public org.eclipse.emf.ecore.resource.URIHandler getURIHandler(URI uri) {
+ return new PropertiesURIHandler();
+ }
+ };
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesURIHandler.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesURIHandler.java
new file mode 100644
index 00000000000..781f79bc0a1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/catalog/PropertiesURIHandler.java
@@ -0,0 +1,191 @@
+/*****************************************************************************
+ * 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.catalog;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.URIHandler;
+import org.eclipse.papyrus.properties.Activator;
+
+/**
+ * A URI Handler for URIs with the ppe:/ scheme
+ *
+ * @author Camille Letavernier
+ */
+public class PropertiesURIHandler implements URIHandler {
+
+ /**
+ * The segment for environment models
+ */
+ public static final String ENVIRONMENT_SEGMENT = "environment"; //$NON-NLS-1$
+
+ /**
+ * The segment for context models
+ */
+ public static final String CONTEXT_SEGMENT = "context"; //$NON-NLS-1$
+
+ /**
+ * The handled URI scheme (ppe)
+ */
+ public static final String PROPERTIES_SCHEME = "ppe"; //$NON-NLS-1$
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canHandle(URI uri) {
+ return uri != null && PROPERTIES_SCHEME.equals(uri.scheme());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException {
+ URI convertedURI = getConvertedURI(uri);
+ URIHandler handler = getDelegateHandler(convertedURI);
+ return handler.createInputStream(convertedURI, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException {
+ URI convertedURI = getConvertedURI(uri);
+ URIHandler handler = getDelegateHandler(convertedURI);
+ return handler.createOutputStream(convertedURI, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void delete(URI uri, Map<?, ?> options) throws IOException {
+ URI convertedURI = getConvertedURI(uri);
+ URIHandler handler = getDelegateHandler(convertedURI);
+ handler.delete(convertedURI, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<String, ?> contentDescription(URI uri, Map<?, ?> options) throws IOException {
+ URI convertedURI = getConvertedURI(uri);
+ URIHandler handler = getDelegateHandler(convertedURI);
+ return handler.contentDescription(convertedURI, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean exists(URI uri, Map<?, ?> options) {
+ URI convertedURI = getConvertedURI(uri);
+ URIHandler handler = getDelegateHandler(convertedURI);
+ return handler.exists(convertedURI, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<String, ?> getAttributes(URI uri, Map<?, ?> options) {
+ URI convertedURI = getConvertedURI(uri);
+ URIHandler handler = getDelegateHandler(convertedURI);
+ return handler.getAttributes(convertedURI, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException {
+ URI convertedURI = getConvertedURI(uri);
+ URIHandler handler = getDelegateHandler(convertedURI);
+ handler.setAttributes(convertedURI, attributes, options);
+ }
+
+ /**
+ * Returns the URIHandler that can handle the given URI
+ *
+ * @param convertedURI
+ * The URI obtained after converting the ppe:/ URI to a standard URI
+ * @return
+ * The URIHandler corresponding to the converted URI
+ */
+ protected URIHandler getDelegateHandler(URI convertedURI) {
+ if(convertedURI == null) {
+ return null;
+ }
+
+ for(URIHandler handler : URIHandler.DEFAULT_HANDLERS) {
+ if(handler.canHandle(convertedURI)) {
+ return handler;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Converts the ppe:/ URI to a standard URI
+ *
+ * @param sourceURI
+ * The ppe:/ URI to convert
+ * @return
+ * The standard URI
+ */
+ public URI getConvertedURI(URI sourceURI) {
+ if(sourceURI == null) {
+ throw new IllegalArgumentException("sourceURI shall not be null"); //$NON-NLS-1$
+ }
+ String firstSegment = sourceURI.segment(0);
+ URI targetURI = URI.createURI(""); //$NON-NLS-1$
+ if(firstSegment.equals(ENVIRONMENT_SEGMENT)) {
+ for(int i = 1; i < sourceURI.segmentsList().size(); i++) {
+ String segment = sourceURI.segmentsList().get(i);
+ targetURI = targetURI.appendSegment(segment);
+ }
+ } else if(firstSegment.equals(CONTEXT_SEGMENT)) {
+ for(int i = 1; i < sourceURI.segmentsList().size(); i++) {
+ String segment = sourceURI.segmentsList().get(i);
+ targetURI = targetURI.appendSegment(segment);
+ }
+ } else {
+ throw new IllegalArgumentException(sourceURI + " is not a valid URI"); //$NON-NLS-1$
+ }
+
+ URI pluginURI = targetURI.resolve(URI.createURI("platform:/plugin/")); //$NON-NLS-1$
+
+ if(!exists(pluginURI)) {
+ URI workspaceURI = targetURI.resolve(URI.createURI("platform:/resource/")); //$NON-NLS-1$
+ if(!exists(workspaceURI)) {
+ URI preferenceURI = targetURI.resolve(URI.createFileURI(Activator.getDefault().getPreferencesPath().toString() + "/")); //$NON-NLS-1$
+ if(!exists(preferenceURI)) {
+ return null;
+ }
+ return preferenceURI;
+ }
+ return workspaceURI;
+ }
+
+ return pluginURI;
+ }
+
+ private boolean exists(URI uri) {
+ for(URIHandler handler : DEFAULT_HANDLERS) {
+ if(handler.canHandle(uri)) {
+ return handler.exists(uri, Collections.EMPTY_MAP);
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/AbstractConstraint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/AbstractConstraint.java
new file mode 100644
index 00000000000..5b6616c140b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/AbstractConstraint.java
@@ -0,0 +1,184 @@
+/*****************************************************************************
+ * 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.constraints;
+
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.contexts.ConfigProperty;
+import org.eclipse.papyrus.properties.contexts.ConstraintDescriptor;
+import org.eclipse.papyrus.properties.contexts.DisplayUnit;
+import org.eclipse.papyrus.properties.contexts.ReferenceProperty;
+import org.eclipse.papyrus.properties.contexts.SimpleConstraint;
+import org.eclipse.papyrus.properties.contexts.ValueProperty;
+import org.eclipse.papyrus.properties.contexts.View;
+
+/**
+ * An abstract implementation for the Constraint interface.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public abstract class AbstractConstraint implements Constraint {
+
+ /**
+ * The descriptor used to instantiate this constraint.
+ * Contains some attributes for this constraint
+ */
+ protected ConstraintDescriptor descriptor;
+
+ /**
+ * The display unit (Section or View) associated to this constraint
+ */
+ protected DisplayUnit display;
+
+ public final void setConstraintDescriptor(ConstraintDescriptor descriptor) {
+ this.descriptor = descriptor;
+ display = getDisplay(descriptor);
+ if(descriptor instanceof SimpleConstraint) {
+ setDescriptor((SimpleConstraint)descriptor);
+ }
+ }
+
+ private DisplayUnit getDisplay(ConstraintDescriptor descriptor) {
+ if(descriptor.getDisplay() == null) {
+ if(descriptor.eContainer() instanceof ConstraintDescriptor) {
+ return getDisplay((ConstraintDescriptor)descriptor.eContainer());
+ }
+ }
+ return descriptor.getDisplay();
+ }
+
+ public View getView() {
+ if(display instanceof View) {
+ return (View)display;
+ } else {
+ Activator.log.warn("The constraint " + descriptor.getName() + " isn't owned by a View"); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+ }
+
+ /**
+ * A constraint for a Single element (Exactly one) overrides
+ * the same constraint for a multiple element (One or more)
+ */
+ public boolean overrides(Constraint constraint) {
+ if(equivalent(constraint)) {
+ if(getView().getElementMultiplicity() == 1) {
+ if(constraint.getView().getElementMultiplicity() != 1) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Tests if two constraints are equivalent.
+ * Two constraints are equivalent if they have the same parameters.
+ * Two equivalent constraints may have different Display units, with
+ * different multiplicities.
+ *
+ * @param constraint
+ * @return
+ * True if this object is equivalent to the given constraint
+ */
+ protected abstract boolean equivalent(Constraint constraint);
+
+ public ConstraintDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Returns the ConfigProperty corresponding to the given propertyName
+ *
+ * @param propertyName
+ * The name of the property to retrieve
+ * @return
+ * The ConfigProperty corresponding to the given propertyName
+ */
+ protected ConfigProperty getProperty(String propertyName) {
+ if(descriptor == null || !(descriptor instanceof SimpleConstraint)) {
+ Activator.log.warn("The constraint descriptor has not been set for this constraint : " + this); //$NON-NLS-1$
+ } else {
+ for(ConfigProperty property : ((SimpleConstraint)descriptor).getProperties()) {
+ if(property.getName().equals(propertyName)) {
+ return property;
+ }
+ }
+ }
+
+ Activator.log.warn("The property " + propertyName + " has not been set for constraint " + descriptor.getName()); //$NON-NLS-1$ //$NON-NLS-2$
+
+ return null;
+ }
+
+ /**
+ * Returns the value associated to the given property
+ *
+ * @param propertyName
+ * The name of the property for which we want to retrieve the value
+ * The name must correspond to a valid ValueProperty
+ * @return
+ * The value associated to the given property
+ *
+ * @see #getReferenceValue(String)
+ */
+ protected String getValue(String propertyName) {
+ ConfigProperty property = getProperty(propertyName);
+
+ if(property instanceof ValueProperty) {
+ return ((ValueProperty)property).getValue();
+ }
+
+ Activator.log.warn("The property " + propertyName + " is not a ValueProperty (Constraint " + descriptor.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ return null;
+ }
+
+ /**
+ * Returns the value associated to the given property
+ *
+ * @param propertyName
+ * The name of the property for which we want to retrieve the value
+ * The name must correspond to a valid ReferenceProperty
+ * @return
+ * The value associated to the given property
+ *
+ * @see #getValue(String)
+ */
+ protected Object getReferenceValue(String propertyName) {
+ ConfigProperty property = getProperty(propertyName);
+ if(property instanceof ReferenceProperty) {
+ return ((ReferenceProperty)property).getValue();
+ }
+
+ Activator.log.warn("The property " + propertyName + " is not a ReferenceProperty (Constraint " + descriptor.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ return null;
+ }
+
+ /**
+ * Sets the Constraint Descriptor for this constraint.
+ * The constraint descriptor may contain some parameters to configure this
+ * constraint.
+ * Implementors may override.
+ *
+ * @param descriptor
+ * The constraint descriptor to be associated to this constraint
+ *
+ * @see #setConstraintDescriptor(ConstraintDescriptor)
+ */
+ protected void setDescriptor(SimpleConstraint descriptor) {
+ //Implementors may override
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/CompoundConstraint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/CompoundConstraint.java
new file mode 100644
index 00000000000..d567470c344
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/CompoundConstraint.java
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * 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.constraints;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A Composite constraint. It matches a given selection if and only if
+ * all its sub constraints match this selection.
+ *
+ * @author Camille Letavernier
+ */
+public class CompoundConstraint extends AbstractConstraint {
+
+ /**
+ * Adds a sub-constraint to this constraint
+ *
+ * @param subConstraint
+ * The sub-constraint to be added
+ */
+ public void addConstraint(Constraint subConstraint) {
+ constraints.add(subConstraint);
+ }
+
+ /**
+ * A Composite Constraints matches a selection if and only if
+ * all its inner constraints match it
+ */
+ public boolean match(Object selection) {
+ for(Constraint constraint : constraints) {
+ if(!constraint.match(selection)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean overrides(Constraint constraint) {
+ if(constraints.size() == 0) {
+ return false;
+ }
+
+ if(constraints.size() == 1) {
+ return constraints.get(0).overrides(constraint);
+ }
+
+ //A Composite overrides another Composite if at least one sub-constraint overrides another one,
+ //and each sub-constraint is at least equal to another one
+ if(constraint instanceof CompoundConstraint) {
+ boolean atLeastOneOverride = false;
+ for(Constraint subConstraint : constraints) {
+ boolean equalsOrOverride = false;
+ for(Constraint otherSubConstraint : ((CompoundConstraint)constraint).constraints) {
+ if(subConstraint.overrides(otherSubConstraint)) {
+ atLeastOneOverride = true;
+ break;
+ }
+ if(subConstraint.equals(otherSubConstraint)) {
+ equalsOrOverride = true;
+ }
+ }
+
+ if(!equalsOrOverride) {
+ return false;
+ }
+ }
+
+ if(atLeastOneOverride) {
+ return true;
+ }
+ } else { //At least one of our constraints must override or be equal to the other constraint
+ for(Constraint c : constraints) {
+ if(c.overrides(constraint) || c.equals(constraint)) {
+ //TODO : The equals() method is not defined for most constraint implementations.
+ //We may actually need an "isEquivalent" method, defined in the Constraint Interface
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return constraints.toString();
+ }
+
+ private List<Constraint> constraints = new LinkedList<Constraint>();
+
+ @Override
+ protected boolean equivalent(Constraint constraint) {
+ return false;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/Constraint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/Constraint.java
new file mode 100644
index 00000000000..f8e337a2cb7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/Constraint.java
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * 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.constraints;
+
+import org.eclipse.papyrus.properties.contexts.ConstraintDescriptor;
+import org.eclipse.papyrus.properties.contexts.View;
+
+/**
+ * An interface representing a Constraint. A Constraint is used to test if a selection
+ * is matching a pre-configured property view.
+ *
+ * @author Camille Letavernier
+ *
+ */
+//TODO : To be refactored
+//The constraint framework should be accessible by other plug-ins which don't
+//necessarily depend on oep.properties
+public interface Constraint {
+
+ /**
+ * Sets the Constraint Descriptor for this constraint.
+ * The constraint descriptor may contain some parameters to configure this
+ * constraint
+ *
+ * @param descriptor
+ * The constraint descriptor to be associated to this constraint
+ */
+ public void setConstraintDescriptor(ConstraintDescriptor descriptor);
+
+ /**
+ * Tests if this constraint matches the given object
+ *
+ * @param selection
+ * The object to be tested against this constraint
+ * @return
+ * True if this constraint matches the given object
+ */
+ public boolean match(Object selection);
+
+ /**
+ * Returns the view associated to this constraint, or null if the constraint is associated to another
+ * kind of display unit (e.g. a section)
+ *
+ * @return
+ * The view associated to this constraint
+ */
+ public View getView();
+
+ /**
+ * Tests if this constraint should override the given constraint. If true,
+ * the other constraint's display unit won't be displayed. A constraint should
+ * never override itself, and you should ensure that there are no loops in the
+ * constraint overriding graph. If such a loops occurs, nothing will be displayed
+ *
+ * @param constraint
+ * The tested constraint
+ * @return
+ * True if this constraint overrides the given constraint
+ */
+ public boolean overrides(Constraint constraint);
+
+ /**
+ * @return the constraint descriptor associated to this constraint
+ */
+ public ConstraintDescriptor getDescriptor();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFInstanceOfConstraint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFInstanceOfConstraint.java
new file mode 100644
index 00000000000..1e26bfa6145
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFInstanceOfConstraint.java
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * 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.constraints;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.papyrus.properties.contexts.SimpleConstraint;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+import org.eclipse.papyrus.service.edit.Activator;
+
+/**
+ * A constraint testing if a Selection is an EObject, instance of the given
+ * EClass. The EClass is identified by its nsURI and name.
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class EMFInstanceOfConstraint extends AbstractConstraint {
+
+ private String className;
+
+ private String nsUri;
+
+ private EPackage metamodel;
+
+ @Override
+ protected void setDescriptor(SimpleConstraint descriptor) {
+ className = getValue("className"); //$NON-NLS-1$
+ nsUri = getValue("nsUri"); //$NON-NLS-1$
+ metamodel = EPackage.Registry.INSTANCE.getEPackage(nsUri);
+ if(metamodel == null) {
+ Activator.log.warn("Metamodel with nsUri " + nsUri + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * A class constraint overrides its superclass constraints
+ * e.g. : instanceOf(Class) overrides instanceOf(Classifier)
+ */
+ @Override
+ public boolean overrides(Constraint otherConstraint) {
+ if(!(otherConstraint instanceof EMFInstanceOfConstraint)) {
+ return false;
+ }
+
+ EMFInstanceOfConstraint constraint = (EMFInstanceOfConstraint)otherConstraint;
+ EClass thisClass = EMFHelper.getEClass(nsUri, className);
+ EClass otherClass = EMFHelper.getEClass(constraint.nsUri, constraint.className);
+ boolean result = (!equals(constraint)) && EMFHelper.isSubclass(thisClass, otherClass) && thisClass != otherClass;
+
+ return result || super.overrides(constraint);
+ }
+
+ public boolean match(Object selection) {
+ EObject selectedItem = EMFHelper.getEObject(selection);
+
+ if(selectedItem != null) {
+ return EMFHelper.isInstance(selectedItem, className, metamodel);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "EMFInstanceOfConstraint (" + nsUri + "/" + className + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ @Override
+ protected boolean equivalent(Constraint constraint) {
+ if(this == constraint) {
+ return true;
+ }
+ if(constraint == null) {
+ return false;
+ }
+ if(!(constraint instanceof EMFInstanceOfConstraint)) {
+ return false;
+ }
+ EMFInstanceOfConstraint other = (EMFInstanceOfConstraint)constraint;
+ if(className == null) {
+ if(other.className != null) {
+ return false;
+ }
+ } else if(!className.equals(other.className)) {
+ return false;
+ }
+ if(nsUri == null) {
+ if(other.nsUri != null) {
+ return false;
+ }
+ } else if(!nsUri.equals(other.nsUri)) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFQueryConstraint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFQueryConstraint.java
new file mode 100644
index 00000000000..c5bbc23b794
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/EMFQueryConstraint.java
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * 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.constraints;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.facet.infra.query.OCLModelQuery;
+import org.eclipse.emf.facet.infra.query.QueryFactory;
+import org.eclipse.emf.facet.infra.query.core.AbstractModelQuery;
+import org.eclipse.emf.facet.infra.query.core.ModelQuerySetCatalog;
+import org.eclipse.emf.facet.infra.query.runtime.ModelQueryResult;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.contexts.ConfigProperty;
+import org.eclipse.papyrus.properties.contexts.ReferenceProperty;
+import org.eclipse.papyrus.properties.contexts.SimpleConstraint;
+import org.eclipse.papyrus.properties.contexts.ValueProperty;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+
+/**
+ * A constraint applying an EMF Query on a selection. The Query should return
+ * a Boolean.
+ *
+ * @author Camille Letavernier
+ */
+public class EMFQueryConstraint extends AbstractConstraint {
+
+ private OCLModelQuery query;
+
+ @Override
+ protected void setDescriptor(SimpleConstraint descriptor) {
+ ConfigProperty property = getProperty("query"); //$NON-NLS-1$
+ if(property instanceof ReferenceProperty) {
+ query = (OCLModelQuery)getReferenceValue("query"); //$NON-NLS-1$
+ } else {
+ String queryExpression = ((ValueProperty)property).getValue();
+ query = QueryFactory.eINSTANCE.createOCLModelQuery();
+ query.setQuery(queryExpression);
+ query.setReturnType(EcorePackage.eINSTANCE.getEBoolean());
+ query.getScope().add(EcorePackage.eINSTANCE.getEObject());
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public boolean match(Object selection) {
+ if(query == null) {
+ return false;
+ }
+
+ EObject selectedItem = EMFHelper.getEObject(selection);
+
+ if(selectedItem != null) {
+ try {
+ ModelQuerySetCatalog catalog = ModelQuerySetCatalog.getSingleton();
+ AbstractModelQuery abstractQuery = catalog.getModelQueryImpl(query);
+ ModelQueryResult result = abstractQuery.evaluate(selectedItem);
+ Object value = result.getValue();
+ return value == null ? false : (Boolean)value;
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ }
+
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean equivalent(Constraint constraint) {
+ if(constraint != null && constraint instanceof EMFQueryConstraint) {
+ EMFQueryConstraint other = (EMFQueryConstraint)constraint;
+ return other.query.equals(query);
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaInstanceOf.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaInstanceOf.java
new file mode 100644
index 00000000000..bffd8a55747
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaInstanceOf.java
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * 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.constraints;
+
+import org.eclipse.papyrus.properties.contexts.SimpleConstraint;
+import org.eclipse.papyrus.properties.util.ClassLoader;
+
+/**
+ * A Constraint to test if an object is an instance of a given
+ * Java class
+ *
+ * @author Camille Letavernier
+ */
+public class JavaInstanceOf extends AbstractConstraint {
+
+ private Class<?> clazz;
+
+ @Override
+ public void setDescriptor(SimpleConstraint descriptor) {
+ ClassLoader loader = new ClassLoader();
+ clazz = loader.loadClass(getValue("class")); //$NON-NLS-1$
+ }
+
+ public boolean match(Object selection) {
+ if(clazz == null) {
+ return false;
+ }
+
+ return clazz.isInstance(selection);
+ }
+
+ @Override
+ protected boolean equivalent(Constraint constraint) {
+ return false; //TODO
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQuery.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQuery.java
new file mode 100644
index 00000000000..7c26513db61
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQuery.java
@@ -0,0 +1,17 @@
+package org.eclipse.papyrus.properties.constraints;
+
+
+public interface JavaQuery {
+
+ public boolean match(Object selection);
+
+ public class FalseQuery implements JavaQuery {
+
+ public FalseQuery() {
+ }
+
+ public boolean match(Object selection) {
+ return false;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQueryConstraint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQueryConstraint.java
new file mode 100644
index 00000000000..b243c04d6ac
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/JavaQueryConstraint.java
@@ -0,0 +1,53 @@
+package org.eclipse.papyrus.properties.constraints;
+
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.constraints.JavaQuery.FalseQuery;
+import org.eclipse.papyrus.properties.contexts.ConstraintDescriptor;
+
+/**
+ * This constraint allows to define a Java Query (without parameters) without
+ * defining it in an environment file.
+ *
+ * The constraint takes one parameter ("className"), which defines the
+ * qualified name of the Java class used to implement the constraint.
+ *
+ * The Java class must implement the {@link JavaQuery} interface
+ *
+ * @author Camille Letavernier
+ */
+public class JavaQueryConstraint extends AbstractConstraint {
+
+ public final static String QUERY_CLASS_NAME_PROPERTY = "className"; //$NON-NLS-1$
+
+ private JavaQuery query = new FalseQuery();
+
+ protected void setDescriptor(ConstraintDescriptor descriptor) {
+ String queryClassName = getValue(QUERY_CLASS_NAME_PROPERTY);
+ if(queryClassName != null) {
+ try {
+ Class<? extends JavaQuery> queryClass = Class.forName(queryClassName).asSubclass(JavaQuery.class);
+ query = queryClass.newInstance();
+ } catch (ClassNotFoundException ex) {
+ Activator.log.error(ex);
+ } catch (InstantiationException ex) {
+ Activator.log.error(ex);
+ } catch (IllegalAccessException ex) {
+ Activator.log.error(ex);
+ }
+ }
+ }
+
+ public boolean match(Object selection) {
+ return query.match(selection);
+ }
+
+ @Override
+ protected boolean equivalent(Constraint constraint) {
+ if(constraint instanceof JavaQueryConstraint) {
+ return ((JavaQueryConstraint)constraint).query.getClass().equals(query.getClass());
+ }
+ return false;
+ }
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/TrueConstraint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/TrueConstraint.java
new file mode 100644
index 00000000000..681400cbad3
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/constraints/TrueConstraint.java
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * 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.constraints;
+
+/**
+ * A Constraint always returning true.
+ *
+ * @author Camille Letavernier
+ */
+public class TrueConstraint extends AbstractConstraint {
+
+ public boolean match(Object selection) {
+ return true;
+ }
+
+ @Override
+ protected boolean equivalent(Constraint constraint) {
+ //return constraint != null && constraint instanceof TrueConstraint;
+ return false; //TrueConstraint is always true ; it shouldn't override another "always true" constraint
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/CreateInDialog.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/CreateInDialog.java
new file mode 100644
index 00000000000..93659322c8e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/CreateInDialog.java
@@ -0,0 +1,180 @@
+/*****************************************************************************
+ * 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.creation;
+
+import java.util.Arrays;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.jface.dialogs.TrayDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.widgets.layout.PropertiesLayout;
+import org.eclipse.papyrus.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.widgets.editors.ReferenceDialog;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+
+public class CreateInDialog extends TrayDialog {
+
+ /**
+ * The ContentProvider for browsing potential container EObjects
+ */
+ protected IStaticContentProvider containerContentProvider;
+
+ /**
+ * The ContentProvider for browsing potential containment EReferences.
+ * The input of this content provider is the object selected through the
+ * containerContentProvider
+ */
+ protected IStaticContentProvider referenceContentProvider;
+
+ /**
+ * The LabelProvider for displaying potential container EObjects
+ */
+ protected ILabelProvider containerLabelProvider;
+
+ /**
+ * The LabelProvider for displaying potential containment EReferences
+ */
+ protected ILabelProvider referenceLabelProvider;
+
+ /**
+ * This dialog's shell's title
+ */
+ protected String title;
+
+ protected EObject container;
+
+ protected EReference containmentReference;
+
+ protected ReferenceDialog referenceDialog;
+
+ /**
+ * The instance of object being created
+ */
+ protected Object input;
+
+ public CreateInDialog(Shell parentShell, Object input) {
+ super(parentShell);
+ this.input = input;
+ }
+
+ @Override
+ public void create() {
+ super.create();
+ getShell().setText(title);
+ getShell().setImage(Activator.getDefault().getImage(org.eclipse.papyrus.widgets.Activator.PLUGIN_ID, "icons/papyrus.png")); //$NON-NLS-1$
+ Label label = new Label(getDialogArea(), SWT.NONE);
+ label.setText("Choose the parent element for the new object:");
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ data.horizontalIndent = 5;
+ data.verticalIndent = 5;
+ label.setLayoutData(data);
+
+ final ReferenceDialog containerDialog = new ReferenceDialog(getDialogArea(), SWT.NONE);
+ containerDialog.setLabel("Container : ");
+ containerDialog.setLabelProvider(containerLabelProvider);
+ containerDialog.setContentProvider(containerContentProvider);
+ containerDialog.setInput(input);
+
+ referenceDialog = new ReferenceDialog(getDialogArea(), SWT.NONE);
+ referenceDialog.setLabel("Reference : ");
+ referenceDialog.setLabelProvider(referenceLabelProvider);
+ referenceDialog.setContentProvider(referenceContentProvider);
+
+ containerDialog.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ container = (EObject)containerDialog.getValue();
+ referenceDialog.setInput(container);
+ referenceContentProvider.inputChanged(null, null, container);
+ if(referenceContentProvider.getElements().length == 0) {
+ referenceDialog.setValue(null);
+ } else if(referenceContentProvider.getElements().length == 1) {
+ referenceDialog.setValue(referenceContentProvider.getElements()[0]);
+ } else {
+ if(!Arrays.asList(referenceContentProvider.getElements()).contains(referenceDialog.getValue())) {
+ referenceDialog.setValue(null);
+ }
+ }
+ updateControls();
+ }
+ });
+
+ referenceDialog.addCommitListener(new ICommitListener() {
+
+ public void commit(AbstractEditor editor) {
+ containmentReference = (EReference)referenceDialog.getValue();
+ updateControls();
+ }
+ });
+
+ updateControls();
+ getShell().setSize(450, 180);
+ }
+
+ protected void updateControls() {
+ referenceDialog.setReadOnly(referenceContentProvider.getElements().length < 2);
+
+ if(container == null || containmentReference == null) {
+ getButton(OK).setEnabled(false);
+ return;
+ }
+
+ getButton(OK).setEnabled(container.eClass().getEAllReferences().contains(containmentReference));
+ }
+
+ @Override
+ protected Composite getDialogArea() {
+ return (Composite)super.getDialogArea();
+ }
+
+ public EObject getContainer() {
+ return container;
+ }
+
+ public EReference getContainmentReference() {
+ return containmentReference;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+ composite.setLayout(new PropertiesLayout(true));
+ return composite;
+ }
+
+ @Override
+ protected boolean isResizable() {
+ return true;
+ }
+
+ public void setProviders(IStaticContentProvider containerContentProvider, IStaticContentProvider referenceContentProvider, ILabelProvider containerLabelProvider, ILabelProvider referenceLabelProvider) {
+ this.containerContentProvider = containerContentProvider;
+ this.referenceContentProvider = referenceContentProvider;
+ this.containerLabelProvider = containerLabelProvider;
+ this.referenceLabelProvider = referenceLabelProvider;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EcorePropertyEditorFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EcorePropertyEditorFactory.java
new file mode 100644
index 00000000000..d5f7652d0e5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EcorePropertyEditorFactory.java
@@ -0,0 +1,401 @@
+/*****************************************************************************
+ * 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.creation;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.messages.Messages;
+import org.eclipse.papyrus.properties.providers.CreateInFeatureContentProvider;
+import org.eclipse.papyrus.properties.util.EClassNameComparator;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+
+/**
+ * A ReferenceFactory used to instantiate and edit EObjects.
+ * The specified nsUri and ClassName are used to instantiate the EObject.
+ * The matching {@link org.eclipse.papyrus.properties.contexts.View}s from all
+ * applied {@link org.eclipse.papyrus.properties.contexts.Context}s are used to
+ * display the right form to edit the EObject.
+ *
+ * If no EClass is specified, a list of all concrete subclasses of {@link #type} will be displayed before the instantiation.
+ *
+ * @author Camille Letavernier
+ */
+public class EcorePropertyEditorFactory extends PropertyEditorFactory {
+
+ /**
+ * The (abstract) EClass to instantiate
+ */
+ protected EClass type;
+
+ /**
+ * The (concrete) EClass to instantiate
+ * Should be a subclass of {@link #type}
+ */
+ protected EClass eClass;
+
+ /**
+ * The Namespace URI of the (concrete) EClass to instantiate
+ */
+ protected String nsUri;
+
+ /**
+ * The name of the (concrete) EClass to instantiate
+ */
+ protected String className;
+
+ /**
+ * The reference in which the object will be set.
+ */
+ protected EReference referenceIn;
+
+ /**
+ * The ContentProvider for browsing potential container EObjects
+ */
+ protected IStaticContentProvider containerContentProvider;
+
+ /**
+ * The ContentProvider for browsing potential containment EReferences.
+ * The input of this content provider is the object selected through the
+ * containerContentProvider
+ */
+ protected CreateInFeatureContentProvider referenceContentProvider;
+
+ /**
+ * The LabelProvider for displaying potential container EObjects
+ */
+ protected ILabelProvider containerLabelProvider;
+
+ /**
+ * The LabelProvider for displaying potential containment EReferences
+ */
+ protected ILabelProvider referenceLabelProvider;
+
+ /**
+ * Store information about where each object should be added on validation
+ */
+ protected Map<EObject, CreateIn> createIn = new HashMap<EObject, CreateIn>();
+
+ /**
+ *
+ * Constructor.
+ *
+ * The factory will be able to instantiate the given EClass
+ *
+ * @param type
+ * The type of EClass to instantiate when creating new EObjects.
+ */
+ public EcorePropertyEditorFactory(EReference referenceIn) {
+ if(referenceIn == null) {
+ throw new IllegalArgumentException("The referenceIn parameter must be set"); //$NON-NLS-1$
+ }
+
+ this.referenceIn = referenceIn;
+ this.type = referenceIn.getEReferenceType();
+ }
+
+ /**
+ * @return the nsUri of the EClass used by this factory to instantiate new EObjects
+ * @see #getClassName
+ */
+ public String getNsUri() {
+ return nsUri;
+ }
+
+ /**
+ * @return the className of the EClass used by this factory to instantiate new EObjects
+ * @see #getNsUri()
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Sets the nsUri of the EClass used by this factory to instantiate new EObjects
+ *
+ * @param nsUri
+ * @see #getClassName
+ */
+ public void setNsUri(String nsUri) {
+ this.nsUri = nsUri;
+ checkEClass();
+ }
+
+ /**
+ * Sets the className of the EClass used by this factory to instantiate new EObjects
+ *
+ * @param className
+ * @see #getNsUri()
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ checkEClass();
+ }
+
+ private void checkEClass() {
+ if(nsUri != null && className != null) {
+ EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri);
+ if(ePackage == null) {
+ Activator.log.warn("Cannot find the EPackage corresponding to URI " + nsUri); //$NON-NLS-1$
+ }
+ eClass = (EClass)ePackage.getEClassifier(className);
+ if(eClass == null) {
+ Activator.log.warn("Cannot find the EClass " + className + " in the package " + nsUri); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean canCreateObject() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object createObject(Control widget) {
+ Object instance;
+ if (referenceIn.isContainment()){
+ instance = simpleCreateObject(widget);
+ } else {
+ instance = createObjectInDifferentContainer(widget);
+ }
+
+ return super.createObject(widget, instance);
+ }
+
+ protected EObject simpleCreateObject(Control widget) {
+ EClass eClass = chooseEClass(widget);
+ if(eClass == null) {
+ return null;
+ }
+
+ EObject instance = eClass.getEPackage().getEFactoryInstance().create(eClass);
+ return instance;
+ }
+
+ protected EObject createObjectInDifferentContainer(Control widget) {
+ EObject instance = simpleCreateObject(widget);
+ if(instance == null) {
+ return null;
+ }
+
+ containerContentProvider.inputChanged(null, null, instance);
+ referenceContentProvider.setType(instance.eClass());
+ CreateInDialog dialog = new CreateInDialog(widget.getShell(), instance);
+ dialog.setProviders(containerContentProvider, referenceContentProvider, containerLabelProvider, referenceLabelProvider);
+ dialog.setTitle(getCreationDialogTitle());
+ int result = dialog.open();
+ if(result != Window.OK) {
+ return null;
+ }
+ CreateIn createIn = new CreateIn();
+ createIn.createInObject = dialog.getContainer();
+ createIn.createInReference = dialog.getContainmentReference();
+ this.createIn.put(instance, createIn);
+
+ return instance;
+ }
+
+ /**
+ * Gets the EClass to instantiate
+ * If the {@link #eClass} has been specified, then it is returned.
+ * Otherwise, displays a list of all valid concrete EClasses that
+ * are subtypes of {@link #type}, from which the user can choose
+ * the one to instantiate.
+ *
+ * @param widget
+ * The control used to open a selection list (if more than one EClass
+ * can be instantiated)
+ * @return
+ * The EClass to instantiate
+ */
+ protected EClass chooseEClass(Control widget) {
+ if(eClass != null) {
+ return eClass;
+ }
+
+ List<EClass> availableClasses = getAvailableEClasses();
+ if(availableClasses.isEmpty()) {
+ return null;
+ }
+
+ if(availableClasses.size() == 1) {
+ this.className = availableClasses.get(0).getName();
+ return availableClasses.get(0);
+ }
+
+ final Menu menu = new Menu(widget);
+ for(EClass eClass : availableClasses) {
+ final MenuItem item = new MenuItem(menu, SWT.NONE);
+ item.setText(eClass.getName());
+ item.setData("eClass", eClass); //$NON-NLS-1$
+ item.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ EcorePropertyEditorFactory.this.eClass = (EClass)item.getData("eClass"); //$NON-NLS-1$
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ // Nothing
+ }
+
+ });
+ }
+
+ menu.setVisible(true);
+
+ //The menu is blocking the thread
+ Display display = widget.getDisplay();
+ while(menu.isVisible()) {
+ try {
+ if(!display.readAndDispatch()) {
+ display.sleep();
+ }
+ } catch (Throwable ex) {
+ Activator.log.error(ex);
+ }
+ }
+ if(!display.isDisposed()) {
+ display.update();
+ }
+
+ EClass eClass = this.eClass;
+ if(eClass != null) {
+ className = eClass.getName();
+ }
+ this.eClass = null;
+
+ return eClass;
+ }
+
+ /**
+ * @return
+ * The list of {@link EClass} that can be instantiated.
+ * This is the list of all concrete subclasses of {@link #type}
+ */
+ protected List<EClass> getAvailableEClasses() {
+ List<EClass> availableEClasses = EMFHelper.getSubclassesOf(type, true);
+ Collections.sort(availableEClasses, new EClassNameComparator());
+ return availableEClasses;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Collection<Object> validateObjects(Collection<Object> objectsToValidate) {
+ if(!referenceIn.isContainment()) {
+ for(Object objectToValidate : objectsToValidate) {
+ //We add the object to the containment reference
+ //They will be automatically added to the edited reference
+ //(referenceIn) after this method returns
+ CreateIn creationInformation = this.createIn.get(objectToValidate);
+ if(creationInformation != null) {
+ creationInformation.createInObject.eSet(creationInformation.createInReference, objectToValidate);
+ } else {
+ Activator.log.warn("Unknown object : " + objectToValidate);
+ }
+ }
+ }
+
+ return objectsToValidate;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getCreationDialogTitle() {
+ return Messages.EcorePropertyEditorFactory_CreateANew + className;
+ }
+
+ @Override
+ public String getEditionDialogTitle(Object objectToEdit) {
+ if(objectToEdit instanceof EObject) {
+ return "Edit " + ((EObject)objectToEdit).eClass().getName();
+ }
+ return super.getEditionDialogTitle(objectToEdit);
+ }
+
+ /**
+ * @return
+ * The EClass that will be instantiated, or null if this hasn't been forced
+ */
+ public EClass getEClass() {
+ return eClass;
+ }
+
+ protected class CreateIn {
+
+ /**
+ * The (containment) reference in which the object will be created
+ * May be the same or different from {@link #referenceIn}
+ */
+ public EReference createInReference;
+
+ /**
+ * The (container) EObject in which the object will be created
+ */
+ public EObject createInObject;
+ }
+
+ /**
+ * Sets the same label provider for both #referenceLabelProvider
+ * and #containerLabelProvider
+ *
+ * @param labelProvider
+ */
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ setContainerLabelProvider(labelProvider);
+ setReferenceLabelProvider(labelProvider);
+ }
+
+ public void setReferenceLabelProvider(ILabelProvider labelProvider) {
+ this.referenceLabelProvider = labelProvider;
+ }
+
+ public void setContainerLabelProvider(ILabelProvider labelProvider) {
+ this.containerLabelProvider = labelProvider;
+ }
+
+ public void setContainerContentProvider(IStaticContentProvider contentProvider) {
+ this.containerContentProvider = contentProvider;
+ }
+
+ public void setReferenceContentProvider(CreateInFeatureContentProvider contentProvider) {
+ this.referenceContentProvider = contentProvider;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EditionDialog.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EditionDialog.java
new file mode 100644
index 00000000000..20edaa1da9d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/EditionDialog.java
@@ -0,0 +1,249 @@
+/*****************************************************************************
+ * 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.creation;
+
+import java.text.Collator;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.properties.Activator;
+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.messages.Messages;
+import org.eclipse.papyrus.properties.runtime.DefaultDisplayEngine;
+import org.eclipse.papyrus.properties.runtime.DisplayEngine;
+import org.eclipse.papyrus.properties.xwt.XWTSection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionDialog;
+
+
+/**
+ * A dialog used to display an edition form for a given object.
+ * The form is described by the given {@link View}s
+ *
+ * @author Camille Letavernier
+ */
+//TODO : This dialog should use the Embedded Display Engine
+public class EditionDialog extends SelectionDialog {
+
+ private Set<View> views;
+
+ private Object input;
+
+ private Set<XWTSection> sections = new HashSet<XWTSection>();
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param shell
+ * The shell in which the dialog will be opened
+ */
+ protected EditionDialog(Shell shell) {
+ super(shell);
+ }
+
+ @Override
+ public void create() {
+ super.create();
+ if(getShell().getText() == null || "".equals(getShell().getText())) { //$NON-NLS-1$
+ setTitle(Messages.EditionDialog_CreateANewElement);
+ }
+ getShell().setImage(Activator.getDefault().getImage("org.eclipse.papyrus.widgets", "/icons/papyrus.png")); //$NON-NLS-1$ //$NON-NLS-2$
+ getShell().addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ dispose();
+ }
+
+ });
+
+ display();
+
+ //The values are data-binded, thus are edited in real time. It is not possible to cancel (However, Ctrl+Z should work)
+ getButton(IDialogConstants.CANCEL_ID).setEnabled(false);
+ }
+
+ @Override
+ public Composite getDialogArea() {
+ return (Composite)super.getDialogArea();
+ }
+
+ /**
+ * Sets the object being edited by this dialog
+ *
+ * @param input
+ */
+ public void setInput(Object input) {
+ this.input = input;
+ }
+
+ /**
+ * Sets the Views used to edit the input object
+ *
+ * @param views
+ */
+ public void setViews(Set<View> views) {
+ this.views = views;
+ }
+
+ private void display() {
+ DisplayEngine display = new DefaultDisplayEngine();
+
+ IStructuredSelection selection = new StructuredSelection(input);
+
+ Composite parent = new Composite(getDialogArea(), SWT.NONE);
+ parent.setLayout(new FillLayout());
+ parent.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
+ getShell().setSize(600, 400);
+
+ final Set<Tab> tabsList = new LinkedHashSet<Tab>();
+
+ for(View view : views) {
+ for(Section section : view.getSections()) {
+ tabsList.add(section.getTab());
+ }
+ }
+
+ List<Tab> allTabs = new LinkedList<Tab>(tabsList);
+
+ Collections.sort(allTabs, new Comparator<Tab>() {
+
+ /**
+ * compares two tabs each other
+ *
+ * @param tab1
+ * first tab to compare
+ * @param tab2
+ * second tab to compare
+ * @return a negative integer if the first tab should be placed before the second tab
+ */
+ public int compare(Tab tab1, Tab tab2) {
+ int priority1 = getPriority(tab1);
+ int priority2 = getPriority(tab2);
+
+ if(priority1 < priority2) {
+ return -1;
+ }
+
+ if(priority1 > priority2) {
+ return 1;
+ }
+
+ //p1 == p2
+
+ priority1 = getXWTTabPriority(tab1);
+ priority2 = getXWTTabPriority(tab2);
+
+ if(priority1 < priority2) {
+ return -1;
+ }
+
+ if(priority1 > priority2) {
+ return 1;
+ }
+
+ //p1 == p2
+
+ String label1 = tab1.getLabel();
+ String label2 = tab2.getLabel();
+
+ return Collator.getInstance().compare(label1, label2);
+ }
+
+ private Tab getPreviousTab(Tab tab) {
+ Tab afterTab = tab.getAfterTab();
+ if(tabsList.contains(afterTab)) {
+ return afterTab;
+ }
+
+ // not found. Return null
+ return null;
+ }
+
+ private int getPriority(Tab tab) {
+ Tab previousTab = getPreviousTab(tab);
+ if(previousTab != null) {
+ return getPriority(previousTab) + 1;
+ }
+
+ return getXWTTabPriority(tab);
+ }
+
+ private int getXWTTabPriority(Tab tab) {
+ return tab.getPriority();
+ }
+
+ });
+
+ Map<Tab, Composite> tabs = new LinkedHashMap<Tab, Composite>();
+ if(allTabs.size() > 1) {
+ CTabFolder tabFolder = new CTabFolder(parent, SWT.BOTTOM);
+ tabFolder.setSelectionBackground(new Color[]{ tabFolder.getDisplay().getSystemColor(SWT.COLOR_WHITE), tabFolder.getBackground() }, new int[]{ 100 }, true);
+ tabFolder.setLayout(new FillLayout());
+ for(Tab tab : allTabs) {
+ CTabItem item = new CTabItem(tabFolder, SWT.NONE);
+ Composite tabControl = new Composite(tabFolder, SWT.NONE);
+ item.setControl(tabControl);
+ item.setText(tab.getLabel());
+ tabs.put(tab, tabControl);
+ }
+ } else if(!allTabs.isEmpty()) {
+ Tab tab = allTabs.get(0);
+ tabs.put(tab, parent);
+ }
+
+ for(View view : views) {
+ for(Section section : view.getSections()) {
+ XWTSection xwtSection = new XWTSection(section, view, display);
+ sections.add(xwtSection);
+
+ xwtSection.createControls(tabs.get(section.getTab()), null);
+ xwtSection.setInput(null, selection);
+ xwtSection.refresh();
+ }
+ }
+
+ getShell().pack();
+ }
+
+ /**
+ * Disposes this dialog
+ */
+ public void dispose() {
+ for(XWTSection section : sections) {
+ section.dispose();
+ }
+ sections.clear();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/PropertyEditorFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/PropertyEditorFactory.java
new file mode 100644
index 00000000000..c0ece02fb59
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/creation/PropertyEditorFactory.java
@@ -0,0 +1,176 @@
+/*****************************************************************************
+ * 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.creation;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.messages.Messages;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+import org.eclipse.papyrus.properties.runtime.ConstraintEngine;
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * A generic ReferenceValueFactory, which uses the Property View configurations
+ * to edit objects. For a given object, the factory uses the matching constraints
+ * to find the property views associated to the object, and displays these views
+ * in a Dialog.
+ * This factory cannot instantiate new objects. However, subclasses should override {@link #createObject(Control)} and {@link #canCreateObject()} to
+ * enable
+ * this behavior.
+ *
+ * @see org.eclipse.papyrus.properties.creation.EditionDialog
+ *
+ * @author Camille Letavernier
+ */
+public class PropertyEditorFactory implements ReferenceValueFactory {
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public PropertyEditorFactory() {
+ }
+
+ /**
+ * Return a null value. Implementors should override when object creation
+ * needs to be supported. Implementors may rely on {@link #createObject(Control, Object)}
+ *
+ * @see org.eclipse.papyrus.widgets.creation.ReferenceValueFactory#createObject(org.eclipse.swt.widgets.Control)
+ * @see #createObject(org.eclipse.swt.widgets.Control, Object)
+ *
+ * @param widget
+ * The widget from which this method is called. May be used to retrieve the current shell
+ * @return
+ * The newly created object
+ */
+ public Object createObject(Control widget) {
+ return null;
+ }
+
+ /**
+ * This class cannot instantiate objects. However, this method provides
+ * a base implementation to be used by subclasses.
+ *
+ * Subclasses should instantiate the base object, which will then be
+ * editable via a property dialog.
+ *
+ * @param widget
+ * The widget used to open the dialog
+ * @param source
+ * The created EObject. If null, nothing will happen
+ * @return
+ * The source EObject, which potential in-place modifications
+ */
+ protected Object createObject(Control widget, Object source) {
+ if(source == null) {
+ return null;
+ }
+
+ IStructuredSelection selection = new StructuredSelection(source);
+
+ ConstraintEngine constraintEngine = ConfigurationManager.instance.constraintEngine;
+ Set<View> views = constraintEngine.getViews(selection);
+ if(!views.isEmpty()) {
+ EditionDialog dialog = new EditionDialog(widget.getShell());
+ dialog.setViews(views);
+ dialog.setInput(source);
+ dialog.setTitle(getCreationDialogTitle());
+
+ int result = dialog.open();
+ if(result != Window.OK) {
+ return null;
+ }
+ }
+
+ return source;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Collection<Object> validateObjects(Collection<Object> objectsToValidate) {
+ return objectsToValidate;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canEdit() {
+ return true;
+ }
+
+ /**
+ * Edits the given object via the matching Property view, if any
+ * The editing Dialog is directly binded to the underlying object, which means that all modifications are applied
+ * in real time, and cannot be undone (Except via the "Undo" command). The "Cancel" button is thus disabled.
+ *
+ * @see org.eclipse.papyrus.widgets.creation.ReferenceValueFactory#edit(org.eclipse.swt.widgets.Control, java.lang.Object)
+ *
+ * @param widget
+ * The widget calling the factory. The Dialog for editing the object will open in this widget's shell
+ * @param source
+ * The object to edit
+ */
+ public Object edit(Control widget, Object source) {
+ IStructuredSelection selection = new StructuredSelection(source);
+
+ ConstraintEngine constraintEngine = ConfigurationManager.instance.constraintEngine;
+
+ Set<View> views = constraintEngine.getViews(selection);
+ if(!views.isEmpty()) {
+ EditionDialog dialog = new EditionDialog(widget.getShell());
+ dialog.setTitle(getEditionDialogTitle(source));
+ dialog.setViews(views);
+ dialog.setInput(source);
+
+ dialog.open();
+ }
+
+ return source;
+ }
+
+ /**
+ * The standard Property Editor Factory cannot instantiate new objects.
+ * However, subclasses may override this method to return true if they
+ * implement {@link #createObject(Control)}
+ *
+ * @see org.eclipse.papyrus.widgets.creation.ReferenceValueFactory#canCreateObject()
+ *
+ * @return
+ * True if the factory can create a new instance
+ */
+ public boolean canCreateObject() {
+ return false;
+ }
+
+ /**
+ * @return
+ * The title of the dialog used to edit the newly created instance
+ *
+ * @see #canCreateObject()
+ * @see #createObject(Control)
+ */
+ public String getCreationDialogTitle() {
+ return Messages.PropertyEditorFactory_CreateANewElement;
+ }
+
+ public String getEditionDialogTitle(Object objectToEdit) {
+ return "Edit an element";
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/AnnotationObservableValue.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/AnnotationObservableValue.java
new file mode 100644
index 00000000000..de992398741
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/AnnotationObservableValue.java
@@ -0,0 +1,133 @@
+/*****************************************************************************
+ * 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.databinding;
+
+import java.util.Map.Entry;
+
+import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.common.util.EMap;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+
+/**
+ * An IObservableValue for editing EMF EAnnotations
+ *
+ * @author Camille Letavernier
+ */
+public class AnnotationObservableValue extends AbstractObservableValue {
+
+ /**
+ * The EModelElement to edit.
+ */
+ protected EModelElement source;
+
+ /**
+ * The editing domain on which the commands will be executed
+ */
+ protected EditingDomain domain;
+
+ /**
+ * The name of the annotation to use
+ */
+ protected String annotationName;
+
+ /**
+ * The annotation key to edit
+ */
+ protected String key;
+
+ /**
+ * The EAnnotation being edited
+ * May be null
+ */
+ protected EAnnotation annotation;
+
+ /**
+ * Constructor.
+ *
+ * Creates an IObservableValue for the annotation. The annotation doesn't
+ * need to be created beforehand
+ *
+ * @param source
+ * The EObject owning the annotation
+ * @param domain
+ * The editing domain on which the commands will be executed
+ * @param annotationName
+ * The name of the annotation
+ * @param key
+ * The name of annotation's property to edit
+ */
+ public AnnotationObservableValue(EModelElement source, EditingDomain domain, String annotationName, String key) {
+ this.source = source;
+ this.domain = domain;
+ this.annotationName = annotationName;
+ this.key = key;
+ annotation = source.getEAnnotation(annotationName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getValueType() {
+ return String.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Object doGetValue() {
+ if(annotation == null) {
+ return null;
+ }
+
+ return annotation.getDetails().get(key);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doSetValue(Object value) {
+ if(!(value instanceof String)) {
+ return;
+ }
+
+ CompoundCommand emfCommand = new CompoundCommand("Set " + key);
+
+ if(annotation == null) {
+ annotation = EcoreFactory.eINSTANCE.createEAnnotation();
+ SetCommand command = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_Source(), source);
+ emfCommand.append(command);
+ }
+
+ EMap<String, String> details = new BasicEMap<String, String>();
+ for(Entry<String, String> entry : annotation.getDetails().entrySet()) {
+ details.put(entry.getKey(), entry.getValue());
+ }
+
+ details.put(key, (String)value);
+
+ SetCommand command = new SetCommand(domain, annotation, EcorePackage.eINSTANCE.getEAnnotation_Details(), details);
+ emfCommand.append(command);
+
+ domain.getCommandStack().execute(emfCommand);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableList.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableList.java
new file mode 100644
index 00000000000..d3620ad01bb
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableList.java
@@ -0,0 +1,331 @@
+/*****************************************************************************
+ * 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.databinding;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.list.ObservableList;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+
+/**
+ * An ObservableList using EMF Commands to edit the underlying list.
+ * The commands are executed when the {@link #commit(AbstractEditor)} method is called.
+ * However, the read operations (such as get, size, ...) return up-to-date
+ * results, even when {@link #commit(AbstractEditor)} hasn't been called.
+ *
+ * @author Camille Letavernier
+ */
+@SuppressWarnings({ "unchecked", "rawtypes" })
+public class EMFObservableList extends ObservableList implements ICommitListener {
+
+ /**
+ * The list of commands that haven't been executed yet
+ */
+ protected List<Command> commands = new LinkedList<Command>();
+
+ /**
+ * The editing domain on which the commands will be executed
+ */
+ protected EditingDomain editingDomain;
+
+ /**
+ * The edited EObject
+ */
+ protected EObject source;
+
+ /**
+ * The feature being edited
+ */
+ protected EStructuralFeature feature;
+
+ /**
+ * The list to be updated only on #commit() calls
+ */
+ protected List<?> concreteList;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param wrappedList
+ * The list to be edited when #commit() is called
+ * @param domain
+ * The editing domain on which the commands will be executed
+ * @param source
+ * The EObject from which the list will be retrieved
+ * @param feature
+ * The feature from which the list will be retrieved
+ */
+ public EMFObservableList(List<?> wrappedList, EditingDomain domain, EObject source, EStructuralFeature feature) {
+ super(new LinkedList<Object>(wrappedList), Object.class);
+ this.concreteList = wrappedList;
+ this.editingDomain = domain;
+ this.source = source;
+ this.feature = feature;
+ }
+
+ /**
+ * Forces this list to commit all the pending commands. Only one composite command will
+ * be executed, and can be undone in a single operation.
+ *
+ * @see org.eclipse.papyrus.widgets.editors.ICommitListener#commit(AbstractEditor)
+ *
+ */
+ public void commit(AbstractEditor editor) {
+
+ if(commands.isEmpty()) {
+ return;
+ }
+
+ CompoundCommand compoundCommand = new CompoundCommand() {
+
+ @Override
+ public void execute() {
+ super.execute();
+ refreshCacheList();
+ }
+
+ @Override
+ public void undo() {
+ super.undo();
+ refreshCacheList();
+ }
+
+ @Override
+ public void redo() {
+ super.redo();
+ refreshCacheList();
+ }
+
+ /**
+ * We have a sequential execution : the method canExecute() in
+ * the command n+1 depends on the result of the command n. We can't
+ * check every command's canExecute() method here, so we only
+ * check the first one.
+ *
+ */
+ @Override
+ public boolean canExecute() {
+ return commandList.isEmpty() ? false : commandList.get(0).canExecute();
+ }
+
+ //TODO : edit the execute() method to call the remaining canExecute() checks
+ //during the execution
+ //(n).canExecute()
+ //(n).execute()
+ //(n+1).canExecute()
+ //(n+1).execute()
+ };
+
+ for(Command cmd : commands) {
+ compoundCommand.append(cmd);
+ }
+
+ editingDomain.getCommandStack().execute(compoundCommand);
+ commands.clear();
+ }
+
+ /**
+ * Refresh the cached list by copying the real list
+ */
+ protected void refreshCacheList() {
+ wrappedList.clear();
+ wrappedList.addAll(concreteList);
+ fireListChange(null);
+ }
+
+ @Override
+ public void add(int index, Object value) {
+ Command command = getAddCommand(index, value);
+ commands.add(command);
+
+ wrappedList.add(index, value);
+ fireListChange(null);
+ }
+
+ @Override
+ public void clear() {
+ Command command = getClearCommand();
+ commands.add(command);
+
+ wrappedList.clear();
+ fireListChange(null);
+ }
+
+ @Override
+ public boolean add(Object o) {
+ Command command = getAddCommand(o);
+ commands.add(command);
+
+ boolean result = wrappedList.add(o);
+ fireListChange(null);
+ return result;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ Command command = getRemoveCommand(o);
+
+ commands.add(command);
+
+ boolean result = wrappedList.remove(o);
+ fireListChange(null);
+ return result;
+ }
+
+ @Override
+ public boolean addAll(Collection c) {
+ Command command = getAddAllCommand(c);
+ commands.add(command);
+
+ boolean result = wrappedList.addAll(c);
+ fireListChange(null);
+ return result;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection c) {
+ Command command = getAddAllCommand(index, c);
+ commands.add(command);
+
+ boolean result = wrappedList.addAll(index, c);
+ fireListChange(null);
+ return result;
+ }
+
+ @Override
+ public boolean removeAll(Collection c) {
+ Command command = getRemoveCommand(c);
+ commands.add(command);
+
+ boolean result = wrappedList.removeAll(c);
+ fireListChange(null);
+ return result;
+ }
+
+ @Override
+ public boolean retainAll(Collection c) {
+ Command command = getRetainAllCommand(c);
+ commands.add(command);
+
+ boolean result = wrappedList.retainAll(c);
+ fireListChange(null);
+ return result;
+ }
+
+ @Override
+ public Object set(int index, Object element) {
+ Command command = getSetCommand(index, element);
+ commands.add(command);
+
+ Object result = wrappedList.set(index, element);
+ fireListChange(null);
+ return result;
+ }
+
+ @Override
+ public Object move(int oldIndex, int newIndex) {
+ commands.addAll(getMoveCommands(oldIndex, newIndex));
+
+ Object value = get(oldIndex);
+ wrappedList.remove(oldIndex);
+ wrappedList.add(newIndex, value);
+
+ fireListChange(null);
+
+ return value;
+ }
+
+ @Override
+ public Object remove(int index) {
+ Object value = get(index);
+ if(value != null) {
+ Command command = getRemoveCommand(index);
+ commands.add(command);
+ }
+
+ Object result = wrappedList.remove(index);
+ fireListChange(null);
+ return result;
+ }
+
+ protected Command getAddCommand(int index, Object value) {
+ return AddCommand.create(editingDomain, source, feature, value, index);
+ }
+
+ protected Command getAddCommand(Object value) {
+ return AddCommand.create(editingDomain, source, feature, value);
+ }
+
+ protected Command getAddAllCommand(Collection<?> values) {
+ return AddCommand.create(editingDomain, source, feature, values);
+ }
+
+ protected Command getAddAllCommand(int index, Collection<?> values) {
+ return AddCommand.create(editingDomain, source, feature, values, index);
+ }
+
+ protected Command getClearCommand() {
+ return getRemoveAllCommand(new LinkedList<Object>(wrappedList));
+ }
+
+ protected Command getRemoveCommand(int index) {
+ Object value = get(index);
+ return getRemoveCommand(value);
+ }
+
+ protected Command getRemoveCommand(Object value) {
+ return RemoveCommand.create(editingDomain, source, feature, value);
+ }
+
+ protected Command getRemoveAllCommand(Collection<?> values) {
+ return RemoveCommand.create(editingDomain, source, feature, values);
+ }
+
+ protected List<Command> getMoveCommands(int oldIndex, int newIndex) {
+ Object value = get(oldIndex);
+ List<Command> commands = new LinkedList<Command>();
+ commands.add(getRemoveCommand(value));
+ commands.add(getAddCommand(newIndex, value));
+ return commands;
+ }
+
+ protected Command getRetainAllCommand(Collection<?> values) {
+ List<Object> objectsToRemove = new LinkedList<Object>();
+ for(Object object : values) {
+ if(!contains(object)) {
+ objectsToRemove.add(object);
+ }
+ }
+ if(!objectsToRemove.isEmpty()) {
+ return getRemoveAllCommand(objectsToRemove);
+ } else {
+ return null;
+ }
+ }
+
+ protected Command getSetCommand(int index, Object value) {
+ return SetCommand.create(editingDomain, source, feature, value, index);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableValue.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableValue.java
new file mode 100644
index 00000000000..ed945ec73e1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/EMFObservableValue.java
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * 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.databinding;
+
+import org.eclipse.core.databinding.observable.Realm;
+import org.eclipse.emf.databinding.EObjectObservableValue;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+
+/**
+ * An Observable value to edit EMF values through EMF commands.
+ *
+ * @author Camille Letavernier
+ */
+public class EMFObservableValue extends EObjectObservableValue {
+
+ /**
+ * The editing domain on which the commands will be executed
+ */
+ protected EditingDomain domain;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param eObject
+ * The eObject being edited
+ * @param eStructuralFeature
+ * The structuralFeature being edited
+ * @param domain
+ * The Editing domain on which the commands will be executed
+ */
+ public EMFObservableValue(EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) {
+ this(Realm.getDefault(), eObject, eStructuralFeature, domain);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param realm
+ * @param eObject
+ * The eObject being edited
+ * @param eStructuralFeature
+ * The structuralFeature being edited
+ * @param domain
+ * The Editing domain on which the commands will be executed
+ */
+ public EMFObservableValue(Realm realm, EObject eObject, EStructuralFeature eStructuralFeature, EditingDomain domain) {
+ super(realm, eObject, eStructuralFeature);
+ this.domain = domain;
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ EObject eObject = EMFHelper.getEObject(value);
+ if(eObject != null) {
+ value = eObject;
+ }
+
+ SetCommand command = getSetCommand(value);
+ domain.getCommandStack().execute(command);
+ }
+
+ /**
+ * Returns the command used to edit the value
+ *
+ * @param value
+ * The new value
+ * @return
+ * The Set command used to edit the value
+ */
+ protected SetCommand getSetCommand(Object value) {
+ return new SetCommand(domain, eObject, eStructuralFeature, value);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservable.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservable.java
new file mode 100644
index 00000000000..318f26bf0fd
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservable.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * 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.databinding;
+
+import org.eclipse.core.databinding.observable.IObservable;
+
+/**
+ * An interface for Composite IObservables
+ *
+ * @author Camille Letavernier
+ * @deprecated Replaced by AggregatedObservable
+ */
+@Deprecated
+public interface MultipleObservable extends IObservable {
+
+ /**
+ * Adds an IObservable to this composite Observable
+ *
+ * @param observable
+ * The IObservable to add
+ * @return
+ * true if the observable has been successfully added, false otherwise
+ */
+ public boolean add(IObservable observable);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableList.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableList.java
new file mode 100644
index 00000000000..1cb3514c88f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableList.java
@@ -0,0 +1,187 @@
+/*****************************************************************************
+ * 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.databinding;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.ObservableList;
+import org.eclipse.papyrus.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+
+//TODO : Implement the getters
+//The list may be either the union or the intersection of all sublists
+//Union : allows the "remove" and "removeAll" on a group of lists (Even if one of the sublists doesn't contain the given element)
+//Intersection : Closer to the behavior of the CompositeValue (The current value is displayed only if it is shared by all elements)
+//The Union is probably a better solution
+//Simple solution : bind read operations to the first sub-list
+
+/**
+ * A Composite ObservableList. Modifications are forwarded to each sublist
+ * The read operations are not supported. This list behaves as if it were empty
+ *
+ * @author Camille Letavernier
+ */
+//TODO : Add listeners on sub-observables, and remove them on dispose
+public class MultipleObservableList extends ObservableList implements ICommitListener, MultipleObservable {
+
+ List<IObservableList> observableLists = new LinkedList<IObservableList>();
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public MultipleObservableList() {
+ super(new LinkedList<Object>(), Object.class);
+ throw new UnsupportedOperationException("This class is not supported yet"); //$NON-NLS-1$
+ }
+
+ @Override
+ public void add(int index, Object element) {
+ for(IObservableList observableList : observableLists) {
+ observableList.add(index, element);
+ }
+ }
+
+ @Override
+ public void clear() {
+ for(IObservableList observableList : observableLists) {
+ observableList.clear();
+ }
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ boolean contains = false;
+
+ for(IObservableList observableList : observableLists) {
+ if(observableList.contains(o)) {
+ contains = true;
+ } else {
+ return false;
+ }
+ }
+
+ return contains;
+ }
+
+ @Override
+ public boolean add(Object o) {
+ for(IObservableList observableList : observableLists) {
+ observableList.add(o);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ for(IObservableList observableList : observableLists) {
+ observableList.remove(o);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean containsAll(Collection c) {
+ boolean containsAll = false;
+ for(IObservableList observableList : observableLists) {
+ containsAll = containsAll && observableList.containsAll(c);
+ }
+ return containsAll;
+ }
+
+ @Override
+ public boolean addAll(Collection c) {
+ for(IObservableList observableList : observableLists) {
+ observableList.addAll(c);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection c) {
+ for(IObservableList observableList : observableLists) {
+ observableList.addAll(index, c);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean removeAll(Collection c) {
+ for(IObservableList observableList : observableLists) {
+ observableList.removeAll(c);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean retainAll(Collection c) {
+ for(IObservableList observableList : observableLists) {
+ observableList.retainAll(c);
+ }
+ return true;
+ }
+
+ @Override
+ public Object set(int index, Object element) {
+ for(IObservableList observableList : observableLists) {
+ observableList.set(index, element);
+ }
+ return null;
+ }
+
+ @Override
+ public Object move(int oldIndex, int newIndex) {
+ for(IObservableList observableList : observableLists) {
+ observableList.move(oldIndex, newIndex);
+ }
+ return null;
+ }
+
+ @Override
+ public Object remove(int index) {
+ for(IObservableList observableList : observableLists) {
+ observableList.remove(index);
+ }
+ return null;
+ }
+
+ public void commit(AbstractEditor editor) {
+ for(IObservableList observableList : observableLists) {
+ if(observableList instanceof ICommitListener) {
+ ((ICommitListener)observableList).commit(editor);
+ }
+ }
+ }
+
+ public boolean add(IObservable observable) {
+ if(observable instanceof IObservableList) {
+ observableLists.add((IObservableList)observable);
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ for(IObservableList observable : observableLists) {
+ observable.dispose();
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableValue.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableValue.java
new file mode 100644
index 00000000000..653659df22d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/databinding/MultipleObservableValue.java
@@ -0,0 +1,178 @@
+/*****************************************************************************
+ * 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.databinding;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.value.AbstractObservableValue;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.ValueDiff;
+import org.eclipse.papyrus.widgets.databinding.AggregatedObservable;
+
+/**
+ * MultipleObservableValue is used to map a single element
+ * to a collection of model elements.
+ *
+ * It is especially used when displaying a Property View for multiple elements,
+ * when we want to edit the same property for all of them.
+ *
+ * All sub-elements will be edited at the same time, with the same value.
+ */
+//TODO : Add listeners on sub-observables, and remove them on dispose
+public class MultipleObservableValue extends AbstractObservableValue implements AggregatedObservable, IChangeListener {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param values
+ * The collection of sub-elements for this MultipleObservableValue
+ *
+ */
+ public MultipleObservableValue(Collection<IObservableValue> values) {
+ if(values != null) {
+ observableValues.addAll(values);
+ }
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public MultipleObservableValue() {
+
+ }
+
+ public Object getValueType() {
+ if(observableValues.isEmpty()) {
+ return null;
+ }
+
+ return observableValues.get(0).getValueType();
+ }
+
+ /**
+ * If all objects have the same value, returns this value
+ * Otherwise, returns the defaultGetValue
+ * If the defaultGetValue hasn't been set, returns null
+ */
+ @Override
+ protected Object doGetValue() {
+ if(hasDifferentValues() || observableValues.isEmpty()) {
+ return null;
+ }
+
+ return observableValues.get(0).getValue();
+ }
+
+ private boolean equals(Object value, Object currentValue) {
+ if(value == currentValue) {
+ return true;
+ }
+ if(value == null) {
+ return false;
+ }
+ return value.equals(currentValue);
+ }
+
+ @Override
+ protected void doSetValue(Object value) {
+ for(IObservableValue observable : observableValues) {
+ observable.setValue(value);
+ }
+ }
+
+ public AggregatedObservable aggregate(IObservable observable) {
+ if(observable instanceof IObservableValue) {
+ observableValues.add((IObservableValue)observable);
+ observable.addChangeListener(this);
+ return this;
+ }
+ return null;
+ }
+
+ /**
+ * @return the list of sub-observable values
+ */
+ public List<IObservableValue> getObservableValues() {
+ return observableValues;
+ }
+
+ /**
+ * @return the list of observed values
+ */
+ public List<Object> getObservedValues() {
+ List<Object> result = new LinkedList<Object>();
+ for(IObservableValue value : getObservableValues()) {
+ result.add(value.getValue());
+ }
+ return result;
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ for(IObservableValue observable : observableValues) {
+ observable.removeChangeListener(this);
+ observable.dispose();
+ }
+ }
+
+ protected List<IObservableValue> observableValues = new LinkedList<IObservableValue>();
+
+ public boolean hasDifferentValues() {
+ if(observableValues.isEmpty()) {
+ return false;
+ }
+
+ Object currentValue = null;
+ boolean firstValue = true;
+ for(IObservableValue observable : observableValues) {
+ if(firstValue) {
+ firstValue = false;
+ currentValue = observable.getValue();
+ } else {
+ Object value = observable.getValue();
+ if(equals(value, currentValue)) {
+ continue;
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void handleChange(ChangeEvent event) {
+ //We're not interested in the old and new values
+ //We just return two different values so that a change event is fired
+ super.fireValueChange(new ValueDiff() {
+
+ @Override
+ public Object getOldValue() {
+ return true;
+ }
+
+ @Override
+ public Object getNewValue() {
+ return false;
+ }
+ });
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/ContextExtensionPoint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/ContextExtensionPoint.java
new file mode 100644
index 00000000000..36e53470fa1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/ContextExtensionPoint.java
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * 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.extensions;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+
+/**
+ * Handles the extension point org.eclipse.papyrus.properties.context
+ * Registers the given Context models to the Property View framework
+ *
+ * @author Camille Letavernier
+ */
+public class ContextExtensionPoint {
+
+ private final String EXTENSION_ID = "org.eclipse.papyrus.properties.context"; //$NON-NLS-1$
+
+ /**
+ * Constructor
+ */
+ public ContextExtensionPoint() {
+ IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID);
+
+ for(IConfigurationElement e : config) {
+ final String contextResource = e.getAttribute("contextModel"); //$NON-NLS-1$
+ URI uri = URI.createURI("ppe:/context/" + e.getContributor().getName() + "/" + contextResource); //$NON-NLS-1$ //$NON-NLS-2$
+ //URI uri = URI.createPlatformPluginURI(e.getContributor().getName() + "/" + contextResource, true); //$NON-NLS-1$
+ try {
+ ConfigurationManager.instance.addContext(uri);
+ } catch (IOException ex) {
+ Activator.log.error("The plugin " + e.getContributor() + " contributed an invalid extension for " + EXTENSION_ID, ex); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/EnvironmentExtensionPoint.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/EnvironmentExtensionPoint.java
new file mode 100644
index 00000000000..53465a72e3e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/extensions/EnvironmentExtensionPoint.java
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * 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.extensions;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+
+/**
+ * Handles the extension point org.eclipse.papyrus.properties.environment
+ * Registers the given Environment models to the Property View framework
+ *
+ * @author Camille Letavernier
+ */
+public class EnvironmentExtensionPoint {
+
+ private final String EXTENSION_ID = "org.eclipse.papyrus.properties.environment"; //$NON-NLS-1$
+
+ /**
+ *
+ * Constructor.
+ *
+ */
+ public EnvironmentExtensionPoint() {
+ IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID);
+
+ for(IConfigurationElement e : config) {
+ final String environmentResource = e.getAttribute("environmentModel"); //$NON-NLS-1$
+ URI uri = URI.createURI("ppe:/environment/" + e.getContributor().getName() + "/" + environmentResource); //$NON-NLS-1$ //$NON-NLS-2$
+ //URI uri = URI.createPlatformPluginURI(e.getContributor().getName() + "/" + environmentResource, true); //$NON-NLS-1$
+ try {
+ ConfigurationManager.instance.addEnvironment(uri);
+ } catch (IOException ex) {
+ Activator.log.error("The plugin " + e.getContributor() + " contributed an invalid " + "extension for " + EXTENSION_ID, ex); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/Messages.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/Messages.java
new file mode 100644
index 00000000000..de8f1a843a8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/Messages.java
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * 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.messages;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * String externalisation for plug-in org.eclipse.papyrus.properties
+ *
+ * @author Camille Letavernier
+ */
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.properties.messages.messages"; //$NON-NLS-1$
+
+ public static String EcorePropertyEditorFactory_CreateANew;
+
+ public static String EditionDialog_CreateANewElement;
+
+ public static String Preferences_ConflictWarning1;
+
+ public static String Preferences_ConflictWarning2;
+
+ public static String Preferences_ConflictWarningTitle;
+
+ public static String Preferences_Contexts;
+
+ public static String Preferences_Custom;
+
+ public static String Preferences_Plugin;
+
+ public static String PropertyEditorFactory_CreateANewElement;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/messages.properties b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/messages.properties
new file mode 100644
index 00000000000..151b75538e6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/messages/messages.properties
@@ -0,0 +1,9 @@
+EcorePropertyEditorFactory_CreateANew=Create a new
+EditionDialog_CreateANewElement=Create a new Element
+Preferences_ConflictWarning1=Warning : When two sections with the same ID are displayed in the same property view, only the first of them is displayed. The following conflicts may occur : \n\n
+Preferences_ConflictWarning2=\nPlease note that if these sections apply to different elements, there won't be any conflict. Do you wish to continue ?
+Preferences_ConflictWarningTitle=Warning : Conflicts detected
+Preferences_Contexts=Contexts :
+Preferences_Custom=custom
+Preferences_Plugin=plugin
+PropertyEditorFactory_CreateANewElement=Create a new element
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AbstractModelElement.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AbstractModelElement.java
new file mode 100644
index 00000000000..0aea92d384f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AbstractModelElement.java
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.creation.PropertyEditorFactory;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.widgets.providers.EmptyContentProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+/**
+ * Provides a default implementation for ModelElement methods applied on the
+ * modelElement's properties.
+ *
+ * @author Camille Letavernier
+ */
+public abstract class AbstractModelElement implements ModelElement {
+
+ /**
+ * The DataSource owning this ModelElement
+ */
+ protected DataSource dataSource;
+
+ private final List<IObservable> observables = new LinkedList<IObservable>();
+
+ /**
+ * Constructor.
+ */
+ protected AbstractModelElement() {
+ }
+
+ public IStaticContentProvider getContentProvider(String propertyPath) {
+ return EmptyContentProvider.instance;
+ }
+
+ public ILabelProvider getLabelProvider(String propertyPath) {
+ return null;
+ }
+
+ public boolean isOrdered(String propertyPath) {
+ return true;
+ }
+
+ public boolean isUnique(String propertyPath) {
+ return false;
+ }
+
+ public boolean isMandatory(String propertyPath) {
+ return false;
+ }
+
+ public boolean isEditable(String propertyPath) {
+ return true;
+ }
+
+ public boolean forceRefresh(String propertyPath) {
+ return false;
+ }
+
+ public void setDataSource(DataSource source) {
+ this.dataSource = source;
+ }
+
+ /**
+ * Finds the property associated to the given propertyPath
+ *
+ * @param propertyPath
+ * The name of the property to retrieve
+ * @return the property associated to the given propertyPath
+ */
+ protected Property getProperty(String propertyPath) {
+ return ConfigurationManager.instance.getProperty(propertyPath, dataSource.getView().getContext());
+ }
+
+ /**
+ * @see org.eclipse.papyrus.properties.modelelement.ModelElement#getValueFactory(java.lang.String)
+ *
+ * @param propertyPath
+ * @return a default factory based on the property view configuration to
+ * edit objects, as if they were selected in an editor
+ */
+ public ReferenceValueFactory getValueFactory(String propertyPath) {
+ return new PropertyEditorFactory();
+ }
+
+ public Object getDefaultValue(String propertyPath) {
+ return null;
+ }
+
+ public boolean getDirectCreation(String propertyPath) {
+ return false;
+ }
+
+ public final IObservable getObservable(String propertyPath) {
+ IObservable observable = doGetObservable(propertyPath);
+ if(observable != null) {
+ observables.add(observable);
+ }
+ return observable;
+ }
+
+ /**
+ * Creates the IObservable for the given propertyPath
+ *
+ * @param propertyPath
+ * The path of the property we want to observe
+ * @return
+ * The new IObservable
+ */
+ protected abstract IObservable doGetObservable(String propertyPath);
+
+ public void dispose() {
+ for(IObservable observable : observables) {
+ observable.dispose();
+ }
+ observables.clear();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElement.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElement.java
new file mode 100644
index 00000000000..ed6205083ae
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElement.java
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.properties.databinding.AnnotationObservableValue;
+
+/**
+ * A ModelElement for handling EAnnotations
+ *
+ * @author Camille Letavernier
+ */
+public class AnnotationModelElement extends AbstractModelElement {
+
+ /**
+ * The EModelElement owning the represented EAnnotation
+ */
+ protected EModelElement source;
+
+ /**
+ * The editing domain on which the modification commands will be executed
+ */
+ protected EditingDomain domain;
+
+ /**
+ * The name of the annotation being represented
+ */
+ protected String annotationName;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param source
+ * The EModelElement owning the EAnnotation that will be edited
+ * @param domain
+ * The EditingDomain on which the commands will be executed
+ * @param annotationName
+ * The name of the EAnnotation to edit. The EAnnotation doesn't need to exist yet
+ */
+ public AnnotationModelElement(EModelElement source, EditingDomain domain, String annotationName) {
+ this.source = source;
+ this.domain = domain;
+ this.annotationName = annotationName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IObservable doGetObservable(String propertyPath) {
+ return new AnnotationObservableValue(source, domain, annotationName, propertyPath);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElementFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElementFactory.java
new file mode 100644
index 00000000000..26abb390ac8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/AnnotationModelElementFactory.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+
+/**
+ * A ModelElementFactory for AnnotationModelElements
+ *
+ * @author Camille Letavernier
+ */
+public class AnnotationModelElementFactory implements ModelElementFactory {
+
+ public ModelElement createFromSource(Object sourceElement, DataContextElement context) {
+ EObject source = EMFHelper.getEObject(sourceElement);
+ if(source == null) {
+ Activator.log.warn("Unable to resolve the selected element to an EObject"); //$NON-NLS-1$
+ return null;
+ }
+
+ if (! (source instanceof EModelElement)){
+ Activator.log.warn("The selected element must be an EModelElement"); //$NON-NLS-1$
+ }
+
+ EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(source);
+ return new AnnotationModelElement((EModelElement)source, domain, context.getName());
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/CompositeModelElement.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/CompositeModelElement.java
new file mode 100644
index 00000000000..1be001b89f7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/CompositeModelElement.java
@@ -0,0 +1,188 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.properties.databinding.MultipleObservableValue;
+import org.eclipse.papyrus.widgets.databinding.AggregatedObservable;
+import org.eclipse.papyrus.widgets.providers.EmptyContentProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+/**
+ * A ModelElement to handle MultiSelection property views.
+ * It is composed of standard ModelElement. The result of method
+ * calls are an aggregation of the results of the same method calls
+ * on each sub-element, when this makes sense (i.e. for booleans)
+ * When an aggregation is not possible, the result of the same method
+ * call on the first element is returned (e.g. for Content and Label providers)
+ *
+ * @author Camille Letavernier
+ */
+public class CompositeModelElement extends AbstractModelElement {
+
+ @Override
+ public IObservable doGetObservable(String propertyPath) {
+
+ AggregatedObservable observableComposite = null;
+
+ for(ModelElement element : elements) {
+ IObservable observable = element.getObservable(propertyPath);
+
+ //Otherwise, we use a standard AggregatedComposite
+ if(observableComposite == null) {
+ if(observable instanceof AggregatedObservable) {
+ observableComposite = (AggregatedObservable)observable;
+ } else {
+ if(observable instanceof IObservableValue) {
+ observableComposite = new MultipleObservableValue().aggregate(observable);
+ if(observableComposite == null) {
+ return null;
+ }
+ } else {
+ return null; //The support for CompositeObservableList is too complicated.
+ //There are too many non-trivial choices (Union or Intersection display,
+ //unadapted behavior of MultipleValueEditors, ...)
+ //observableComposite = new MultipleObservableList();
+ }
+ }
+ } else {
+ if((observableComposite = observableComposite.aggregate(observable)) == null) {
+ return null;
+ }
+ }
+ }
+
+ return observableComposite;
+ }
+
+ /**
+ * Adds a sub-model element to this CompositeModelElement
+ *
+ * @param element
+ * The sub-model element to be added
+ */
+ public void addModelElement(ModelElement element) {
+ elements.add(element);
+ }
+
+ @Override
+ public IStaticContentProvider getContentProvider(String propertyPath) {
+ if(elements.isEmpty()) {
+ return EmptyContentProvider.instance;
+ }
+
+ return elements.get(0).getContentProvider(propertyPath);
+ }
+
+ @Override
+ public ILabelProvider getLabelProvider(String propertyPath) {
+ if(elements.isEmpty()) {
+ return null;
+ }
+
+ return elements.get(0).getLabelProvider(propertyPath);
+ }
+
+ @Override
+ public boolean isOrdered(String propertyPath) {
+ if(elements.isEmpty()) {
+ return false;
+ }
+
+ for(ModelElement element : elements) {
+ if(element.isOrdered(propertyPath)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean isUnique(String propertyPath) {
+ if(elements.isEmpty()) {
+ return false;
+ }
+
+ for(ModelElement element : elements) {
+ if(!element.isUnique(propertyPath)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isMandatory(String propertyPath) {
+ if(elements.isEmpty()) {
+ return false;
+ }
+
+ for(ModelElement element : elements) {
+ if(!element.isMandatory(propertyPath)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isEditable(String propertyPath) {
+ if(elements.isEmpty()) {
+ return false;
+ }
+
+ for(ModelElement element : elements) {
+ if(!element.isEditable(propertyPath)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private List<ModelElement> elements = new LinkedList<ModelElement>();
+
+ @Override
+ public boolean forceRefresh(String propertyPath) {
+ if(elements.isEmpty()) {
+ return false;
+ }
+
+ for(ModelElement element : elements) {
+ if(element.forceRefresh(propertyPath)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public Object getDefaultValue(String propertyPath) {
+ if(elements.isEmpty()) {
+ return null;
+ }
+ return elements.get(0).getDefaultValue(propertyPath);
+ }
+
+ public List<ModelElement> getSubElements() {
+ return elements;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSource.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSource.java
new file mode 100644
index 00000000000..9fe01cff839
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSource.java
@@ -0,0 +1,346 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.widgets.providers.EmptyContentProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+/**
+ * A DataSource is an object encapsulating one or more {@link ModelElement}s.
+ * It contains methods to resolve property paths, and forward the methods to
+ * the right ModelElement.
+ *
+ * For example, a UML class stereotyped with the SysML::Blocks::Block will have
+ * two ModelElements : one for UML, and one for the Block stereotype.
+ *
+ * It will be able to resolve paths such as UML:Class:name or
+ * SysML:Blocks:Block:isEncapsulated
+ *
+ * The methods such as isUnique, isEditable or getContentProvider will be
+ * delegated to the resolved ModelElement, with a truncated property path.
+ *
+ * For example, a call to DataSource#isEditable("UML:Class:name") will be
+ * forwarded to UMLModelElement#isEditable("name")
+ *
+ * @author Camille Letavernier
+ */
+public class DataSource implements IChangeListener {
+
+ private Set<IChangeListener> changeListeners = new HashSet<IChangeListener>();
+
+ private List<IObservable> observed = new LinkedList<IObservable>();
+
+ private View view;
+
+ private IStructuredSelection selection;
+
+ private Map<String, ModelElement> elements = new HashMap<String, ModelElement>();
+
+ /**
+ * Constructs a new DataSource from the given view and selection
+ *
+ * @param view
+ * @param selection
+ *
+ * @see DataSourceFactory#createDataSourceFromSelection(IStructuredSelection, View)
+ */
+ protected DataSource(View view, IStructuredSelection selection) {
+ this.view = view;
+ this.selection = selection;
+ }
+
+ /**
+ * Return the instance of ModelElement associated to the given path
+ *
+ * @param propertyPath
+ * The propertyPath to lookup
+ * @return
+ * The ModelElement associated to the given propertyPath
+ */
+ public ModelElement getModelElement(String propertyPath) {
+ //ConfigurationManager.instance.getProperty(propertyPath)
+ String key = propertyPath.substring(0, propertyPath.lastIndexOf(":")); //$NON-NLS-1$
+ ModelElement element = elements.get(key);
+ if(element == null) { //Try to resolve the modelElements on-the-fly
+ element = DataSourceFactory.instance.getModelElementFromPropertyPath(this, propertyPath);
+ if(element == null) {
+ Activator.log.warn("Unable to find a ModelElement for " + propertyPath + ". Elements : " + elements); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+ elements.put(key, element);
+ }
+ return element;
+ }
+
+ private String getLocalPropertyPath(String propertyPath) {
+ return propertyPath.substring(propertyPath.lastIndexOf(":") + 1); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns an IObservable corresponding to the given property path
+ * The observable may be either an IObservableValue or an IObservableList
+ * The call to this method is delegated to the corresponding ModelElement
+ *
+ * @param propertyPath
+ * The property path for which we want to retrieve an ObservableValue
+ * @return
+ * The IObservable corresponding to the given propertyPath
+ */
+ public IObservable getObservable(String propertyPath) {
+ String localPropertyPath = getLocalPropertyPath(propertyPath);
+ ModelElement element = getModelElement(propertyPath);
+
+ if(element == null) {
+ return null;
+ }
+
+ IObservable observable = element.getObservable(localPropertyPath);
+ if(observable != null) {
+ observable.addChangeListener(this);
+ observed.add(observable);
+ }
+
+ return observable;
+ }
+
+ @Override
+ public String toString() {
+ return "[DataSource] " + super.toString(); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns an IStaticContentProvider corresponding to the given property path
+ * The call to this method is delegated to the corresponding ModelElement
+ *
+ * @param propertyPath
+ * The property path for which we want to retrieve a ContentProvider
+ * @return
+ * The IStaticContentProvider corresponding to the given propertyPath
+ */
+ public IStaticContentProvider getContentProvider(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return EmptyContentProvider.instance;
+ }
+
+ String localPropertyPath = getLocalPropertyPath(propertyPath);
+ return element.getContentProvider(localPropertyPath);
+ }
+
+ /**
+ * Returns an ILabelProvider corresponding to the given property path
+ * The call to this method is delegated to the corresponding ModelElement
+ *
+ * @param propertyPath
+ * The property path for which we want to retrieve an ILabelProvider
+ * @return
+ * The ILabelProvider corresponding to the given propertyPath
+ */
+ public ILabelProvider getLabelProvider(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return null;
+ }
+ String localPropertyPath = getLocalPropertyPath(propertyPath);
+ return element.getLabelProvider(localPropertyPath);
+ }
+
+ /**
+ * Adds a change listener to this DataSource. The listener will be notified
+ * each time a change occurs on one of the IObservable produced by this DataSource
+ *
+ * @see DataSource#getObservable(String)
+ * @param listener
+ * The Change listener
+ */
+ public void addChangeListener(IChangeListener listener) {
+ changeListeners.add(listener);
+ }
+
+ /**
+ * Removes a change listener from this DataSource.
+ *
+ * @param listener
+ * The listener to remove
+ * @see DataSource#addChangeListener(IChangeListener)
+ */
+ public void removeChangeListener(IChangeListener listener) {
+ changeListeners.remove(listener);
+ }
+
+ public void handleChange(ChangeEvent event) {
+ for(IChangeListener listener : changeListeners) {
+ listener.handleChange(event);
+ }
+ }
+
+ /**
+ * @return The view associated to this DataSource
+ */
+ public View getView() {
+ return view;
+ }
+
+ /**
+ * @return the selection associated to this DataSource
+ */
+ public IStructuredSelection getSelection() {
+ return selection;
+ }
+
+ /**
+ * @param propertyPath
+ * @return
+ * true if the property represented by this propertyPath is ordered
+ */
+ public boolean isOrdered(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return false;
+ }
+ return element.isOrdered(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * @param propertyPath
+ * @return
+ * true if the property represented by this propertyPath is unique
+ */
+ public boolean isUnique(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return false;
+ }
+ return element.isUnique(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * @param propertyPath
+ * @return
+ * true if the property represented by this propertyPath is mandatory
+ */
+ public boolean isMandatory(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return false;
+ }
+ return element.isMandatory(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * @param propertyPath
+ * @return
+ * true if the property represented by this propertyPath is editable
+ */
+ public boolean isEditable(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return false;
+ }
+ return element.isEditable(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * Returns true if the given property should be refresh each time a change
+ * occurs in the property view. May help when the IObservable doesn't
+ * catch some change events (For example, for some Ecore derived
+ * properties).
+ *
+ * @param propertyPath
+ * @return true if the refresh should be forced
+ */
+ public boolean forceRefresh(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return false;
+ }
+ return element.forceRefresh(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * Return the value factory associated to the given path. May be null
+ *
+ * @param propertyPath
+ * The property path to lookup
+ * @return
+ * The factory used to edit and/or instantiate values for this property path
+ */
+ public ReferenceValueFactory getValueFactory(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return null;
+ }
+ return element.getValueFactory(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * Return the default value for the given property path
+ *
+ * @param propertyPath
+ * @return
+ * The default value for the given property
+ */
+ public Object getDefaultValue(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return null;
+ }
+ return element.getDefaultValue(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * Indicates if the widget should use the direct creation.
+ * The direct edition will disable the possibility to browse
+ * existing elements when the "add" button is pressed.
+ *
+ * This is essentially relevant for containment references : this method
+ * should return false if the widget should only allow creation of new
+ * elements.
+ *
+ * @param propertyPath
+ * @return
+ * True if the widget should use the direct edition option for the given property
+ */
+ public boolean getDirectCreation(String propertyPath) {
+ ModelElement element = getModelElement(propertyPath);
+ if(element == null) {
+ return true;
+ }
+ return element.getDirectCreation(getLocalPropertyPath(propertyPath));
+ }
+
+ /**
+ * Disposes this data source.
+ * This will dispose all ModelElements and IObservable created by this DataSource
+ */
+ public void dispose() {
+ for(ModelElement element : elements.values()) {
+ element.dispose();
+ }
+ elements.clear();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSourceFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSourceFactory.java
new file mode 100644
index 00000000000..778463423be
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/DataSourceFactory.java
@@ -0,0 +1,240 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.contexts.DataContextRoot;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.environment.ModelElementFactoryDescriptor;
+import org.eclipse.papyrus.properties.util.ClassLoader;
+import org.eclipse.papyrus.properties.util.Util;
+import org.eclipse.papyrus.widgets.Activator;
+
+/**
+ * A Factory to build and populate DataSource with the right ModelElements
+ *
+ * @author Camille Letavernier
+ */
+// FIXME : sources is never cleared (Memory leak)
+// TODO : The DataSource probably don't need a factory. Most methods are related
+// to ModelElement.
+public class DataSourceFactory {
+
+ /**
+ * Singleton instance for DataSourceFactory
+ */
+ public static DataSourceFactory instance = new DataSourceFactory();
+
+ /**
+ * Creates a new DataSource from a selection and a view.
+ *
+ * @param selection
+ * The selection of Objects
+ * @param view
+ * The view to display
+ * @return The DataSource that can be passed to the DisplayEngine to display
+ * the view
+ */
+ public DataSource createDataSourceFromSelection(
+ IStructuredSelection selection, View view) {
+ SelectionEntry selectionEntry = new SelectionEntry(selection, view);
+
+ if (!sources.containsKey(selectionEntry)) {
+ DataSource source = new DataSource(view, selection);
+ sources.put(selectionEntry, source);
+ }
+
+ return sources.get(selectionEntry);
+ }
+
+ public void removeFromCache(IStructuredSelection selection, View view){
+ if(selection == null || view == null) {
+ return;
+ }
+
+ SelectionEntry entry = new SelectionEntry(selection, view);
+ sources.remove(entry);
+ }
+
+ /**
+ * Returns the ModelElement corresponding to the given propertyPath and
+ * DataSource
+ *
+ * @param source
+ * The DataSource used to retrieved informations such as the View
+ * and the Selection
+ * @param propertyPath
+ * The path describing the property for which we want a
+ * ModelElement
+ * @return The matching modelElement
+ */
+ public ModelElement getModelElementFromPropertyPath(DataSource source,
+ String propertyPath) {
+ String key = propertyPath.substring(0, propertyPath.lastIndexOf(":")); //$NON-NLS-1$
+ for (Context context : Util.getDependencies(source.getView()
+ .getContext())) {
+ DataContextElement element = Util.getContextElementByQualifiedName(
+ key, context.getDataContexts());
+ if (element != null) {
+ ModelElement modelElement = DataSourceFactory.instance
+ .createModelElement(element, source.getSelection());
+ if (modelElement != null) {
+ modelElement.setDataSource(source);
+ }
+ return modelElement;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Creates a ModelElement from the given DataContextElement and Selection.
+ *
+ * @param contextElement
+ * The contextElement for which we are creating a ModelElement
+ * @param selection
+ * The list of objects currently selected
+ * @return The model element corresponding to the given contextElement and
+ * selection
+ */
+ private ModelElement createModelElement(DataContextElement contextElement,
+ IStructuredSelection selection) {
+ if (selection.size() == 1) { // Single Selection
+ ModelElement modelElement = createFromSource(
+ selection.getFirstElement(), contextElement);
+ return modelElement;
+ } else { // MultiSelection
+ CompositeModelElement composite = new CompositeModelElement();
+
+ Iterator<?> it = selection.iterator();
+ while (it.hasNext()) {
+ ModelElement element = createFromSource(it.next(),
+ contextElement);
+ if (element != null) {
+ composite.addModelElement(element);
+ }
+ }
+
+ return composite;
+ }
+ }
+
+ /**
+ * Retrieves the ModelElementFactory for the given DataContextElement. The
+ * ModelElementFactory is declared by the DataContextRoot owning the given
+ * DataContextElement
+ *
+ * @param context
+ * The DataContextElement for which we want to retrieve the
+ * ModelElementFactory
+ * @return The ModelElementFactory corresponding to the given
+ * DataContextElement
+ */
+ private ModelElementFactory getFactory(DataContextElement context) {
+ ClassLoader loader = new ClassLoader();
+ DataContextRoot rootPackage = getRootPackage(context);
+ ModelElementFactoryDescriptor factoryDescriptor = rootPackage
+ .getModelElementFactory();
+
+ if (factoryDescriptor == null) {
+ Activator.log
+ .warn("No ModelElementFactory is attached to DataContextElement " + getQualifiedName(context)); //$NON-NLS-1$
+ return null;
+ }
+
+ String factoryName = factoryDescriptor.getFactoryClass();
+ ModelElementFactory factory = (ModelElementFactory) loader
+ .newInstance(factoryName);
+
+ return factory;
+ }
+
+ private ModelElement createFromSource(Object source,
+ DataContextElement context) {
+ ModelElementFactory factory = getFactory(context);
+
+ if (factory == null) {
+ return null;
+ }
+
+ return factory.createFromSource(source, context);
+ }
+
+ private DataContextRoot getRootPackage(DataContextElement context) {
+ if (context.getPackage() == null) {
+ return (DataContextRoot) context;
+ }
+ return getRootPackage(context.getPackage());
+ }
+
+ private String getQualifiedName(DataContextElement context) {
+ if (context.getPackage() == null) {
+ return context.getName();
+ }
+ return getQualifiedName(context.getPackage()) + ":" + context.getName(); //$NON-NLS-1$
+ }
+
+ /**
+ * Singleton Constructor.
+ */
+ private DataSourceFactory() {
+
+ }
+
+ private class SelectionEntry {
+
+ private IStructuredSelection selection;
+
+ private View view;
+
+ public SelectionEntry(IStructuredSelection selection, View view) {
+ if(selection == null) {
+ throw new IllegalArgumentException("The selection must not be null");
+ }
+ if(view == null) {
+ throw new IllegalArgumentException("The view must not be null");
+ }
+ this.selection = selection;
+ this.view = view;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof SelectionEntry)) {
+ return false;
+ }
+
+ SelectionEntry other = (SelectionEntry) obj;
+ return other.view.equals(view) && selection.equals(other.selection);
+ }
+
+ @Override
+ public int hashCode() {
+ return selection.hashCode() + view.hashCode();
+ }
+ }
+
+ /**
+ * More than one {@link XWTSection} may share the same DataSource.
+ * They all need to listen on the same source, so that they can correctly
+ * refresh themselves. We maintain a cache for each Selection/View pair.
+ *
+ * The cache is cleaned when the sections are disposed.
+ */
+ private Map<SelectionEntry, DataSource> sources = new HashMap<SelectionEntry, DataSource>();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElement.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElement.java
new file mode 100644
index 00000000000..486e96864a2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElement.java
@@ -0,0 +1,294 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.databinding.EMFProperties;
+import org.eclipse.emf.databinding.FeaturePath;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.creation.EcorePropertyEditorFactory;
+import org.eclipse.papyrus.properties.databinding.EMFObservableList;
+import org.eclipse.papyrus.properties.databinding.EMFObservableValue;
+import org.eclipse.papyrus.properties.providers.EMFObjectLabelProvider;
+import org.eclipse.papyrus.properties.providers.EcoreEnumeratorContentProvider;
+import org.eclipse.papyrus.properties.providers.EcoreReferenceContentProvider;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.widgets.providers.EmptyContentProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+/**
+ * A ModelElement to manipulate EMF objects.
+ * This ModelElement uses EMFProperties to retrieve Observables when there
+ * is no Editing Domain, and {@link EMFObservableValue} / {@link EMFObservableList} when
+ * an Editing domain is available
+ *
+ * @author Camille Letavernier
+ */
+public class EMFModelElement extends AbstractModelElement {
+
+ /**
+ * The EObject manipulated by this ModelElement
+ */
+ protected EObject source;
+
+ /**
+ * The Editing Domain of the EObject for this ModelElement
+ */
+ protected EditingDomain domain;
+
+ /**
+ *
+ * Constructs a new EMFModelElement for the given EObject
+ *
+ * @param source
+ */
+ public EMFModelElement(EObject source) {
+ this(source, null);
+ }
+
+ /**
+ *
+ * Constructs a new EMFModelElement for the given EObject and Editing Domain
+ *
+ * @param source
+ * @param domain
+ */
+ public EMFModelElement(EObject source, EditingDomain domain) {
+ this.source = source;
+ this.domain = domain;
+ }
+
+ /**
+ * @return the EditingDomain for this ModelElement
+ */
+ public EditingDomain getDomain() {
+ return domain;
+ }
+
+ /**
+ * @return the EObject for this ModelElement
+ */
+ public EObject getSource() {
+ return source;
+ }
+
+ @Override
+ protected IObservable doGetObservable(String propertyPath) {
+ FeaturePath featurePath = getFeaturePath(propertyPath);
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return null;
+ }
+
+ if(feature.getUpperBound() != 1) {
+ IObservableList list = domain == null ? EMFProperties.list(featurePath).observe(source) : new EMFObservableList(EMFProperties.list(featurePath).observe(source), domain, getSource(featurePath), feature);
+ return list;
+ }
+
+ IObservableValue value = domain == null ? EMFProperties.value(featurePath).observe(source) : new EMFObservableValue(getSource(featurePath), feature, domain);
+ return value;
+ }
+
+ /**
+ * Returns the last EObject by following the given featurePath from the {@link #source} EObject
+ * The last feature of the featurePath can be used to retrieve value from the returned EObject
+ *
+ * @param featurePath
+ * @return the EObject found by resolving to the given FeaturePath
+ */
+ public EObject getSource(FeaturePath featurePath) {
+ EObject currentSource = source;
+ EStructuralFeature[] features = featurePath.getFeaturePath();
+ for(int i = 0; i < features.length - 1; i++) {
+ currentSource = (EObject)currentSource.eGet(features[i]);
+ }
+ return currentSource;
+ }
+
+ /**
+ * Returns the feature represented by the given FeaturePath
+ *
+ * @param featurePath
+ * @return
+ * The last feature obtained by navigating the feature path
+ */
+ public EStructuralFeature getFeature(FeaturePath featurePath) {
+ EStructuralFeature[] features = featurePath.getFeaturePath();
+ return features[features.length - 1];
+ }
+
+ /**
+ * Returns the feature represented by the given propertyPath.
+ *
+ * @param propertyPath
+ * The property path may contain one or more dots to navigate the properties (e.g. : feature1.feature2.feature3)
+ * @return
+ * The last feature obtained by resolving the full property path
+ */
+ public EStructuralFeature getFeature(String propertyPath) {
+ FeaturePath featurePath = getFeaturePath(propertyPath);
+ return getFeature(featurePath);
+ }
+
+ /**
+ * Returns the featurePath corresponding to the given propertyPath
+ *
+ * @param propertyPath
+ * The property path may contain one or more dots to navigate the properties (e.g. : feature1.feature2.feature3)
+ * @return
+ * The featurePath corresponding to the given propertyPath
+ */
+ public FeaturePath getFeaturePath(String propertyPath) {
+ String[] featureNames = propertyPath.split("\\."); //$NON-NLS-1$
+ EStructuralFeature[] features = new EStructuralFeature[featureNames.length];
+
+ int i = 0;
+ EClass currentClass = source.eClass();
+ for(String featureName : featureNames) {
+ EStructuralFeature feature = currentClass.getEStructuralFeature(featureName);
+ features[i++] = feature;
+ if(i < featureNames.length) {
+ if(feature instanceof EReference) {
+ EReference reference = (EReference)feature;
+ EClassifier type = reference.getEType();
+ if(type instanceof EClass) {
+ currentClass = (EClass)type;
+ continue;
+ }
+ }
+
+ Activator.log.warn("Cannot find feature path " + propertyPath + " for EClass " + source.eClass()); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+ }
+
+ return FeaturePath.fromList(features);
+ }
+
+ @Override
+ public IStaticContentProvider getContentProvider(String propertyPath) {
+ FeaturePath featurePath = getFeaturePath(propertyPath);
+ EStructuralFeature feature = getFeature(featurePath);
+ if(feature == null) {
+ return EmptyContentProvider.instance;
+ }
+ EClassifier type = feature.getEType();
+ if(type instanceof EEnum) {
+ return new EcoreEnumeratorContentProvider(feature);
+ } else if(type instanceof EClass) {
+ return new EcoreReferenceContentProvider(feature, getSource(featurePath));
+ }
+
+ return EmptyContentProvider.instance;
+ }
+
+ @Override
+ public ILabelProvider getLabelProvider(String propertyPath) {
+ return new EMFObjectLabelProvider();
+ }
+
+ @Override
+ public boolean isOrdered(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return true;
+ }
+ return feature.isOrdered();
+ }
+
+ @Override
+ public boolean isUnique(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return false;
+ }
+ return feature.isUnique();
+ }
+
+ @Override
+ public boolean isMandatory(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return false;
+ }
+
+ return EMFHelper.isRequired(feature);
+ }
+
+ @Override
+ public boolean isEditable(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return false;
+ }
+ return feature.isChangeable() && !EMFHelper.isReadOnly(source);
+ }
+
+ @Override
+ public boolean forceRefresh(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return false;
+ }
+ return feature.isDerived();
+ }
+
+ @Override
+ public ReferenceValueFactory getValueFactory(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature != null) {
+ if(feature instanceof EReference) {
+ EReference reference = (EReference)feature;
+ if(reference.isContainment()) {
+ return new EcorePropertyEditorFactory(reference);
+ }
+ }
+ }
+
+ return super.getValueFactory(propertyPath);
+ }
+
+ @Override
+ public Object getDefaultValue(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return null;
+ }
+ return feature.getDefaultValue();
+ }
+
+ @Override
+ public boolean getDirectCreation(String propertyPath) {
+ EStructuralFeature feature = getFeature(propertyPath);
+ if(feature == null) {
+ return false;
+ }
+
+ if(feature instanceof EAttribute) {
+ return false;
+ }
+
+ return ((EReference)feature).isContainment();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElementFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElementFactory.java
new file mode 100644
index 00000000000..38a26fb0900
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/EMFModelElementFactory.java
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+
+/**
+ * A ModelElementFactory for creating {@link EMFModelElement}s
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class EMFModelElementFactory implements ModelElementFactory {
+
+ public ModelElement createFromSource(Object sourceElement, DataContextElement context) {
+ EObject source = EMFHelper.getEObject(sourceElement);
+ if(source == null) {
+ Activator.log.warn("Unable to resolve the selected element to an EObject"); //$NON-NLS-1$
+ return null;
+ }
+
+ EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(source);
+ return new EMFModelElement(source, domain);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElement.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElement.java
new file mode 100644
index 00000000000..bb1a860edcf
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElement.java
@@ -0,0 +1,155 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+/**
+ * An interface representing Model Elements. A ModelElement is associated to a
+ * DataContextElement, and should provide access to all properties for a given
+ * object, though the mean of {@link IObservable}s. It should also be able to
+ * provide informations about each property, such as a ContentProvider for
+ * references.
+ *
+ * @author Camille Letavernier
+ */
+public interface ModelElement {
+
+ /**
+ * Returns an IObservable for the given propertyPath. The IObservable
+ * may be either an IObservableValue or an IObservableList.
+ *
+ * @param propertyPath
+ * The property for which we need an IObservable
+ * @return
+ * The IObservable corresponding to the given propertyPath
+ */
+ public IObservable getObservable(String propertyPath);
+
+ /**
+ * Returns an IStaticContentProvider for the given propertyPath. The
+ * returned value should not be null. If there is no content provider,
+ * use {@link EmptyContentProvider#instance}
+ *
+ * @param propertyPath
+ * The name of the property for which we want a Content provider
+ * @return
+ * The IStaticContentProvider containing the available values for
+ * the given property
+ */
+ public IStaticContentProvider getContentProvider(String propertyPath);
+
+ /**
+ * Returns an ILabelProvider for the given propertypath, or null if
+ * a default LabelProvider should be used.
+ *
+ * @param propertyPath
+ * @return
+ * the LabelProvider for the given path
+ */
+ public ILabelProvider getLabelProvider(String propertyPath);
+
+ /**
+ * Returns true if the given property should be ordered. Only relevant
+ * for Collection properties.
+ *
+ * @param propertyPath
+ * @return
+ * true is the property should be ordered
+ */
+ public boolean isOrdered(String propertyPath);
+
+ /**
+ * Returns true if the elements from the given property should be unique.
+ * Only relevant for Colleciton properties.
+ *
+ * @param propertyPath
+ * @return
+ * true if the elements should be unique
+ */
+ public boolean isUnique(String propertyPath);
+
+ /**
+ * Returns true if the given property is Mandatory.
+ *
+ * @param propertyPath
+ * @return true if the property is mandatory
+ */
+ public boolean isMandatory(String propertyPath);
+
+ /**
+ * Returns true if the given property is editable.
+ *
+ * @param propertyPath
+ * @return true if the given property is editable.
+ */
+ public boolean isEditable(String propertyPath);
+
+ /**
+ * Returns true if the given property should be refreshed each time a
+ * change occurs in the property view. This may help when the IObservable
+ * doesn't catch some change events (For example, for some Ecore derived
+ * properties).
+ *
+ * @param propertyPath
+ * @return true if the refresh should be forced
+ */
+ public boolean forceRefresh(String propertyPath);
+
+ /**
+ * Sets the DataSource associated to this model element
+ *
+ * @param source
+ * The DataSource to associate to this model element
+ */
+ public void setDataSource(DataSource source);
+
+ /**
+ * @param propertyPath
+ * the propertyPath to lookup
+ * @return the default factory used to handle operations such as object
+ * creation or edition, or null if these operations are not supported.
+ * This factory will typically be used by Multiple value editors, to
+ * create or edit a single entry.
+ */
+ public ReferenceValueFactory getValueFactory(String propertyPath);
+
+ /**
+ * @param propertyPath
+ * @return The default value for the property
+ */
+ public Object getDefaultValue(String propertyPath);
+
+ /**
+ * Indicates if the widget should be use the direct creation.
+ * The direct edition will disable the possibility to browse
+ * existing elements when the "add" button is pressed.
+ *
+ * This is essentially relevant for containment references : this method
+ * should return false if the widget should only allow creation of new
+ * elements.
+ *
+ * @param propertyPath
+ * @return True if the widget should use the direct edition option for the given property
+ *
+ */
+ public boolean getDirectCreation(String propertyPath);
+
+ /**
+ * Disposes this ModelElement
+ * All created IObservable will be disposed
+ */
+ public void dispose();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElementFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElementFactory.java
new file mode 100644
index 00000000000..1c893600554
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/modelelement/ModelElementFactory.java
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * 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.modelelement;
+
+import org.eclipse.papyrus.properties.contexts.DataContextElement;
+
+/**
+ * An interface representing ModelElementFactories.
+ * ModelElementFactories are meant to be instantiated reflectively, thus should
+ * always provide a 0-arg constructor.
+ *
+ * @author Camille Letavernier
+ */
+public interface ModelElementFactory {
+
+ /**
+ * Creates a new ModelElement for given Object and DataContextElement
+ *
+ * @param sourceElement
+ * The Object for which we need to build a ModelElement. Note that this element
+ * comes directly from the Eclipse selection, and may need to be adapted to get
+ * the actual semantic object (e.g. sourceElement may be a GMF EditPart, and needs
+ * to be adapted to retrieve the EObject). The factory is responsible for resolving
+ * the semantic object in such a case.
+ * @param context
+ * The DataContextElement containing the properties that the Property View framework
+ * is susceptible to ask for.
+ * @return
+ * The ModelElement corresponding to the sourceElement
+ */
+ public ModelElement createFromSource(Object sourceElement, DataContextElement context);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/preferences/Preferences.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/preferences/Preferences.java
new file mode 100644
index 00000000000..82d10e9f3c9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/preferences/Preferences.java
@@ -0,0 +1,171 @@
+/*****************************************************************************
+ * 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.preferences;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.messages.Messages;
+import org.eclipse.papyrus.properties.runtime.ConfigurationConflict;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+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.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * The PreferencePage for the Papyrus Property View. Offers an UI to enable or disable
+ * property view contexts.
+ *
+ * @author Camille Letavernier
+ */
+public class Preferences extends PreferencePage implements IWorkbenchPreferencePage {
+
+ private boolean changeOccured = false;
+
+ public void init(IWorkbench workbench) {
+ //Nothing
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Composite self = new Composite(parent, SWT.NONE);
+ self.setLayout(new GridLayout(1, false));
+ self.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Label label = new Label(self, SWT.NONE);
+ label.setText(Messages.Preferences_Contexts);
+
+ final ConfigurationManager configurationManager = ConfigurationManager.instance;
+
+ contextState.init();
+
+ for(Context context : configurationManager.getContexts()) {
+ boolean applied = configurationManager.isApplied(context);
+ Button checkbox = new Button(self, SWT.CHECK);
+ checkbox.setText(getLabel(context));
+ checkbox.setSelection(applied);
+ final Context theContext = context;
+ contextState.setContextState(theContext, applied);
+
+ checkbox.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ contextState.setContextState(theContext, ((Button)e.widget).getSelection());
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ //Nothing
+ }
+
+ });
+
+ checkboxes.put(context, checkbox);
+ }
+
+ changeOccured = false;
+ return null;
+ }
+
+ @Override
+ public boolean performOk() {
+ return contextState.saveContext() && super.performOk();
+ }
+
+ @Override
+ public void performApply() {
+ contextState.saveContext();
+ }
+
+ @Override
+ public void performDefaults() {
+ for(Context context : ConfigurationManager.instance.getContexts()) {
+ boolean applied = ConfigurationManager.instance.isPlugin(context);
+ Button checkbox = checkboxes.get(context);
+ if(checkbox != null) {
+ checkbox.setSelection(applied);
+ }
+
+ contextState.setContextState(context, applied);
+ }
+ }
+
+ private String getLabel(Context context) {
+ return context.getName() + " (" + (ConfigurationManager.instance.isPlugin(context) ? Messages.Preferences_Plugin : Messages.Preferences_Custom) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private final ContextState contextState = new ContextState();
+
+ private Map<Context, Button> checkboxes = new HashMap<Context, Button>();
+
+ private class ContextState {
+
+ public ContextState() {
+ }
+
+ public void init() {
+ contexts.clear();
+ }
+
+ public void setContextState(Context context, boolean applied) {
+ contexts.put(context, applied);
+ changeOccured = true;
+ }
+
+ public boolean saveContext() {
+ for(Entry<Context, Boolean> entry : contexts.entrySet()) {
+ if(entry.getValue()) {
+ ConfigurationManager.instance.enableContext(entry.getKey(), false);
+ } else {
+ ConfigurationManager.instance.disableContext(entry.getKey(), false);
+ }
+ }
+
+ ConfigurationManager.instance.update();
+
+ Collection<ConfigurationConflict> conflicts = ConfigurationManager.instance.checkConflicts();
+
+ if(changeOccured && !conflicts.isEmpty()) {
+ String errorMessage = Messages.Preferences_ConflictWarning1;
+ for(ConfigurationConflict conflict : conflicts) {
+ errorMessage += conflict.toString() + "\n"; //$NON-NLS-1$
+ }
+ errorMessage += Messages.Preferences_ConflictWarning2;
+
+ MessageDialog dialog = new MessageDialog(getShell(), Messages.Preferences_ConflictWarningTitle, null, errorMessage, MessageDialog.WARNING, new String[]{ IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 1);
+ int result = dialog.open();
+ if(result != 0) {
+ return false;
+ }
+ }
+
+ changeOccured = false;
+ return true;
+ }
+
+ private Map<Context, Boolean> contexts = new HashMap<Context, Boolean>();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/ContainerContentProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/ContainerContentProvider.java
new file mode 100644
index 00000000000..914f6292d9e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/ContainerContentProvider.java
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * 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.providers;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.modelexplorer.widgets.GraphicalModelExplorerBasedContentProvider;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+
+
+
+public class ContainerContentProvider extends GraphicalModelExplorerBasedContentProvider {
+
+ protected EClass type;
+
+ protected Object input;
+
+ public ContainerContentProvider(EClass wantedType) {
+ super(null, getHistoryId(wantedType));
+ this.type = wantedType;
+ }
+
+ private static String getHistoryId(EClass type) {
+ return "history_createIn_" + type.getEPackage().getName() + ":" + type.getName(); //$NON-NLS-1$ //$NON-NLS-2$
+
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ this.input = newInput;
+ if(newInput instanceof EObject) {
+ this.type = ((EObject)newInput).eClass();
+ }
+ }
+
+ @Override
+ public boolean isValidValue(Object value) {
+ Object adaptedValue = getAdaptedValue(value);
+ if(adaptedValue instanceof EObject) {
+ //We cannot create objects in a read-only object
+ if(EMFHelper.isReadOnly((EObject)adaptedValue)) {
+ return false;
+ }
+
+ //We need at least one valid containment reference to store this
+ //type of object
+ for(EReference reference : ((EObject)adaptedValue).eClass().getEAllReferences()) {
+ if(reference.isContainment() && EMFHelper.isSubclass(this.type, reference.getEReferenceType())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/CreateInFeatureContentProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/CreateInFeatureContentProvider.java
new file mode 100644
index 00000000000..36ce36943fd
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/CreateInFeatureContentProvider.java
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ * 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.providers;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+
+public interface CreateInFeatureContentProvider extends IStaticContentProvider, IStructuredContentProvider {
+
+ /**
+ * Sets the type of feature we're looking for
+ *
+ * @param type
+ */
+ public void setType(EClass type);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectFilteredLabelProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectFilteredLabelProvider.java
new file mode 100644
index 00000000000..1acc1fa20b8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectFilteredLabelProvider.java
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * 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.providers;
+
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+
+public class EMFObjectFilteredLabelProvider extends EMFObjectLabelProvider implements IFilteredLabelProvider {
+
+ public boolean accept(IStructuredSelection selection) {
+ if(selection.size() == 1) {
+ return accept(selection.getFirstElement());
+ }
+
+ Iterator<?> iterator = selection.iterator();
+ while(iterator.hasNext()) {
+ Object element = iterator.next();
+ if(!accept(element)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected boolean accept(Object element) {
+ if(element instanceof EObject) {
+ return true;
+ }
+
+ if(element instanceof IAdaptable) {
+ return ((IAdaptable)element).getAdapter(EObject.class) instanceof EObject;
+ }
+
+ return false;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectLabelProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectLabelProvider.java
new file mode 100644
index 00000000000..b5e30b25148
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EMFObjectLabelProvider.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Added support for enum literals
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Implementation of IDetailLabelProvider
+ *******************************************************************************/
+package org.eclipse.papyrus.properties.providers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+import org.eclipse.papyrus.widgets.providers.IDetailLabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * This class handles title label for tabbed properties.
+ *
+ * @author Jerome Benois
+ */
+public class EMFObjectLabelProvider extends AdapterFactoryLabelProvider implements IDetailLabelProvider {
+
+ /** item provider class */
+ private static final Class<?> IItemLabelProviderClass = IItemLabelProvider.class;
+
+ /** list of adapter factories, identified by their Ids */
+ private static Map<String, AdapterFactory> factories = new HashMap<String, AdapterFactory>();
+
+ /** emf item provider facctories */
+ private static final String EXT_FACTORIES = "org.eclipse.emf.edit.itemProviderAdapterFactories"; //$NON-NLS-1$
+
+ /**
+ * Creates a new EMFObjectLabelProvider.
+ */
+ public EMFObjectLabelProvider() {
+ super(new ReflectiveItemProviderAdapterFactory());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getText(Object element) {
+ String title = ""; //$NON-NLS-1$
+ if(element instanceof Enumerator) {
+ return ((Enumerator)element).getName();
+ }
+ EObject eObject = getModel(element);
+ IItemLabelProvider itemLabelProvider = getItemLabelProvider(eObject);
+ if(itemLabelProvider != null) {
+ title = itemLabelProvider.getText(eObject);
+ }
+
+ if("".equals(title)) { //$NON-NLS-1$
+ title = super.getText(eObject);
+ }
+
+ return title;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Image getImage(Object element) {
+ Image result = null;
+ EObject eObject = getModel(element);
+ IItemLabelProvider itemLabelProvider = getItemLabelProvider(eObject);
+ if(itemLabelProvider != null) {
+ result = getImageFromObject(itemLabelProvider.getImage(eObject));
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the EObject from the given element
+ *
+ * @param element
+ * the element to adapt
+ * @return the EObject from the given element
+ */
+ protected EObject getModel(Object element) {
+ if(element instanceof EObject) {
+ return (EObject)element;
+ }
+
+ EObject eObject = null;
+ if(element != null && element instanceof StructuredSelection) {
+ StructuredSelection selection = (StructuredSelection)element;
+ Object o = selection.getFirstElement();
+ if(o instanceof EObject) {
+ eObject = (EObject)o;
+ } else if(o instanceof IGraphicalEditPart) {
+ IGraphicalEditPart editPart = (IGraphicalEditPart)o;
+ eObject = editPart.resolveSemanticElement();
+ } // try to adapt into EObject
+ else if(o instanceof IAdaptable) {
+ eObject = (EObject)((IAdaptable)o).getAdapter(EObject.class);
+ }
+
+ }
+ return eObject;
+ }
+
+ /**
+ * Returns the item provider for the given object
+ *
+ * @param eObject
+ * the object to display
+ * @return the item label provider for the given eobject
+ */
+ private IItemLabelProvider getItemLabelProvider(EObject eObject) {
+ IItemLabelProvider itemLabelProvider = null;
+ if(eObject != null) {
+ AdapterFactory adapterFactory = getEditFactory(eObject);
+ if(adapterFactory != null) {
+ return (IItemLabelProvider)adapterFactory.adapt(eObject, IItemLabelProviderClass);
+ }
+ }
+ return itemLabelProvider;
+ }
+
+ /**
+ * Gets the edit factory.
+ *
+ * @param eobject
+ * the eobject
+ *
+ * @return the edits the factory
+ */
+ public static AdapterFactory getEditFactory(EObject eobject) {
+ String uri = eobject.eClass().getEPackage().getNsURI();
+ return getFactory(uri);
+ }
+
+ /**
+ * Gets the factory from uri.
+ *
+ * @param uri
+ * the uri
+ *
+ * @return the factory
+ */
+ public static AdapterFactory getFactory(String uri) {
+ AdapterFactory factory = factories.get(uri);
+ if(factory == null) {
+ IConfigurationElement[] extensions = Platform.getExtensionRegistry().getConfigurationElementsFor(EXT_FACTORIES);
+ for(IConfigurationElement e : extensions) {
+ if(uri.equals(e.getAttribute("uri"))) { //$NON-NLS-1$
+ try {
+ factory = (AdapterFactory)e.createExecutableExtension("class"); //$NON-NLS-1$
+ if(factory != null) {
+ factories.put(uri, factory);
+ }
+ } catch (CoreException e1) {
+ // do nothing
+ }
+ }
+ }
+ }
+ return factory;
+ }
+
+ public String getDetail(Object object) {
+ object = getModel(object);
+ return getText(object) + " - " + getQualifiedClassName(object); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the qualified Class name of the given EObject, or an
+ * empty String if the object is not an EObject
+ *
+ * @param object
+ * @return The qualified name of this object's class, or an empty
+ * String if the object is not an EObject
+ */
+ protected String getQualifiedClassName(Object object) {
+ if(object instanceof EObject) {
+ EObject eObject = (EObject)object;
+ EClass eClass = eObject.eClass();
+ return EMFHelper.getQualifiedName(eClass, "::"); //$NON-NLS-1$
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreEnumeratorContentProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreEnumeratorContentProvider.java
new file mode 100644
index 00000000000..54da02e895a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreEnumeratorContentProvider.java
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ * 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.providers;
+
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+/**
+ * An IStaticContentProvider for EMF enumerators.
+ *
+ * @author Camille Letavernier
+ */
+public class EcoreEnumeratorContentProvider implements IStaticContentProvider {
+
+ /**
+ * The feature representing the Enumerator for this ContentProvider
+ */
+ protected EStructuralFeature feature;
+
+ /**
+ * Constructs an EcoreEnumerator for the given Structural Feature
+ *
+ * @param feature
+ */
+ public EcoreEnumeratorContentProvider(EStructuralFeature feature) {
+ this.feature = feature;
+ }
+
+ public void dispose() {
+ //Nothing here
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ //Nothing here
+ }
+
+ public Object[] getElements() {
+ EClassifier type = feature.getEType();
+ EEnum enumerated = (EEnum)type;
+ EEnumLiteral[] literals = enumerated.getELiterals().toArray(new EEnumLiteral[0]);
+ Enumerator[] values = new Enumerator[literals.length];
+
+ int i = 0;
+ for(EEnumLiteral literal : literals) {
+ Enumerator value = literal.getInstance();
+ values[i++] = value;
+ }
+
+ return values;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreReferenceContentProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreReferenceContentProvider.java
new file mode 100644
index 00000000000..c814eaed095
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EcoreReferenceContentProvider.java
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * 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.providers;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.widgets.providers.AbstractFilteredContentProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+
+/**
+ * An IStaticContentProvider for EMF references.
+ *
+ * @author Camille Letavernier
+ */
+public class EcoreReferenceContentProvider extends AbstractFilteredContentProvider implements IStaticContentProvider {
+
+ private EObject eObject;
+
+ private EStructuralFeature feature;
+
+ private AdapterFactory factory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param feature
+ * The feature representing the reference for which we want to retrieve possible values
+ * @param eObject
+ */
+ public EcoreReferenceContentProvider(EStructuralFeature feature, EObject eObject) {
+ this.feature = feature;
+ this.eObject = eObject;
+ }
+
+ public Object[] getElements() {
+ if(eObject == null || feature == null) {
+ return new Object[0];
+ }
+
+ EClass eClass = eObject.eClass();
+ if(eClass == null) {
+ Activator.log.debug("problems during initialization, looking for availables values");//$NON-NLS-1$
+ return new Object[0];
+ }
+
+ if(!(feature instanceof EReference)) {
+ Activator.log.debug("feature is not a reference, looking for availables values: " + feature);//$NON-NLS-1$
+ return new Object[0];
+ }
+
+ IItemPropertySource itemPropertySource = (IItemPropertySource)factory.adapt(eObject, IItemPropertySource.class);
+ if(itemPropertySource == null) {
+ Activator.log.debug("impossible to find item Property source for " + eObject);//$NON-NLS-1$
+ return new Object[0];
+ }
+ IItemPropertyDescriptor itemPropertyDescriptor = itemPropertySource.getPropertyDescriptor(eObject, feature);
+ if(itemPropertyDescriptor == null) {
+ Activator.log.debug("impossible to find item Property descriptor for " + eObject + " and " + feature);//$NON-NLS-1$ //$NON-NLS-2$
+ return new Object[0];
+ }
+
+ Collection<?> values = itemPropertyDescriptor.getChoiceOfValues(eObject);
+
+ values.remove(null); //Removes null values from the collection
+
+ return values.toArray();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedComboViewer.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedComboViewer.java
new file mode 100644
index 00000000000..9195ae7d02f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedComboViewer.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * 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.providers;
+
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+
+public class EncapsulatedComboViewer extends ComboViewer {
+
+ public EncapsulatedComboViewer(ComboViewer viewer) {
+ super(viewer.getCCombo());
+ if(viewer.getContentProvider() != null) {
+ super.setContentProvider(viewer.getContentProvider());
+ }
+ if(viewer.getInput() != null) {
+ super.setInput(viewer.getInput());
+ }
+ if(viewer.getLabelProvider() != null) {
+ super.setLabelProvider(viewer.getLabelProvider());
+ }
+ if(viewer.getFilters() != null) {
+ super.setFilters(viewer.getFilters());
+ }
+ }
+
+ @Override
+ public void setFilters(ViewerFilter[] filters) {
+ for(ViewerFilter filter : filters) {
+ addFilter(filter);
+ }
+ }
+
+ @Override
+ public void addFilter(ViewerFilter filter) {
+ super.addFilter(new EncapsulatedViewerFilter(filter));
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedViewerFilter.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedViewerFilter.java
new file mode 100644
index 00000000000..f296c7185c7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/EncapsulatedViewerFilter.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * 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.providers;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.widgets.providers.UnchangedObject;
+import org.eclipse.papyrus.widgets.providers.UnsetObject;
+
+
+public class EncapsulatedViewerFilter extends ViewerFilter {
+
+ private ViewerFilter viewerFilter;
+
+ public EncapsulatedViewerFilter(ViewerFilter encapsulated) {
+ this.viewerFilter = encapsulated;
+ }
+
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if(element == UnsetObject.instance || element == UnchangedObject.instance) {
+ return true;
+ }
+ return viewerFilter.select(viewer, parentElement, element);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/FeatureContentProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/FeatureContentProvider.java
new file mode 100644
index 00000000000..56492a2fe03
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/FeatureContentProvider.java
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * 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.providers;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+
+public class FeatureContentProvider implements CreateInFeatureContentProvider {
+
+ private EClass type;
+
+ // private Viewer viewer;
+
+ private Object input;
+
+ public FeatureContentProvider(EClass type) {
+ this.type = type;
+ }
+
+ public void setType(EClass type) {
+ this.type = type;
+ }
+
+ public void dispose() {
+ // Nothing
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ // this.viewer = viewer;
+ this.input = newInput;
+ }
+
+ public Object[] getElements() {
+ return getElements(input);
+ }
+
+ public Object[] getElements(Object inputElement) {
+ EObject inputEObject = EMFHelper.getEObject(input);
+ if(inputEObject == null) {
+ return new Object[0];
+ }
+ List<Object> elements = new LinkedList<Object>();
+ for(EReference reference : inputEObject.eClass().getEAllReferences()) {
+ if(reference.isContainment()) {
+ if(EMFHelper.isSubclass(type, reference.getEReferenceType())) {
+ elements.add(reference);
+ }
+ }
+ }
+ return elements.toArray();
+ }
+} \ No newline at end of file
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/IFilteredLabelProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/IFilteredLabelProvider.java
new file mode 100644
index 00000000000..4ccfe7cccde
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/IFilteredLabelProvider.java
@@ -0,0 +1,21 @@
+/*****************************************************************************
+ * 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.providers;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+
+public interface IFilteredLabelProvider extends ILabelProvider {
+
+ public boolean accept(IStructuredSelection selection);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/SelectionLabelProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/SelectionLabelProvider.java
new file mode 100644
index 00000000000..defaeaf282b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/SelectionLabelProvider.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * 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.providers;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A class for providing labels for a selected element.
+ * This label provider dispatchs the calls to the label providers
+ * registered through an extension point, according to the given selection
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class SelectionLabelProvider extends LabelProvider {
+
+ public static final String EXTENSION_ID = "org.eclipse.papyrus.properties.labelprovider"; //$NON-NLS-1$
+
+ public static final String LABEL_PROVIDER_PROPERTY = "labelProvider"; //$NON-NLS-1$
+
+ public static final String PRIORITY_PROPERTY = "priority"; //$NON-NLS-1$
+
+ protected final TreeMap<Integer, Collection<IFilteredLabelProvider>> labelProviders = new TreeMap<Integer, Collection<IFilteredLabelProvider>>();
+
+ public SelectionLabelProvider() {
+ readExtensionPoint();
+ }
+
+ protected void readExtensionPoint() {
+ IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_ID);
+
+ for(IConfigurationElement e : config) {
+ try {
+ final IFilteredLabelProvider provider = (IFilteredLabelProvider)e.createExecutableExtension(LABEL_PROVIDER_PROPERTY);
+ final int priority = Integer.parseInt(e.getAttribute(PRIORITY_PROPERTY));
+ getLabelProviders(priority).add(provider);
+ } catch (Exception ex) {
+ Activator.log.error("Cannot load the label provider : " + e.getAttribute(LABEL_PROVIDER_PROPERTY), ex);
+ }
+ }
+ }
+
+ protected Collection<IFilteredLabelProvider> getLabelProviders(int priority) {
+ if(!labelProviders.containsKey(priority)) {
+ labelProviders.put(priority, new LinkedList<IFilteredLabelProvider>());
+ }
+ return labelProviders.get(priority);
+ }
+
+ @Override
+ public String getText(Object element) {
+ return getLabelProvider(element).getText(element);
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return getLabelProvider(element).getImage(element);
+ }
+
+ protected ILabelProvider getLabelProvider(Object element) {
+ if(element instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection)element;
+ for(Collection<IFilteredLabelProvider> providers : labelProviders.values()) {
+ for(IFilteredLabelProvider labelProvider : providers) {
+ if(labelProvider.accept(selection)) {
+ return labelProvider;
+ }
+ }
+ }
+ }
+
+ return new LabelProvider(); //Default
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProvider.java
new file mode 100644
index 00000000000..0ac0704cffb
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProvider.java
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * 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.providers;
+
+import org.eclipse.papyrus.properties.widgets.MaskProvider;
+
+/**
+ * Given the way the XWT files are parsed, the MaskProvider is passed to its
+ * parent before being fully initialized.
+ *
+ * This interface enables a MaskProvider to notify its parent when it is ready,
+ * so that the parent is forced to wait for its MaskProvider to be ready before
+ * it can call any method on it.
+ *
+ * @author Camille Letavernier
+ */
+public interface XWTCompliantMaskProvider extends MaskProvider {
+
+ public void addMaskProviderListener(XWTCompliantMaskProviderListener listener);
+
+ public void removeMaskProviderListener(XWTCompliantMaskProviderListener listener);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProviderListener.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProviderListener.java
new file mode 100644
index 00000000000..a2b86c927f0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/providers/XWTCompliantMaskProviderListener.java
@@ -0,0 +1,23 @@
+/*****************************************************************************
+ * 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.providers;
+
+/**
+ *
+ * @author Camille Letavernier
+ *
+ * @see XWTCompliantMaskProvider
+ */
+public interface XWTCompliantMaskProviderListener {
+
+ public void notifyReady(XWTCompliantMaskProvider provider);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationConflict.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationConflict.java
new file mode 100644
index 00000000000..e05c896e4bf
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationConflict.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.contexts.Context;
+
+/**
+ * Represents a conflict in the applied Property view configurations
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class ConfigurationConflict {
+
+ /**
+ * The ID of the section being in conflict
+ */
+ public String sectionID;
+
+ /**
+ * The list of contexts being in conflict
+ */
+ public List<Context> conflictingContexts;
+
+ /**
+ * Constructor.
+ *
+ * Creates a conflict descriptor for the given section ID
+ *
+ * @param sectionID
+ * The ID of the section being in conflict
+ */
+ public ConfigurationConflict(String sectionID) {
+ conflictingContexts = new LinkedList<Context>();
+ this.sectionID = sectionID;
+ }
+
+ /**
+ * Adds a conflicting context
+ *
+ * @param context
+ */
+ public void addContext(Context context) {
+ conflictingContexts.add(context);
+ }
+
+ @Override
+ public String toString() {
+ String result = sectionID + " : "; //$NON-NLS-1$
+ for(Context context : conflictingContexts) {
+ result += context.getName() + ", "; //$NON-NLS-1$
+ }
+ return result.substring(0, result.length() - 2);
+ }
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationManager.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationManager.java
new file mode 100644
index 00000000000..9dd0228bc05
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConfigurationManager.java
@@ -0,0 +1,672 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+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.papyrus.properties.Activator;
+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.Section;
+import org.eclipse.papyrus.properties.contexts.Tab;
+import org.eclipse.papyrus.properties.environment.CompositeWidgetType;
+import org.eclipse.papyrus.properties.environment.Environment;
+import org.eclipse.papyrus.properties.environment.EnvironmentPackage;
+import org.eclipse.papyrus.properties.environment.LayoutType;
+import org.eclipse.papyrus.properties.environment.Namespace;
+import org.eclipse.papyrus.properties.environment.PropertyEditorType;
+import org.eclipse.papyrus.properties.environment.StandardWidgetType;
+import org.eclipse.papyrus.properties.environment.Type;
+import org.eclipse.papyrus.properties.environment.WidgetType;
+import org.eclipse.papyrus.properties.extensions.ContextExtensionPoint;
+import org.eclipse.papyrus.properties.extensions.EnvironmentExtensionPoint;
+import org.eclipse.papyrus.properties.root.PropertiesRoot;
+import org.eclipse.papyrus.properties.root.RootFactory;
+import org.eclipse.papyrus.properties.runtime.preferences.ContextDescriptor;
+import org.eclipse.papyrus.properties.runtime.preferences.Preferences;
+import org.eclipse.papyrus.properties.runtime.preferences.PreferencesFactory;
+import org.eclipse.papyrus.properties.util.EMFHelper;
+import org.eclipse.papyrus.properties.util.Util;
+
+/**
+ * Central class of the Property View framework. It lists the available environments and contexts,
+ * and is responsible for Enabling or Disabling contexts programmatically.
+ *
+ * All {@link Context}s should have unique names.
+ *
+ * @see ContextExtensionPoint
+ * @see EnvironmentExtensionPoint
+ * @see Preferences
+ * @see ConfigurationManager#instance
+ *
+ * @author Camille Letavernier
+ */
+public class ConfigurationManager {
+
+ private final Preferences preferences;
+
+ private final PropertiesRoot root;
+
+ private ResourceSet resourceSet = new ResourceSetImpl();
+
+ private boolean started = false;
+
+ /**
+ * All contexts (Whether they are applied or not)
+ */
+ private Map<URI, Context> contexts = new LinkedHashMap<URI, Context>();
+
+ private Set<Context> enabledContexts = new LinkedHashSet<Context>();
+
+ /**
+ * The global constraint engine
+ */
+ public ConstraintEngine constraintEngine;
+
+ /**
+ * The singleton instance
+ */
+ public final static ConfigurationManager instance = new ConfigurationManager();
+
+ private ConfigurationManager() {
+ constraintEngine = new DefaultConstraintEngine();
+ enabledContexts = new HashSet<Context>();
+
+ root = RootFactory.eINSTANCE.createPropertiesRoot();
+
+ preferences = loadPreferences();
+ }
+
+ private void start() {
+ if(started) {
+ return;
+ }
+
+ started = true;
+
+ new ContextExtensionPoint();
+ new EnvironmentExtensionPoint();
+
+ loadCustomContexts();
+ }
+
+ private EObject loadEMFModel(URI sourceURI) throws IOException {
+ return EMFHelper.loadEMFModel(resourceSet, sourceURI);
+ }
+
+ private Preferences loadPreferences() {
+ IPath path = Activator.getDefault().getPreferencesPath();
+ String preferencesPath = path.toString() + "/preferences.xmi"; //$NON-NLS-1$
+ URI preferencesURI = URI.createFileURI(preferencesPath);
+
+ try {
+ EObject model = loadEMFModel(preferencesURI);
+ if(model != null && model instanceof Preferences) {
+ return (Preferences)model;
+ }
+ } catch (Exception ex) {
+ //File not found : we ignore the exception //TODO : improve the exceptions (FileNotFound is not the only one that can occur)
+ }
+
+ //If we're here, then the preferences.xmi doesn't exist or isn't valid : we create it
+
+ return createPreferences(preferencesURI);
+ }
+
+ private Preferences createPreferences(URI preferencesURI) {
+ Preferences preferencesStore = PreferencesFactory.eINSTANCE.createPreferences();
+
+ Resource resource = resourceSet.createResource(preferencesURI);
+ resource.getContents().add(preferencesStore);
+ saveModel(preferencesStore);
+
+ return preferencesStore;
+ }
+
+ private void loadCustomContexts() {
+ IPath path = Activator.getDefault().getPreferencesPath();
+ File preferencesDirectory = path.toFile();
+ for(File contextDirectory : preferencesDirectory.listFiles()) {
+ try {
+ if(contextDirectory.isDirectory()) {
+ loadCustomContext(contextDirectory);
+ }
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ }
+ }
+ }
+
+ /**
+ * Refresh the Context represented by the given File. The File should be
+ * a valid Context model. This method should be called when a model is edited
+ * at runtime.
+ *
+ * @param contextFile
+ * A File containing a valid Context model
+ */
+ public void refresh(File contextFile) {
+ URI contextURI = URI.createFileURI(contextFile.getAbsolutePath());
+
+ //TODO : get the right URI from the context file :
+ //ppe:/context/<plugin>/<path> if it is in the workspace,
+ //ppe:/context/<preferences>/<path> if it is registered through preferences
+
+ if(contexts.containsKey(contextURI)) {
+ //Unloads the previous objects corresponding to this context
+ Context previousContext = contexts.get(contextURI);
+ enabledContexts.remove(previousContext);
+ previousContext.eResource().unload();
+
+ //Adds the new object corresponding to this context
+ try {
+ addContext(contextURI);
+ constraintEngine.contextChanged();
+ } catch (IOException ex) {
+ Activator.log.error(ex);
+ }
+ }
+ }
+
+ private void loadCustomContext(File contextDirectory) throws IOException {
+ String contextPath = contextDirectory.getPath() + "/" + contextDirectory.getName() + ".ctx"; //$NON-NLS-1$ //$NON-NLS-2$
+ URI contextURI = URI.createFileURI(contextPath);
+ EObject model = loadEMFModel(contextURI);
+ if(model instanceof Context) {
+ Context context = (Context)model;
+ addContext(context, isApplied(context));
+ }
+ }
+
+ /**
+ * Tests if a Context is enabled.
+ *
+ * @param context
+ * @return
+ * true if the given context is enabled.
+ *
+ * @see Preferences
+ */
+ public boolean isApplied(Context context) {
+ return findDescriptor(context).isApplied();
+ }
+
+ /**
+ * Retrieves the ContextDescriptor associated to the specified context.
+ * If a matching descriptor cannot be found, a new Descriptor is created
+ * in the preferences.
+ *
+ * @param context
+ * @return
+ */
+ private ContextDescriptor findDescriptor(Context context) {
+ if(context.getName() == null || context.getName().equals("")) { //$NON-NLS-1$
+ return null;
+ }
+
+ for(ContextDescriptor descriptor : preferences.getContexts()) {
+ if(descriptor.getName().equals(context.getName())) {
+ return descriptor;
+ }
+ }
+ //The descriptor hasn't been found : We create it
+
+ ContextDescriptor descriptor = PreferencesFactory.eINSTANCE.createContextDescriptor();
+ descriptor.setName(context.getName());
+ preferences.getContexts().add(descriptor);
+ savePreferences();
+ return descriptor;
+ }
+
+ /**
+ * Adds a context via its URI. The URI should represent a valid Context model.
+ * The model is loaded in the ConfigurationManager's resourceSet.
+ *
+ * @param uri
+ * The context's URI
+ * @throws IOException
+ * If the model behind this URI is not a valid Context
+ */
+ public void addContext(URI uri) throws IOException {
+ Context context = (Context)loadEMFModel(uri);
+ if(context != null) {
+ addContext(context, isApplied(context));
+ }
+ }
+
+ /**
+ * Programmatically register a new context to this ConfigurationManager.
+ * Most of the time, new contexts should be registered through {@link ContextExtensionPoint}.
+ * However, you can still call this method when creating a Context at runtime, programmatically
+ * (Wizards, ...)
+ * All {@link Context} should have unique names
+ *
+ * @param context
+ * The new context to register
+ * @param apply
+ * Whether the context should be enabled or not
+ *
+ * @see ConfigurationManager#addContext(URI)
+ */
+ public void addContext(Context context, boolean apply) {
+ contexts.put(context.eResource().getURI(), context);
+ if(apply) {
+ enableContext(context, true);
+ } else {
+ disableContext(context, true);
+ }
+ }
+
+ /**
+ * @return the list of <strong>enabled</strong> contexts
+ */
+ public Collection<Context> getEnabledContexts() {
+ return enabledContexts;
+ }
+
+ /**
+ * Disable a Context.
+ *
+ * @param context
+ * The Context to disable
+ * @param update
+ * If true, the constraint engine will be updated to handle the
+ * modification
+ * If false, you should call manually {@link #update()} to refresh
+ * the constraint engine
+ * @see Preferences
+ * @see #enableContext(Context, boolean)
+ */
+ public void disableContext(Context context, boolean update) {
+ update = enabledContexts.remove(context) && update;
+
+ //Update the preferences
+ ContextDescriptor descriptor = findDescriptor(context);
+ if(descriptor.isApplied()) {
+ descriptor.setApplied(false);
+ savePreferences();
+ }
+
+ if(update) {
+ //Update the Engine
+ update();
+ }
+ }
+
+ /**
+ * Enables a Context
+ *
+ * @param context
+ * The Context to enable
+ * @param update
+ * If true, the constraint engine will be updated to handle the
+ * modification
+ * If false, you should call manually {@link #update()} to refresh
+ * the constraint engine
+ *
+ * @see #disableContext(Context, boolean)
+ */
+ public void enableContext(Context context, boolean update) {
+
+ enabledContexts.add(context);
+ //root.getContexts().add(context);
+
+ //Update the preferences
+ ContextDescriptor descriptor = findDescriptor(context);
+ if(!descriptor.isApplied()) {
+ descriptor.setApplied(true);
+ savePreferences();
+ }
+
+ if(update) {
+ //Update the Engine
+ constraintEngine.addContext(context);
+ }
+ }
+
+ /**
+ * Tests if a Context is a plugin context. plugin contexts
+ * are registered through {@link ContextExtensionPoint} and are
+ * read-only.
+ *
+ * @param context
+ * @return
+ * True if the context comes from a plugin, and is thus read-only
+ */
+ public boolean isPlugin(Context context) {
+ URI uri = context.eResource().getURI();
+ boolean result = !(uri.isFile() || uri.isPlatformResource());
+ return result;
+ }
+
+ /**
+ * Loads a Context from the given URI. The model is loaded in the {@link ConfigurationManager}'s resourceSet
+ *
+ * @param uri
+ * The URI from which the Context is loaded
+ * @return
+ * The loaded context
+ * @throws IOException
+ * If the URI doesn't represent a valid Context model
+ */
+ public Context getContext(URI uri) throws IOException {
+ return (Context)loadEMFModel(uri);
+ }
+
+ private void addEnvironment(Environment environment) {
+ root.getEnvironments().add(environment);
+ }
+
+ /**
+ * Adds a new Environment from the given URI.
+ *
+ * @param uri
+ * The URI from which the Environment is retrieved.
+ * @throws IOException
+ * if the URI doesn't represent a valid Environment model
+ */
+ public void addEnvironment(URI uri) throws IOException {
+ Environment environment = (Environment)loadEMFModel(uri);
+ addEnvironment(environment);
+ }
+
+ /**
+ * @return
+ * The PropertiesRoot for the Property view framework. The PropertiesRoot contains
+ * all registered Environments and Contexts (Whether they are enabled or disabled)
+ */
+ public PropertiesRoot getPropertiesRoot() {
+ return root;
+ }
+
+ /**
+ * Returns the context from the given context name
+ *
+ * @param contextName
+ * The name of the context to retrieve
+ * @return
+ * The context corresponding to the given name
+ */
+ public Context getContext(String contextName) {
+ for(Context context : getContexts()) {
+ if(context.getName().equals(contextName)) {
+ return context;
+ }
+ }
+ return null;
+ }
+
+ private void savePreferences() {
+ saveModel(preferences);
+ }
+
+ private void saveModel(EObject eObject) {
+ try {
+ eObject.eResource().save(Collections.EMPTY_MAP);
+ } catch (IOException ex) {
+ Activator.log.error(ex);
+ }
+ }
+
+ /**
+ * Returns all the known contexts, whether they are applied or not.
+ * To get only applied contexts, see {@link #getEnabledContexts()}
+ *
+ * @return All known contexts
+ *
+ * @see PropertiesRoot#getContexts()
+ */
+ public Collection<Context> getContexts() {
+ return contexts.values();
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends WidgetType> T getDefaultWidget(int featureID, Class<T> theClass, String widgetName, String namespacePrefix) {
+ EStructuralFeature feature = EnvironmentPackage.Literals.ENVIRONMENT.getEStructuralFeature(featureID);
+ for(Environment environment : root.getEnvironments()) {
+ T widget = findWidgetTypeByClassName((EList<T>)environment.eGet(feature), widgetName, namespacePrefix);
+ if(widget != null) {
+ return widget;
+ }
+ }
+ return null;
+ }
+
+
+ private <T extends WidgetType> T findWidgetTypeByClassName(Collection<T> types, String className, String namespacePrefix) {
+ for(T widgetType : types) {
+ if(widgetType.getWidgetClass().equals(className) && Util.namespaceEqualsByName(widgetType.getNamespace(), namespacePrefix)) {
+ return widgetType;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the default implementation of CompositeWidgetType
+ */
+ public CompositeWidgetType getDefaultCompositeType() {
+ return getDefaultWidget(EnvironmentPackage.ENVIRONMENT__COMPOSITE_WIDGET_TYPES, CompositeWidgetType.class, "Composite", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * @return the default implementation of LayoutType
+ */
+ public LayoutType getDefaultLayoutType() {
+ return getDefaultWidget(EnvironmentPackage.ENVIRONMENT__LAYOUT_TYPES, LayoutType.class, "PropertiesLayout", "ppel"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * @return the default implementation of StandardWidgetType
+ */
+ public StandardWidgetType getDefaultWidgetType() {
+ return getDefaultWidget(EnvironmentPackage.ENVIRONMENT__WIDGET_TYPES, StandardWidgetType.class, "Label", ""); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * @param propertyType
+ * @param multiple
+ * @return the default implementation of PropertyEditorType for the given property Type
+ * and multiplicity
+ */
+ public PropertyEditorType getDefaultEditorType(Type propertyType, boolean multiple) {
+ String propertyEditorName = null;
+ switch(propertyType) {
+ case BOOLEAN:
+ propertyEditorName = multiple ? "MultiBoolean" : "BooleanRadio"; //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ case ENUMERATION:
+ propertyEditorName = multiple ? "MultiEnum" : "EnumCombo"; //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ case INTEGER:
+ propertyEditorName = multiple ? "MultiInteger" : "IntegerEditor"; //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ case REFERENCE:
+ propertyEditorName = multiple ? "MultiReference" : "ReferenceDialog"; //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ case STRING:
+ propertyEditorName = multiple ? "MultiString" : "StringEditor"; //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ }
+
+ if(propertyEditorName == null) {
+ return null;
+ }
+
+ return getDefaultWidget(EnvironmentPackage.ENVIRONMENT__PROPERTY_EDITOR_TYPES, PropertyEditorType.class, propertyEditorName, "ppe"); //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the default XWT namespaces
+ *
+ * @return the default XWT namespaces
+ */
+ public Set<Namespace> getBaseNamespaces() {
+ Set<Namespace> result = new HashSet<Namespace>();
+ result.add(getNamespaceByName("")); //$NON-NLS-1$
+ result.add(getNamespaceByName("x")); //$NON-NLS-1$
+ result.add(getNamespaceByName("j")); //$NON-NLS-1$
+ return result;
+ }
+
+ /**
+ * @param name
+ * @return
+ * The namespace corresponding to the given name
+ */
+ public Namespace getNamespaceByName(String name) {
+ for(Environment environment : root.getEnvironments()) {
+ for(Namespace namespace : environment.getNamespaces()) {
+ if(Util.namespaceEqualsByName(namespace, name)) {
+ return namespace;
+ }
+ }
+ }
+ Activator.log.warn("Cannot find a registered namespace for '" + name + "'"); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+
+ /**
+ * @param property
+ * @return
+ * the default PropertyEditorType for the given Property
+ */
+ public PropertyEditorType getDefaultEditorType(Property property) {
+ return getDefaultEditorType(property.getType(), property.getMultiplicity() != 1);
+ }
+
+ /**
+ * Disable, then unregisters a Context. The Context won't be available anymore in the framework
+ * (not even in the Preferences page). This method <strong>won't</strong> delete the context's files
+ * on the file system.
+ *
+ * @param context
+ * The context to delete
+ */
+ public void deleteContext(Context context) {
+ contexts.remove(context.eResource().getURI());
+ disableContext(context, true);
+ root.getContexts().remove(context);
+ }
+
+ /**
+ * Initializes the ConfigurationManager instance. This method should be called only once
+ */
+ public static void init() {
+ instance.start();
+ }
+
+ /**
+ * Retrieves the Property object associated to the propertyPath in the given context
+ *
+ * @param propertyPath
+ * @param context
+ * @return
+ * The property associated to the given propertyPath
+ */
+ public Property getProperty(String propertyPath, Context context) {
+ String elementName = propertyPath.substring(0, propertyPath.lastIndexOf(":")); //$NON-NLS-1$
+ String propertyName = propertyPath.substring(propertyPath.lastIndexOf(":") + 1, propertyPath.length()); //$NON-NLS-1$
+ Set<DataContextElement> elements = new HashSet<DataContextElement>();
+
+ Collection<Context> allContexts;
+
+ if(context == null) {
+ allContexts = getContexts();
+ } else {
+ allContexts = Util.getDependencies(context);
+ }
+
+ for(Context ctx : allContexts) {
+ elements.addAll(ctx.getDataContexts());
+ }
+
+ DataContextElement element = Util.getContextElementByQualifiedName(elementName, elements);
+ if(element != null) {
+ for(Property property : element.getProperties()) {
+ if(property.getName().equals(propertyName)) {
+ return property;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Updates the constraint engine to handle changes in the contexts
+ * activation
+ */
+ public void update() {
+ constraintEngine.contextChanged();
+ }
+
+ /**
+ * Checks the conflicts between all applied configurations
+ * A Conflict may occur when two sections have the same ID : they can't
+ * be displayed at the same time
+ *
+ * @return
+ * The list of conflicts
+ */
+ public Collection<ConfigurationConflict> checkConflicts() {
+ Map<String, List<Context>> sections = new HashMap<String, List<Context>>();
+ Map<String, ConfigurationConflict> conflicts = new HashMap<String, ConfigurationConflict>();
+
+ for(Context context : getEnabledContexts()) {
+ for(Tab tab : context.getTabs()) {
+ for(Section section : tab.getSections()) {
+ String sectionID = section.getName();
+ List<Context> contexts = sections.get(sectionID);
+ if(contexts == null) {
+ contexts = new LinkedList<Context>();
+ sections.put(sectionID, contexts);
+ } else {
+ ConfigurationConflict conflict = conflicts.get(sectionID);
+ if(conflict == null) {
+ conflict = new ConfigurationConflict(sectionID);
+ conflicts.put(sectionID, conflict);
+
+ conflict.addContext(contexts.get(0));
+ }
+
+ conflict.addContext(context);
+ }
+
+ contexts.add(context);
+ }
+ }
+ }
+
+ return conflicts.values();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintEngine.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintEngine.java
new file mode 100644
index 00000000000..96f1724b548
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintEngine.java
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import java.util.Set;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.View;
+
+/**
+ * An interface representing a Constraint Engine.
+ * The Constraint Engine is responsible for retrieving the views
+ * to display for a given ISelection.
+ *
+ * @author Camille Letavernier
+ */
+public interface ConstraintEngine {
+
+ /**
+ * Return the views corresponding to the given ISelection, or an Empty set
+ * if no matching view can be found.
+ *
+ * @param forSelection
+ * The selection from which to retrieve the views
+ * @return
+ * The views corresponding to the given selection
+ */
+ public Set<View> getViews(ISelection forSelection);
+
+ /**
+ * Adds a {@link Context} to this ConstraintEngine. The context is used to
+ * retrieve the set of views this ConstraintEngine can return when matching
+ * a selection.
+ *
+ * @param context
+ */
+ public void addContext(Context context);
+
+ /**
+ * Informs this ConstraintEngine that the set of enabled contexts has changed.
+ * If the method {@link #addContext(Context)} has been called, the {@link #contextChanged()} won't be called. However, if a context has been
+ * removed or edited, the {@link #contextChanged()} method will be called.
+ */
+ public void contextChanged();
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintFactory.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintFactory.java
new file mode 100644
index 00000000000..d0f3e9dd1e6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/ConstraintFactory.java
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.constraints.CompoundConstraint;
+import org.eclipse.papyrus.properties.constraints.Constraint;
+import org.eclipse.papyrus.properties.contexts.CompositeConstraint;
+import org.eclipse.papyrus.properties.contexts.ConstraintDescriptor;
+import org.eclipse.papyrus.properties.contexts.SimpleConstraint;
+
+/**
+ * A Singleton class for creating {@link Constraint}s from a {@link ConstraintDescriptor}
+ *
+ * @author Camille Letavernier
+ */
+public class ConstraintFactory {
+
+ private ConstraintFactory() {
+
+ }
+
+ /**
+ * @return the singleton instance
+ */
+ public static ConstraintFactory getInstance() {
+ return instance;
+ }
+
+ /**
+ * Creates a new Constraint from the given ConstraintDescriptor
+ *
+ * @param model
+ * The ConstraintDescriptor describing the Constraint
+ * @return
+ * The new constraint instance
+ */
+ public Constraint createFromModel(ConstraintDescriptor model) {
+ Constraint constraint = null;
+ if(model instanceof CompositeConstraint) {
+ CompoundConstraint cConstraint = new CompoundConstraint();
+ cConstraint.setConstraintDescriptor(model);
+ for(SimpleConstraint descriptor : ((CompositeConstraint)model).getConstraints()) {
+ Constraint subConstraint = loadConstraint(descriptor);
+ cConstraint.addConstraint(subConstraint);
+ }
+
+ constraint = cConstraint;
+ } else {
+ constraint = loadConstraint((SimpleConstraint)model);
+ }
+ return constraint;
+ }
+
+ private Constraint loadConstraint(SimpleConstraint model) {
+ String className = model.getConstraintType().getConstraintClass();
+ Constraint constraint = null;
+
+ if(model.getConstraintType().eIsProxy()) {
+ Activator.log.error("The constraint URI cannot be resolved. Constraint : " + model.getName() + ". " + model.getConstraintType(), null);
+ return null;
+ }
+
+ try {
+ constraint = (Constraint)Class.forName(className).newInstance();
+ constraint.setConstraintDescriptor(model);
+ } catch (Exception ex) {
+ Activator.log.error("Cannot load constraint " + model.getName(), ex); //$NON-NLS-1$
+ }
+
+ return constraint;
+ }
+
+ private static ConstraintFactory instance = new ConstraintFactory();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultConstraintEngine.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultConstraintEngine.java
new file mode 100644
index 00000000000..c878ba5e530
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultConstraintEngine.java
@@ -0,0 +1,155 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.papyrus.properties.constraints.Constraint;
+import org.eclipse.papyrus.properties.contexts.ConstraintDescriptor;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.View;
+
+/**
+ * The default implementation for ConstraintEngine
+ *
+ * @author Camille Letavernier
+ */
+public class DefaultConstraintEngine implements ConstraintEngine {
+
+ private final Set<Constraint> constraints = new LinkedHashSet<Constraint>();
+
+ public void contextChanged() {
+ constraints.clear();
+ Collection<Context> contexts = ConfigurationManager.instance.getEnabledContexts();
+ for(Context context : contexts) {
+ addContext(context);
+ }
+ }
+
+ public void addContext(final Context context) {
+ for(View view : context.getViews()) {
+ for(ConstraintDescriptor descriptor : view.getConstraints()) {
+ Constraint constraint = ConstraintFactory.getInstance().createFromModel(descriptor);
+ if(constraint != null) {
+ constraints.add(constraint);
+ }
+ }
+ }
+ }
+
+ public Set<View> getViews(final ISelection forSelection) {
+ Set<View> result = new HashSet<View>();
+
+ IStructuredSelection selection;
+ if(forSelection instanceof IStructuredSelection) {
+ selection = (IStructuredSelection)forSelection;
+ } else {
+ return result;
+ }
+
+ Set<Constraint> matchedConstraints = match(selection);
+
+ return getViews(matchedConstraints);
+ }
+
+ private Set<Constraint> match(final IStructuredSelection selection) {
+ Set<Constraint> matchedConstraints = new LinkedHashSet<Constraint>();
+
+ if(selection.isEmpty()) {
+ return matchedConstraints;
+ }
+
+ for(Constraint c : constraints) {
+ int elementMultiplicity = c.getView().getElementMultiplicity();
+ int selectionSize = selection.size();
+ if(elementMultiplicity == 1) {
+ if(selectionSize == 1) {
+ if(c.match(selection.getFirstElement())) {
+ matchedConstraints.add(c);
+ }
+ }
+ } else if(elementMultiplicity == selectionSize || elementMultiplicity < 0) {
+ boolean allMatch = true;
+ Iterator<?> selectionIterator = selection.iterator();
+ while(selectionIterator.hasNext()) {
+ Object selectedItem = selectionIterator.next();
+ if(!c.match(selectedItem)) {
+ allMatch = false;
+ break;
+ }
+ }
+ if(allMatch) {
+ matchedConstraints.add(c);
+ }
+ }
+ }
+
+ // System.out.println(selection);
+
+ // String logValue;
+ //
+ // logValue = "Filtered Constraints : "; //$NON-NLS-1$
+ // for(Constraint constraint : matchedConstraints) {
+ // Context context = ((View)constraint.getDescriptor().getDisplay()).getContext();
+ // logValue += context.getName() + "::" + constraint.getDescriptor().getName() + ", ";
+ // }
+ // Activator.log.warn(logValue);
+
+ resolveConstraintConflicts(matchedConstraints);
+
+ // logValue = "Filtered Constraints : "; //$NON-NLS-1$
+ // for(Constraint constraint : matchedConstraints) {
+ // Context context = ((View)constraint.getDescriptor().getDisplay()).getContext();
+ // logValue += context.getName() + "::" + constraint.getDescriptor().getName() + ", ";
+ // }
+ // Activator.log.warn(logValue);
+
+
+
+ return matchedConstraints;
+ }
+
+ private void resolveConstraintConflicts(final Set<Constraint> matchedConstraints) {
+ Set<Constraint> constraintsSet = new HashSet<Constraint>(matchedConstraints);
+ for(Constraint c : constraintsSet) {
+ for(Constraint c2 : constraintsSet) {
+ if(c == c2) {
+ continue;
+ }
+
+ if(c.getDescriptor().getOverriddenConstraints().contains(c2.getDescriptor())) {
+ matchedConstraints.remove(c2);
+ continue;
+ }
+
+ if(c2.getDescriptor().isOverrideable() && c.overrides(c2)) {
+ matchedConstraints.remove(c2);
+ continue;
+ }
+ }
+ }
+ }
+
+ private Set<View> getViews(final Set<Constraint> matchedConstraints) {
+ Set<View> views = new LinkedHashSet<View>();
+ for(Constraint c : matchedConstraints) {
+ views.add(c.getView());
+ }
+ return views;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultDisplayEngine.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultDisplayEngine.java
new file mode 100644
index 00000000000..d0935a03210
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DefaultDisplayEngine.java
@@ -0,0 +1,233 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.e4.xwt.DefaultLoadingContext;
+import org.eclipse.e4.xwt.ILoadingContext;
+import org.eclipse.e4.xwt.XWT;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.catalog.PropertiesURIHandler;
+import org.eclipse.papyrus.properties.contexts.Context;
+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.modelelement.DataSource;
+import org.eclipse.papyrus.properties.xwt.XWTTabDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+
+/**
+ * A default implementation for {@link DisplayEngine}
+ *
+ * @author Camille Letavernier
+ */
+public class DefaultDisplayEngine implements DisplayEngine {
+
+ private ILoadingContext loadingContext = new DefaultLoadingContext(getClass().getClassLoader());
+
+ private Set<String> displayedSections = new HashSet<String>();
+
+ private Set<Control> controls = new HashSet<Control>();
+
+ private boolean allowDuplicate;
+
+ /**
+ * Constructs a new DisplayEnginet that doesn't allow the duplication of sections
+ */
+ public DefaultDisplayEngine() {
+ this(false);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param allowDuplicate
+ * If false, two calls of {@link #createSection(Composite, Section, DataSource)} with the same
+ * section will display the section only once : only the first call is taken into account
+ * The main property view doesn't allow duplication, to avoid redundancy when two views link to
+ * the same section.
+ */
+ public DefaultDisplayEngine(boolean allowDuplicate) {
+ this.allowDuplicate = allowDuplicate;
+ }
+
+ public List<ITabDescriptor> getTabDescriptors(Set<View> views) {
+
+ Map<String, XWTTabDescriptor> result = new LinkedHashMap<String, XWTTabDescriptor>();
+
+ Set<String> selectedSections = new HashSet<String>();
+
+ for(View view : views) {
+ for(Section section : view.getSections()) {
+ if(selectedSections.contains(section.getName())) {
+ continue;
+ }
+
+ Tab tab = section.getTab();
+
+ if(tab == null) {
+ Activator.log.warn("Null tab for " + section); //$NON-NLS-1$
+ continue;
+ }
+
+ XWTTabDescriptor descriptor;
+
+ if(result.containsKey(tab.getId())) {
+ descriptor = result.get(tab.getId());
+ } else {
+ descriptor = new XWTTabDescriptor(tab);
+ result.put(tab.getId(), descriptor);
+ }
+
+ descriptor.addSection(section, view, this);
+ selectedSections.add(section.getName());
+ }
+ }
+
+ disposeControls();
+ return new LinkedList<ITabDescriptor>(result.values());
+ }
+
+ /**
+ * Disposes the controls created by this DisplayEngine
+ * This should not dispose the engine itself, which can be reused.
+ */
+ protected void disposeControls() {
+ for(Control control : controls) {
+ control.dispose();
+ }
+ displayedSections.clear();
+ controls.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void dispose() {
+ disposeControls();
+ }
+
+ public Control createSection(Composite parent, Section section, DataSource source) {
+ if(source == null) {
+ return null;
+ }
+
+ if(!allowDuplicate && displayedSections.contains(section.getName())) {
+ return null;
+ }
+
+ Control control = createSection(parent, section, loadXWTFile(section), source);
+
+ displayedSections.add(section.getName());
+
+ if(control != null) {
+ controls.add(control);
+ }
+
+ return control;
+ }
+
+ public void refreshSection(Composite parent, Section section, DataSource source) {
+ for(Control control : parent.getChildren()) {
+ control.dispose();
+ }
+
+ createSection(parent, section, loadXWTFile(section), source);
+ }
+
+ public Control createSection(Composite parent, Section section, URL sectionFile, DataSource source) {
+ if(sectionFile == null) {
+ sectionFile = loadXWTFile(section);
+ if(sectionFile == null) {
+ return null;
+ }
+ }
+
+ ILoadingContext xwtContext = XWT.getLoadingContext();
+ XWT.setLoadingContext(loadingContext);
+
+ Control control = null;
+
+ try {
+ control = (Control)XWT.load(parent, sectionFile, source);
+
+ if(control != null) {
+ control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ controls.add(control);
+ }
+ } catch (Exception ex) {
+ Activator.log.error("Error while loading " + section.getSectionFile(), ex); //$NON-NLS-1$
+ disposeControls();
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("An error occured in the property view. The file " + section.getSectionFile() + " could not be loaded"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ layout(parent);
+
+ XWT.setLoadingContext(xwtContext);
+
+ return control;
+ }
+
+ private URL loadXWTFile(Section section) {
+ EObject tab = section.eContainer();
+ Context context = (Context)tab.eContainer();
+ if(context.eResource() == null) {
+ context = ConfigurationManager.instance.getContext(context.getName());
+ Activator.log.warn("No resource for Context : " + context + " ; refreshing the model"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ URI sectionURI = URI.createURI(section.getSectionFile());
+ URI baseURI = context.eResource().getURI();
+ if(PropertiesURIHandler.PROPERTIES_SCHEME.equals(baseURI.scheme())) {
+ PropertiesURIHandler handler = new PropertiesURIHandler();
+ baseURI = handler.getConvertedURI(baseURI);
+ }
+ sectionURI = sectionURI.resolve(baseURI);
+
+ try {
+ URL url = new URL(sectionURI.toString());
+ return url;
+ } catch (IOException ex) {
+ Activator.log.error(ex);
+ }
+
+ return null;
+ }
+
+ private void layout(Composite parent) {
+ parent.getParent().getParent().layout();
+ parent.getParent().layout();
+ parent.layout();
+ }
+
+ public void removeSection(Composite parent) {
+ for(Control control : parent.getChildren()) {
+ control.dispose();
+ }
+ layout(parent);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DisplayEngine.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DisplayEngine.java
new file mode 100644
index 00000000000..da356435d1e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/DisplayEngine.java
@@ -0,0 +1,102 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.papyrus.properties.contexts.Section;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.modelelement.DataSource;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
+
+/**
+ * An interface representing a Display Engine.
+ * A Display Engine is responsible for displaying {@link Section}s in a given Composite.
+ * It is also responsible for retrieving the {@link ITabDescriptor}s for a given set of {@link View}s
+ *
+ * @author Camille Letavernier
+ */
+public interface DisplayEngine {
+
+ /**
+ * Returns a list of ITabDescriptors for the given set of Views.
+ * The list of tabs is retrieved by navigating the views' sections
+ *
+ * @param views
+ * The views from which to retrieve the tab descriptors
+ * @return
+ * The tab descriptors corresponding to the given views
+ */
+ public List<ITabDescriptor> getTabDescriptors(Set<View> views);
+
+ /**
+ * Displays the section in the given parent Composite, and binds the widgets
+ * to the given DataSource.
+ *
+ * @param parent
+ * The Composite widget in which the section is displayed
+ * @param section
+ * The section to display
+ * @param source
+ * The DataSource to bind to the section's widgets.
+ * @return
+ * The generated Control
+ */
+ public Control createSection(Composite parent, Section section, DataSource source);
+
+ /**
+ * Displays the section in the given parent Composite. The section is loaded from
+ * the given URL instead of the section's sectionFile.
+ *
+ * @param parent
+ * The Composite widget in which the section is displayed. Should not be null
+ * @param section
+ * The section to display. Should not be null
+ * @param sectionFile
+ * The URL replacing the section's sectionFile. If null, the section's sectionFile will
+ * be used
+ * @param source
+ * The DataSource to bind to the section's widgets. May be null.
+ * @return
+ * The generated Control
+ */
+ public Control createSection(Composite parent, Section section, URL sectionFile, DataSource source);
+
+ /**
+ * Refresh the given section.
+ *
+ * @param parent
+ * The Composite in which the section should be displayed.
+ * @param section
+ * The section to display.
+ * @param source
+ * The DataSource to bind to the section's widgets.
+ */
+ public void refreshSection(Composite parent, Section section, DataSource source);
+
+ /**
+ * Dispose the section's contents.
+ *
+ * @param self
+ * The Composite containing the section's Control.
+ */
+ public void removeSection(Composite self);
+
+ /**
+ * Disposes this display engine
+ */
+ public void dispose();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/EmbeddedDisplayEngine.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/EmbeddedDisplayEngine.java
new file mode 100644
index 00000000000..4a7ae706fa8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/runtime/EmbeddedDisplayEngine.java
@@ -0,0 +1,239 @@
+/*****************************************************************************
+ * 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.runtime;
+
+import java.text.Collator;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.viewers.ISelection;
+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.xwt.XWTSection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.ISection;
+
+/**
+ * A Property View display engine which can be embedded in a composite
+ *
+ * @author Camille Letavernier
+ */
+public class EmbeddedDisplayEngine extends DefaultDisplayEngine implements SelectionListener {
+
+ private String lastTabId;
+
+ /**
+ * The displayed CTabFolder
+ * May be null
+ */
+ protected CTabFolder currentFolder;
+
+ protected Composite self;
+
+ /**
+ * The currently displayed sections
+ */
+ protected Set<ISection> displayedSections = new HashSet<ISection>();
+
+ /**
+ *
+ * @param views
+ * @param parent
+ * @param selection
+ * @param style
+ * SWT.BOTTOM or SWT.TOP (Tabs' position)
+ */
+ public void display(Set<View> views, Composite parent, ISelection selection, int style) {
+ disposeControls();
+
+ self = new Composite(parent, SWT.NONE);
+
+ self.setLayout(new FillLayout());
+
+ final Set<Tab> tabsList = new LinkedHashSet<Tab>();
+
+ for(View view : views) {
+ for(Section section : view.getSections()) {
+ tabsList.add(section.getTab());
+ }
+ }
+
+ List<Tab> allTabs = new LinkedList<Tab>(tabsList);
+
+ Collections.sort(allTabs, new Comparator<Tab>() {
+
+ /**
+ * compares two tabs each other
+ *
+ * @param tab1
+ * first tab to compare
+ * @param tab2
+ * second tab to compare
+ * @return a negative integer if the first tab should be placed before the second tab
+ */
+ public int compare(Tab tab1, Tab tab2) {
+ int priority1 = getPriority(tab1);
+ int priority2 = getPriority(tab2);
+
+ if(priority1 < priority2) {
+ return -1;
+ }
+
+ if(priority1 > priority2) {
+ return 1;
+ }
+
+ //p1 == p2
+
+ priority1 = getXWTTabPriority(tab1);
+ priority2 = getXWTTabPriority(tab2);
+
+ if(priority1 < priority2) {
+ return -1;
+ }
+
+ if(priority1 > priority2) {
+ return 1;
+ }
+
+ //p1 == p2
+
+ String label1 = tab1.getLabel();
+ String label2 = tab2.getLabel();
+
+ return Collator.getInstance().compare(label1, label2);
+ }
+
+ private Tab getPreviousTab(Tab tab) {
+ Tab afterTab = tab.getAfterTab();
+ if(tabsList.contains(afterTab)) {
+ return afterTab;
+ }
+
+ // not found. Return null
+ return null;
+ }
+
+ private int getPriority(Tab tab) {
+ Tab previousTab = getPreviousTab(tab);
+ if(previousTab != null) {
+ return getPriority(previousTab) + 1;
+ }
+
+ return getXWTTabPriority(tab);
+ }
+
+ private int getXWTTabPriority(Tab tab) {
+ return tab.getPriority();
+ }
+
+ });
+
+ Map<Tab, Composite> tabs = new LinkedHashMap<Tab, Composite>();
+
+ if(allTabs.size() > 1) {
+ CTabItem selectedTab = null;
+
+ currentFolder = new CTabFolder(self, style);
+ currentFolder.setSelectionBackground(new Color[]{ currentFolder.getDisplay().getSystemColor(SWT.COLOR_WHITE), currentFolder.getBackground() }, new int[]{ 100 }, true);
+ currentFolder.setLayout(new FillLayout());
+ for(Tab tab : allTabs) {
+ CTabItem item = new CTabItem(currentFolder, SWT.NONE);
+ Composite tabControl = new Composite(currentFolder, SWT.NONE);
+ item.setControl(tabControl);
+ item.setText(tab.getLabel());
+ item.setData("id", tab.getId()); //$NON-NLS-1$
+ if(tab.getId().equals(lastTabId)) {
+ selectedTab = item;
+ }
+ tabs.put(tab, tabControl);
+ }
+ currentFolder.addSelectionListener(this);
+
+
+ if(selectedTab == null) {
+ selectedTab = currentFolder.getItem(0);
+ }
+
+ currentFolder.setSelection(selectedTab);
+ } else if(!allTabs.isEmpty()) {
+ Tab tab = allTabs.get(0);
+ tabs.put(tab, self);
+ } else {
+ return;
+ }
+
+ for(View view : views) {
+ for(Section section : view.getSections()) {
+ XWTSection xwtSection = new XWTSection(section, view, this);
+
+ xwtSection.createControls(tabs.get(section.getTab()), null);
+ xwtSection.setInput(null, selection);
+ xwtSection.refresh();
+
+ displayedSections.add(xwtSection);
+ }
+ }
+
+ self.layout();
+ }
+
+ @Override
+ protected void disposeControls() {
+ super.disposeControls();
+ if(self != null) {
+ self.dispose();
+ self = null;
+ currentFolder = null;
+ }
+
+ // if(currentFolder != null) {
+ // currentFolder.dispose();
+ // currentFolder = null;
+ // }
+
+ for(ISection section : displayedSections) {
+ section.dispose();
+ }
+ }
+
+ public void widgetSelected(SelectionEvent e) {
+ if(e.widget instanceof CTabFolder) {
+ CTabFolder folder = (CTabFolder)e.widget;
+ CTabItem lastTab = folder.getSelection();
+ Object lastId = lastTab.getData("id"); //$NON-NLS-1$
+ if(lastId != null && lastId instanceof String) {
+ lastTabId = (String)lastId;
+ }
+ }
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ //Nothing
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/ClassLoader.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/ClassLoader.java
new file mode 100644
index 00000000000..7ceeb137fa7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/ClassLoader.java
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * 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.util;
+
+import org.eclipse.papyrus.properties.Activator;
+
+/**
+ * A Helper class for Class Loading.
+ *
+ * @author Camille Letavernier
+ */
+//TODO : Rename that class to ClassLoaderHelper (avoir class name conflict with the standard ClassLoader)
+//TODO : Change all methods to static methods
+//TODO : Move that class to a more generic plug-in
+public class ClassLoader {
+
+ /**
+ * Loads the class matching the given className. Exceptions are caught and sent
+ * to the Logger.
+ *
+ * @param className
+ * The qualified name of the Class to load.
+ * @return
+ * The loaded Class, or null if an error occured
+ */
+ public Class<?> loadClass(String className) {
+ try {
+ Class<?> clazz = Activator.getDefault().getBundle().loadClass(className);
+ return clazz;
+ } catch (ClassNotFoundException ex) {
+ Activator.log.error("The class " + className + " doesn't exist", ex); //$NON-NLS-1$
+ } catch (NullPointerException ex) {
+ Activator.log.error("Cannot load class " + className, ex); //$NON-NLS-1$
+ }
+
+ return null;
+ }
+
+ /**
+ * Loads and returns the class denoted by the given className.
+ * Checks that the loaded class is a subtype of the given Class.
+ *
+ * @param className
+ * The qualified name of the class to be loaded
+ * @param asSubClass
+ * The interface or class that the loaded class must implement or extend
+ * @return
+ * The loaded class, or null if the class doesn't exist or is invalid.
+ * In such a case, the exception is logged.
+ */
+ public <T> Class<? extends T> loadClass(String className, Class<T> asSubClass) {
+ Class<?> theClass = loadClass(className);
+ if(theClass == null) {
+ return null;
+ }
+
+ try {
+ Class<? extends T> typedClass = theClass.asSubclass(asSubClass);
+ return typedClass;
+ } catch (ClassCastException ex) {
+ Activator.log.error(String.format("The class %1$s doesn't extend or implement %2$s", className, asSubClass.getName()), ex); //$NON-NLS-1$
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a new instance of class denoted by the given className.
+ * Checks that the instantiated class is a subtype of the given class
+ *
+ * @param className
+ * The qualified name of the class to be instantiated
+ * @param asSubclass
+ * The interface or class that the loaded class must implement or extend
+ * @return
+ * An instance of the loaded class, or null if a valid instance
+ * cannot be created. In such a case, the exception is logged.
+ */
+ public <T> T newInstance(String className, Class<T> asSubclass) {
+ Class<? extends T> typedClass = loadClass(className, asSubclass);
+ if(typedClass == null) {
+ return null;
+ }
+
+ return newInstance(typedClass);
+ }
+
+ /**
+ * Returns a new Instance of the given class
+ *
+ * @param className
+ * The qualified name of the Class to instantiate
+ * @return
+ * A new instance of the given class, or null if the class couldn't be
+ * instantiated
+ */
+ public Object newInstance(String className) {
+ return newInstance(loadClass(className));
+ }
+
+ /**
+ * Returns a new Instance of the given class
+ *
+ * @param theClass
+ * The Class to instantiate
+ * @return
+ * A new instance of the given class, or null if the class couldn't be
+ * instantiated
+ */
+ public <T extends Object> T newInstance(Class<T> theClass) {
+ if(theClass == null) {
+ return null;
+ }
+
+ try {
+ return theClass.newInstance();
+ } catch (IllegalAccessException ex) {
+ Activator.log.error("Cannot find a valid public constructor for the class " + theClass.getName(), ex); //$NON-NLS-1$
+ } catch (InstantiationException ex) {
+ Activator.log.error(String.format("The class %s cannot be instantiated.", theClass.getName()), ex); //$NON-NLS-1$
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EClassNameComparator.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EClassNameComparator.java
new file mode 100644
index 00000000000..a68e86ece8f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EClassNameComparator.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * 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.util;
+
+import java.text.Collator;
+import java.util.Comparator;
+
+import org.eclipse.emf.ecore.EClass;
+
+/**
+ * A class for comparing EClasses by name
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class EClassNameComparator implements Comparator<EClass> {
+
+ public int compare(EClass class1, EClass class2) {
+ if(class1 == null) {
+ return class2 == null ? 0 : -1;
+ }
+
+ return Collator.getInstance().compare(class1.getName(), class2.getName());
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EMFHelper.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EMFHelper.java
new file mode 100644
index 00000000000..7e2cc41dad5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/EMFHelper.java
@@ -0,0 +1,380 @@
+/*****************************************************************************
+ * 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.util;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.papyrus.properties.Activator;
+
+/**
+ * A Helper class for manipulating EMF Objects
+ *
+ * @author Camille Letavernier
+ */
+//TODO : To be refactored
+//This class could be useful in other plug-ins, which don't necessarily depend
+//on oep.properties
+public class EMFHelper {
+
+ /**
+ * Returns the EClass corresponding to the given nsUri and className
+ *
+ * @param nsUri
+ * The NSURI of the EClass' EPackage
+ * @param className
+ * The EClass' name
+ * @return
+ * The EClass instance, or null if the EClass couldn't be found
+ */
+ public static EClass getEClass(String nsUri, String className) {
+ EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri);
+ if(ePackage == null) {
+ Activator.log.warn("Cannot find an EPackage matching the nsURI " + nsUri); //$NON-NLS-1$
+ return null;
+ }
+ return getEClass(ePackage, className);
+ }
+
+ /**
+ * Return the EClass corresponding to the given EPackage and className
+ *
+ * @param metamodel
+ * The EClass' EPackage
+ * @param className
+ * The EClass' name
+ * @return
+ * The EClass instance, or null if the EClass couldn't be found
+ */
+ public static EClass getEClass(EPackage metamodel, String className) {
+ EClassifier classifier = metamodel.getEClassifier(className);
+ if(classifier == null) {
+ Activator.log.warn("Classifier " + className + " not found in metamodel " + metamodel.getName() + " (" + metamodel.getNsURI() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ if(classifier instanceof EClass) {
+ return (EClass)classifier;
+ } else {
+ Activator.log.warn("Classifier " + className + " in " + metamodel.getName() + " (" + metamodel.getNsURI() + ") is not an EClass"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+
+ return null;
+ }
+
+ /**
+ * Tests if an Object is an instance of the given EClass
+ *
+ * @param element
+ * The EObject to test
+ * @param className
+ * The name of the EClass
+ * @param metamodel
+ * The EPackage owning the EClass
+ * @return
+ * True if the EObject is an instance of the EClass, or of one of the EClass' subtypes
+ */
+ public static boolean isInstance(EObject element, String className, EPackage metamodel) {
+
+ EClassifier theClass = metamodel.getEClassifier(className);
+
+ if(theClass == null) {
+ Activator.log.warn("Class " + className + " not found in Metamodel : " + metamodel.getName() + " (" + metamodel.getNsURI() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ return false;
+ }
+
+ return theClass.isInstance(element);
+ }
+
+ /**
+ * Tests if the given eClass is a Subclass of fromClass
+ *
+ * @param eClass
+ * @param fromClass
+ * @return
+ * true if eClass is a subclass of fromClass
+ */
+ public static boolean isSubclass(EClass eClass, EClass fromClass) {
+ //Everything is an EObject
+ if(eClass != null && fromClass == EcorePackage.eINSTANCE.getEObject()) {
+ return true;
+ }
+
+ if(eClass == fromClass) {
+ return true;
+ }
+
+ List<EClass> superTypes = eClass.getEAllSuperTypes();
+ if(superTypes.contains(fromClass)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the EObject corresponding to the input object
+ * Tests if the input is an EObject, or if it is Adaptable
+ * to an EObject
+ *
+ * @param source
+ * @return An EObject corresponding to the input source, or null
+ * if the EObject could not be resolved
+ */
+ public static EObject getEObject(Object source) {
+ if(source instanceof EObject) {
+ return (EObject)source;
+ } else if(source instanceof IAdaptable) {
+ return (EObject)((IAdaptable)source).getAdapter(EObject.class);
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the eClass' qualified name. The qualified name is obtained by the concatenation
+ * of its package hierarchy with the class name, separated by the given separator
+ *
+ * @param eClass
+ * @param separator
+ * The separator used between each package name
+ * @return
+ * The EClass' qualified name
+ */
+ public static String getQualifiedName(EClass eClass, String separator) {
+ return getQualifiedName(eClass.getEPackage(), separator) + separator + eClass.getName();
+ }
+
+ /**
+ * Return the ePackage's qualified name. The qualified name is obtained by the concatenation
+ * of its superPackage hierarchy with the ePackage name, separated by the given separator
+ *
+ * @param ePackage
+ * @param separator
+ * The separator used between each package name
+ * @return
+ * The EPackage's qualified name
+ */
+ public static String getQualifiedName(EPackage ePackage, String separator) {
+ if(ePackage.getESuperPackage() == null) {
+ return ePackage.getName();
+ }
+ return getQualifiedName(ePackage.getESuperPackage(), separator) + separator + ePackage.getName();
+ }
+
+
+ /**
+ * Loads and returns the first EObject at the given URI.
+ * The EObject is loaded in the given resourceSet.
+ *
+ * @param resourceSet
+ * The ResourceSet in which the model will be loaded
+ * @param uri
+ * The URI describing the location of the model to load
+ * @return
+ * The first EObject located at the given URI
+ * @throws IOException
+ *
+ */
+ public static EObject loadEMFModel(ResourceSet resourceSet, URI uri) throws IOException {
+ if(resourceSet == null) {
+ 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) {
+ IOException exception = new IOException(ex.toString());
+ exception.initCause(ex);
+ throw exception;
+ }
+
+ return null;
+ }
+
+ /**
+ * Return the root package containing the given package, or the package
+ * itself if it is already the root
+ *
+ * @param ePackage
+ * @return
+ * The Root package
+ */
+ public static EPackage getRootPackage(EPackage ePackage) {
+ if(ePackage == null) {
+ return null;
+ }
+
+ if(ePackage.getESuperPackage() == null) {
+ return ePackage;
+ }
+ return getRootPackage(ePackage.getESuperPackage());
+ }
+
+
+ /**
+ * Return the list of EClasses that are subtypes
+ * of the given EClass
+ *
+ * @param type
+ * @param concreteClassesOnly
+ * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered
+ * @return
+ * The list of EClasses implementing or extending the given EClass
+ */
+ public static List<EClass> getSubclassesOf(EClass type, boolean concreteClassesOnly) {
+ List<EClass> result = new LinkedList<EClass>();
+ if(!concreteClassesOnly || (!type.isAbstract() && !type.isInterface())) {
+ result.add(type);
+ }
+
+ EPackage ePackage = getRootPackage(type.getEPackage());
+ getSubclassesOf(type, ePackage, result, concreteClassesOnly);
+ return result;
+ }
+
+ private static void getSubclassesOf(EClass type, EPackage fromPackage, List<EClass> result, boolean concreteClassesOnly) {
+ for(EClassifier classifier : fromPackage.getEClassifiers()) {
+ if(classifier instanceof EClass) {
+ EClass eClass = (EClass)classifier;
+ if(eClass.getEAllSuperTypes().contains(type)) {
+ if(!concreteClassesOnly || (!eClass.isAbstract() && !eClass.isInterface())) {
+ result.add(eClass);
+ }
+ }
+ }
+ }
+
+ for(EPackage subPackage : fromPackage.getESubpackages()) {
+ getSubclassesOf(type, subPackage, result, concreteClassesOnly);
+ }
+ }
+
+ /**
+ * Tests if an EObject is read only
+ * Delegates to the EObject's editing domain if it can be found
+ *
+ * @param eObject
+ * @return
+ * True if the EObject is read only
+ */
+ public static boolean isReadOnly(EObject eObject) {
+ EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
+ return isReadOnly(eObject, domain);
+ }
+
+ /**
+ * Tests if an EObject is read only
+ * Delegates to the given editing domain if it isn't null
+ *
+ * @param eObject
+ * @param domain
+ * @return
+ * True if the EObject is read only
+ */
+ public static boolean isReadOnly(EObject eObject, EditingDomain domain) {
+ return isReadOnly(eObject.eResource(), domain);
+ }
+
+ /**
+ * Tests if the Resource is read only
+ * Delegates to the given editing domain if it isn't null
+ *
+ * @param resource
+ * @param domain
+ * @return
+ * True if the Resource is read only
+ */
+ public static boolean isReadOnly(Resource resource, EditingDomain domain) {
+ if(domain instanceof AdapterFactoryEditingDomain) {
+ return ((AdapterFactoryEditingDomain)domain).isReadOnly(resource);
+ }
+
+ if(resource == null) {
+ return false;
+ }
+
+ ResourceSet resourceSet = resource.getResourceSet();
+
+ if(resourceSet == null) {
+ return false;
+ }
+
+ Map<String, ?> attributes = resourceSet.getURIConverter().getAttributes(resource.getURI(), null);
+ Boolean readOnly = (Boolean)attributes.get(URIConverter.ATTRIBUTE_READ_ONLY);
+
+ return readOnly == null ? false : readOnly;
+ }
+
+ /**
+ * Tests if the given EStructuralFeature is required (ie. should always
+ * have a value)
+ *
+ * A feature is required if at least of one the following conditions if
+ * true :
+ *
+ * - It has a defaultValue
+ * - Its lowerBound is at least 1
+ * - It is an enumeration (Enumerations always have a default value)
+ * - It is a Java primitive type, and is not marked as Unsettable
+ *
+ * @param feature
+ * the feature to test
+ * @return
+ * true if the feature is required, false otherwise
+ */
+ public static boolean isRequired(EStructuralFeature feature) {
+ //EEnums are always required, as an EEnum always has a default value
+ if(feature.getEType() instanceof EEnum) {
+ return true;
+ }
+
+ //At least one value means it is required
+ if(feature.getLowerBound() >= 1) {
+ return true;
+ }
+
+ //Java primitive types cannot have a null value
+ //if the feature is not specifically marked as unsettable, then it is required
+ if(feature.getEType().getInstanceClass().isPrimitive() && !feature.isUnsettable()) {
+ return true;
+ }
+
+ //If there is a default value, there is always a value
+ if(feature.getDefaultValueLiteral() != null) {
+ return true;
+ }
+
+ return false; //The property if not required
+ }
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/Util.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/Util.java
new file mode 100644
index 00000000000..90e34a754e4
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/util/Util.java
@@ -0,0 +1,288 @@
+/*****************************************************************************
+ * 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.util;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.papyrus.properties.Activator;
+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.environment.Namespace;
+
+/**
+ * A Helper class for miscellaneous elements of the Property view framework
+ *
+ * @author Camille Letavernier
+ */
+public class Util {
+
+ /**
+ * @param source
+ * @return
+ * the given String with the first letter capitalized
+ */
+ public static String firstToUpper(String source) {
+ if(source.length() == 0) {
+ return source;
+ }
+ return source.substring(0, 1).toUpperCase() + source.substring(1);
+ }
+
+ /**
+ * @param source
+ * @return
+ * the given String with the first letter lowered
+ */
+ public static String firstToLower(String source) {
+ if(source.length() == 0) {
+ return source;
+ }
+ return source.substring(0, 1).toLowerCase() + source.substring(1);
+ }
+
+ /**
+ * @param variableName
+ * @return
+ * A formatted version of the given variable name
+ */
+ public static String getLabel(String variableName) {
+ //"CamelCase" to "Natural case"
+ String formattedValue = variableName;
+
+ //replace fooBar by foo Bar
+ formattedValue = formattedValue.replaceAll("([a-z])([A-Z])", "$1 $2"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ //replace FOOAndBar by FOO And Bar
+ formattedValue = formattedValue.replaceAll("([A-Z]+)([A-Z])([a-z])", "$1 $2$3"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ //Capitalize the first word and lower the other ones : foo Bar -> Foo bar
+ //Keep the upper case for acronyms FOO Bar -> FOO bar
+ String[] words = formattedValue.split("\\s+"); //$NON-NLS-1$
+ formattedValue = firstToUpper(words[0]);
+ for(int i = 1; i < words.length; i++) {
+ formattedValue += " "; //$NON-NLS-1$
+ if(words[i].matches("^[A-Z]{2,}")) { //$NON-NLS-1$
+ formattedValue += words[i];
+ } else {
+ formattedValue += firstToLower(words[i]);
+ }
+ }
+
+ Activator.log.debug("\"" + formattedValue + "\""); //$NON-NLS-1$ //$NON-NLS-2$
+ return formattedValue;
+ }
+
+ /**
+ * Tests if the given value is equal to the namespace's value
+ *
+ * @param namespace
+ * @param value
+ * @return
+ * True if they are equal
+ */
+ public static boolean namespaceEquals(Namespace namespace, String value) {
+ if(namespace == null) {
+ return value == null || value.trim().equals(""); //$NON-NLS-1$
+ } else {
+ return namespace.getValue().equals(value);
+ }
+ }
+
+ /**
+ * Tests if the given name is equal to the namespace's name
+ *
+ * @param namespace
+ * @param name
+ * @return
+ * True if they are equal
+ */
+ public static boolean namespaceEqualsByName(Namespace namespace, String name) {
+ if(namespace == null) {
+ return name == null || name.trim().equals(""); //$NON-NLS-1$
+ } else {
+ return namespace.getName().equals(name);
+ }
+ }
+
+ /**
+ * Return the full value of the namespace declaration
+ * e.g. clr-namespace:org.eclipse.papyrus.properties
+ *
+ * @param namespace
+ * The namespace we want to prefix
+ * @return
+ * The prefixed namespace
+ */
+ public static String getPrefixedValue(Namespace namespace) {
+ String prefixedValue = ""; //$NON-NLS-1$
+ if(namespace.getPrefix() != null && !namespace.getPrefix().trim().equals("")) { //$NON-NLS-1$
+ prefixedValue = namespace.getPrefix() + ":"; //$NON-NLS-1$
+ }
+ prefixedValue += namespace.getValue();
+
+ return prefixedValue;
+ }
+
+ /**
+ * Return the full name of the namespace declaration
+ * e.g. xmlns:ppe
+ *
+ * @param namespace
+ * The namespace for which we want to get the qualified name
+ * @return
+ * The namespace's qualified name
+ */
+ public static String getQualifiedName(Namespace namespace) {
+ if(namespace.getName() == null || namespace.getName().trim().equals("")) { //$NON-NLS-1$
+ return "xmlns"; //$NON-NLS-1$
+ } else {
+ return "xmlns:" + namespace.getName(); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Retrieve the DataContextElement matching the given qualifiedName.
+ *
+ * @param qualifiedName
+ * The fully qualified name of the DataContextElement. The separator is ":"
+ * e.g. : UML:NamedElement
+ * @param fromContextElements
+ * The collection of DataContextElements in which the method should look
+ * @return
+ * The matching DataContextElement, or null if none was found
+ */
+ public static DataContextElement getContextElementByQualifiedName(String qualifiedName, Collection<? extends DataContextElement> fromContextElements) {
+ int index = qualifiedName.indexOf(":"); //$NON-NLS-1$
+ if(index >= 0) {
+ String name = qualifiedName.substring(0, index);
+ qualifiedName = qualifiedName.substring(qualifiedName.indexOf(":") + 1, qualifiedName.length()); //$NON-NLS-1$
+ for(DataContextElement contextElement : fromContextElements) {
+ if(contextElement instanceof DataContextPackage && contextElement.getName().equals(name)) {
+ DataContextElement result = getContextElementByQualifiedName(qualifiedName, ((DataContextPackage)contextElement).getElements());
+ if(result != null) {
+ return result;
+ }
+ }
+ }
+ } else {
+ for(DataContextElement element : fromContextElements) {
+ if(element.getName().equals(qualifiedName)) {
+ return element;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the list of Context on which the given context depends, directly
+ * or indirectly
+ *
+ * @param context
+ * The context for which we want to retrieve the list of dependencies
+ * @return
+ * The list of Contexts on which the given context depends
+ */
+ public static List<Context> getDependencies(Context context) {
+ List<Context> result = new LinkedList<Context>();
+ if(context == null) {
+ return result;
+ }
+
+ result.add(context);
+ findDependencies(context, result);
+ return result;
+ }
+
+ private static void findDependencies(Context context, List<Context> result) {
+ for(Context dependency : context.getDependencies()) {
+ if(!result.contains(dependency)) {
+ result.add(dependency);
+ findDependencies(dependency, result);
+ }
+ }
+ }
+
+ /**
+ * Returns the set of DataContextElement containing the whole inheritance hierarchy
+ * for the given source DataContextElements
+ *
+ * @param source
+ * The collection of DataContextElements for which we want to retrieve all inherited elements
+ * @return
+ * All DataContextElements inherited (Directly or indirectly) by at least one of the source
+ * context elements
+ */
+ public static Set<DataContextElement> getAllContextElements(Collection<DataContextElement> source) {
+ Set<DataContextElement> result = new HashSet<DataContextElement>();
+ getAllContextElements(source, result);
+ return result;
+ }
+
+ private static void getAllContextElements(Collection<DataContextElement> source, Set<DataContextElement> result) {
+ for(DataContextElement element : source) {
+ if(!result.contains(element)) {
+ result.add(element);
+ getAllContextElements(element.getSupertypes(), result);
+ }
+ }
+ }
+
+ /**
+ * A util method to make big strings fit in a restricted amount of space,
+ * such as a tooltip. The method will add new lines in the string at
+ * a regular interval.
+ *
+ * @param string
+ * The string to split
+ * @param maxCharPerLine
+ * The maximum number of characters per line in the resulting string
+ * @return
+ * The split string
+ */
+ public static String resizeString(String string, int maxCharPerLine) {
+ if(string == null || string.trim().length() <= maxCharPerLine) {
+ return string.trim();
+ }
+
+ String[] stringChunks = string.split("\n|\r|\r\n|\n\r"); //$NON-NLS-1$
+
+ List<String> chunks = new LinkedList<String>();
+
+ for(String chunk : stringChunks) {
+ chunk = chunk.trim();
+ if(chunk.length() > maxCharPerLine) {
+ Matcher matcher = Pattern.compile("(.{0," + maxCharPerLine + "}\\b\\p{Punct}?)").matcher(chunk); //$NON-NLS-1$ //$NON-NLS-2$
+ while(matcher.find()) {
+ String group = matcher.group(1);
+ chunks.add(group);
+ }
+ } else {
+ chunks.add(chunk);
+ }
+ }
+
+ String result = ""; //$NON-NLS-1$
+ for(String chunk : chunks) {
+ result += chunk.trim() + "\n"; //$NON-NLS-1$
+ }
+
+ return result.trim();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/AbstractPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/AbstractPropertyEditor.java
new file mode 100644
index 00000000000..607391d99d6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/AbstractPropertyEditor.java
@@ -0,0 +1,497 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.Property;
+import org.eclipse.papyrus.properties.modelelement.DataSource;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+import org.eclipse.papyrus.properties.util.Util;
+import org.eclipse.papyrus.widgets.editors.AbstractEditor;
+import org.eclipse.papyrus.widgets.editors.AbstractListEditor;
+import org.eclipse.papyrus.widgets.editors.AbstractValueEditor;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * An Abstract class to factorize code for PropertyEditors. PropertyEditors are
+ * <strong>not</strong> required to extend this class, but could benefit from
+ * its methods.
+ *
+ * @author Camille Letavernier
+ */
+public abstract class AbstractPropertyEditor implements IChangeListener {
+
+ /**
+ * The qualified propertyPath. Represents the property edited by this widget
+ */
+ protected String propertyPath; //Format : "DataContextElement:propertyName"
+
+ /**
+ * The DataSource representing the semantic objects
+ */
+ protected DataSource input;
+
+ private boolean readOnly = false;
+
+ private boolean isEditable = true;
+
+ /**
+ * The SWT Widget (For list properties only)
+ */
+ protected AbstractListEditor listEditor;
+
+ /**
+ * The SWT Widget (For single values only)
+ */
+ protected AbstractValueEditor valueEditor;
+
+ /**
+ * The IObservableList representing the semantic property
+ * (For list properties only)
+ */
+ protected IObservableList observableList;
+
+ /**
+ * The IObservableValue representing the semantic property
+ * (For single values only)
+ */
+ protected IObservableValue observableValue;
+
+ /**
+ * Indicates if the editor's label should be displayed
+ */
+ protected boolean showLabel = true;
+
+ /**
+ * The custom label used by this editor. If set, it replaces the property's default label
+ */
+ protected String customLabel;
+
+ /**
+ * The maximum number of characters per line for wrapping descriptions
+ */
+ public static int descriptionMaxCharPerLine = 200;
+
+ /**
+ * Constructor.
+ * When using this constructor, you should explicitly call the #setEditor method.
+ */
+ protected AbstractPropertyEditor() {
+ }
+
+ /**
+ * Constructor. Constructs a new PropertyEditor with the given ListEditor
+ *
+ * @param editor
+ */
+ protected AbstractPropertyEditor(AbstractListEditor editor) {
+ setEditor(editor);
+ }
+
+ /**
+ * Constructor. Constructs a new PropertyEditor with the given ValueEditor
+ *
+ * @param editor
+ */
+ protected AbstractPropertyEditor(AbstractValueEditor editor) {
+ setEditor(editor);
+ }
+
+ /**
+ * Sets the ListEditor for this PropertyEditor
+ *
+ * @param editor
+ */
+ protected void setEditor(AbstractListEditor editor) {
+ this.listEditor = editor;
+ addDisposeListener(editor);
+ }
+
+ /**
+ * Sets the ValueEditor for this PropertyEditor
+ *
+ * @param editor
+ */
+ protected void setEditor(AbstractValueEditor editor) {
+ this.valueEditor = editor;
+ addDisposeListener(editor);
+ }
+
+ private void addDisposeListener(AbstractEditor editor) {
+ editor.addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ if(input != null) {
+ input.removeChangeListener(AbstractPropertyEditor.this);
+ }
+ }
+ });
+ }
+
+ /**
+ * Checks if this editor has all the input needed to do the dataBinding.
+ * As this editor can be instantiated through the XWT Framework, which is
+ * based on an XML parser, there is no determinism in the order in which
+ * the parameters are set.
+ */
+ protected void checkInput() {
+ if(propertyPath != null && input != null) {
+ isEditable = input.isEditable(propertyPath);
+ try {
+ doBinding();
+ } catch (Exception ex) {
+ //TODO : Handle the exception here. Display something ?
+ Activator.log.error(ex);
+ }
+ updateLabel();
+ }
+ }
+
+ /**
+ * Binds the AbstractEditor (Either List or Value editor) to the semantic element
+ */
+ protected void doBinding() {
+ boolean isReadOnly = getReadOnly();
+
+ if(listEditor != null) {
+ IObservableList inputObservableList = getInputObservableList();
+
+ if(inputObservableList != null) {
+ listEditor.setModelObservable(inputObservableList);
+ }
+
+ } else if(valueEditor != null) {
+ IObservableValue inputObservableValue = getInputObservableValue();
+
+ if(inputObservableValue != null) {
+ valueEditor.setModelObservable(inputObservableValue);
+ }
+ }
+
+ applyReadOnly(isReadOnly);
+
+ if(input.forceRefresh(propertyPath)) {
+ input.addChangeListener(this);
+ }
+ }
+
+ /**
+ * Applies the readOnly state to the editor
+ *
+ * @param readOnly
+ * Indicates if this widget should be read-only
+ */
+ protected void applyReadOnly(boolean readOnly) {
+ AbstractEditor editor = getEditor();
+ if(editor != null) {
+ editor.setReadOnly(readOnly);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ //TODO : This method handles a change on the DataSource. This should not be a ChangeEvent, as the DataSource is not an IObservable
+ //This method should be changed, and the source of the event should be checked (Otherwise, it cannot be extended).
+ //TODO : Remove the "final" modifier to let subclasses extend this behavior,
+ //when the source of the event is checked. Until then, it is not safe to override this method
+ public final void handleChange(ChangeEvent event) {
+ //Handle the "forceRefresh" behavior when the input DataSource sends a ChangeEvent
+ AbstractEditor editor = getEditor();
+ if(editor != null) {
+ editor.refreshValue();
+ }
+ }
+
+ /**
+ * Sets the property path for this PropertyEditor.
+ * The propertyPath elements should be separated by ":"
+ * e.g. UML:NamedElement:name
+ *
+ * @param path
+ */
+ public void setProperty(String path) {
+ propertyPath = path;
+ updateLabel();
+ updateDescription();
+ checkInput();
+ }
+
+ /**
+ * Updates the label for this PropertyEditor.
+ */
+ public void updateLabel() {
+ String label = getLabel();
+ // if(input != null && propertyPath != null && input.isMandatory(propertyPath)) {
+ // label += " *"; //$NON-NLS-1$
+ // }
+
+ if(showLabel) {
+ if(valueEditor != null) {
+ valueEditor.setLabel(label);
+ } else if(listEditor != null) {
+ listEditor.setLabel(label);
+ }
+ }
+ }
+
+ /**
+ * @return the property path for this Property editor.
+ */
+ public String getProperty() {
+ return propertyPath;
+ }
+
+ /**
+ * Sets the input DataSource for this Property editor.
+ *
+ * @param input
+ */
+ public void setInput(DataSource input) {
+ this.input = input;
+ checkInput();
+ }
+
+ /**
+ * @return the input DataSource for this Property editor
+ */
+ public DataSource getInput() {
+ return input;
+ }
+
+ /**
+ * @return the formatted property name for this Property Editor
+ */
+ protected String getLabel() {
+ if(customLabel != null) {
+ return customLabel;
+ }
+
+ Property property = getModelProperty();
+ if(property == null || property.getLabel() == null || property.getLabel().trim().equals("")) { //$NON-NLS-1$
+ return Util.getLabel(getLocalPropertyPath());
+ }
+
+ return property.getLabel();
+ }
+
+ /**
+ * Updates the description for this PropertyEditor.
+ * The description is the widget's ToolTipText
+ */
+ protected void updateDescription() {
+ String description = ""; //$NON-NLS-1$
+ Property property = getModelProperty();
+ if(property != null) {
+ description = property.getDescription();
+ }
+
+ //Append the propertyPath to the description
+ if(description == null || description.trim().equals("")) { //$NON-NLS-1$
+ description = getLocalPropertyPath();
+ } else {
+ description = Util.resizeString(description, descriptionMaxCharPerLine);
+ description = getLocalPropertyPath() + ": " + description;
+ }
+
+ if(valueEditor != null) {
+ valueEditor.setToolTipText(description);
+ } else if(listEditor != null) {
+ listEditor.setToolTipText(description);
+ }
+ }
+
+ /**
+ * Finds the property associated to the Editor's {@link #propertyPath}
+ *
+ * @return The property associated to the Editor's {@link #propertyPath}
+ */
+ protected Property getModelProperty() {
+ if(propertyPath == null) {
+ return null;
+ }
+ Context context = getContext();
+ return ConfigurationManager.instance.getProperty(propertyPath, context);
+ }
+
+ private Context getContext() {
+ if(input == null) {
+ return null;
+ } else {
+ return input.getView().getContext();
+ }
+ }
+
+ /**
+ * Marks this editor as readOnly
+ *
+ * @param readOnly
+ */
+ public void setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ getEditor().setReadOnly(getReadOnly());
+ }
+
+ /**
+ * @return the AbstractEditor for this PropertyEditor
+ */
+ public AbstractEditor getEditor() {
+ return valueEditor == null ? listEditor : valueEditor;
+ }
+
+ /**
+ * Tests if this editor is read-only
+ *
+ * @return
+ * True if this editor is read-only
+ */
+ public boolean getReadOnly() {
+ boolean result = readOnly || !isEditable;
+ return result;
+ }
+
+ /**
+ * @return the IObservableList for this propertyEditor, or null if it is not
+ * available
+ */
+ protected IObservableList getInputObservableList() {
+ if(observableList == null) {
+ try {
+ observableList = (IObservableList)input.getObservable(propertyPath);
+ } catch (Exception ex) {
+ Activator.log.error("Cannot find a valid IObservable for " + propertyPath, ex); //$NON-NLS-1$
+ }
+ }
+
+ return observableList;
+ }
+
+ /**
+ * @return the IObservableValue for this propertyEditor, or null if it is not
+ * available
+ */
+ protected IObservableValue getInputObservableValue() {
+ if(observableValue == null) {
+ try {
+ observableValue = (IObservableValue)input.getObservable(propertyPath);
+ } catch (Exception ex) {
+ Activator.log.error("Cannot find a valid IObservable for " + propertyPath, ex); //$NON-NLS-1$
+ }
+ }
+
+ return observableValue;
+ }
+
+ /**
+ * Returns the IObservable for this propertyEditor, or null if it is
+ * not available
+ *
+ * @return The IObservable associated to this propertyEditor
+ */
+ protected IObservable getInputObservable() {
+ if(listEditor != null) {
+ return getInputObservableList();
+ }
+ if(valueEditor != null) {
+ return getInputObservableValue();
+ }
+ return null;
+ }
+
+ /**
+ * @return the last segment of the property path (Which is the property name)
+ */
+ protected String getLocalPropertyPath() {
+ return propertyPath.substring(propertyPath.lastIndexOf(":") + 1); //$NON-NLS-1$
+ }
+
+ /**
+ * Sets the editor's Layout Data
+ *
+ * @param data
+ */
+ public void setLayoutData(Object data) {
+ if(getEditor() != null) {
+ getEditor().setLayoutData(data);
+ }
+ }
+
+ /**
+ * Returns the editor's Layout Data
+ *
+ * @return
+ * The editor's layout data
+ */
+ public Object getLayoutData() {
+ return getEditor() == null ? null : getEditor().getLayoutData();
+ }
+
+ /**
+ * Indicates whether the editor's label should be displayed or not
+ *
+ * @param showLabel
+ */
+ public void setShowLabel(boolean showLabel) {
+ AbstractEditor editor = getEditor();
+ this.showLabel = showLabel;
+ if(editor != null) {
+ editor.setDisplayLabel(showLabel);
+ }
+ }
+
+ /**
+ * Indicates whether the editor's label is displayed or not
+ *
+ * @return
+ * true if the label should be displayed
+ */
+ public boolean getShowLabel() {
+ return this.showLabel;
+ }
+
+ /**
+ * Sets the label for this editor. The label will replace the property's
+ * default label
+ *
+ * @param customLabel
+ * The label to use with this property editor
+ */
+ public void setCustomLabel(String customLabel) {
+ this.customLabel = customLabel;
+ updateLabel();
+ }
+
+ /**
+ * @return the custom label used by this property editor. May be null
+ */
+ public String getCustomLabel() {
+ return this.customLabel;
+ }
+
+ /**
+ * @return the Control defined by this Property Editor
+ */
+ public Control getControl() {
+ if(valueEditor == null) {
+ return listEditor;
+ }
+ return valueEditor;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCheckbox.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCheckbox.java
new file mode 100644
index 00000000000..176d1a1de6f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCheckbox.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing booleans through a CheckBox
+ *
+ * @see org.eclipse.papyrus.widgets.editors.BooleanCheckbox
+ *
+ * @author Camille Letavernier
+ */
+public class BooleanCheckbox extends AbstractPropertyEditor {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public BooleanCheckbox(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.BooleanCheckbox(parent, style));
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCombo.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCombo.java
new file mode 100644
index 00000000000..bff4d275fd5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanCombo.java
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing booleans through a ComboBox
+ *
+ * @see org.eclipse.papyrus.widgets.editors.BooleanCombo
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class BooleanCombo extends AbstractPropertyEditor {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public BooleanCombo(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.BooleanRadio(parent, style));
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanRadio.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanRadio.java
new file mode 100644
index 00000000000..1c97ea7261c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanRadio.java
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing booleans with two Radio buttons
+ *
+ * @see org.eclipse.papyrus.widgets.editors.BooleanRadio
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class BooleanRadio extends AbstractPropertyEditor {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public BooleanRadio(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.BooleanRadio(parent, style));
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanToggle.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanToggle.java
new file mode 100644
index 00000000000..b6269020f21
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/BooleanToggle.java
@@ -0,0 +1,85 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * A Widget for editing Booleans. The widget is a button with two states.
+ * The button can have either an image or a text
+ *
+ * @author Camille Letavernier
+ */
+public class BooleanToggle extends AbstractPropertyEditor {
+
+ private org.eclipse.papyrus.widgets.editors.BooleanToggle toggle;
+
+ private String imagePath;
+
+ private String text;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The parent in which the widget will be created
+ * @param style
+ */
+ public BooleanToggle(Composite parent, int style) {
+ toggle = new org.eclipse.papyrus.widgets.editors.BooleanToggle(parent, style);
+ setEditor(toggle);
+ }
+
+ /**
+ * Sets this button's text
+ *
+ * @param text
+ */
+ public void setText(String text) {
+ toggle.setText(this.text = text);
+ }
+
+ /**
+ * Return this button's text
+ *
+ * @return this button's text
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * Sets this button's image
+ *
+ * @param imagePath
+ * The path to the image, in the form /<plug-in>/<path>
+ */
+ public void setImage(String imagePath) {
+ this.imagePath = imagePath;
+ Image image = Activator.getDefault().getImageFromPlugin(imagePath);
+ toggle.setImage(image);
+ }
+
+ /**
+ * Returns the path to this editor's image
+ *
+ * @return
+ * The path to this editor's image
+ */
+ public String getImage() {
+ return imagePath;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumCombo.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumCombo.java
new file mode 100644
index 00000000000..5e65ae425b4
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumCombo.java
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing enumerations through a ComboBox
+ *
+ * @see org.eclipse.papyrus.widgets.editors.BooleanCheckbox
+ *
+ * @author Camille Letavernier
+ */
+public class EnumCombo extends AbstractPropertyEditor {
+
+ /**
+ * The EnumCombo widget
+ */
+ protected org.eclipse.papyrus.widgets.editors.EnumCombo enumCombo;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public EnumCombo(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.EnumCombo(parent, style));
+ enumCombo = (org.eclipse.papyrus.widgets.editors.EnumCombo)valueEditor;
+ }
+
+ /**
+ * @Problem : The different options come from input.
+ * When we don't have an input (e.g. : during preview),
+ * we don't have the different values, and we can't
+ * display the correct preview.
+ * @TODO : Retrieve the values from the DataContext if possible.
+ */
+ @Override
+ protected void doBinding() {
+ enumCombo.setProviders(input.getContentProvider(propertyPath), input.getLabelProvider(propertyPath));
+
+ enumCombo.setUnsettable(!input.isMandatory(propertyPath));
+
+ super.doBinding();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumRadio.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumRadio.java
new file mode 100644
index 00000000000..38c3b77fd06
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/EnumRadio.java
@@ -0,0 +1,76 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing booleans with radio buttons.
+ * This Editor should only be used with Enums which have only
+ * a small amount of values.
+ *
+ * @see org.eclipse.papyrus.widgets.editors.EnumRadio
+ *
+ * @author Camille Letavernier
+ */
+public class EnumRadio extends AbstractPropertyEditor {
+
+ /**
+ * The EnumRadio widget
+ */
+ protected org.eclipse.papyrus.widgets.editors.EnumRadio enumRadio;
+
+ private int numColumns = -1;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public EnumRadio(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.EnumRadio(parent, style));
+ enumRadio = (org.eclipse.papyrus.widgets.editors.EnumRadio)valueEditor;
+ }
+
+ /**
+ * Sets the maximum number of columns for this editor. The radio values
+ * will be distributed according to this number
+ *
+ * @param numColumns
+ */
+ public void setNumColumns(int numColumns) {
+ this.numColumns = numColumns;
+ enumRadio.setNumColumns(numColumns);
+ }
+
+ /**
+ * Return the maximum number of columns for this editor
+ *
+ * @return
+ * The number of columns for this editor
+ */
+ public int getNumColumns() {
+ return numColumns;
+ }
+
+ @Override
+ protected void doBinding() {
+ enumRadio.setProviders(input.getContentProvider(propertyPath), input.getLabelProvider(propertyPath));
+
+ //enumRadio.setUnsettable(! input.isMandatory(propertyPath));
+
+ super.doBinding();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerEditor.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerEditor.java
new file mode 100644
index 00000000000..4fb3f9a82be
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerEditor.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing integers through a Text field
+ *
+ * @see org.eclipse.papyrus.widgets.editors.IntegerEditor
+ *
+ * @author Camille Letavernier
+ */
+public class IntegerEditor extends AbstractPropertyEditor {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public IntegerEditor(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.IntegerEditor(parent, style));
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerMask.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerMask.java
new file mode 100644
index 00000000000..1b82f696629
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerMask.java
@@ -0,0 +1,101 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.papyrus.properties.providers.XWTCompliantMaskProvider;
+import org.eclipse.papyrus.properties.providers.XWTCompliantMaskProviderListener;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A widget to edit mask-based Integer values
+ * The integer value is interpreted as a list of boolean values
+ * The widget cannot use more than 32 masks
+ *
+ * @author Camille Letavernier
+ */
+public class IntegerMask extends AbstractPropertyEditor implements XWTCompliantMaskProviderListener {
+
+ private org.eclipse.papyrus.widgets.editors.IntegerMask editor;
+
+ private XWTCompliantMaskProvider maskProvider;
+
+ private boolean maskProviderReady = false;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which this widget will be created
+ * @param style
+ */
+ public IntegerMask(Composite parent, int style) {
+ editor = new org.eclipse.papyrus.widgets.editors.IntegerMask(parent, style);
+ setEditor(editor);
+ }
+
+ @Override
+ protected void checkInput() {
+ if(maskProvider != null && maskProviderReady) {
+ super.checkInput();
+ }
+ }
+
+ /**
+ * @return the number of columns for this editor
+ *
+ */
+ public int getNumColumns() {
+ return editor.getNumColumns();
+ }
+
+ /**
+ * Sets the number of columns for this editor. The mask checkboxes will be
+ * distributed according to this number
+ *
+ * @param numColumns
+ */
+ public void setNumColumns(int numColumns) {
+ editor.setNumColumns(numColumns);
+ }
+
+ /**
+ * Sets the MaskProvider for this editor
+ *
+ * @param provider
+ */
+ public void setMaskProvider(XWTCompliantMaskProvider provider) {
+ if(this.maskProvider != null) {
+ maskProvider.removeMaskProviderListener(this);
+ }
+
+ maskProviderReady = false;
+ this.maskProvider = provider;
+ provider.addMaskProviderListener(this);
+ checkInput();
+ }
+
+ /**
+ *
+ * @return the MaskProvider associated to this editor
+ */
+ public XWTCompliantMaskProvider getMaskProvider() {
+ return maskProvider;
+ }
+
+ public void notifyReady(XWTCompliantMaskProvider provider) {
+ this.maskProviderReady = true;
+ editor.setMasks(maskProvider.getMasks());
+ provider.removeMaskProviderListener(this);
+ checkInput();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerSpinner.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerSpinner.java
new file mode 100644
index 00000000000..7bfa1b9b82d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/IntegerSpinner.java
@@ -0,0 +1,92 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A widget for editing Integer values with a SWT Spinner
+ *
+ * @author Camille Letavernier
+ *
+ * @see org.eclipse.papyrus.widgets.editors.IntegerSpinner
+ * @see org.eclipse.swt.widgets.Spinner
+ */
+public class IntegerSpinner extends AbstractPropertyEditor {
+
+ private org.eclipse.papyrus.widgets.editors.IntegerSpinner spinner;
+
+ private int minimum = 0, maximum = 100, increment = 1;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ */
+ public IntegerSpinner(Composite parent, int style) {
+ spinner = new org.eclipse.papyrus.widgets.editors.IntegerSpinner(parent, style);
+ spinner.setMinimum(minimum);
+ spinner.setMaximum(maximum);
+ spinner.setIncrement(increment);
+ setEditor(spinner);
+ }
+
+ /**
+ * @return the minimum value for the spinner
+ */
+ public int getMinimum() {
+ return minimum;
+ }
+
+ /**
+ * @param minimum
+ * the minimum value for the spinner
+ */
+ public void setMinimum(int minimum) {
+ this.minimum = minimum;
+ spinner.setMinimum(minimum);
+ }
+
+ /**
+ * @return the maximum value for the spinner
+ */
+ public int getMaximum() {
+ return maximum;
+ }
+
+ /**
+ * @param maximum
+ * the maximum value for the spinner
+ */
+ public void setMaximum(int maximum) {
+ this.maximum = maximum;
+ spinner.setMaximum(maximum);
+ }
+
+ /**
+ * @return the increment value for the spinner
+ */
+ public int getIncrement() {
+ return increment;
+ }
+
+ /**
+ * @param increment
+ * the increment value for the spinner
+ */
+ public void setIncrement(int increment) {
+ this.increment = increment;
+ spinner.setIncrement(increment);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/InvalidWidget.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/InvalidWidget.java
new file mode 100644
index 00000000000..d7c3f968a77
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/InvalidWidget.java
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.widgets.editors.StringLabel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A class for displaying invalid widgets without raising Java errors
+ * The widget will display an error, and may display the property label
+ * if it is available
+ *
+ * @author Camille Letavernier
+ */
+public class InvalidWidget extends AbstractPropertyEditor {
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * The Composite in which the editor will be created
+ * @param style
+ * The style to apply to the editor
+ */
+ public InvalidWidget(Composite parent, int style) {
+ super();
+ StringLabel editor = new StringLabel(parent, style);
+ setEditor(editor);
+
+ editor.getValueLabel().setText("Property view Error : invalid widget type"); //$NON-NLS-1$
+ editor.getValueLabel().setImage(Activator.getDefault().getImage("icons/error.gif")); //$NON-NLS-1$
+ }
+
+ @Override
+ public void doBinding() {
+ //Skip to avoid the binding between the property's value and the CLabel
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MaskProvider.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MaskProvider.java
new file mode 100644
index 00000000000..4195a6fc95c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MaskProvider.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import java.util.Map;
+
+/**
+ * An interface for providing Masks for editing mask-based integer values
+ *
+ * @author Camille Letavernier
+ *
+ * @see IntegerMask
+ */
+public interface MaskProvider {
+
+ /**
+ * @return the list of masks and their String descriptions
+ */
+ public Map<Integer, String> getMasks();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiInteger.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiInteger.java
new file mode 100644
index 00000000000..3a271a4985e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiInteger.java
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.widgets.editors.MultipleIntegerEditor;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing multiple integers in a List
+ *
+ * @see org.eclipse.papyrus.widgets.editors.MultipleIntegerEditor
+ *
+ * @author Camille Letavernier
+ */
+public class MultiInteger extends AbstractPropertyEditor {
+
+ /**
+ * The MultipleIntegerEditor widget
+ */
+ protected MultipleIntegerEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public MultiInteger(Composite parent, int style) {
+ editor = new MultipleIntegerEditor(parent, style);
+ super.setEditor(editor);
+ }
+
+ @Override
+ protected void doBinding() {
+ editor.setOrdered(input.isOrdered(propertyPath));
+ editor.setUnique(input.isUnique(propertyPath));
+
+ if(getInputObservableList() instanceof ICommitListener) {
+ editor.addCommitListener((ICommitListener)getInputObservableList());
+ }
+
+ super.doBinding();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReference.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReference.java
new file mode 100644
index 00000000000..85d2bdc178d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReference.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.widgets.editors.MultipleReferenceEditor;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing multiple references in a List
+ *
+ * @see org.eclipse.papyrus.widgets.editors.BooleanCheckbox
+ *
+ * @author Camille Letavernier
+ */
+public class MultiReference extends AbstractPropertyEditor {
+
+ /**
+ * The MultipleReferenceEditor widget
+ */
+ protected MultipleReferenceEditor editor;
+
+ /**
+ * The ReferenceValueFactory allowing creation and direct editing of values
+ */
+ protected ReferenceValueFactory factory;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public MultiReference(Composite parent, int style) {
+ editor = new MultipleReferenceEditor(parent, style);
+ super.setEditor(editor);
+ }
+
+ @Override
+ protected void doBinding() {
+ IStaticContentProvider contentProvider = input.getContentProvider(propertyPath);
+ ILabelProvider labelProvider = input.getLabelProvider(propertyPath);
+
+ if(getInputObservableList() instanceof ICommitListener) {
+ editor.addCommitListener((ICommitListener)getInputObservableList());
+ }
+
+ editor.setProviders(contentProvider, labelProvider);
+ editor.setOrdered(input.isOrdered(propertyPath));
+ editor.setUnique(input.isUnique(propertyPath));
+ if(factory == null) {
+ editor.setFactory(input.getValueFactory(propertyPath));
+ } else {
+ editor.setFactory(factory);
+ }
+ editor.setDirectCreation(input.getDirectCreation(propertyPath));
+
+ super.doBinding();
+ }
+
+ /**
+ * Sets the {@link ReferenceValueFactory} for this Editor. The factory
+ * allows creation and direct edition of objects.
+ *
+ * @param factory
+ */
+ public void setFactory(ReferenceValueFactory factory) {
+ this.factory = factory;
+ editor.setFactory(factory);
+ }
+
+ /**
+ * @return the {@link ReferenceValueFactory} used by this editor
+ */
+ public ReferenceValueFactory getFactory() {
+ return factory;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferenceEditorWithPropertyView.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferenceEditorWithPropertyView.java
new file mode 100644
index 00000000000..e664556ef24
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferenceEditorWithPropertyView.java
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import java.util.Set;
+
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+import org.eclipse.papyrus.properties.runtime.EmbeddedDisplayEngine;
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.widgets.editors.AbstractListEditor;
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.widgets.editors.MultipleReferenceEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+
+public class MultiReferenceEditorWithPropertyView extends AbstractListEditor implements ISelectionChangedListener {
+
+ protected MultipleReferenceEditor multiReferenceEditor;
+
+ protected Composite propertiesComposite;
+
+ protected EmbeddedDisplayEngine displayEngine = new EmbeddedDisplayEngine();
+
+ public MultiReferenceEditorWithPropertyView(Composite parent, int style) {
+ super(parent, style);
+ // parent.setBackground(getDisplay().getSystemColor(SWT.COLOR_RED));
+ ((GridLayout)getLayout()).numColumns++;
+
+ multiReferenceEditor = new MultipleReferenceEditor(this, style);
+ multiReferenceEditor.addSelectionChangedListener(this);
+ multiReferenceEditor.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, true));
+
+ propertiesComposite = new Composite(this, style);
+ propertiesComposite.setLayout(new FillLayout());
+ propertiesComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ }
+
+ @Override
+ public GridData getDefaultLayoutData() {
+ GridData data = super.getDefaultLayoutData();
+ data.grabExcessVerticalSpace = true;
+ data.grabExcessHorizontalSpace = true;
+ data.verticalAlignment = SWT.FILL;
+ return data;
+ }
+
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ multiReferenceEditor.setReadOnly(readOnly);
+ propertiesComposite.setEnabled(!readOnly);
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return multiReferenceEditor.isReadOnly();
+ }
+
+ @Override
+ public void setToolTipText(String text) {
+ multiReferenceEditor.setToolTipText(text);
+ }
+
+ @Override
+ public void setLabel(String label) {
+ multiReferenceEditor.setLabel(label);
+ }
+
+ public void setOrdered(boolean ordered) {
+ multiReferenceEditor.setOrdered(ordered);
+ }
+
+ public void setUnique(boolean unique) {
+ multiReferenceEditor.setUnique(unique);
+ }
+
+ @Override
+ public void setModelObservable(IObservableList modelObservable) {
+ multiReferenceEditor.setModelObservable(modelObservable);
+ //TODO : Set the initial selection (first element) to the editor
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ multiReferenceEditor.removeSelectionChangedListener(this);
+ }
+
+ public void selectionChanged(SelectionChangedEvent event) {
+ ISelection selection = event.getSelection();
+
+ Set<View> views = ConfigurationManager.instance.constraintEngine.getViews(selection);
+ displayEngine.display(views, propertiesComposite, selection, SWT.NONE);
+ this.layout();
+ propertiesComposite.layout();
+
+ //TODO : How can we force the property view layout ?
+ //In the tabbed property view, we need to go up to the 4th parent
+ getParent().layout(); //This one works in the embedded editor
+
+ // In the Eclipse Tabbed Property View, we need to go this far...
+ // getParent().getParent().getParent().getParent().layout();
+ }
+
+ public void setFactory(ReferenceValueFactory valueFactory) {
+ multiReferenceEditor.setFactory(valueFactory);
+ }
+
+ public void setDirectCreation(boolean directCreation) {
+ multiReferenceEditor.setDirectCreation(directCreation);
+ }
+
+ public void setLabelProvider(ILabelProvider labelProvider) {
+ multiReferenceEditor.setLabelProvider(labelProvider);
+ }
+
+ @Override
+ public void addCommitListener(ICommitListener commitListener) {
+ multiReferenceEditor.addCommitListener(commitListener);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferencePropertyEditorWithPropertyView.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferencePropertyEditorWithPropertyView.java
new file mode 100644
index 00000000000..b17ad1c2c7d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiReferencePropertyEditorWithPropertyView.java
@@ -0,0 +1,49 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+import org.eclipse.swt.widgets.Composite;
+
+
+public class MultiReferencePropertyEditorWithPropertyView extends AbstractPropertyEditor {
+
+ protected MultiReferenceEditorWithPropertyView editor;
+
+ public MultiReferencePropertyEditorWithPropertyView(Composite parent, int style){
+ editor = new MultiReferenceEditorWithPropertyView(parent, style);
+ setEditor(editor);
+ }
+
+ @Override
+ protected void doBinding() {
+ // IStaticContentProvider contentProvider = input.getContentProvider(propertyPath);
+ ILabelProvider labelProvider = input.getLabelProvider(propertyPath);
+
+ if(getInputObservableList() instanceof ICommitListener) {
+ editor.addCommitListener((ICommitListener)getInputObservableList());
+ }
+
+ if(labelProvider != null) {
+ editor.setLabelProvider(labelProvider);
+ }
+
+ editor.setOrdered(input.isOrdered(propertyPath));
+ editor.setUnique(input.isUnique(propertyPath));
+
+ editor.setFactory(input.getValueFactory(propertyPath));
+ editor.setDirectCreation(input.getDirectCreation(propertyPath));
+
+ super.doBinding();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiString.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiString.java
new file mode 100644
index 00000000000..0d78333cb02
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/MultiString.java
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.papyrus.widgets.editors.ICommitListener;
+import org.eclipse.papyrus.widgets.editors.MultipleStringEditor;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing multiple strings in a list
+ *
+ * @see org.eclipse.papyrus.widgets.editors.MultipleStringEditor
+ *
+ * @author Camille Letavernier
+ */
+public class MultiString extends AbstractPropertyEditor {
+
+ /**
+ * The MultipleStringEditor widget
+ */
+ protected MultipleStringEditor editor;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public MultiString(Composite parent, int style) {
+ editor = new MultipleStringEditor(parent, style);
+ super.setEditor(editor);
+ }
+
+ @Override
+ protected void doBinding() {
+ editor.setOrdered(input.isOrdered(propertyPath));
+ editor.setUnique(input.isUnique(propertyPath));
+
+ if(getInputObservableList() instanceof ICommitListener) {
+ editor.addCommitListener((ICommitListener)getInputObservableList());
+ }
+
+ super.doBinding();
+ }
+
+ /**
+ *
+ * @return the ListViewer associated to this editor
+ */
+ public TreeViewer getViewer() {
+ return editor.getViewer();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceCombo.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceCombo.java
new file mode 100644
index 00000000000..5331f4b9069
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceCombo.java
@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.papyrus.properties.providers.EncapsulatedComboViewer;
+import org.eclipse.papyrus.widgets.providers.HierarchicToFlatContentProvider;
+import org.eclipse.papyrus.widgets.providers.IHierarchicContentProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+import org.eclipse.papyrus.widgets.providers.TreeToFlatContentProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing references through a ComboBox
+ *
+ * @see org.eclipse.papyrus.widgets.editors.ReferenceCombo
+ *
+ * @author Camille Letavernier
+ */
+public class ReferenceCombo extends AbstractPropertyEditor {
+
+ /**
+ * The ReferenceCombo widget
+ */
+ protected org.eclipse.papyrus.widgets.editors.ReferenceCombo combo;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public ReferenceCombo(Composite parent, int style) {
+ combo = new org.eclipse.papyrus.widgets.editors.ReferenceCombo(parent, style);
+ super.setEditor(combo);
+ }
+
+ @Override
+ protected void doBinding() {
+ IStaticContentProvider contentProvider = input.getContentProvider(propertyPath);
+ if(contentProvider instanceof IHierarchicContentProvider) {
+ contentProvider = new HierarchicToFlatContentProvider((IHierarchicContentProvider)contentProvider);
+ combo.setViewer(new EncapsulatedComboViewer(combo.getViewer()));
+ } else if(contentProvider instanceof ITreeContentProvider) {
+ contentProvider = new TreeToFlatContentProvider((ITreeContentProvider)contentProvider);
+ combo.setViewer(new EncapsulatedComboViewer(combo.getViewer()));
+ }
+
+ ILabelProvider labelProvider = input.getLabelProvider(propertyPath);
+
+ combo.setProviders(contentProvider, labelProvider);
+ combo.setUnsettable(!input.isMandatory(propertyPath));
+
+ super.doBinding();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceDialog.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceDialog.java
new file mode 100644
index 00000000000..4f3e1ad0a55
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceDialog.java
@@ -0,0 +1,85 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.papyrus.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing references through a Dialog
+ *
+ * @see org.eclipse.papyrus.widgets.editors.ReferenceDialog
+ *
+ * @author Camille Letavernier
+ */
+public class ReferenceDialog extends AbstractPropertyEditor {
+
+ /**
+ * The ReferenceDialog widget
+ */
+ protected org.eclipse.papyrus.widgets.editors.ReferenceDialog editor;
+
+ /**
+ * The ValueFactory used to create or edit Objects directly from
+ * this editor
+ */
+ protected ReferenceValueFactory factory;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public ReferenceDialog(Composite parent, int style) {
+ editor = new org.eclipse.papyrus.widgets.editors.ReferenceDialog(parent, style);
+ setEditor(editor);
+ }
+
+ @Override
+ protected void doBinding() {
+ IStaticContentProvider provider = input.getContentProvider(propertyPath);
+ editor.setLabelProvider(input.getLabelProvider(propertyPath));
+ editor.setContentProvider(provider);
+ editor.setDirectCreation(input.getDirectCreation(propertyPath));
+ if(factory == null) { //Use the default factory from the DataSource
+ editor.setValueFactory(input.getValueFactory(propertyPath));
+ } else { //Use the factory explicitly specified
+ editor.setValueFactory(factory);
+ }
+
+ super.doBinding();
+ }
+
+ /**
+ * Sets the ValueFactory used to create or edit Objects directly from
+ * this editor
+ *
+ * @param factory
+ */
+ public void setFactory(ReferenceValueFactory factory) {
+ this.factory = factory;
+ editor.setValueFactory(factory);
+ }
+
+ /**
+ * @return The ValueFactory used to create or edit Objects directly from
+ * this editor
+ */
+ public ReferenceValueFactory getFactory() {
+ return factory;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceLabel.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceLabel.java
new file mode 100644
index 00000000000..b9fe94b60bb
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ReferenceLabel.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.widgets.editors.StringLabel;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A property editor to display a reference's value as a CLabel, filled
+ * via a LabelProvider
+ *
+ * @author Camille Letavernier
+ *
+ */
+public class ReferenceLabel extends AbstractPropertyEditor {
+
+ private StringLabel editor;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ */
+ public ReferenceLabel(Composite parent, int style) {
+ editor = new StringLabel(parent, style);
+ setEditor(editor);
+ }
+
+ @Override
+ public void doBinding() {
+ ILabelProvider labelProvider = input.getLabelProvider(propertyPath);
+ if(labelProvider != null) {
+ editor.setLabelProvider(labelProvider);
+ }
+
+ super.doBinding();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringCombo.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringCombo.java
new file mode 100644
index 00000000000..b4bae2d7ed5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringCombo.java
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Property Editor for editing a String with an editable combo.
+ * The combo proposes a set of default values.
+ *
+ * @author Camille Letavernier
+ */
+public class StringCombo extends AbstractPropertyEditor {
+
+ /**
+ * The StringCombo widget used by this property editor
+ */
+ protected org.eclipse.papyrus.widgets.editors.StringCombo editor;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ */
+ public StringCombo(Composite parent, int style) {
+ editor = new org.eclipse.papyrus.widgets.editors.StringCombo(parent, style);
+ super.setEditor(editor);
+ }
+
+ @Override
+ public void doBinding() {
+ IStaticContentProvider contentProvider = input.getContentProvider(propertyPath);
+ editor.setContentProvider(contentProvider);
+ editor.setUnsettable(!input.isMandatory(propertyPath));
+
+ ILabelProvider labelProvider = input.getLabelProvider(propertyPath);
+ if(labelProvider != null) {
+ editor.setLabelProvider(labelProvider);
+ }
+ super.doBinding();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringEditor.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringEditor.java
new file mode 100644
index 00000000000..75db72fb9fe
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringEditor.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing strings through a Text field
+ *
+ * @see org.eclipse.papyrus.widgets.editors.StringEditor
+ *
+ * @author Camille Letavernier
+ */
+public class StringEditor extends AbstractPropertyEditor {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public StringEditor(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.StringEditor(parent, style));
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringFileSelector.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringFileSelector.java
new file mode 100644
index 00000000000..7d817954d4f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringFileSelector.java
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A Widget for selecting Files on the workspace or on the file system.
+ * The widgets only edits String values : it uses the path of the files
+ *
+ * @author Camille Letavernier
+ */
+public class StringFileSelector extends AbstractPropertyEditor {
+
+ /**
+ * The StringFileSelector widget used by this property editor
+ */
+ protected org.eclipse.papyrus.widgets.editors.StringFileSelector selector;
+
+ /**
+ * The filtered extensions
+ * This should be a 1-1 mapping with {@link #filterNames}
+ */
+ protected String[] filterExtensions;
+
+ /**
+ * The name of the filters.
+ * This should be a 1-1 mapping with {@link #filterExtensions}
+ */
+ protected String[] filterNames;
+
+ /**
+ * Enables the "browse workspace" feature
+ */
+ protected boolean allowWorkspace = true;
+
+ /**
+ * Enables the "browse file system" feature
+ */
+ protected boolean allowFileSystem = true;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param parent
+ * @param style
+ */
+ public StringFileSelector(Composite parent, int style) {
+ selector = new org.eclipse.papyrus.widgets.editors.StringFileSelector(parent, style);
+ super.setEditor(selector);
+ }
+
+ /**
+ *
+ * @param filterExtensions
+ */
+ public void setFilterExtensions(String[] filterExtensions) {
+ this.filterExtensions = filterExtensions;
+ checkFilters();
+ }
+
+ /**
+ *
+ * @param filterNames
+ */
+ public void setFilterNames(String[] filterNames) {
+ this.filterNames = filterNames;
+ checkFilters();
+ }
+
+ /**
+ * Checks if the filters are valid
+ */
+ protected void checkFilters() {
+ if(filterExtensions != null && filterNames != null) {
+ //TODO
+ selector.setFilters(filterExtensions, filterNames);
+ }
+ }
+
+ /**
+ * Indicates whether the editor should allow browsing the workspace or not
+ *
+ * @param allowWorkspace
+ */
+ public void setAllowWorkspace(boolean allowWorkspace) {
+ this.allowWorkspace = allowWorkspace;
+ selector.setAllowWorkspace(allowWorkspace);
+ }
+
+ /**
+ *
+ * @return true if the editor can browse the workspace
+ */
+ public boolean getAllowWorkspace() {
+ return allowWorkspace;
+ }
+
+ /**
+ * Indicates whether the editor should allow browsing the file system or not
+ *
+ * @param allowFileSystem
+ */
+ public void setAllowFileSystem(boolean allowFileSystem) {
+ this.allowFileSystem = allowFileSystem;
+ selector.setAllowFileSystem(allowFileSystem);
+ }
+
+ /**
+ *
+ * @return true if the editor can browse the fileSystem
+ */
+ public boolean getAllowFileSystem() {
+ return allowFileSystem;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringLabel.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringLabel.java
new file mode 100644
index 00000000000..92fe145ff37
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringLabel.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.widgets;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for displaying strings as a CLabel
+ * This editor is read-only
+ *
+ * @see org.eclipse.papyrus.widgets.editors.StringLabel
+ *
+ * @author Camille Letavernier
+ */
+public class StringLabel extends AbstractPropertyEditor {
+
+ private org.eclipse.papyrus.widgets.editors.StringLabel editor;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public StringLabel(Composite parent, int style) {
+ editor = new org.eclipse.papyrus.widgets.editors.StringLabel(parent, style);
+ setEditor(editor);
+ }
+
+ @Override
+ protected void doBinding() {
+ ILabelProvider labelProvider = input.getLabelProvider(propertyPath);
+ editor.setLabelProvider(labelProvider);
+ super.doBinding();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringMultiline.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringMultiline.java
new file mode 100644
index 00000000000..889903e2a31
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/StringMultiline.java
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A PropertyEditor for editing multiline strings through a Text field
+ *
+ * @see org.eclipse.papyrus.widgets.editors.StringEditor
+ *
+ * @author Camille Letavernier
+ */
+public class StringMultiline extends AbstractPropertyEditor {
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public StringMultiline(Composite parent, int style) {
+ super(new org.eclipse.papyrus.widgets.editors.StringEditor(parent, style | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP));
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ViewEditor.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ViewEditor.java
new file mode 100644
index 00000000000..4886fffe5da
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/ViewEditor.java
@@ -0,0 +1,238 @@
+/*****************************************************************************
+ * 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.widgets;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.IObservable;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.papyrus.properties.Activator;
+import org.eclipse.papyrus.properties.contexts.Context;
+import org.eclipse.papyrus.properties.contexts.Section;
+import org.eclipse.papyrus.properties.contexts.View;
+import org.eclipse.papyrus.properties.databinding.MultipleObservableValue;
+import org.eclipse.papyrus.properties.runtime.ConfigurationManager;
+import org.eclipse.papyrus.properties.runtime.DefaultDisplayEngine;
+import org.eclipse.papyrus.properties.runtime.DisplayEngine;
+import org.eclipse.papyrus.properties.widgets.layout.PropertiesLayout;
+import org.eclipse.papyrus.properties.xwt.XWTSection;
+import org.eclipse.papyrus.widgets.editors.AbstractEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * An Editor for displaying a whole property {@link View} on a sub-object.
+ * If the property is a list, there will be one view per element in the list.
+ *
+ * The view's tabs will be ignored : the sections are embedded in the caller's
+ * tab.
+ */
+public class ViewEditor extends AbstractPropertyEditor {
+
+ private String viewPath;
+
+ private Composite self;
+
+ private Collection<XWTSection> sections;
+
+ /**
+ * Constructor.
+ *
+ * @param parent
+ * The composite in which the widget will be displayed
+ * @param style
+ * The style for the widget
+ */
+ public ViewEditor(Composite parent, int style) {
+ self = new Composite(parent, SWT.NONE);
+ PropertiesLayout layout = new PropertiesLayout(1, true);
+ layout.horizontalSpacing = 0;
+ layout.marginWidth = 0;
+ self.setLayout(layout);
+ }
+
+ @Override
+ public void checkInput() {
+ if(propertyPath != null && input != null && viewPath != null) {
+ display();
+ }
+ }
+
+ /**
+ * Sets the number of columns for this editor. If the property is a list,
+ * there will be one view per element in the list : these views will be
+ * distributed in the given number of columns.
+ *
+ * @param numColumns
+ */
+ public void setNumColumns(int numColumns) {
+ ((PropertiesLayout)self.getLayout()).numColumns = numColumns;
+ }
+
+ /**
+ * @return the number of columns for this editor.
+ */
+ public int getNumColumns() {
+ return ((PropertiesLayout)self.getLayout()).numColumns;
+ }
+
+ /**
+ * Sets the view for this editor. The view is represented by its viewPath, which is
+ * of form ContextName:ViewName
+ * e.g. : UML:Class
+ * The Context should be registered in the ConfigurationManager
+ *
+ * @param viewPath
+ * The path of the view used to display the given property
+ */
+ public void setView(String viewPath) {
+ this.viewPath = viewPath;
+ checkInput();
+ }
+
+ /**
+ * @return the qualified name of the view associated to this editor
+ */
+ public String getView() {
+ return viewPath;
+ }
+
+ private View resolveView() {
+ String contextName = viewPath.substring(0, viewPath.indexOf(":")); //$NON-NLS-1$
+ String viewName = viewPath.substring(viewPath.indexOf(":") + 1); //$NON-NLS-1$
+ Context context = ConfigurationManager.instance.getContext(contextName);
+ for(View view : context.getViews()) {
+ if(view.getName().equals(viewName)) {
+ return view;
+ }
+ }
+ return null;
+ }
+
+ private void display() {
+ View view = resolveView();
+
+ if(view == null) {
+ Activator.log.warn("Unabled to resolve view : " + viewPath); //$NON-NLS-1$
+ return;
+ }
+
+ IObservable observable = input.getObservable(propertyPath);
+ if(observable == null) {
+ return;
+ }
+
+ DisplayEngine display = new DefaultDisplayEngine(true);
+
+ sections = new LinkedList<XWTSection>();
+
+ if(observable instanceof IObservableValue) {
+ IObservableValue observableValue = (IObservableValue)observable;
+ if(observableValue instanceof MultipleObservableValue) {
+ MultipleObservableValue multipleObservable = (MultipleObservableValue)observableValue;
+ display(display, multipleObservable.getObservedValues(), view);
+ } else {
+ Object value = observableValue.getValue();
+ display(display, value, view);
+ }
+ } else if(observable instanceof IObservableList) {
+ IObservableList observableList = (IObservableList)observable;
+ for(Object value : observableList) {
+ display(display, value, view);
+ }
+ }
+
+ updateControls();
+ }
+
+ /**
+ * Displays the given view in the display engine, with the given object.
+ *
+ * @param display
+ * The Display engine used to display the view. It should allow duplication,
+ * as for list properties, the same section will be displayed for each element
+ * in the list.
+ * @param data
+ * The raw object for which we are displaying the view.
+ * @param view
+ * The view to display
+ */
+ protected void display(DisplayEngine display, Object data, View view) {
+ display(display, Collections.singletonList(data), view);
+ }
+
+ /**
+ * Displays the given view in the display engine, with the given object.
+ *
+ * @param display
+ * The Display engine used to display the view. It should allow duplication,
+ * as for list properties, the same section will be displayed for each element
+ * in the list.
+ * @param selectedElements
+ * The list of objects for which we are displaying the view
+ * @param view
+ * The view to display
+ */
+ protected void display(DisplayEngine display, List<Object> selectedElements, View view) {
+ for(Section section : view.getSections()) {
+ XWTSection xwtSection = new XWTSection(section, view, display);
+ sections.add(xwtSection);
+
+ ISelection selection = new StructuredSelection(selectedElements);
+
+ xwtSection.createControls(new Composite(self, SWT.NONE), null);
+ xwtSection.setInput(null, selection);
+ xwtSection.refresh();
+ }
+ }
+
+ /**
+ * Updates the displayed widgets to mark them as readOnly if needed.
+ */
+ protected void updateControls() {
+ for(Control container : self.getChildren()) {
+ if(container instanceof Composite) {
+ for(Control control : ((Composite)container).getChildren()) {
+ if(control instanceof AbstractEditor) {
+ AbstractEditor editor = (AbstractEditor)control;
+ editor.setReadOnly(getReadOnly() || editor.isReadOnly());
+ }
+ }
+ }
+ }
+
+ self.setEnabled(!getReadOnly());
+ }
+
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ super.setReadOnly(readOnly);
+ updateControls();
+ }
+
+ @Override
+ protected void doBinding() {
+ //Nothing to do here
+ }
+
+ @Override
+ public Control getControl() {
+ return self;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/GridData.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/GridData.java
new file mode 100644
index 00000000000..17bdfb12263
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/GridData.java
@@ -0,0 +1,639 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation (org.eclipse.swt.layout.GridData)
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ *******************************************************************************/
+package org.eclipse.papyrus.properties.widgets.layout;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * <code>GridData</code> is the layout data object associated with <code>GridLayout</code>. To set a <code>GridData</code> object into a
+ * control, you use the <code>Control.setLayoutData(Object)</code> method.
+ * <p>
+ * There are two ways to create a <code>GridData</code> object with certain fields set. The first is to set the fields directly, like this:
+ *
+ * <pre>
+ * GridData gridData = new GridData();
+ * gridData.horizontalAlignment = GridData.FILL;
+ * gridData.grabExcessHorizontalSpace = true;
+ * button1.setLayoutData(gridData);
+ *
+ * gridData = new GridData();
+ * gridData.horizontalAlignment = GridData.FILL;
+ * gridData.verticalAlignment = GridData.FILL;
+ * gridData.grabExcessHorizontalSpace = true;
+ * gridData.grabExcessVerticalSpace = true;
+ * gridData.horizontalSpan = 2;
+ * button2.setLayoutData(gridData);
+ * </pre>
+ *
+ * The second is to take advantage of <code>GridData</code> convenience constructors, for example:
+ *
+ * <pre>
+ * button1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ * button2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+ * </pre>
+ *
+ * </p>
+ * <p>
+ * NOTE: Do not reuse <code>GridData</code> objects. Every control in a <code>Composite</code> that is managed by a <code>GridLayout</code> must have
+ * a unique <code>GridData</code> object. If the layout data for a control in a <code>GridLayout</code> is null at layout time, a unique
+ * <code>GridData</code> object is created for it.
+ * </p>
+ *
+ * @see PropertiesLayout
+ * @see Control#setLayoutData
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * @see org.eclipse.swt.layout.GridData
+ */
+public final class GridData {
+
+ /**
+ * verticalAlignment specifies how controls will be positioned
+ * vertically within a cell.
+ *
+ * The default value is CENTER.
+ *
+ * Possible values are:
+ * <ul>
+ * <li>SWT.BEGINNING (or SWT.TOP): Position the control at the top of the cell</li>
+ * <li>SWT.CENTER: Position the control in the vertical center of the cell</li>
+ * <li>SWT.END (or SWT.BOTTOM): Position the control at the bottom of the cell</li>
+ * <li>SWT.FILL: Resize the control to fill the cell vertically</li>
+ * </ul>
+ */
+ public int verticalAlignment = CENTER;
+
+ /**
+ * horizontalAlignment specifies how controls will be positioned
+ * horizontally within a cell.
+ *
+ * The default value is BEGINNING.
+ *
+ * Possible values are:
+ * <ul>
+ * <li>SWT.BEGINNING (or SWT.LEFT): Position the control at the left of the cell</li>
+ * <li>SWT.CENTER: Position the control in the horizontal center of the cell</li>
+ * <li>SWT.END (or SWT.RIGHT): Position the control at the right of the cell</li>
+ * <li>SWT.FILL: Resize the control to fill the cell horizontally</li>
+ * </ul>
+ */
+ public int horizontalAlignment = BEGINNING;
+
+ /**
+ * widthHint specifies the preferred width in pixels. This value
+ * is the wHint passed into Control.computeSize(int, int, boolean)
+ * to determine the preferred size of the control.
+ *
+ * The default value is SWT.DEFAULT.
+ *
+ * @see Control#computeSize(int, int, boolean)
+ */
+ public int widthHint = SWT.DEFAULT;
+
+ /**
+ * heightHint specifies the preferred height in pixels. This value
+ * is the hHint passed into Control.computeSize(int, int, boolean)
+ * to determine the preferred size of the control.
+ *
+ * The default value is SWT.DEFAULT.
+ *
+ * @see Control#computeSize(int, int, boolean)
+ */
+ public int heightHint = SWT.DEFAULT;
+
+ /**
+ * horizontalIndent specifies the number of pixels of indentation
+ * that will be placed along the left side of the cell.
+ *
+ * The default value is 0.
+ */
+ public int horizontalIndent = 0;
+
+ /**
+ * verticalIndent specifies the number of pixels of indentation
+ * that will be placed along the top side of the cell.
+ *
+ * The default value is 0.
+ *
+ * @since 3.1
+ */
+ public int verticalIndent = 0;
+
+ /**
+ * horizontalSpan specifies the number of column cells that the control
+ * will take up.
+ *
+ * The default value is 1.
+ */
+ public int horizontalSpan = 1;
+
+ /**
+ * verticalSpan specifies the number of row cells that the control
+ * will take up.
+ *
+ * The default value is 1.
+ */
+ public int verticalSpan = 1;
+
+ /**
+ * <p>
+ * grabExcessHorizontalSpace specifies whether the width of the cell changes depending on the size of the parent Composite. If
+ * grabExcessHorizontalSpace is <code>true</code>, the following rules apply to the width of the cell:
+ * </p>
+ * <ul>
+ * <li>If extra horizontal space is available in the parent, the cell will grow to be wider than its preferred width. The new width will be
+ * "preferred width + delta" where delta is the extra horizontal space divided by the number of grabbing columns.</li>
+ * <li>If there is not enough horizontal space available in the parent, the cell will shrink until it reaches its minimum width as specified by
+ * GridData.minimumWidth. The new width will be the maximum of "minimumWidth" and "preferred width - delta", where delta is the amount of space
+ * missing divided by the number of grabbing columns.</li>
+ * <li>If the parent is packed, the cell will be its preferred width as specified by GridData.widthHint.</li>
+ * <li>If the control spans multiple columns and there are no other grabbing controls in any of the spanned columns, the last column in the span
+ * will grab the extra space. If there is at least one other grabbing control in the span, the grabbing will be spread over the columns already
+ * marked as grabExcessHorizontalSpace.</li>
+ * </ul>
+ *
+ * <p>
+ * The default value is false.
+ * </p>
+ *
+ * @see GridData#minimumWidth
+ * @see GridData#widthHint
+ */
+ public boolean grabExcessHorizontalSpace = false;
+
+ /**
+ * <p>
+ * grabExcessVerticalSpace specifies whether the height of the cell changes depending on the size of the parent Composite. If
+ * grabExcessVerticalSpace is <code>true</code>, the following rules apply to the height of the cell:
+ * </p>
+ * <ul>
+ * <li>If extra vertical space is available in the parent, the cell will grow to be taller than its preferred height. The new height will be
+ * "preferred height + delta" where delta is the extra vertical space divided by the number of grabbing rows.</li>
+ * <li>If there is not enough vertical space available in the parent, the cell will shrink until it reaches its minimum height as specified by
+ * GridData.minimumHeight. The new height will be the maximum of "minimumHeight" and "preferred height - delta", where delta is the amount of
+ * space missing divided by the number of grabbing rows.</li>
+ * <li>If the parent is packed, the cell will be its preferred height as specified by GridData.heightHint.</li>
+ * <li>If the control spans multiple rows and there are no other grabbing controls in any of the spanned rows, the last row in the span will grab
+ * the extra space. If there is at least one other grabbing control in the span, the grabbing will be spread over the rows already marked as
+ * grabExcessVerticalSpace.</li>
+ * </ul>
+ *
+ * <p>
+ * The default value is false.
+ * </p>
+ *
+ * @see GridData#minimumHeight
+ * @see GridData#heightHint
+ */
+ public boolean grabExcessVerticalSpace = false;
+
+ /**
+ * minimumWidth specifies the minimum width in pixels. This value
+ * applies only if grabExcessHorizontalSpace is true. A value of
+ * SWT.DEFAULT means that the minimum width will be the result
+ * of Control.computeSize(int, int, boolean) where wHint is
+ * determined by GridData.widthHint.
+ *
+ * The default value is 0.
+ *
+ * @since 3.1
+ * @see Control#computeSize(int, int, boolean)
+ * @see GridData#widthHint
+ */
+ public int minimumWidth = 0;
+
+ /**
+ * minimumHeight specifies the minimum height in pixels. This value
+ * applies only if grabExcessVerticalSpace is true. A value of
+ * SWT.DEFAULT means that the minimum height will be the result
+ * of Control.computeSize(int, int, boolean) where hHint is
+ * determined by GridData.heightHint.
+ *
+ * The default value is 0.
+ *
+ * @since 3.1
+ * @see Control#computeSize(int, int, boolean)
+ * @see GridData#heightHint
+ */
+ public int minimumHeight = 0;
+
+ /**
+ * exclude informs the layout to ignore this control when sizing
+ * and positioning controls. If this value is <code>true</code>,
+ * the size and position of the control will not be managed by the
+ * layout. If this value is <code>false</code>, the size and
+ * position of the control will be computed and assigned.
+ *
+ * The default value is <code>false</code>.
+ *
+ * @since 3.1
+ */
+ public boolean exclude = false;
+
+ /**
+ * Value for horizontalAlignment or verticalAlignment.
+ * Position the control at the top or left of the cell.
+ * Not recommended. Use SWT.BEGINNING, SWT.TOP or SWT.LEFT instead.
+ */
+ public static final int BEGINNING = SWT.BEGINNING;
+
+ /**
+ * Value for horizontalAlignment or verticalAlignment.
+ * Position the control in the vertical or horizontal center of the cell
+ * Not recommended. Use SWT.CENTER instead.
+ */
+ public static final int CENTER = 2;
+
+ /**
+ * Value for horizontalAlignment or verticalAlignment.
+ * Position the control at the bottom or right of the cell
+ * Not recommended. Use SWT.END, SWT.BOTTOM or SWT.RIGHT instead.
+ */
+ public static final int END = 3;
+
+ /**
+ * Value for horizontalAlignment or verticalAlignment.
+ * Resize the control to fill the cell horizontally or vertically.
+ * Not recommended. Use SWT.FILL instead.
+ */
+ public static final int FILL = SWT.FILL;
+
+ /**
+ * Style bit for <code>new GridData(int)</code>.
+ * Position the control at the top of the cell.
+ * Not recommended. Use <code>new GridData(int, SWT.BEGINNING, boolean, boolean)</code> instead.
+ */
+ public static final int VERTICAL_ALIGN_BEGINNING = 1 << 1;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to position the
+ * control in the vertical center of the cell.
+ * Not recommended. Use <code>new GridData(int, SWT.CENTER, boolean, boolean)</code> instead.
+ */
+ public static final int VERTICAL_ALIGN_CENTER = 1 << 2;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to position the
+ * control at the bottom of the cell.
+ * Not recommended. Use <code>new GridData(int, SWT.END, boolean, boolean)</code> instead.
+ */
+ public static final int VERTICAL_ALIGN_END = 1 << 3;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to resize the
+ * control to fill the cell vertically.
+ * Not recommended. Use <code>new GridData(int, SWT.FILL, boolean, boolean)</code> instead
+ */
+ public static final int VERTICAL_ALIGN_FILL = 1 << 4;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to position the
+ * control at the left of the cell.
+ * Not recommended. Use <code>new GridData(SWT.BEGINNING, int, boolean, boolean)</code> instead.
+ */
+ public static final int HORIZONTAL_ALIGN_BEGINNING = 1 << 5;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to position the
+ * control in the horizontal center of the cell.
+ * Not recommended. Use <code>new GridData(SWT.CENTER, int, boolean, boolean)</code> instead.
+ */
+ public static final int HORIZONTAL_ALIGN_CENTER = 1 << 6;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to position the
+ * control at the right of the cell.
+ * Not recommended. Use <code>new GridData(SWT.END, int, boolean, boolean)</code> instead.
+ */
+ public static final int HORIZONTAL_ALIGN_END = 1 << 7;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to resize the
+ * control to fill the cell horizontally.
+ * Not recommended. Use <code>new GridData(SWT.FILL, int, boolean, boolean)</code> instead.
+ */
+ public static final int HORIZONTAL_ALIGN_FILL = 1 << 8;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to resize the
+ * control to fit the remaining horizontal space.
+ * Not recommended. Use <code>new GridData(int, int, true, boolean)</code> instead.
+ */
+ public static final int GRAB_HORIZONTAL = 1 << 9;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to resize the
+ * control to fit the remaining vertical space.
+ * Not recommended. Use <code>new GridData(int, int, boolean, true)</code> instead.
+ */
+ public static final int GRAB_VERTICAL = 1 << 10;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to resize the
+ * control to fill the cell vertically and to fit the remaining
+ * vertical space.
+ * FILL_VERTICAL = VERTICAL_ALIGN_FILL | GRAB_VERTICAL
+ * Not recommended. Use <code>new GridData(int, SWT.FILL, boolean, true)</code> instead.
+ */
+ public static final int FILL_VERTICAL = VERTICAL_ALIGN_FILL | GRAB_VERTICAL;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to resize the
+ * control to fill the cell horizontally and to fit the remaining
+ * horizontal space.
+ * FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL | GRAB_HORIZONTAL
+ * Not recommended. Use <code>new GridData(SWT.FILL, int, true, boolean)</code> instead.
+ */
+ public static final int FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL | GRAB_HORIZONTAL;
+
+ /**
+ * Style bit for <code>new GridData(int)</code> to resize the
+ * control to fill the cell horizontally and vertically and
+ * to fit the remaining horizontal and vertical space.
+ * FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL
+ * Not recommended. Use <code>new GridData(SWT.FILL, SWT.FILL, true, true)</code> instead.
+ */
+ public static final int FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL;
+
+ protected int cacheWidth = -1, cacheHeight = -1;
+
+ protected int defaultWhint, defaultHhint, defaultWidth = -1, defaultHeight = -1;
+
+ protected int currentWhint, currentHhint, currentWidth = -1, currentHeight = -1;
+
+ /**
+ * Constructs a new instance of GridData using
+ * default values.
+ */
+ public GridData() {
+ super();
+ }
+
+ /**
+ * Constructs a new instance based on the GridData style.
+ * This constructor is not recommended.
+ *
+ * @param style
+ * the GridData style
+ */
+ public GridData(int style) {
+ super();
+ if((style & VERTICAL_ALIGN_BEGINNING) != 0)
+ verticalAlignment = BEGINNING;
+ if((style & VERTICAL_ALIGN_CENTER) != 0)
+ verticalAlignment = CENTER;
+ if((style & VERTICAL_ALIGN_FILL) != 0)
+ verticalAlignment = FILL;
+ if((style & VERTICAL_ALIGN_END) != 0)
+ verticalAlignment = END;
+ if((style & HORIZONTAL_ALIGN_BEGINNING) != 0)
+ horizontalAlignment = BEGINNING;
+ if((style & HORIZONTAL_ALIGN_CENTER) != 0)
+ horizontalAlignment = CENTER;
+ if((style & HORIZONTAL_ALIGN_FILL) != 0)
+ horizontalAlignment = FILL;
+ if((style & HORIZONTAL_ALIGN_END) != 0)
+ horizontalAlignment = END;
+ grabExcessHorizontalSpace = (style & GRAB_HORIZONTAL) != 0;
+ grabExcessVerticalSpace = (style & GRAB_VERTICAL) != 0;
+ }
+
+ /**
+ * Constructs a new instance of GridData according to the parameters.
+ *
+ * @param horizontalAlignment
+ * how control will be positioned horizontally within a cell,
+ * one of: SWT.BEGINNING (or SWT.LEFT), SWT.CENTER, SWT.END (or SWT.RIGHT), or SWT.FILL
+ * @param verticalAlignment
+ * how control will be positioned vertically within a cell,
+ * one of: SWT.BEGINNING (or SWT.TOP), SWT.CENTER, SWT.END (or SWT.BOTTOM), or SWT.FILL
+ * @param grabExcessHorizontalSpace
+ * whether cell will be made wide enough to fit the remaining horizontal space
+ * @param grabExcessVerticalSpace
+ * whether cell will be made high enough to fit the remaining vertical space
+ *
+ * @since 3.0
+ */
+ public GridData(int horizontalAlignment, int verticalAlignment, boolean grabExcessHorizontalSpace, boolean grabExcessVerticalSpace) {
+ this(horizontalAlignment, verticalAlignment, grabExcessHorizontalSpace, grabExcessVerticalSpace, 1, 1);
+ }
+
+ /**
+ * Constructs a new instance of GridData according to the parameters.
+ *
+ * @param horizontalAlignment
+ * how control will be positioned horizontally within a cell,
+ * one of: SWT.BEGINNING (or SWT.LEFT), SWT.CENTER, SWT.END (or SWT.RIGHT), or SWT.FILL
+ * @param verticalAlignment
+ * how control will be positioned vertically within a cell,
+ * one of: SWT.BEGINNING (or SWT.TOP), SWT.CENTER, SWT.END (or SWT.BOTTOM), or SWT.FILL
+ * @param grabExcessHorizontalSpace
+ * whether cell will be made wide enough to fit the remaining horizontal space
+ * @param grabExcessVerticalSpace
+ * whether cell will be made high enough to fit the remaining vertical space
+ * @param horizontalSpan
+ * the number of column cells that the control will take up
+ * @param verticalSpan
+ * the number of row cells that the control will take up
+ *
+ * @since 3.0
+ */
+ public GridData(int horizontalAlignment, int verticalAlignment, boolean grabExcessHorizontalSpace, boolean grabExcessVerticalSpace, int horizontalSpan, int verticalSpan) {
+ super();
+ this.horizontalAlignment = horizontalAlignment;
+ this.verticalAlignment = verticalAlignment;
+ this.grabExcessHorizontalSpace = grabExcessHorizontalSpace;
+ this.grabExcessVerticalSpace = grabExcessVerticalSpace;
+ this.horizontalSpan = horizontalSpan;
+ this.verticalSpan = verticalSpan;
+ }
+
+ /**
+ * Constructs a new instance of GridData according to the parameters.
+ * A value of SWT.DEFAULT indicates that no minimum width or
+ * no minimum height is specified.
+ *
+ * @param width
+ * a minimum width for the column
+ * @param height
+ * a minimum height for the row
+ *
+ * @since 3.0
+ */
+ public GridData(int width, int height) {
+ super();
+ this.widthHint = width;
+ this.heightHint = height;
+ }
+
+ /**
+ * Creates a new Properties GridData from a SWT GridData
+ *
+ * @param layoutData
+ * The SWT GridData to copy
+ */
+ public GridData(org.eclipse.swt.layout.GridData layoutData) {
+ this.exclude = layoutData.exclude;
+ this.grabExcessHorizontalSpace = layoutData.grabExcessHorizontalSpace;
+ this.grabExcessVerticalSpace = layoutData.grabExcessVerticalSpace;
+ this.heightHint = layoutData.heightHint;
+ this.horizontalAlignment = layoutData.horizontalAlignment;
+ this.horizontalIndent = layoutData.horizontalIndent;
+ this.horizontalSpan = layoutData.horizontalSpan;
+ this.minimumHeight = layoutData.minimumHeight;
+ this.minimumWidth = layoutData.minimumWidth;
+ this.verticalAlignment = layoutData.verticalAlignment;
+ this.verticalIndent = layoutData.verticalIndent;
+ this.verticalSpan = layoutData.verticalSpan;
+ this.widthHint = layoutData.widthHint;
+
+ }
+
+ protected void computeSize(Control control, int wHint, int hHint, boolean flushCache) {
+ if(cacheWidth != -1 && cacheHeight != -1)
+ return;
+ if(wHint == this.widthHint && hHint == this.heightHint) {
+ if(defaultWidth == -1 || defaultHeight == -1 || wHint != defaultWhint || hHint != defaultHhint) {
+ Point size = control.computeSize(wHint, hHint, flushCache);
+ defaultWhint = wHint;
+ defaultHhint = hHint;
+ defaultWidth = size.x;
+ defaultHeight = size.y;
+ }
+ cacheWidth = defaultWidth;
+ cacheHeight = defaultHeight;
+ return;
+ }
+ if(currentWidth == -1 || currentHeight == -1 || wHint != currentWhint || hHint != currentHhint) {
+ Point size = control.computeSize(wHint, hHint, flushCache);
+ currentWhint = wHint;
+ currentHhint = hHint;
+ currentWidth = size.x;
+ currentHeight = size.y;
+ }
+ cacheWidth = currentWidth;
+ cacheHeight = currentHeight;
+ }
+
+ protected void flushCache() {
+ cacheWidth = cacheHeight = -1;
+ defaultWidth = defaultHeight = -1;
+ currentWidth = currentHeight = -1;
+ }
+
+ protected String getName() {
+ String string = getClass().getName();
+ int index = string.lastIndexOf('.');
+ if(index == -1)
+ return string;
+ return string.substring(index + 1, string.length());
+ }
+
+ /**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the GridData object
+ */
+ @Override
+ public String toString() {
+ String hAlign = ""; //$NON-NLS-1$
+ switch(horizontalAlignment) {
+ case SWT.FILL:
+ hAlign = "SWT.FILL"; //$NON-NLS-1$
+ break;
+ case SWT.BEGINNING:
+ hAlign = "SWT.BEGINNING"; //$NON-NLS-1$
+ break;
+ case SWT.LEFT:
+ hAlign = "SWT.LEFT"; //$NON-NLS-1$
+ break;
+ case SWT.END:
+ hAlign = "SWT.END"; //$NON-NLS-1$
+ break;
+ case END:
+ hAlign = "GridData.END"; //$NON-NLS-1$
+ break;
+ case SWT.RIGHT:
+ hAlign = "SWT.RIGHT"; //$NON-NLS-1$
+ break;
+ case SWT.CENTER:
+ hAlign = "SWT.CENTER"; //$NON-NLS-1$
+ break;
+ case CENTER:
+ hAlign = "GridData.CENTER"; //$NON-NLS-1$
+ break;
+ default:
+ hAlign = "Undefined " + horizontalAlignment; //$NON-NLS-1$
+ break;
+ }
+ String vAlign = ""; //$NON-NLS-1$
+ switch(verticalAlignment) {
+ case SWT.FILL:
+ vAlign = "SWT.FILL"; //$NON-NLS-1$
+ break;
+ case SWT.BEGINNING:
+ vAlign = "SWT.BEGINNING"; //$NON-NLS-1$
+ break;
+ case SWT.TOP:
+ vAlign = "SWT.TOP"; //$NON-NLS-1$
+ break;
+ case SWT.END:
+ vAlign = "SWT.END"; //$NON-NLS-1$
+ break;
+ case END:
+ vAlign = "GridData.END"; //$NON-NLS-1$
+ break;
+ case SWT.BOTTOM:
+ vAlign = "SWT.BOTTOM"; //$NON-NLS-1$
+ break;
+ case SWT.CENTER:
+ vAlign = "SWT.CENTER"; //$NON-NLS-1$
+ break;
+ case CENTER:
+ vAlign = "GridData.CENTER"; //$NON-NLS-1$
+ break;
+ default:
+ vAlign = "Undefined " + verticalAlignment; //$NON-NLS-1$
+ break;
+ }
+ String string = getName() + " {"; //$NON-NLS-1$
+ string += "horizontalAlignment=" + hAlign + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(horizontalIndent != 0)
+ string += "horizontalIndent=" + horizontalIndent + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(horizontalSpan != 1)
+ string += "horizontalSpan=" + horizontalSpan + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(grabExcessHorizontalSpace)
+ string += "grabExcessHorizontalSpace=" + grabExcessHorizontalSpace + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(widthHint != SWT.DEFAULT)
+ string += "widthHint=" + widthHint + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(minimumWidth != 0)
+ string += "minimumWidth=" + minimumWidth + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ string += "verticalAlignment=" + vAlign + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(verticalIndent != 0)
+ string += "verticalIndent=" + verticalIndent + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(verticalSpan != 1)
+ string += "verticalSpan=" + verticalSpan + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(grabExcessVerticalSpace)
+ string += "grabExcessVerticalSpace=" + grabExcessVerticalSpace + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(heightHint != SWT.DEFAULT)
+ string += "heightHint=" + heightHint + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(minimumHeight != 0)
+ string += "minimumHeight=" + minimumHeight + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ if(exclude)
+ string += "exclude=" + exclude + " "; //$NON-NLS-1$ //$NON-NLS-2$
+ string = string.trim();
+ string += "}"; //$NON-NLS-1$
+ return string;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/PropertiesLayout.java b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/PropertiesLayout.java
new file mode 100644
index 00000000000..f562d143ec8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.properties/src/org/eclipse/papyrus/properties/widgets/layout/PropertiesLayout.java
@@ -0,0 +1,962 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation (org.eclipse.swt.layout.GridLayout)
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Default values for GridData
+ *******************************************************************************/
+package org.eclipse.papyrus.properties.widgets.layout;
+
+import org.eclipse.papyrus.widgets.Activator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Layout;
+import org.eclipse.swt.widgets.Scrollable;
+
+/**
+ * Layout based on {@link org.eclipse.swt.layout.GridLayout} This layout is basically the same as GridLayout, except for default values (Especially
+ * the default GridData)
+ * If an element doesn't have a GridData, a default one is created, which takes as much horizontal space as possible.
+ * The goal is to enable a nice layout for the Property View, without requiring each Control to have an explicit GridData
+ * However, explicit GridData are still supported.
+ *
+ * Instances of this class lay out the control children of a <code>Composite</code> in a grid.
+ * <p>
+ * <code>GridLayout</code> has a number of configuration fields, and the controls it lays out can have an associated layout data object, called
+ * <code>GridData</code>. The power of <code>GridLayout</code> lies in the ability to configure <code>GridData</code> for each control in the layout.
+ * </p>
+ * <p>
+ * The following code creates a shell managed by a <code>GridLayout</code> with 3 columns:
+ *
+ * <pre>
+ * Display display = new Display();
+ * Shell shell = new Shell(display);
+ * GridLayout gridLayout = new GridLayout();
+ * gridLayout.numColumns = 3;
+ * shell.setLayout(gridLayout);
+ * </pre>
+ *
+ * The <code>numColumns</code> field is the most important field in a <code>GridLayout</code>. Widgets are laid out in columns from left to right, and
+ * a new row is created when <code>numColumns</code> + 1 controls are added to the <code>Composite<code>.
+ * </p>
+ *
+ * @see GridData
+ * @see <a href="http://www.eclipse.org/swt/snippets/#gridlayout">GridLayout snippets</a>
+ * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: LayoutExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * @see org.eclipse.swt.layout.GridLayout
+ */
+public class PropertiesLayout extends Layout {
+
+ /**
+ * numColumns specifies the number of cell columns in the layout.
+ * If numColumns has a value less than 1, the layout will not
+ * set the size and position of any controls.
+ *
+ * The default value is 1.
+ */
+ public int numColumns = 1;
+
+ /**
+ * The adjusted number of columns
+ * If the number of controls is lower than the number of columns,
+ * some columns will be removed to let these controls take all
+ * the available space
+ * GridData#horizontalSpan is taken into account
+ */
+ private int adjustedNumColumns = 1;
+
+ /**
+ * makeColumnsEqualWidth specifies whether all columns in the layout
+ * will be forced to have the same width.
+ *
+ * The default value is true.
+ */
+ public boolean makeColumnsEqualWidth = true;
+
+ /**
+ * marginWidth specifies the number of pixels of horizontal margin
+ * that will be placed along the left and right edges of the layout.
+ *
+ * The default value is 5.
+ */
+ public int marginWidth = 5;
+
+ /**
+ * marginHeight specifies the number of pixels of vertical margin
+ * that will be placed along the top and bottom edges of the layout.
+ *
+ * The default value is 0.
+ */
+ public int marginHeight = 0;
+
+ /**
+ * marginLeft specifies the number of pixels of horizontal margin
+ * that will be placed along the left edge of the layout.
+ *
+ * The default value is 0.
+ *
+ * @since 3.1
+ */
+ public int marginLeft = 0;
+
+ /**
+ * marginTop specifies the number of pixels of vertical margin
+ * that will be placed along the top edge of the layout.
+ *
+ * The default value is 0.
+ *
+ * @since 3.1
+ */
+ public int marginTop = 0;
+
+ /**
+ * marginRight specifies the number of pixels of horizontal margin
+ * that will be placed along the right edge of the layout.
+ *
+ * The default value is 0.
+ *
+ * @since 3.1
+ */
+ public int marginRight = 0;
+
+ /**
+ * marginBottom specifies the number of pixels of vertical margin
+ * that will be placed along the bottom edge of the layout.
+ *
+ * The default value is 0.
+ *
+ * @since 3.1
+ */
+ public int marginBottom = 0;
+
+ /**
+ * horizontalSpacing specifies the number of pixels between the right
+ * edge of one cell and the left edge of its neighbouring cell to
+ * the right.
+ *
+ * The default value is 5.
+ */
+ public int horizontalSpacing = 5;
+
+ /**
+ * verticalSpacing specifies the number of pixels between the bottom
+ * edge of one cell and the top edge of its neighbouring cell underneath.
+ *
+ * The default value is 0.
+ */
+ public int verticalSpacing = 0;
+
+ /**
+ * Constructs a new instance of this class.
+ */
+ public PropertiesLayout() {
+ this(false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param useMargins
+ * If false, there won't be any margin. If true, default margins
+ * will be used
+ */
+ public PropertiesLayout(boolean useMargins) {
+ if(!useMargins) {
+ marginHeight = 0;
+ marginWidth = 0;
+ }
+ }
+
+ /**
+ * Constructs a new instance of this class given the
+ * number of columns, and whether or not the columns
+ * should be forced to have the same width.
+ * If numColumns has a value less than 1, the layout will not
+ * set the size and position of any controls.
+ *
+ * @param numColumns
+ * the number of columns in the grid
+ * @param makeColumnsEqualWidth
+ * whether or not the columns will have equal width
+ *
+ * @since 2.0
+ */
+ public PropertiesLayout(int numColumns, boolean makeColumnsEqualWidth) {
+ this(numColumns, makeColumnsEqualWidth, false);
+ }
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param numColumns
+ * the number of columns in the grid
+ * @param makeColumnsEqualWidth
+ * whether or not the columns will have equal width
+ * @param useMargins
+ * If false, there won't be any margin. If true, default margins
+ * will be used
+ */
+ public PropertiesLayout(int numColumns, boolean makeColumnsEqualWidth, boolean useMargins) {
+ this(useMargins);
+ this.numColumns = numColumns;
+ this.makeColumnsEqualWidth = makeColumnsEqualWidth;
+ }
+
+ @Override
+ protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
+ Point size = layout(composite, false, 0, 0, wHint, hHint, flushCache);
+ if(wHint != SWT.DEFAULT) {
+ size.x = wHint;
+ }
+ if(hHint != SWT.DEFAULT) {
+ size.y = hHint;
+ }
+ return size;
+ }
+
+ @Override
+ protected boolean flushCache(Control control) {
+ GridData data = getLayoutData(control);
+ if(data != null) {
+ data.flushCache();
+ }
+ return true;
+ }
+
+ protected GridData getData(Control[][] grid, int row, int column, int rowCount, int columnCount, boolean first) {
+ Control control = grid[row][column];
+ if(control != null) {
+ GridData data = getLayoutData(control);
+ int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
+ int vSpan = Math.max(1, data.verticalSpan);
+ int i = first ? row + vSpan - 1 : row - vSpan + 1;
+ int j = first ? column + hSpan - 1 : column - hSpan + 1;
+ if(0 <= i && i < rowCount) {
+ if(0 <= j && j < columnCount) {
+ if(control == grid[i][j]) {
+ return data;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void layout(Composite composite, boolean flushCache) {
+ Rectangle rect = composite.getClientArea();
+ layout(composite, true, rect.x, rect.y, rect.width, rect.height, flushCache);
+ }
+
+ /**
+ * Removes columns when there are less controls than columns,
+ * to take all the available space
+ *
+ * @param composite
+ */
+ protected void adjustColumns(Composite composite) {
+ int numChildren = composite.getChildren().length;
+ adjustedNumColumns = numColumns;
+
+ if(numChildren < numColumns) {
+ int totalColumns = 0;
+
+ for(Control child : composite.getChildren()) {
+ GridData data = getLayoutData(child);
+ totalColumns += data.horizontalSpan;
+ }
+
+ if(totalColumns < numColumns) {
+ adjustedNumColumns = totalColumns;
+ }
+ }
+
+ if(adjustedNumColumns < 1) {
+ adjustedNumColumns = 1;
+ }
+ }
+
+ protected Point layout(Composite composite, boolean move, int x, int y, int width, int height, boolean flushCache) {
+ adjustColumns(composite);
+
+ Control[] children = composite.getChildren();
+ int count = 0;
+
+ for(int i = 0; i < children.length; i++) {
+ Control control = children[i];
+ GridData data = getLayoutData(control);
+ if(data == null || !data.exclude) {
+ children[count++] = children[i];
+ }
+ }
+
+ if(count == 0) {
+ return new Point(marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom);
+ }
+ for(int i = 0; i < count; i++) {
+ Control child = children[i];
+ GridData data = getLayoutData(child);
+ if(data == null) {
+ child.setLayoutData(data = new GridData());
+ }
+ if(flushCache) {
+ data.flushCache();
+ }
+ data.computeSize(child, data.widthHint, data.heightHint, flushCache);
+ if(data.grabExcessHorizontalSpace && data.minimumWidth > 0) {
+ if(data.cacheWidth < data.minimumWidth) {
+ int trim = 0;
+ //TEMPORARY CODE
+ if(child instanceof Scrollable) {
+ Rectangle rect = ((Scrollable)child).computeTrim(0, 0, 0, 0);
+ trim = rect.width;
+ } else {
+ trim = child.getBorderWidth() * 2;
+ }
+ data.cacheWidth = data.cacheHeight = SWT.DEFAULT;
+ data.computeSize(child, Math.max(0, data.minimumWidth - trim), data.heightHint, false);
+ }
+ }
+ if(data.grabExcessVerticalSpace && data.minimumHeight > 0) {
+ data.cacheHeight = Math.max(data.cacheHeight, data.minimumHeight);
+ }
+ }
+
+ /* Build the grid */
+ int row = 0, column = 0, rowCount = 0, columnCount = adjustedNumColumns;
+ Control[][] grid = new Control[4][columnCount];
+ for(int i = 0; i < count; i++) {
+ Control child = children[i];
+ GridData data = getLayoutData(child);
+ int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
+ int vSpan = Math.max(1, data.verticalSpan);
+ while(true) {
+ int lastRow = row + vSpan;
+ if(lastRow >= grid.length) {
+ Control[][] newGrid = new Control[lastRow + 4][columnCount];
+ System.arraycopy(grid, 0, newGrid, 0, grid.length);
+ grid = newGrid;
+ }
+ if(grid[row] == null) {
+ grid[row] = new Control[columnCount];
+ }
+ while(column < columnCount && grid[row][column] != null) {
+ column++;
+ }
+ int endCount = column + hSpan;
+ if(endCount <= columnCount) {
+ int index = column;
+ while(index < endCount && grid[row][index] == null) {
+ index++;
+ }
+ if(index == endCount) {
+ break;
+ }
+ column = index;
+ }
+ if(column + hSpan >= columnCount) {
+ column = 0;
+ row++;
+ }
+ }
+ for(int j = 0; j < vSpan; j++) {
+ if(grid[row + j] == null) {
+ grid[row + j] = new Control[columnCount];
+ }
+ for(int k = 0; k < hSpan; k++) {
+ grid[row + j][column + k] = child;
+ }
+ }
+ rowCount = Math.max(rowCount, row + vSpan);
+ column += hSpan;
+ }
+
+ /* Column widths */
+ int availableWidth = width - horizontalSpacing * (columnCount - 1) - (marginLeft + marginWidth * 2 + marginRight);
+ int expandCount = 0;
+ int[] widths = new int[columnCount];
+ int[] minWidths = new int[columnCount];
+ boolean[] expandColumn = new boolean[columnCount];
+ for(int j = 0; j < columnCount; j++) {
+ for(int i = 0; i < rowCount; i++) {
+ GridData data = getData(grid, i, j, rowCount, columnCount, true);
+ if(data != null) {
+ int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
+ if(hSpan == 1) {
+ int w = data.cacheWidth + data.horizontalIndent;
+ widths[j] = Math.max(widths[j], w);
+ if(data.grabExcessHorizontalSpace) {
+ if(!expandColumn[j]) {
+ expandCount++;
+ }
+ expandColumn[j] = true;
+ }
+ if(!data.grabExcessHorizontalSpace || data.minimumWidth != 0) {
+ w = !data.grabExcessHorizontalSpace || data.minimumWidth == SWT.DEFAULT ? data.cacheWidth : data.minimumWidth;
+ w += data.horizontalIndent;
+ minWidths[j] = Math.max(minWidths[j], w);
+ }
+ }
+ }
+ }
+ for(int i = 0; i < rowCount; i++) {
+ GridData data = getData(grid, i, j, rowCount, columnCount, false);
+ if(data != null) {
+ int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
+ if(hSpan > 1) {
+ int spanWidth = 0, spanMinWidth = 0, spanExpandCount = 0;
+ for(int k = 0; k < hSpan; k++) {
+ spanWidth += widths[j - k];
+ spanMinWidth += minWidths[j - k];
+ if(expandColumn[j - k]) {
+ spanExpandCount++;
+ }
+ }
+ if(data.grabExcessHorizontalSpace && spanExpandCount == 0) {
+ expandCount++;
+ expandColumn[j] = true;
+ }
+ int w = data.cacheWidth + data.horizontalIndent - spanWidth - (hSpan - 1) * horizontalSpacing;
+ if(w > 0) {
+ if(makeColumnsEqualWidth) {
+ int equalWidth = (w + spanWidth) / hSpan;
+ int remainder = (w + spanWidth) % hSpan, last = -1;
+ for(int k = 0; k < hSpan; k++) {
+ widths[last = j - k] = Math.max(equalWidth, widths[j - k]);
+ }
+ if(last > -1) {
+ widths[last] += remainder;
+ }
+ } else {
+ if(spanExpandCount == 0) {
+ widths[j] += w;
+ } else {
+ int delta = w / spanExpandCount;
+ int remainder = w % spanExpandCount, last = -1;
+ for(int k = 0; k < hSpan; k++) {
+ if(expandColumn[j - k]) {
+ widths[last = j - k] += delta;
+ }
+ }
+ if(last > -1) {
+ widths[last] += remainder;
+ }
+ }
+ }
+ }
+ if(!data.grabExcessHorizontalSpace || data.minimumWidth != 0) {
+ w = !data.grabExcessHorizontalSpace || data.minimumWidth == SWT.DEFAULT ? data.cacheWidth : data.minimumWidth;
+ w += data.horizontalIndent - spanMinWidth - (hSpan - 1) * horizontalSpacing;
+ if(w > 0) {
+ if(spanExpandCount == 0) {
+ minWidths[j] += w;
+ } else {
+ int delta = w / spanExpandCount;
+ int remainder = w % spanExpandCount, last = -1;
+ for(int k = 0; k < hSpan; k++) {
+ if(expandColumn[j - k]) {
+ minWidths[last = j - k] += delta;
+ }
+ }
+ if(last > -1) {
+ minWidths[last] += remainder;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(makeColumnsEqualWidth) {
+ int minColumnWidth = 0;
+ int columnWidth = 0;
+ for(int i = 0; i < columnCount; i++) {
+ minColumnWidth = Math.max(minColumnWidth, minWidths[i]);
+ columnWidth = Math.max(columnWidth, widths[i]);
+ }
+ columnWidth = width == SWT.DEFAULT || expandCount == 0 ? columnWidth : Math.max(minColumnWidth, availableWidth / columnCount);
+ for(int i = 0; i < columnCount; i++) {
+ expandColumn[i] = expandCount > 0;
+ widths[i] = columnWidth;
+ }
+ } else {
+ if(width != SWT.DEFAULT && expandCount > 0) {
+ int totalWidth = 0;
+ for(int i = 0; i < columnCount; i++) {
+ totalWidth += widths[i];
+ }
+ int c = expandCount;
+ int delta = (availableWidth - totalWidth) / c;
+ int remainder = (availableWidth - totalWidth) % c;
+ int last = -1;
+ while(totalWidth != availableWidth) {
+ for(int j = 0; j < columnCount; j++) {
+ if(expandColumn[j]) {
+ if(widths[j] + delta > minWidths[j]) {
+ widths[last = j] = widths[j] + delta;
+ } else {
+ widths[j] = minWidths[j];
+ expandColumn[j] = false;
+ c--;
+ }
+ }
+ }
+ if(last > -1) {
+ widths[last] += remainder;
+ }
+
+ for(int j = 0; j < columnCount; j++) {
+ for(int i = 0; i < rowCount; i++) {
+ GridData data = getData(grid, i, j, rowCount, columnCount, false);
+ if(data != null) {
+ int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
+ if(hSpan > 1) {
+ if(!data.grabExcessHorizontalSpace || data.minimumWidth != 0) {
+ int spanWidth = 0, spanExpandCount = 0;
+ for(int k = 0; k < hSpan; k++) {
+ spanWidth += widths[j - k];
+ if(expandColumn[j - k]) {
+ spanExpandCount++;
+ }
+ }
+ int w = !data.grabExcessHorizontalSpace || data.minimumWidth == SWT.DEFAULT ? data.cacheWidth : data.minimumWidth;
+ w += data.horizontalIndent - spanWidth - (hSpan - 1) * horizontalSpacing;
+ if(w > 0) {
+ if(spanExpandCount == 0) {
+ widths[j] += w;
+ } else {
+ int delta2 = w / spanExpandCount;
+ int remainder2 = w % spanExpandCount, last2 = -1;
+ for(int k = 0; k < hSpan; k++) {
+ if(expandColumn[j - k]) {
+ widths[last2 = j - k] += delta2;
+ }
+ }
+ if(last2 > -1) {
+ widths[last2] += remainder2;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(c == 0) {
+ break;
+ }
+ totalWidth = 0;
+ for(int i = 0; i < columnCount; i++) {
+ totalWidth += widths[i];
+ }
+ delta = (availableWidth - totalWidth) / c;
+ remainder = (availableWidth - totalWidth) % c;
+ last = -1;
+ }
+ }
+ }
+
+ /* Wrapping */
+ GridData[] flush = null;
+ int flushLength = 0;
+ if(width != SWT.DEFAULT) {
+ for(int j = 0; j < columnCount; j++) {
+ for(int i = 0; i < rowCount; i++) {
+ GridData data = getData(grid, i, j, rowCount, columnCount, false);
+ if(data != null) {
+ if(data.heightHint == SWT.DEFAULT) {
+ Control child = grid[i][j];
+ //TEMPORARY CODE
+ int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
+ int currentWidth = 0;
+ for(int k = 0; k < hSpan; k++) {
+ currentWidth += widths[j - k];
+ }
+ currentWidth += (hSpan - 1) * horizontalSpacing - data.horizontalIndent;
+ if((currentWidth != data.cacheWidth && data.horizontalAlignment == SWT.FILL) || (data.cacheWidth > currentWidth)) {
+ int trim = 0;
+ if(child instanceof Scrollable) {
+ Rectangle rect = ((Scrollable)child).computeTrim(0, 0, 0, 0);
+ trim = rect.width;
+ } else {
+ trim = child.getBorderWidth() * 2;
+ }
+ data.cacheWidth = data.cacheHeight = SWT.DEFAULT;
+ data.computeSize(child, Math.max(0, currentWidth - trim), data.heightHint, false);
+ if(data.grabExcessVerticalSpace && data.minimumHeight > 0) {
+ data.cacheHeight = Math.max(data.cacheHeight, data.minimumHeight);
+ }
+ if(flush == null) {
+ flush = new GridData[count];
+ }
+ flush[flushLength++] = data;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Row heights */
+ int availableHeight = height - verticalSpacing * (rowCount - 1) - (marginTop + marginHeight * 2 + marginBottom);
+ expandCount = 0;
+ int[] heights = new int[rowCount];
+ int[] minHeights = new int[rowCount];
+ boolean[] expandRow = new boolean[rowCount];
+ for(int i = 0; i < rowCount; i++) {
+ for(int j = 0; j < columnCount; j++) {
+ GridData data = getData(grid, i, j, rowCount, columnCount, true);
+ if(data != null) {
+ int vSpan = Math.max(1, Math.min(data.verticalSpan, rowCount));
+ if(vSpan == 1) {
+ int h = data.cacheHeight + data.verticalIndent;
+ heights[i] = Math.max(heights[i], h);
+ if(data.grabExcessVerticalSpace) {
+ if(!expandRow[i]) {
+ expandCount++;
+ }
+ expandRow[i] = true;
+ }
+ if(!data.grabExcessVerticalSpace || data.minimumHeight != 0) {
+ h = !data.grabExcessVerticalSpace || data.minimumHeight == SWT.DEFAULT ? data.cacheHeight : data.minimumHeight;
+ h += data.verticalIndent;
+ minHeights[i] = Math.max(minHeights[i], h);
+ }
+ }
+ }
+ }
+ for(int j = 0; j < columnCount; j++) {
+ GridData data = getData(grid, i, j, rowCount, columnCount, false);
+ if(data != null) {
+ int vSpan = Math.max(1, Math.min(data.verticalSpan, rowCount));
+ if(vSpan > 1) {
+ int spanHeight = 0, spanMinHeight = 0, spanExpandCount = 0;
+ for(int k = 0; k < vSpan; k++) {
+ spanHeight += heights[i - k];
+ spanMinHeight += minHeights[i - k];
+ if(expandRow[i - k]) {
+ spanExpandCount++;
+ }
+ }
+ if(data.grabExcessVerticalSpace && spanExpandCount == 0) {
+ expandCount++;
+ expandRow[i] = true;
+ }
+ int h = data.cacheHeight + data.verticalIndent - spanHeight - (vSpan - 1) * verticalSpacing;
+ if(h > 0) {
+ if(spanExpandCount == 0) {
+ heights[i] += h;
+ } else {
+ int delta = h / spanExpandCount;
+ int remainder = h % spanExpandCount, last = -1;
+ for(int k = 0; k < vSpan; k++) {
+ if(expandRow[i - k]) {
+ heights[last = i - k] += delta;
+ }
+ }
+ if(last > -1) {
+ heights[last] += remainder;
+ }
+ }
+ }
+ if(!data.grabExcessVerticalSpace || data.minimumHeight != 0) {
+ h = !data.grabExcessVerticalSpace || data.minimumHeight == SWT.DEFAULT ? data.cacheHeight : data.minimumHeight;
+ h += data.verticalIndent - spanMinHeight - (vSpan - 1) * verticalSpacing;
+ if(h > 0) {
+ if(spanExpandCount == 0) {
+ minHeights[i] += h;
+ } else {
+ int delta = h / spanExpandCount;
+ int remainder = h % spanExpandCount, last = -1;
+ for(int k = 0; k < vSpan; k++) {
+ if(expandRow[i - k]) {
+ minHeights[last = i - k] += delta;
+ }
+ }
+ if(last > -1) {
+ minHeights[last] += remainder;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(height != SWT.DEFAULT && expandCount > 0) {
+ int totalHeight = 0;
+ for(int i = 0; i < rowCount; i++) {
+ totalHeight += heights[i];
+ }
+ int c = expandCount;
+ int delta = (availableHeight - totalHeight) / c;
+ int remainder = (availableHeight - totalHeight) % c;
+ int last = -1;
+ while(totalHeight != availableHeight) {
+ for(int i = 0; i < rowCount; i++) {
+ if(expandRow[i]) {
+ if(heights[i] + delta > minHeights[i]) {
+ heights[last = i] = heights[i] + delta;
+ } else {
+ heights[i] = minHeights[i];
+ expandRow[i] = false;
<